aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/DocBook/libata.tmpl47
-rw-r--r--Documentation/feature-removal-schedule.txt19
-rw-r--r--Documentation/leds-class.txt71
-rw-r--r--Documentation/memory-barriers.txt1913
-rw-r--r--Documentation/networking/TODO18
-rw-r--r--Documentation/networking/bcm43xx.txt36
-rw-r--r--Documentation/powerpc/booting-without-of.txt5
-rw-r--r--MAINTAINERS1
-rw-r--r--arch/alpha/kernel/alpha_ksyms.c2
-rw-r--r--arch/alpha/kernel/core_marvel.c2
-rw-r--r--arch/arm/Kconfig10
-rw-r--r--arch/arm/Kconfig-nommu44
-rw-r--r--arch/arm/Makefile9
-rw-r--r--arch/arm/boot/compressed/head.S106
-rw-r--r--arch/arm/common/sharpsl_pm.c10
-rw-r--r--arch/arm/kernel/entry-armv.S2
-rw-r--r--arch/arm/kernel/head-common.S217
-rw-r--r--arch/arm/kernel/head-nommu.S83
-rw-r--r--arch/arm/kernel/head.S207
-rw-r--r--arch/arm/kernel/process.c1
-rw-r--r--arch/arm/kernel/signal.h2
-rw-r--r--arch/arm/kernel/traps.c9
-rw-r--r--arch/arm/mach-pxa/corgi.c11
-rw-r--r--arch/arm/mach-pxa/spitz.c11
-rw-r--r--arch/arm/mach-pxa/tosa.c9
-rw-r--r--arch/arm/mm/proc-xsc3.S1
-rw-r--r--arch/arm26/kernel/armksyms.c2
-rw-r--r--arch/frv/kernel/frv_ksyms.c2
-rw-r--r--arch/h8300/kernel/h8300_ksyms.c2
-rw-r--r--arch/i386/kernel/apic.c22
-rw-r--r--arch/i386/kernel/cpu/mcheck/mce.c4
-rw-r--r--arch/i386/kernel/io_apic.c2
-rw-r--r--arch/i386/kernel/process.c1
-rw-r--r--arch/i386/kernel/syscall_table.S2
-rw-r--r--arch/i386/kernel/traps.c2
-rw-r--r--arch/i386/kernel/vsyscall-sigreturn.S2
-rw-r--r--arch/ia64/kernel/entry.S1
-rw-r--r--arch/ia64/kernel/gate.lds.S1
-rw-r--r--arch/ia64/kernel/iosapic.c265
-rw-r--r--arch/ia64/kernel/palinfo.c8
-rw-r--r--arch/ia64/kernel/time.c2
-rw-r--r--arch/ia64/kernel/topology.c367
-rw-r--r--arch/ia64/kernel/vmlinux.lds.S18
-rw-r--r--arch/ia64/mm/init.c8
-rw-r--r--arch/ia64/mm/ioremap.c6
-rw-r--r--arch/ia64/mm/tlb.c12
-rw-r--r--arch/ia64/sn/kernel/sn2/sn_hwperf.c8
-rw-r--r--arch/m68k/kernel/m68k_ksyms.c1
-rw-r--r--arch/m68knommu/kernel/m68k_ksyms.c2
-rw-r--r--arch/mips/kernel/process.c1
-rw-r--r--arch/parisc/Kconfig6
-rw-r--r--arch/parisc/configs/712_defconfig160
-rw-r--r--arch/parisc/configs/a500_defconfig4
-rw-r--r--arch/parisc/configs/b180_defconfig12
-rw-r--r--arch/parisc/configs/c3000_defconfig252
-rw-r--r--arch/parisc/defconfig165
-rw-r--r--arch/parisc/kernel/cache.c6
-rw-r--r--arch/parisc/kernel/entry.S45
-rw-r--r--arch/parisc/kernel/pacache.S4
-rw-r--r--arch/parisc/kernel/parisc_ksyms.c19
-rw-r--r--arch/parisc/kernel/pdc_chassis.c5
-rw-r--r--arch/parisc/kernel/perf.c2
-rw-r--r--arch/parisc/kernel/syscall_table.S2
-rw-r--r--arch/parisc/lib/iomap.c4
-rw-r--r--arch/parisc/mm/init.c7
-rw-r--r--arch/parisc/mm/ioremap.c54
-rw-r--r--arch/powerpc/Kconfig4
-rw-r--r--arch/powerpc/Kconfig.debug5
-rw-r--r--arch/powerpc/Makefile7
-rw-r--r--arch/powerpc/configs/cell_defconfig133
-rw-r--r--arch/powerpc/configs/mpc8540_ads_defconfig43
-rw-r--r--arch/powerpc/kernel/Makefile11
-rw-r--r--arch/powerpc/kernel/asm-offsets.c2
-rw-r--r--arch/powerpc/kernel/cpu_setup_6xx.S (renamed from arch/ppc/kernel/cpu_setup_6xx.S)0
-rw-r--r--arch/powerpc/kernel/crash_dump.c4
-rw-r--r--arch/powerpc/kernel/entry_32.S8
-rw-r--r--arch/powerpc/kernel/entry_64.S6
-rw-r--r--arch/powerpc/kernel/firmware.c4
-rw-r--r--arch/powerpc/kernel/head_64.S32
-rw-r--r--arch/powerpc/kernel/idle.c (renamed from arch/powerpc/kernel/idle_64.c)79
-rw-r--r--arch/powerpc/kernel/idle_6xx.S18
-rw-r--r--arch/powerpc/kernel/idle_power4.S38
-rw-r--r--arch/powerpc/kernel/irq.c2
-rw-r--r--arch/powerpc/kernel/l2cr_6xx.S (renamed from arch/ppc/kernel/l2cr.S)0
-rw-r--r--arch/powerpc/kernel/legacy_serial.c42
-rw-r--r--arch/powerpc/kernel/lparcfg.c4
-rw-r--r--arch/powerpc/kernel/module_32.c (renamed from arch/ppc/kernel/module.c)0
-rw-r--r--arch/powerpc/kernel/nvram_64.c7
-rw-r--r--arch/powerpc/kernel/paca.c21
-rw-r--r--arch/powerpc/kernel/pci_32.c4
-rw-r--r--arch/powerpc/kernel/pci_64.c1
-rw-r--r--arch/powerpc/kernel/perfmon_fsl_booke.c (renamed from arch/ppc/kernel/perfmon_fsl_booke.c)0
-rw-r--r--arch/powerpc/kernel/proc_ppc64.c3
-rw-r--r--arch/powerpc/kernel/process.c12
-rw-r--r--arch/powerpc/kernel/prom.c154
-rw-r--r--arch/powerpc/kernel/prom_init.c68
-rw-r--r--arch/powerpc/kernel/rtas-proc.c2
-rw-r--r--arch/powerpc/kernel/rtas.c8
-rw-r--r--arch/powerpc/kernel/setup-common.c70
-rw-r--r--arch/powerpc/kernel/setup_32.c75
-rw-r--r--arch/powerpc/kernel/setup_64.c78
-rw-r--r--arch/powerpc/kernel/signal_32.c1
-rw-r--r--arch/powerpc/kernel/signal_64.c3
-rw-r--r--arch/powerpc/kernel/smp.c2
-rw-r--r--arch/powerpc/kernel/swsusp_32.S (renamed from arch/ppc/kernel/swsusp.S)0
-rw-r--r--arch/powerpc/kernel/syscalls.c1
-rw-r--r--arch/powerpc/kernel/sysfs.c12
-rw-r--r--arch/powerpc/kernel/tau_6xx.c (renamed from arch/ppc/kernel/temp.c)0
-rw-r--r--arch/powerpc/kernel/time.c4
-rw-r--r--arch/powerpc/kernel/traps.c35
-rw-r--r--arch/powerpc/kernel/vdso.c9
-rw-r--r--arch/powerpc/kernel/vdso32/sigtramp.S2
-rw-r--r--arch/powerpc/kernel/vdso64/sigtramp.S2
-rw-r--r--arch/powerpc/kernel/vmlinux.lds.S381
-rw-r--r--arch/powerpc/lib/sstep.c2
-rw-r--r--arch/powerpc/math-emu/Makefile (renamed from arch/ppc/math-emu/Makefile)0
-rw-r--r--arch/powerpc/math-emu/double.h (renamed from arch/ppc/math-emu/double.h)0
-rw-r--r--arch/powerpc/math-emu/fabs.c (renamed from arch/ppc/math-emu/fabs.c)0
-rw-r--r--arch/powerpc/math-emu/fadd.c (renamed from arch/ppc/math-emu/fadd.c)0
-rw-r--r--arch/powerpc/math-emu/fadds.c (renamed from arch/ppc/math-emu/fadds.c)0
-rw-r--r--arch/powerpc/math-emu/fcmpo.c (renamed from arch/ppc/math-emu/fcmpo.c)0
-rw-r--r--arch/powerpc/math-emu/fcmpu.c (renamed from arch/ppc/math-emu/fcmpu.c)0
-rw-r--r--arch/powerpc/math-emu/fctiw.c (renamed from arch/ppc/math-emu/fctiw.c)0
-rw-r--r--arch/powerpc/math-emu/fctiwz.c (renamed from arch/ppc/math-emu/fctiwz.c)0
-rw-r--r--arch/powerpc/math-emu/fdiv.c (renamed from arch/ppc/math-emu/fdiv.c)0
-rw-r--r--arch/powerpc/math-emu/fdivs.c (renamed from arch/ppc/math-emu/fdivs.c)0
-rw-r--r--arch/powerpc/math-emu/fmadd.c (renamed from arch/ppc/math-emu/fmadd.c)0
-rw-r--r--arch/powerpc/math-emu/fmadds.c (renamed from arch/ppc/math-emu/fmadds.c)0
-rw-r--r--arch/powerpc/math-emu/fmr.c (renamed from arch/ppc/math-emu/fmr.c)0
-rw-r--r--arch/powerpc/math-emu/fmsub.c (renamed from arch/ppc/math-emu/fmsub.c)0
-rw-r--r--arch/powerpc/math-emu/fmsubs.c (renamed from arch/ppc/math-emu/fmsubs.c)0
-rw-r--r--arch/powerpc/math-emu/fmul.c (renamed from arch/ppc/math-emu/fmul.c)0
-rw-r--r--arch/powerpc/math-emu/fmuls.c (renamed from arch/ppc/math-emu/fmuls.c)0
-rw-r--r--arch/powerpc/math-emu/fnabs.c (renamed from arch/ppc/math-emu/fnabs.c)0
-rw-r--r--arch/powerpc/math-emu/fneg.c (renamed from arch/ppc/math-emu/fneg.c)0
-rw-r--r--arch/powerpc/math-emu/fnmadd.c (renamed from arch/ppc/math-emu/fnmadd.c)0
-rw-r--r--arch/powerpc/math-emu/fnmadds.c (renamed from arch/ppc/math-emu/fnmadds.c)0
-rw-r--r--arch/powerpc/math-emu/fnmsub.c (renamed from arch/ppc/math-emu/fnmsub.c)0
-rw-r--r--arch/powerpc/math-emu/fnmsubs.c (renamed from arch/ppc/math-emu/fnmsubs.c)0
-rw-r--r--arch/powerpc/math-emu/fres.c (renamed from arch/ppc/math-emu/fres.c)0
-rw-r--r--arch/powerpc/math-emu/frsp.c (renamed from arch/ppc/math-emu/frsp.c)0
-rw-r--r--arch/powerpc/math-emu/frsqrte.c (renamed from arch/ppc/math-emu/frsqrte.c)0
-rw-r--r--arch/powerpc/math-emu/fsel.c (renamed from arch/ppc/math-emu/fsel.c)0
-rw-r--r--arch/powerpc/math-emu/fsqrt.c (renamed from arch/ppc/math-emu/fsqrt.c)0
-rw-r--r--arch/powerpc/math-emu/fsqrts.c (renamed from arch/ppc/math-emu/fsqrts.c)0
-rw-r--r--arch/powerpc/math-emu/fsub.c (renamed from arch/ppc/math-emu/fsub.c)0
-rw-r--r--arch/powerpc/math-emu/fsubs.c (renamed from arch/ppc/math-emu/fsubs.c)0
-rw-r--r--arch/powerpc/math-emu/lfd.c (renamed from arch/ppc/math-emu/lfd.c)0
-rw-r--r--arch/powerpc/math-emu/lfs.c (renamed from arch/ppc/math-emu/lfs.c)0
-rw-r--r--arch/powerpc/math-emu/math.c (renamed from arch/ppc/math-emu/math.c)0
-rw-r--r--arch/powerpc/math-emu/mcrfs.c (renamed from arch/ppc/math-emu/mcrfs.c)0
-rw-r--r--arch/powerpc/math-emu/mffs.c (renamed from arch/ppc/math-emu/mffs.c)0
-rw-r--r--arch/powerpc/math-emu/mtfsb0.c (renamed from arch/ppc/math-emu/mtfsb0.c)0
-rw-r--r--arch/powerpc/math-emu/mtfsb1.c (renamed from arch/ppc/math-emu/mtfsb1.c)0
-rw-r--r--arch/powerpc/math-emu/mtfsf.c (renamed from arch/ppc/math-emu/mtfsf.c)0
-rw-r--r--arch/powerpc/math-emu/mtfsfi.c (renamed from arch/ppc/math-emu/mtfsfi.c)0
-rw-r--r--arch/powerpc/math-emu/op-1.h (renamed from arch/ppc/math-emu/op-1.h)0
-rw-r--r--arch/powerpc/math-emu/op-2.h (renamed from arch/ppc/math-emu/op-2.h)0
-rw-r--r--arch/powerpc/math-emu/op-4.h (renamed from arch/ppc/math-emu/op-4.h)0
-rw-r--r--arch/powerpc/math-emu/op-common.h (renamed from arch/ppc/math-emu/op-common.h)0
-rw-r--r--arch/powerpc/math-emu/sfp-machine.h (renamed from arch/ppc/math-emu/sfp-machine.h)0
-rw-r--r--arch/powerpc/math-emu/single.h (renamed from arch/ppc/math-emu/single.h)0
-rw-r--r--arch/powerpc/math-emu/soft-fp.h (renamed from arch/ppc/math-emu/soft-fp.h)0
-rw-r--r--arch/powerpc/math-emu/stfd.c (renamed from arch/ppc/math-emu/stfd.c)0
-rw-r--r--arch/powerpc/math-emu/stfiwx.c (renamed from arch/ppc/math-emu/stfiwx.c)0
-rw-r--r--arch/powerpc/math-emu/stfs.c (renamed from arch/ppc/math-emu/stfs.c)0
-rw-r--r--arch/powerpc/math-emu/types.c (renamed from arch/ppc/math-emu/types.c)0
-rw-r--r--arch/powerpc/math-emu/udivmodti4.c (renamed from arch/ppc/math-emu/udivmodti4.c)0
-rw-r--r--arch/powerpc/mm/fault.c30
-rw-r--r--arch/powerpc/mm/hash_utils_64.c7
-rw-r--r--arch/powerpc/mm/mem.c2
-rw-r--r--arch/powerpc/mm/numa.c2
-rw-r--r--arch/powerpc/mm/pgtable_32.c6
-rw-r--r--arch/powerpc/mm/stab.c2
-rw-r--r--arch/powerpc/oprofile/Makefile2
-rw-r--r--arch/powerpc/oprofile/backtrace.c126
-rw-r--r--arch/powerpc/oprofile/common.c9
-rw-r--r--arch/powerpc/oprofile/op_model_7450.c4
-rw-r--r--arch/powerpc/oprofile/op_model_fsl_booke.c4
-rw-r--r--arch/powerpc/oprofile/op_model_power4.c45
-rw-r--r--arch/powerpc/oprofile/op_model_rs64.c5
-rw-r--r--arch/powerpc/platforms/85xx/Kconfig1
-rw-r--r--arch/powerpc/platforms/cell/Kconfig5
-rw-r--r--arch/powerpc/platforms/cell/Makefile10
-rw-r--r--arch/powerpc/platforms/cell/interrupt.c133
-rw-r--r--arch/powerpc/platforms/cell/interrupt.h2
-rw-r--r--arch/powerpc/platforms/cell/iommu.c16
-rw-r--r--arch/powerpc/platforms/cell/pervasive.c4
-rw-r--r--arch/powerpc/platforms/cell/setup.c11
-rw-r--r--arch/powerpc/platforms/cell/spider-pic.c108
-rw-r--r--arch/powerpc/platforms/cell/spu_base.c17
-rw-r--r--arch/powerpc/platforms/cell/spu_callbacks.c345
-rw-r--r--arch/powerpc/platforms/cell/spufs/backing_ops.c47
-rw-r--r--arch/powerpc/platforms/cell/spufs/context.c24
-rw-r--r--arch/powerpc/platforms/cell/spufs/file.c523
-rw-r--r--arch/powerpc/platforms/cell/spufs/hw_ops.c57
-rw-r--r--arch/powerpc/platforms/cell/spufs/inode.c6
-rw-r--r--arch/powerpc/platforms/cell/spufs/run.c91
-rw-r--r--arch/powerpc/platforms/cell/spufs/sched.c2
-rw-r--r--arch/powerpc/platforms/cell/spufs/spufs.h28
-rw-r--r--arch/powerpc/platforms/cell/spufs/switch.c3
-rw-r--r--arch/powerpc/platforms/chrp/chrp.h2
-rw-r--r--arch/powerpc/platforms/chrp/setup.c77
-rw-r--r--arch/powerpc/platforms/iseries/setup.c13
-rw-r--r--arch/powerpc/platforms/maple/setup.c10
-rw-r--r--arch/powerpc/platforms/powermac/bootx_init.c6
-rw-r--r--arch/powerpc/platforms/powermac/feature.c2
-rw-r--r--arch/powerpc/platforms/powermac/low_i2c.c3
-rw-r--r--arch/powerpc/platforms/powermac/nvram.c14
-rw-r--r--arch/powerpc/platforms/powermac/pci.c5
-rw-r--r--arch/powerpc/platforms/powermac/pfunc_base.c2
-rw-r--r--arch/powerpc/platforms/powermac/setup.c74
-rw-r--r--arch/powerpc/platforms/powermac/time.c4
-rw-r--r--arch/powerpc/platforms/powermac/udbg_scc.c2
-rw-r--r--arch/powerpc/platforms/pseries/eeh.c2
-rw-r--r--arch/powerpc/platforms/pseries/eeh_driver.c16
-rw-r--r--arch/powerpc/platforms/pseries/firmware.c2
-rw-r--r--arch/powerpc/platforms/pseries/hvconsole.c5
-rw-r--r--arch/powerpc/platforms/pseries/pci.c2
-rw-r--r--arch/powerpc/platforms/pseries/pci_dlpar.c11
-rw-r--r--arch/powerpc/platforms/pseries/ras.c2
-rw-r--r--arch/powerpc/platforms/pseries/reconfig.c5
-rw-r--r--arch/powerpc/platforms/pseries/rtasd.c3
-rw-r--r--arch/powerpc/platforms/pseries/setup.c231
-rw-r--r--arch/powerpc/platforms/pseries/xics.c4
-rw-r--r--arch/ppc/Kconfig93
-rw-r--r--arch/ppc/Kconfig.debug7
-rw-r--r--arch/ppc/Makefile6
-rw-r--r--arch/ppc/boot/Makefile7
-rw-r--r--arch/ppc/boot/openfirmware/Makefile109
-rw-r--r--arch/ppc/boot/openfirmware/chrpmain.c101
-rw-r--r--arch/ppc/boot/openfirmware/common.c146
-rw-r--r--arch/ppc/boot/openfirmware/dummy.c4
-rw-r--r--arch/ppc/boot/openfirmware/misc.S67
-rw-r--r--arch/ppc/boot/openfirmware/start.c172
-rw-r--r--arch/ppc/boot/simple/mpc10x_memory.c4
-rw-r--r--arch/ppc/boot/simple/relocate.S2
-rw-r--r--arch/ppc/boot/utils/addnote.c175
-rw-r--r--arch/ppc/boot/utils/hack-coff.c84
-rw-r--r--arch/ppc/boot/utils/mknote.c44
-rw-r--r--arch/ppc/configs/ibmchrp_defconfig875
-rw-r--r--arch/ppc/configs/pmac_defconfig1591
-rw-r--r--arch/ppc/configs/power3_defconfig1035
-rw-r--r--arch/ppc/configs/prep_defconfig (renamed from arch/ppc/configs/common_defconfig)0
-rw-r--r--arch/ppc/kernel/Makefile28
-rw-r--r--arch/ppc/kernel/entry.S60
-rw-r--r--arch/ppc/kernel/head.S183
-rw-r--r--arch/ppc/kernel/idle.c112
-rw-r--r--arch/ppc/kernel/idle_6xx.S233
-rw-r--r--arch/ppc/kernel/idle_power4.S91
-rw-r--r--arch/ppc/kernel/pci.c396
-rw-r--r--arch/ppc/kernel/ppc_htab.c8
-rw-r--r--arch/ppc/kernel/ppc_ksyms.c26
-rw-r--r--arch/ppc/kernel/setup.c256
-rw-r--r--arch/ppc/kernel/smp.c2
-rw-r--r--arch/ppc/lib/strcase.c3
-rw-r--r--arch/ppc/mm/fault.c30
-rw-r--r--arch/ppc/mm/hashtable.S34
-rw-r--r--arch/ppc/mm/init.c13
-rw-r--r--arch/ppc/mm/mmu_context.c2
-rw-r--r--arch/ppc/mm/pgtable.c8
-rw-r--r--arch/ppc/mm/ppc_mmu.c28
-rw-r--r--arch/ppc/platforms/Makefile12
-rw-r--r--arch/ppc/platforms/chrp_nvram.c83
-rw-r--r--arch/ppc/platforms/chrp_pci.c309
-rw-r--r--arch/ppc/platforms/chrp_pegasos_eth.c211
-rw-r--r--arch/ppc/platforms/chrp_setup.c669
-rw-r--r--arch/ppc/platforms/chrp_smp.c99
-rw-r--r--arch/ppc/platforms/chrp_time.c235
-rw-r--r--arch/ppc/platforms/lite5200.c71
-rw-r--r--arch/ppc/platforms/prep_setup.c12
-rw-r--r--arch/ppc/syslib/Makefile2
-rw-r--r--arch/ppc/syslib/mpc52xx_pci.c3
-rw-r--r--arch/ppc/syslib/mpc52xx_setup.c48
-rw-r--r--arch/ppc/syslib/open_pic.c2
-rw-r--r--arch/ppc/syslib/prom.c1429
-rw-r--r--arch/ppc/syslib/prom_init.c1011
-rw-r--r--arch/ppc/xmon/start.c2
-rw-r--r--arch/s390/kernel/smp.c6
-rw-r--r--arch/sh/kernel/cpu/init.c2
-rw-r--r--arch/sh/kernel/setup.c2
-rw-r--r--arch/um/Kconfig3
-rw-r--r--arch/um/Makefile7
-rw-r--r--arch/um/Makefile-x86_642
-rw-r--r--arch/um/drivers/daemon_kern.c13
-rw-r--r--arch/um/drivers/harddog_kern.c8
-rw-r--r--arch/um/drivers/hostaudio_kern.c10
-rw-r--r--arch/um/drivers/mcast_kern.c13
-rw-r--r--arch/um/drivers/mconsole_kern.c140
-rw-r--r--arch/um/drivers/pcap_kern.c13
-rw-r--r--arch/um/drivers/slip_kern.c13
-rw-r--r--arch/um/drivers/slirp_kern.c15
-rw-r--r--arch/um/drivers/ubd_kern.c2
-rw-r--r--arch/um/include/kern_util.h6
-rw-r--r--arch/um/include/line.h18
-rw-r--r--arch/um/include/mem_user.h1
-rw-r--r--arch/um/include/os.h10
-rw-r--r--arch/um/include/sysdep-i386/checksum.h5
-rw-r--r--arch/um/include/sysdep-i386/ptrace.h5
-rw-r--r--arch/um/include/sysdep-i386/tls.h32
-rw-r--r--arch/um/include/sysdep-x86_64/tls.h29
-rw-r--r--arch/um/include/user_util.h5
-rw-r--r--arch/um/kernel/exec_kern.c16
-rw-r--r--arch/um/kernel/mem.c2
-rw-r--r--arch/um/kernel/process_kern.c26
-rw-r--r--arch/um/kernel/ptrace.c44
-rw-r--r--arch/um/kernel/skas/process_kern.c11
-rw-r--r--arch/um/kernel/syscall_kern.c4
-rw-r--r--arch/um/kernel/trap_kern.c8
-rw-r--r--arch/um/kernel/tt/process_kern.c10
-rw-r--r--arch/um/os-Linux/Makefile7
-rw-r--r--arch/um/os-Linux/drivers/ethertap_kern.c13
-rw-r--r--arch/um/os-Linux/drivers/tuntap_kern.c13
-rw-r--r--arch/um/os-Linux/mem.c27
-rw-r--r--arch/um/os-Linux/process.c44
-rw-r--r--arch/um/os-Linux/start_up.c20
-rw-r--r--arch/um/os-Linux/sys-i386/Makefile2
-rw-r--r--arch/um/os-Linux/sys-i386/tls.c33
-rw-r--r--arch/um/os-Linux/tls.c76
-rw-r--r--arch/um/scripts/Makefile.rules26
-rw-r--r--arch/um/scripts/Makefile.unmap22
-rw-r--r--arch/um/sys-i386/Makefile23
-rw-r--r--arch/um/sys-i386/ptrace.c45
-rw-r--r--arch/um/sys-i386/ptrace_user.c10
-rw-r--r--arch/um/sys-i386/signal.c48
-rw-r--r--arch/um/sys-i386/sys_call_table.S2
-rw-r--r--arch/um/sys-i386/syscalls.c16
-rw-r--r--arch/um/sys-i386/tls.c384
-rw-r--r--arch/um/sys-x86_64/Makefile34
-rw-r--r--arch/um/sys-x86_64/tls.c14
-rw-r--r--arch/x86_64/ia32/vsyscall-sigreturn.S23
-rw-r--r--arch/x86_64/kernel/apic.c14
-rw-r--r--arch/x86_64/kernel/early_printk.c2
-rw-r--r--arch/x86_64/kernel/mce.c4
-rw-r--r--arch/x86_64/kernel/pmtimer.c2
-rw-r--r--arch/x86_64/kernel/setup.c2
-rw-r--r--arch/x86_64/kernel/setup64.c4
-rw-r--r--arch/x86_64/kernel/smpboot.c2
-rw-r--r--arch/x86_64/kernel/time.c4
-rw-r--r--arch/x86_64/kernel/traps.c4
-rw-r--r--arch/x86_64/kernel/x8664_ksyms.c2
-rw-r--r--arch/x86_64/mm/fault.c2
-rw-r--r--arch/xtensa/kernel/xtensa_ksyms.c2
-rw-r--r--block/Kconfig8
-rw-r--r--block/elevator.c2
-rw-r--r--block/genhd.c103
-rw-r--r--drivers/Kconfig2
-rw-r--r--drivers/Makefile1
-rw-r--r--drivers/acpi/ec.c4
-rw-r--r--drivers/block/amiflop.c1
-rw-r--r--drivers/char/Kconfig17
-rw-r--r--drivers/char/Makefile4
-rw-r--r--drivers/char/drm/drmP.h16
-rw-r--r--drivers/char/drm/drm_bufs.c20
-rw-r--r--drivers/char/drm/drm_dma.c4
-rw-r--r--drivers/char/drm/drm_memory.c59
-rw-r--r--drivers/char/drm/drm_memory_debug.h70
-rw-r--r--drivers/char/drm/drm_pci.c29
-rw-r--r--drivers/char/drm/drm_pciids.h116
-rw-r--r--drivers/char/drm/i915_dma.c2
-rw-r--r--drivers/char/drm/i915_irq.c2
-rw-r--r--drivers/char/drm/r300_cmdbuf.c86
-rw-r--r--drivers/char/drm/r300_reg.h39
-rw-r--r--drivers/char/drm/radeon_cp.c151
-rw-r--r--drivers/char/drm/radeon_drm.h5
-rw-r--r--drivers/char/drm/radeon_drv.h25
-rw-r--r--drivers/char/drm/radeon_state.c105
-rw-r--r--drivers/char/drm/sis_mm.c2
-rw-r--r--drivers/char/generic_nvram.c5
-rw-r--r--drivers/char/hvc_console.c101
-rw-r--r--drivers/char/hvc_console.h63
-rw-r--r--drivers/char/hvc_rtas.c138
-rw-r--r--drivers/char/hvc_vio.c11
-rw-r--r--drivers/char/hvcs.c1
-rw-r--r--drivers/char/ipmi/ipmi_devintf.c18
-rw-r--r--drivers/char/ipmi/ipmi_kcs_sm.c8
-rw-r--r--drivers/char/ipmi/ipmi_msghandler.c80
-rw-r--r--drivers/char/ipmi/ipmi_poweroff.c2
-rw-r--r--drivers/char/ipmi/ipmi_si_intf.c85
-rw-r--r--drivers/char/ipmi/ipmi_watchdog.c61
-rw-r--r--drivers/char/istallion.c32
-rw-r--r--drivers/char/stallion.c46
-rw-r--r--drivers/char/tty_io.c2
-rw-r--r--drivers/char/vt.c4
-rw-r--r--drivers/edac/Kconfig2
-rw-r--r--drivers/ide/ide-disk.c3
-rw-r--r--drivers/ide/ide-taskfile.c8
-rw-r--r--drivers/ide/pci/via82cxxx.c2
-rw-r--r--drivers/ide/ppc/pmac.c2
-rw-r--r--drivers/ieee1394/ohci1394.c4
-rw-r--r--drivers/infiniband/core/mad.c112
-rw-r--r--drivers/infiniband/core/mad_priv.h3
-rw-r--r--drivers/infiniband/core/mad_rmpp.c54
-rw-r--r--drivers/infiniband/core/user_mad.c30
-rw-r--r--drivers/infiniband/hw/mthca/mthca_av.c2
-rw-r--r--drivers/infiniband/hw/mthca/mthca_cq.c2
-rw-r--r--drivers/infiniband/hw/mthca/mthca_eq.c6
-rw-r--r--drivers/infiniband/hw/mthca/mthca_mad.c2
-rw-r--r--drivers/infiniband/hw/mthca/mthca_mcg.c2
-rw-r--r--drivers/infiniband/hw/mthca/mthca_mr.c4
-rw-r--r--drivers/infiniband/hw/mthca/mthca_pd.c2
-rw-r--r--drivers/infiniband/hw/mthca/mthca_qp.c2
-rw-r--r--drivers/infiniband/hw/mthca/mthca_srq.c4
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_main.c2
-rw-r--r--drivers/infiniband/ulp/srp/ib_srp.c4
-rw-r--r--drivers/input/keyboard/hil_kbd.c56
-rw-r--r--drivers/input/keyboard/hilkbd.c53
-rw-r--r--drivers/input/mouse/hil_ptr.c90
-rw-r--r--drivers/input/serio/gscps2.c4
-rw-r--r--drivers/isdn/sc/ioctl.c9
-rw-r--r--drivers/leds/Kconfig77
-rw-r--r--drivers/leds/Makefile16
-rw-r--r--drivers/leds/led-class.c167
-rw-r--r--drivers/leds/led-core.c25
-rw-r--r--drivers/leds/led-triggers.c239
-rw-r--r--drivers/leds/leds-corgi.c121
-rw-r--r--drivers/leds/leds-ixp4xx-gpio.c215
-rw-r--r--drivers/leds/leds-locomo.c95
-rw-r--r--drivers/leds/leds-spitz.c125
-rw-r--r--drivers/leds/leds-tosa.c131
-rw-r--r--drivers/leds/leds.h44
-rw-r--r--drivers/leds/ledtrig-ide-disk.c62
-rw-r--r--drivers/leds/ledtrig-timer.c170
-rw-r--r--drivers/macintosh/adb.c3
-rw-r--r--drivers/macintosh/adbhid.c4
-rw-r--r--drivers/macintosh/mediabay.c4
-rw-r--r--drivers/md/md.c8
-rw-r--r--drivers/md/raid1.c13
-rw-r--r--drivers/md/raid6main.c2
-rw-r--r--drivers/media/video/cpia_pp.c2
-rw-r--r--drivers/media/video/planb.c2
-rw-r--r--drivers/mmc/Kconfig11
-rw-r--r--drivers/mmc/Makefile5
-rw-r--r--drivers/mmc/au1xmmc.c19
-rw-r--r--drivers/mmc/mmc.c19
-rw-r--r--drivers/mmc/mmci.c4
-rw-r--r--drivers/mmc/omap.c1226
-rw-r--r--drivers/mmc/omap.h55
-rw-r--r--drivers/mmc/pxamci.c24
-rw-r--r--drivers/mmc/sdhci.c6
-rw-r--r--drivers/mmc/wbsd.c9
-rw-r--r--drivers/mtd/chips/amd_flash.c4
-rw-r--r--drivers/mtd/chips/jedec_probe.c19
-rw-r--r--drivers/mtd/chips/sharp.c7
-rw-r--r--drivers/mtd/cmdlinepart.c7
-rw-r--r--drivers/mtd/devices/blkmtd.c13
-rw-r--r--drivers/mtd/devices/block2mtd.c13
-rw-r--r--drivers/mtd/devices/doc2000.c37
-rw-r--r--drivers/mtd/devices/lart.c10
-rw-r--r--drivers/mtd/devices/m25p80.c2
-rw-r--r--drivers/mtd/devices/ms02-nv.c2
-rw-r--r--drivers/mtd/inftlcore.c7
-rw-r--r--drivers/mtd/maps/alchemy-flash.c4
-rw-r--r--drivers/mtd/maps/cfi_flagadm.c2
-rw-r--r--drivers/mtd/maps/dbox2-flash.c2
-rw-r--r--drivers/mtd/maps/dilnetpc.c4
-rw-r--r--drivers/mtd/maps/dmv182.c2
-rw-r--r--drivers/mtd/maps/h720x-flash.c2
-rw-r--r--drivers/mtd/maps/netsc520.c4
-rw-r--r--drivers/mtd/maps/nettel.c3
-rw-r--r--drivers/mtd/maps/ocotea.c6
-rw-r--r--drivers/mtd/maps/pci.c3
-rw-r--r--drivers/mtd/maps/pcmciamtd.c2
-rw-r--r--drivers/mtd/maps/redwood.c3
-rw-r--r--drivers/mtd/maps/sbc8240.c8
-rw-r--r--drivers/mtd/maps/sc520cdp.c2
-rw-r--r--drivers/mtd/maps/scx200_docflash.c2
-rw-r--r--drivers/mtd/maps/sharpsl-flash.c4
-rw-r--r--drivers/mtd/maps/ts5500_flash.c2
-rw-r--r--drivers/mtd/maps/uclinux.c2
-rw-r--r--drivers/mtd/maps/vmax301.c2
-rw-r--r--drivers/mtd/mtd_blkdevs.c32
-rw-r--r--drivers/mtd/mtdblock.c14
-rw-r--r--drivers/mtd/mtdcore.c45
-rw-r--r--drivers/mtd/nand/Kconfig17
-rw-r--r--drivers/mtd/nand/au1550nd.c4
-rw-r--r--drivers/mtd/nand/nand_base.c26
-rw-r--r--drivers/mtd/redboot.c6
-rw-r--r--drivers/net/3c59x.c33
-rw-r--r--drivers/net/8390.h2
-rw-r--r--drivers/net/Kconfig2
-rw-r--r--drivers/net/acenic_firmware.h10
-rw-r--r--drivers/net/b44.c14
-rw-r--r--drivers/net/bonding/bond_3ad.c28
-rw-r--r--drivers/net/bonding/bond_3ad.h1
-rw-r--r--drivers/net/bonding/bond_main.c97
-rw-r--r--drivers/net/bonding/bonding.h4
-rw-r--r--drivers/net/ixp2000/ixpdev.c5
-rw-r--r--drivers/net/natsemi.c18
-rw-r--r--drivers/net/netconsole.c2
-rw-r--r--drivers/net/pcmcia/axnet_cs.c61
-rw-r--r--drivers/net/pcmcia/xirc2ps_cs.c2
-rw-r--r--drivers/net/pcnet32.c4
-rw-r--r--drivers/net/spider_net.c4
-rw-r--r--drivers/net/tg3.c118
-rw-r--r--drivers/net/tokenring/Kconfig2
-rw-r--r--drivers/net/tulip/de4x5.c2
-rw-r--r--drivers/net/via-rhine.c21
-rw-r--r--drivers/net/wireless/Kconfig9
-rw-r--r--drivers/net/wireless/Makefile1
-rw-r--r--drivers/net/wireless/bcm43xx/Kconfig62
-rw-r--r--drivers/net/wireless/bcm43xx/Makefile12
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx.h926
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_debugfs.c499
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_debugfs.h117
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_dma.c968
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_dma.h218
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_ethtool.c50
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_ethtool.h8
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_ilt.c337
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_ilt.h32
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_leds.c293
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_leds.h56
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_main.c3973
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_main.h168
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_phy.c2345
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_phy.h74
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_pio.c606
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_pio.h138
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_power.c358
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_power.h47
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_radio.c2026
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_radio.h99
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_sysfs.c322
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_sysfs.h25
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_wx.c1002
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_wx.h36
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_xmit.c582
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_xmit.h156
-rw-r--r--drivers/net/wireless/hostap/hostap_80211.h2
-rw-r--r--drivers/net/wireless/hostap/hostap_80211_tx.c9
-rw-r--r--drivers/parisc/ccio-dma.c2
-rw-r--r--drivers/parisc/dino.c5
-rw-r--r--drivers/parisc/eisa.c2
-rw-r--r--drivers/parisc/iosapic.c2
-rw-r--r--drivers/parisc/lba_pci.c8
-rw-r--r--drivers/parisc/pdc_stable.c5
-rw-r--r--drivers/parisc/sba_iommu.c6
-rw-r--r--drivers/parisc/superio.c48
-rw-r--r--drivers/pcmcia/vrc4171_card.c12
-rw-r--r--drivers/pcmcia/vrc4173_cardu.c8
-rw-r--r--drivers/scsi/ahci.c4
-rw-r--r--drivers/scsi/ata_piix.c4
-rw-r--r--drivers/scsi/ibmmca.c2
-rw-r--r--drivers/scsi/lasi700.c2
-rw-r--r--drivers/scsi/libata-bmdma.c26
-rw-r--r--drivers/scsi/libata-core.c196
-rw-r--r--drivers/scsi/libata-scsi.c8
-rw-r--r--drivers/scsi/libata.h2
-rw-r--r--drivers/scsi/mesh.c2
-rw-r--r--drivers/scsi/sata_mv.c42
-rw-r--r--drivers/scsi/zalon.c2
-rw-r--r--drivers/serial/8250_gsc.c15
-rw-r--r--drivers/serial/jsm/jsm_tty.c29
-rw-r--r--drivers/serial/mux.c4
-rw-r--r--drivers/usb/core/hcd-pci.c4
-rw-r--r--drivers/usb/net/zd1201.c2
-rw-r--r--drivers/video/Kconfig12
-rw-r--r--drivers/video/Makefile1
-rw-r--r--drivers/video/aty/aty128fb.c7
-rw-r--r--drivers/video/aty/atyfb_base.c7
-rw-r--r--drivers/video/aty/radeon_pm.c4
-rw-r--r--drivers/video/backlight/Kconfig4
-rw-r--r--drivers/video/backlight/backlight.c84
-rw-r--r--drivers/video/backlight/corgi_bl.c124
-rw-r--r--drivers/video/backlight/hp680_bl.c139
-rw-r--r--drivers/video/cfbimgblt.c2
-rw-r--r--drivers/video/cirrusfb.c4
-rw-r--r--drivers/video/console/fbcon.c11
-rw-r--r--drivers/video/console/sticore.c22
-rw-r--r--drivers/video/fbmem.c2
-rw-r--r--drivers/video/matrox/matroxfb_base.c3
-rw-r--r--drivers/video/nvidia/nvidia.c5
-rw-r--r--drivers/video/pxafb.c8
-rw-r--r--drivers/video/radeonfb.c3167
-rw-r--r--drivers/video/riva/fbdev.c9
-rw-r--r--drivers/video/sticore.h37
-rw-r--r--drivers/video/stifb.c95
-rw-r--r--drivers/video/w100fb.c162
-rw-r--r--drivers/video/w100fb.h748
-rw-r--r--fs/Makefile2
-rw-r--r--fs/char_dev.c87
-rw-r--r--fs/cifs/CHANGES18
-rw-r--r--fs/cifs/Makefile2
-rw-r--r--fs/cifs/README7
-rw-r--r--fs/cifs/cifsencrypt.c42
-rw-r--r--fs/cifs/cifsfs.c5
-rw-r--r--fs/cifs/cifsfs.h2
-rw-r--r--fs/cifs/cifsglob.h11
-rw-r--r--fs/cifs/cifspdu.h13
-rw-r--r--fs/cifs/cifsproto.h15
-rw-r--r--fs/cifs/cifssmb.c135
-rw-r--r--fs/cifs/connect.c99
-rw-r--r--fs/cifs/dir.c7
-rw-r--r--fs/cifs/file.c94
-rw-r--r--fs/cifs/inode.c22
-rw-r--r--fs/cifs/link.c2
-rw-r--r--fs/cifs/misc.c46
-rw-r--r--fs/cifs/ntlmssp.c129
-rw-r--r--fs/cifs/ntlmssp.h2
-rw-r--r--fs/cifs/readdir.c7
-rw-r--r--fs/cifs/transport.c22
-rw-r--r--fs/dcache.c50
-rw-r--r--fs/direct-io.c7
-rw-r--r--fs/ext2/file.c2
-rw-r--r--fs/ext3/file.c2
-rw-r--r--fs/hppfs/hppfs_kern.c14
-rw-r--r--fs/locks.c45
-rw-r--r--fs/msdos/namei.c15
-rw-r--r--fs/namei.c3
-rw-r--r--fs/partitions/mac.c3
-rw-r--r--fs/pipe.c41
-rw-r--r--fs/proc/base.c13
-rw-r--r--fs/proc/proc_devtree.c103
-rw-r--r--fs/proc/proc_misc.c163
-rw-r--r--fs/reiserfs/file.c2
-rw-r--r--fs/select.c8
-rw-r--r--fs/splice.c663
-rw-r--r--fs/sync.c164
-rw-r--r--fs/vfat/namei.c18
-rw-r--r--fs/xfs/linux-2.6/mrlock.h2
-rw-r--r--fs/xfs/linux-2.6/xfs_aops.c67
-rw-r--r--fs/xfs/linux-2.6/xfs_aops.h2
-rw-r--r--fs/xfs/linux-2.6/xfs_export.h2
-rw-r--r--fs/xfs/linux-2.6/xfs_ioctl32.c22
-rw-r--r--fs/xfs/linux-2.6/xfs_iops.c2
-rw-r--r--fs/xfs/linux-2.6/xfs_lrw.c2
-rw-r--r--fs/xfs/linux-2.6/xfs_vfs.h2
-rw-r--r--fs/xfs/quota/xfs_dquot_item.c2
-rw-r--r--fs/xfs/quota/xfs_qm.c14
-rw-r--r--fs/xfs/quota/xfs_qm_syscalls.c2
-rw-r--r--fs/xfs/quota/xfs_trans_dquot.c2
-rw-r--r--fs/xfs/xfs_acl.c2
-rw-r--r--fs/xfs/xfs_ag.h2
-rw-r--r--fs/xfs/xfs_alloc.c6
-rw-r--r--fs/xfs/xfs_alloc.h2
-rw-r--r--fs/xfs/xfs_attr.c6
-rw-r--r--fs/xfs/xfs_attr_leaf.c4
-rw-r--r--fs/xfs/xfs_behavior.c4
-rw-r--r--fs/xfs/xfs_behavior.h4
-rw-r--r--fs/xfs/xfs_bmap.c107
-rw-r--r--fs/xfs/xfs_bmap.h8
-rw-r--r--fs/xfs/xfs_buf_item.c4
-rw-r--r--fs/xfs/xfs_cap.h2
-rw-r--r--fs/xfs/xfs_da_btree.c2
-rw-r--r--fs/xfs/xfs_dir2_block.c2
-rw-r--r--fs/xfs/xfs_dir2_leaf.c2
-rw-r--r--fs/xfs/xfs_dir2_node.c2
-rw-r--r--fs/xfs/xfs_dir_leaf.c2
-rw-r--r--fs/xfs/xfs_fsops.c2
-rw-r--r--fs/xfs/xfs_ialloc.c110
-rw-r--r--fs/xfs/xfs_iget.c2
-rw-r--r--fs/xfs/xfs_inode.c14
-rw-r--r--fs/xfs/xfs_inode_item.c2
-rw-r--r--fs/xfs/xfs_itable.c4
-rw-r--r--fs/xfs/xfs_itable.h2
-rw-r--r--fs/xfs/xfs_log.c22
-rw-r--r--fs/xfs/xfs_log.h2
-rw-r--r--fs/xfs/xfs_log_recover.c4
-rw-r--r--fs/xfs/xfs_mount.c4
-rw-r--r--fs/xfs/xfs_mount.h2
-rw-r--r--fs/xfs/xfs_quota.h4
-rw-r--r--fs/xfs/xfs_trans.c6
-rw-r--r--fs/xfs/xfs_trans.h2
-rw-r--r--fs/xfs/xfs_trans_inode.c2
-rw-r--r--fs/xfs/xfs_vfsops.c10
-rw-r--r--fs/xfs/xfs_vnodeops.c12
-rw-r--r--include/asm-arm/arch-ixp23xx/uncompress.h11
-rw-r--r--include/asm-arm/arch-pxa/pxa-regs.h2
-rw-r--r--include/asm-arm/arch-pxa/sharpsl.h2
-rw-r--r--include/asm-arm/unistd.h11
-rw-r--r--include/asm-generic/local.h13
-rw-r--r--include/asm-generic/mutex-dec.h30
-rw-r--r--include/asm-generic/mutex-xchg.h33
-rw-r--r--include/asm-i386/apicdef.h1
-rw-r--r--include/asm-i386/floppy.h34
-rw-r--r--include/asm-i386/local.h6
-rw-r--r--include/asm-i386/unistd.h4
-rw-r--r--include/asm-ia64/asmmacro.h4
-rw-r--r--include/asm-ia64/pal.h34
-rw-r--r--include/asm-ia64/unistd.h3
-rw-r--r--include/asm-parisc/atomic.h3
-rw-r--r--include/asm-parisc/cache.h2
-rw-r--r--include/asm-parisc/cacheflush.h17
-rw-r--r--include/asm-parisc/io.h95
-rw-r--r--include/asm-parisc/local.h16
-rw-r--r--include/asm-parisc/page.h58
-rw-r--r--include/asm-parisc/pci.h5
-rw-r--r--include/asm-parisc/pdc_chassis.h5
-rw-r--r--include/asm-parisc/spinlock.h16
-rw-r--r--include/asm-parisc/thread_info.h3
-rw-r--r--include/asm-powerpc/bug.h36
-rw-r--r--include/asm-powerpc/cputable.h299
-rw-r--r--include/asm-powerpc/firmware.h10
-rw-r--r--include/asm-powerpc/floppy.h5
-rw-r--r--include/asm-powerpc/hvcall.h1
-rw-r--r--include/asm-powerpc/hvconsole.h26
-rw-r--r--include/asm-powerpc/machdep.h43
-rw-r--r--include/asm-powerpc/oprofile_impl.h17
-rw-r--r--include/asm-powerpc/paca.h2
-rw-r--r--include/asm-powerpc/percpu.h2
-rw-r--r--include/asm-powerpc/pmac_feature.h2
-rw-r--r--include/asm-powerpc/processor.h43
-rw-r--r--include/asm-powerpc/prom.h14
-rw-r--r--include/asm-powerpc/reg.h4
-rw-r--r--include/asm-powerpc/smp.h2
-rw-r--r--include/asm-powerpc/spu.h11
-rw-r--r--include/asm-powerpc/syscalls.h58
-rw-r--r--include/asm-powerpc/system.h5
-rw-r--r--include/asm-powerpc/unistd.h38
-rw-r--r--include/asm-powerpc/vdso_datapage.h3
-rw-r--r--include/asm-ppc/machdep.h17
-rw-r--r--include/asm-ppc/mpc52xx.h4
-rw-r--r--include/asm-ppc/pgtable.h3
-rw-r--r--include/asm-ppc/prom.h156
-rw-r--r--include/asm-ppc/serial.h7
-rw-r--r--include/asm-s390/percpu.h2
-rw-r--r--include/asm-um/desc.h12
-rw-r--r--include/asm-um/host_ldt-i386.h34
-rw-r--r--include/asm-um/host_ldt-x86_64.h (renamed from include/asm-um/ldt-x86_64.h)39
-rw-r--r--include/asm-um/ldt-i386.h69
-rw-r--r--include/asm-um/ldt.h41
-rw-r--r--include/asm-um/processor-i386.h35
-rw-r--r--include/asm-um/processor-x86_64.h9
-rw-r--r--include/asm-um/ptrace-generic.h16
-rw-r--r--include/asm-um/ptrace-i386.h41
-rw-r--r--include/asm-um/ptrace-x86_64.h35
-rw-r--r--include/asm-um/segment.h6
-rw-r--r--include/asm-um/thread_info.h16
-rw-r--r--include/asm-um/uaccess.h2
-rw-r--r--include/asm-x86_64/local.h10
-rw-r--r--include/asm-x86_64/unistd.h4
-rw-r--r--include/linux/backlight.h25
-rw-r--r--include/linux/dcache.h1
-rw-r--r--include/linux/fadvise.h6
-rw-r--r--include/linux/fb.h2
-rw-r--r--include/linux/fs.h26
-rw-r--r--include/linux/hrtimer.h16
-rw-r--r--include/linux/ipmi_smi.h16
-rw-r--r--include/linux/leds.h111
-rw-r--r--include/linux/libata.h10
-rw-r--r--include/linux/migrate.h5
-rw-r--r--include/linux/mtd/blktrans.h4
-rw-r--r--include/linux/mtd/doc2000.h4
-rw-r--r--include/linux/mtd/inftl.h5
-rw-r--r--include/linux/namei.h1
-rw-r--r--include/linux/netdevice.h55
-rw-r--r--include/linux/pagemap.h4
-rw-r--r--include/linux/pci_ids.h1
-rw-r--r--include/linux/pid.h96
-rw-r--r--include/linux/pipe_fs_i.h8
-rw-r--r--include/linux/sched.h18
-rw-r--r--include/linux/skbuff.h29
-rw-r--r--include/linux/syscalls.h4
-rw-r--r--include/linux/timer.h8
-rw-r--r--include/linux/tiocl.h1
-rw-r--r--include/net/sock.h91
-rw-r--r--include/net/tcp.h3
-rw-r--r--include/net/xfrm.h16
-rw-r--r--include/rdma/ib_mad.h27
-rw-r--r--kernel/acct.c12
-rw-r--r--kernel/audit.c2
-rw-r--r--kernel/cpuset.c69
-rw-r--r--kernel/exit.c7
-rw-r--r--kernel/fork.c28
-rw-r--r--kernel/futex.c4
-rw-r--r--kernel/futex_compat.c4
-rw-r--r--kernel/hrtimer.c49
-rw-r--r--kernel/module.c1
-rw-r--r--kernel/pid.c212
-rw-r--r--kernel/power/process.c3
-rw-r--r--kernel/sched.c84
-rw-r--r--kernel/signal.c1
-rw-r--r--kernel/sys.c19
-rw-r--r--kernel/timer.c92
-rw-r--r--lib/Kconfig.debug13
-rw-r--r--mm/fadvise.c20
-rw-r--r--mm/hugetlb.c6
-rw-r--r--mm/memory.c2
-rw-r--r--mm/swapfile.c14
-rw-r--r--net/appletalk/ddp.c19
-rw-r--r--net/bridge/netfilter/ebt_802_3.c8
-rw-r--r--net/bridge/netfilter/ebt_among.c8
-rw-r--r--net/bridge/netfilter/ebt_arp.c8
-rw-r--r--net/bridge/netfilter/ebt_arpreply.c8
-rw-r--r--net/bridge/netfilter/ebt_dnat.c8
-rw-r--r--net/bridge/netfilter/ebt_ip.c8
-rw-r--r--net/bridge/netfilter/ebt_limit.c8
-rw-r--r--net/bridge/netfilter/ebt_log.c8
-rw-r--r--net/bridge/netfilter/ebt_mark.c8
-rw-r--r--net/bridge/netfilter/ebt_mark_m.c8
-rw-r--r--net/bridge/netfilter/ebt_pkttype.c8
-rw-r--r--net/bridge/netfilter/ebt_redirect.c8
-rw-r--r--net/bridge/netfilter/ebt_snat.c8
-rw-r--r--net/bridge/netfilter/ebt_stp.c8
-rw-r--r--net/bridge/netfilter/ebt_ulog.c8
-rw-r--r--net/bridge/netfilter/ebt_vlan.c8
-rw-r--r--net/bridge/netfilter/ebtable_broute.c8
-rw-r--r--net/bridge/netfilter/ebtable_filter.c8
-rw-r--r--net/bridge/netfilter/ebtable_nat.c8
-rw-r--r--net/bridge/netfilter/ebtables.c8
-rw-r--r--net/core/dev.c64
-rw-r--r--net/core/sock.c109
-rw-r--r--net/dccp/feat.c6
-rw-r--r--net/decnet/dn_dev.c2
-rw-r--r--net/decnet/netfilter/dn_rtmsg.c8
-rw-r--r--net/econet/af_econet.c124
-rw-r--r--net/ieee80211/ieee80211_wx.c4
-rw-r--r--net/ieee80211/softmac/ieee80211softmac_module.c17
-rw-r--r--net/ieee80211/softmac/ieee80211softmac_priv.h2
-rw-r--r--net/ieee80211/softmac/ieee80211softmac_wx.c12
-rw-r--r--net/ipv4/Kconfig17
-rw-r--r--net/ipv4/Makefile3
-rw-r--r--net/ipv4/ipip.c79
-rw-r--r--net/ipv4/netfilter.c8
-rw-r--r--net/ipv4/netfilter/arp_tables.c8
-rw-r--r--net/ipv4/netfilter/arpt_mangle.c8
-rw-r--r--net/ipv4/netfilter/arptable_filter.c8
-rw-r--r--net/ipv4/netfilter/ip_conntrack_amanda.c8
-rw-r--r--net/ipv4/netfilter/ip_conntrack_ftp.c10
-rw-r--r--net/ipv4/netfilter/ip_conntrack_helper_pptp.c8
-rw-r--r--net/ipv4/netfilter/ip_conntrack_irc.c12
-rw-r--r--net/ipv4/netfilter/ip_conntrack_netbios_ns.c8
-rw-r--r--net/ipv4/netfilter/ip_conntrack_proto_sctp.c8
-rw-r--r--net/ipv4/netfilter/ip_conntrack_standalone.c8
-rw-r--r--net/ipv4/netfilter/ip_conntrack_tftp.c10
-rw-r--r--net/ipv4/netfilter/ip_nat_amanda.c8
-rw-r--r--net/ipv4/netfilter/ip_nat_ftp.c8
-rw-r--r--net/ipv4/netfilter/ip_nat_helper_pptp.c8
-rw-r--r--net/ipv4/netfilter/ip_nat_irc.c8
-rw-r--r--net/ipv4/netfilter/ip_nat_snmp_basic.c8
-rw-r--r--net/ipv4/netfilter/ip_nat_standalone.c8
-rw-r--r--net/ipv4/netfilter/ip_nat_tftp.c8
-rw-r--r--net/ipv4/netfilter/ip_queue.c8
-rw-r--r--net/ipv4/netfilter/ip_tables.c8
-rw-r--r--net/ipv4/netfilter/ipt_CLUSTERIP.c8
-rw-r--r--net/ipv4/netfilter/ipt_DSCP.c8
-rw-r--r--net/ipv4/netfilter/ipt_ECN.c8
-rw-r--r--net/ipv4/netfilter/ipt_LOG.c8
-rw-r--r--net/ipv4/netfilter/ipt_MASQUERADE.c8
-rw-r--r--net/ipv4/netfilter/ipt_NETMAP.c8
-rw-r--r--net/ipv4/netfilter/ipt_REDIRECT.c8
-rw-r--r--net/ipv4/netfilter/ipt_REJECT.c8
-rw-r--r--net/ipv4/netfilter/ipt_SAME.c8
-rw-r--r--net/ipv4/netfilter/ipt_TCPMSS.c8
-rw-r--r--net/ipv4/netfilter/ipt_TOS.c8
-rw-r--r--net/ipv4/netfilter/ipt_TTL.c8
-rw-r--r--net/ipv4/netfilter/ipt_ULOG.c8
-rw-r--r--net/ipv4/netfilter/ipt_addrtype.c8
-rw-r--r--net/ipv4/netfilter/ipt_ah.c8
-rw-r--r--net/ipv4/netfilter/ipt_dscp.c8
-rw-r--r--net/ipv4/netfilter/ipt_ecn.c8
-rw-r--r--net/ipv4/netfilter/ipt_esp.c8
-rw-r--r--net/ipv4/netfilter/ipt_hashlimit.c8
-rw-r--r--net/ipv4/netfilter/ipt_iprange.c8
-rw-r--r--net/ipv4/netfilter/ipt_multiport.c8
-rw-r--r--net/ipv4/netfilter/ipt_owner.c8
-rw-r--r--net/ipv4/netfilter/ipt_recent.c8
-rw-r--r--net/ipv4/netfilter/ipt_tos.c8
-rw-r--r--net/ipv4/netfilter/ipt_ttl.c8
-rw-r--r--net/ipv4/netfilter/iptable_filter.c8
-rw-r--r--net/ipv4/netfilter/iptable_mangle.c8
-rw-r--r--net/ipv4/netfilter/iptable_raw.c8
-rw-r--r--net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c8
-rw-r--r--net/ipv4/tcp_cong.c2
-rw-r--r--net/ipv4/tunnel4.c113
-rw-r--r--net/ipv4/xfrm4_tunnel.c79
-rw-r--r--net/ipv6/Kconfig19
-rw-r--r--net/ipv6/Makefile3
-rw-r--r--net/ipv6/ip6_tunnel.c45
-rw-r--r--net/ipv6/netfilter/ip6_queue.c8
-rw-r--r--net/ipv6/netfilter/ip6_tables.c8
-rw-r--r--net/ipv6/netfilter/ip6t_HL.c8
-rw-r--r--net/ipv6/netfilter/ip6t_LOG.c8
-rw-r--r--net/ipv6/netfilter/ip6t_REJECT.c8
-rw-r--r--net/ipv6/netfilter/ip6t_ah.c8
-rw-r--r--net/ipv6/netfilter/ip6t_dst.c8
-rw-r--r--net/ipv6/netfilter/ip6t_esp.c8
-rw-r--r--net/ipv6/netfilter/ip6t_eui64.c8
-rw-r--r--net/ipv6/netfilter/ip6t_frag.c8
-rw-r--r--net/ipv6/netfilter/ip6t_hbh.c8
-rw-r--r--net/ipv6/netfilter/ip6t_hl.c8
-rw-r--r--net/ipv6/netfilter/ip6t_multiport.c8
-rw-r--r--net/ipv6/netfilter/ip6t_owner.c8
-rw-r--r--net/ipv6/netfilter/ip6t_rt.c8
-rw-r--r--net/ipv6/netfilter/ip6table_filter.c8
-rw-r--r--net/ipv6/netfilter/ip6table_mangle.c8
-rw-r--r--net/ipv6/netfilter/ip6table_raw.c8
-rw-r--r--net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c8
-rw-r--r--net/ipv6/tunnel6.c131
-rw-r--r--net/ipv6/xfrm6_input.c5
-rw-r--r--net/ipv6/xfrm6_tunnel.c81
-rw-r--r--net/ipx/af_ipx.c26
-rw-r--r--net/irda/af_irda.c25
-rw-r--r--net/netfilter/nf_conntrack_ftp.c10
-rw-r--r--net/netfilter/nf_conntrack_proto_sctp.c8
-rw-r--r--net/netfilter/nf_conntrack_standalone.c8
-rw-r--r--net/netfilter/nfnetlink_log.c8
-rw-r--r--net/netfilter/nfnetlink_queue.c8
-rw-r--r--net/netfilter/xt_CLASSIFY.c8
-rw-r--r--net/netfilter/xt_CONNMARK.c8
-rw-r--r--net/netfilter/xt_MARK.c8
-rw-r--r--net/netfilter/xt_NFQUEUE.c8
-rw-r--r--net/netfilter/xt_NOTRACK.c8
-rw-r--r--net/netfilter/xt_comment.c8
-rw-r--r--net/netfilter/xt_connbytes.c8
-rw-r--r--net/netfilter/xt_connmark.c8
-rw-r--r--net/netfilter/xt_conntrack.c8
-rw-r--r--net/netfilter/xt_dccp.c8
-rw-r--r--net/netfilter/xt_helper.c8
-rw-r--r--net/netfilter/xt_length.c8
-rw-r--r--net/netfilter/xt_limit.c8
-rw-r--r--net/netfilter/xt_mac.c8
-rw-r--r--net/netfilter/xt_mark.c8
-rw-r--r--net/netfilter/xt_physdev.c8
-rw-r--r--net/netfilter/xt_pkttype.c8
-rw-r--r--net/netfilter/xt_realm.c8
-rw-r--r--net/netfilter/xt_sctp.c8
-rw-r--r--net/netfilter/xt_state.c8
-rw-r--r--net/netfilter/xt_string.c8
-rw-r--r--net/netfilter/xt_tcpmss.c8
-rw-r--r--net/netfilter/xt_tcpudp.c8
-rw-r--r--net/socket.c6
-rw-r--r--sound/oss/dmasound/dmasound_awacs.c2
-rw-r--r--sound/ppc/pmac.c2
925 files changed, 32746 insertions, 20453 deletions
diff --git a/Documentation/DocBook/libata.tmpl b/Documentation/DocBook/libata.tmpl
index d260d92089ad..5bcbb6ee3bc0 100644
--- a/Documentation/DocBook/libata.tmpl
+++ b/Documentation/DocBook/libata.tmpl
@@ -120,14 +120,27 @@ void (*dev_config) (struct ata_port *, struct ata_device *);
120 <programlisting> 120 <programlisting>
121void (*set_piomode) (struct ata_port *, struct ata_device *); 121void (*set_piomode) (struct ata_port *, struct ata_device *);
122void (*set_dmamode) (struct ata_port *, struct ata_device *); 122void (*set_dmamode) (struct ata_port *, struct ata_device *);
123void (*post_set_mode) (struct ata_port *ap); 123void (*post_set_mode) (struct ata_port *);
124unsigned int (*mode_filter) (struct ata_port *, struct ata_device *, unsigned int);
124 </programlisting> 125 </programlisting>
125 126
126 <para> 127 <para>
127 Hooks called prior to the issue of SET FEATURES - XFER MODE 128 Hooks called prior to the issue of SET FEATURES - XFER MODE
128 command. dev->pio_mode is guaranteed to be valid when 129 command. The optional ->mode_filter() hook is called when libata
129 ->set_piomode() is called, and dev->dma_mode is guaranteed to be 130 has built a mask of the possible modes. This is passed to the
130 valid when ->set_dmamode() is called. ->post_set_mode() is 131 ->mode_filter() function which should return a mask of valid modes
132 after filtering those unsuitable due to hardware limits. It is not
133 valid to use this interface to add modes.
134 </para>
135 <para>
136 dev->pio_mode and dev->dma_mode are guaranteed to be valid when
137 ->set_piomode() and when ->set_dmamode() is called. The timings for
138 any other drive sharing the cable will also be valid at this point.
139 That is the library records the decisions for the modes of each
140 drive on a channel before it attempts to set any of them.
141 </para>
142 <para>
143 ->post_set_mode() is
131 called unconditionally, after the SET FEATURES - XFER MODE 144 called unconditionally, after the SET FEATURES - XFER MODE
132 command completes successfully. 145 command completes successfully.
133 </para> 146 </para>
@@ -230,6 +243,32 @@ void (*dev_select)(struct ata_port *ap, unsigned int device);
230 243
231 </sect2> 244 </sect2>
232 245
246 <sect2><title>Private tuning method</title>
247 <programlisting>
248void (*set_mode) (struct ata_port *ap);
249 </programlisting>
250
251 <para>
252 By default libata performs drive and controller tuning in
253 accordance with the ATA timing rules and also applies blacklists
254 and cable limits. Some controllers need special handling and have
255 custom tuning rules, typically raid controllers that use ATA
256 commands but do not actually do drive timing.
257 </para>
258
259 <warning>
260 <para>
261 This hook should not be used to replace the standard controller
262 tuning logic when a controller has quirks. Replacing the default
263 tuning logic in that case would bypass handling for drive and
264 bridge quirks that may be important to data reliability. If a
265 controller needs to filter the mode selection it should use the
266 mode_filter hook instead.
267 </para>
268 </warning>
269
270 </sect2>
271
233 <sect2><title>Reset ATA bus</title> 272 <sect2><title>Reset ATA bus</title>
234 <programlisting> 273 <programlisting>
235void (*phy_reset) (struct ata_port *ap); 274void (*phy_reset) (struct ata_port *ap);
diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt
index 495858b236b6..59d0c74c79c9 100644
--- a/Documentation/feature-removal-schedule.txt
+++ b/Documentation/feature-removal-schedule.txt
@@ -127,13 +127,6 @@ Who: Christoph Hellwig <hch@lst.de>
127 127
128--------------------------- 128---------------------------
129 129
130What: EXPORT_SYMBOL(lookup_hash)
131When: January 2006
132Why: Too low-level interface. Use lookup_one_len or lookup_create instead.
133Who: Christoph Hellwig <hch@lst.de>
134
135---------------------------
136
137What: CONFIG_FORCED_INLINING 130What: CONFIG_FORCED_INLINING
138When: June 2006 131When: June 2006
139Why: Config option is there to see if gcc is good enough. (in january 132Why: Config option is there to see if gcc is good enough. (in january
@@ -241,3 +234,15 @@ Why: The USB subsystem has changed a lot over time, and it has been
241Who: Greg Kroah-Hartman <gregkh@suse.de> 234Who: Greg Kroah-Hartman <gregkh@suse.de>
242 235
243--------------------------- 236---------------------------
237
238What: find_trylock_page
239When: January 2007
240Why: The interface no longer has any callers left in the kernel. It
241 is an odd interface (compared with other find_*_page functions), in
242 that it does not take a refcount to the page, only the page lock.
243 It should be replaced with find_get_page or find_lock_page if possible.
244 This feature removal can be reevaluated if users of the interface
245 cannot cleanly use something else.
246Who: Nick Piggin <npiggin@suse.de>
247
248---------------------------
diff --git a/Documentation/leds-class.txt b/Documentation/leds-class.txt
new file mode 100644
index 000000000000..8c35c0426110
--- /dev/null
+++ b/Documentation/leds-class.txt
@@ -0,0 +1,71 @@
1LED handling under Linux
2========================
3
4If you're reading this and thinking about keyboard leds, these are
5handled by the input subsystem and the led class is *not* needed.
6
7In its simplest form, the LED class just allows control of LEDs from
8userspace. LEDs appear in /sys/class/leds/. The brightness file will
9set the brightness of the LED (taking a value 0-255). Most LEDs don't
10have hardware brightness support so will just be turned on for non-zero
11brightness settings.
12
13The class also introduces the optional concept of an LED trigger. A trigger
14is a kernel based source of led events. Triggers can either be simple or
15complex. A simple trigger isn't configurable and is designed to slot into
16existing subsystems with minimal additional code. Examples are the ide-disk,
17nand-disk and sharpsl-charge triggers. With led triggers disabled, the code
18optimises away.
19
20Complex triggers whilst available to all LEDs have LED specific
21parameters and work on a per LED basis. The timer trigger is an example.
22
23You can change triggers in a similar manner to the way an IO scheduler
24is chosen (via /sys/class/leds/<device>/trigger). Trigger specific
25parameters can appear in /sys/class/leds/<device> once a given trigger is
26selected.
27
28
29Design Philosophy
30=================
31
32The underlying design philosophy is simplicity. LEDs are simple devices
33and the aim is to keep a small amount of code giving as much functionality
34as possible. Please keep this in mind when suggesting enhancements.
35
36
37LED Device Naming
38=================
39
40Is currently of the form:
41
42"devicename:colour"
43
44There have been calls for LED properties such as colour to be exported as
45individual led class attributes. As a solution which doesn't incur as much
46overhead, I suggest these become part of the device name. The naming scheme
47above leaves scope for further attributes should they be needed.
48
49
50Known Issues
51============
52
53The LED Trigger core cannot be a module as the simple trigger functions
54would cause nightmare dependency issues. I see this as a minor issue
55compared to the benefits the simple trigger functionality brings. The
56rest of the LED subsystem can be modular.
57
58Some leds can be programmed to flash in hardware. As this isn't a generic
59LED device property, this should be exported as a device specific sysfs
60attribute rather than part of the class if this functionality is required.
61
62
63Future Development
64==================
65
66At the moment, a trigger can't be created specifically for a single LED.
67There are a number of cases where a trigger might only be mappable to a
68particular LED (ACPI?). The addition of triggers provided by the LED driver
69should cover this option and be possible to add without breaking the
70current interface.
71
diff --git a/Documentation/memory-barriers.txt b/Documentation/memory-barriers.txt
new file mode 100644
index 000000000000..f8550310a6d5
--- /dev/null
+++ b/Documentation/memory-barriers.txt
@@ -0,0 +1,1913 @@
1 ============================
2 LINUX KERNEL MEMORY BARRIERS
3 ============================
4
5By: David Howells <dhowells@redhat.com>
6
7Contents:
8
9 (*) Abstract memory access model.
10
11 - Device operations.
12 - Guarantees.
13
14 (*) What are memory barriers?
15
16 - Varieties of memory barrier.
17 - What may not be assumed about memory barriers?
18 - Data dependency barriers.
19 - Control dependencies.
20 - SMP barrier pairing.
21 - Examples of memory barrier sequences.
22
23 (*) Explicit kernel barriers.
24
25 - Compiler barrier.
26 - The CPU memory barriers.
27 - MMIO write barrier.
28
29 (*) Implicit kernel memory barriers.
30
31 - Locking functions.
32 - Interrupt disabling functions.
33 - Miscellaneous functions.
34
35 (*) Inter-CPU locking barrier effects.
36
37 - Locks vs memory accesses.
38 - Locks vs I/O accesses.
39
40 (*) Where are memory barriers needed?
41
42 - Interprocessor interaction.
43 - Atomic operations.
44 - Accessing devices.
45 - Interrupts.
46
47 (*) Kernel I/O barrier effects.
48
49 (*) Assumed minimum execution ordering model.
50
51 (*) The effects of the cpu cache.
52
53 - Cache coherency.
54 - Cache coherency vs DMA.
55 - Cache coherency vs MMIO.
56
57 (*) The things CPUs get up to.
58
59 - And then there's the Alpha.
60
61 (*) References.
62
63
64============================
65ABSTRACT MEMORY ACCESS MODEL
66============================
67
68Consider the following abstract model of the system:
69
70 : :
71 : :
72 : :
73 +-------+ : +--------+ : +-------+
74 | | : | | : | |
75 | | : | | : | |
76 | CPU 1 |<----->| Memory |<----->| CPU 2 |
77 | | : | | : | |
78 | | : | | : | |
79 +-------+ : +--------+ : +-------+
80 ^ : ^ : ^
81 | : | : |
82 | : | : |
83 | : v : |
84 | : +--------+ : |
85 | : | | : |
86 | : | | : |
87 +---------->| Device |<----------+
88 : | | :
89 : | | :
90 : +--------+ :
91 : :
92
93Each CPU executes a program that generates memory access operations. In the
94abstract CPU, memory operation ordering is very relaxed, and a CPU may actually
95perform the memory operations in any order it likes, provided program causality
96appears to be maintained. Similarly, the compiler may also arrange the
97instructions it emits in any order it likes, provided it doesn't affect the
98apparent operation of the program.
99
100So in the above diagram, the effects of the memory operations performed by a
101CPU are perceived by the rest of the system as the operations cross the
102interface between the CPU and rest of the system (the dotted lines).
103
104
105For example, consider the following sequence of events:
106
107 CPU 1 CPU 2
108 =============== ===============
109 { A == 1; B == 2 }
110 A = 3; x = A;
111 B = 4; y = B;
112
113The set of accesses as seen by the memory system in the middle can be arranged
114in 24 different combinations:
115
116 STORE A=3, STORE B=4, x=LOAD A->3, y=LOAD B->4
117 STORE A=3, STORE B=4, y=LOAD B->4, x=LOAD A->3
118 STORE A=3, x=LOAD A->3, STORE B=4, y=LOAD B->4
119 STORE A=3, x=LOAD A->3, y=LOAD B->2, STORE B=4
120 STORE A=3, y=LOAD B->2, STORE B=4, x=LOAD A->3
121 STORE A=3, y=LOAD B->2, x=LOAD A->3, STORE B=4
122 STORE B=4, STORE A=3, x=LOAD A->3, y=LOAD B->4
123 STORE B=4, ...
124 ...
125
126and can thus result in four different combinations of values:
127
128 x == 1, y == 2
129 x == 1, y == 4
130 x == 3, y == 2
131 x == 3, y == 4
132
133
134Furthermore, the stores committed by a CPU to the memory system may not be
135perceived by the loads made by another CPU in the same order as the stores were
136committed.
137
138
139As a further example, consider this sequence of events:
140
141 CPU 1 CPU 2
142 =============== ===============
143 { A == 1, B == 2, C = 3, P == &A, Q == &C }
144 B = 4; Q = P;
145 P = &B D = *Q;
146
147There is an obvious data dependency here, as the value loaded into D depends on
148the address retrieved from P by CPU 2. At the end of the sequence, any of the
149following results are possible:
150
151 (Q == &A) and (D == 1)
152 (Q == &B) and (D == 2)
153 (Q == &B) and (D == 4)
154
155Note that CPU 2 will never try and load C into D because the CPU will load P
156into Q before issuing the load of *Q.
157
158
159DEVICE OPERATIONS
160-----------------
161
162Some devices present their control interfaces as collections of memory
163locations, but the order in which the control registers are accessed is very
164important. For instance, imagine an ethernet card with a set of internal
165registers that are accessed through an address port register (A) and a data
166port register (D). To read internal register 5, the following code might then
167be used:
168
169 *A = 5;
170 x = *D;
171
172but this might show up as either of the following two sequences:
173
174 STORE *A = 5, x = LOAD *D
175 x = LOAD *D, STORE *A = 5
176
177the second of which will almost certainly result in a malfunction, since it set
178the address _after_ attempting to read the register.
179
180
181GUARANTEES
182----------
183
184There are some minimal guarantees that may be expected of a CPU:
185
186 (*) On any given CPU, dependent memory accesses will be issued in order, with
187 respect to itself. This means that for:
188
189 Q = P; D = *Q;
190
191 the CPU will issue the following memory operations:
192
193 Q = LOAD P, D = LOAD *Q
194
195 and always in that order.
196
197 (*) Overlapping loads and stores within a particular CPU will appear to be
198 ordered within that CPU. This means that for:
199
200 a = *X; *X = b;
201
202 the CPU will only issue the following sequence of memory operations:
203
204 a = LOAD *X, STORE *X = b
205
206 And for:
207
208 *X = c; d = *X;
209
210 the CPU will only issue:
211
212 STORE *X = c, d = LOAD *X
213
214 (Loads and stores overlap if they are targetted at overlapping pieces of
215 memory).
216
217And there are a number of things that _must_ or _must_not_ be assumed:
218
219 (*) It _must_not_ be assumed that independent loads and stores will be issued
220 in the order given. This means that for:
221
222 X = *A; Y = *B; *D = Z;
223
224 we may get any of the following sequences:
225
226 X = LOAD *A, Y = LOAD *B, STORE *D = Z
227 X = LOAD *A, STORE *D = Z, Y = LOAD *B
228 Y = LOAD *B, X = LOAD *A, STORE *D = Z
229 Y = LOAD *B, STORE *D = Z, X = LOAD *A
230 STORE *D = Z, X = LOAD *A, Y = LOAD *B
231 STORE *D = Z, Y = LOAD *B, X = LOAD *A
232
233 (*) It _must_ be assumed that overlapping memory accesses may be merged or
234 discarded. This means that for:
235
236 X = *A; Y = *(A + 4);
237
238 we may get any one of the following sequences:
239
240 X = LOAD *A; Y = LOAD *(A + 4);
241 Y = LOAD *(A + 4); X = LOAD *A;
242 {X, Y} = LOAD {*A, *(A + 4) };
243
244 And for:
245
246 *A = X; Y = *A;
247
248 we may get either of:
249
250 STORE *A = X; Y = LOAD *A;
251 STORE *A = Y;
252
253
254=========================
255WHAT ARE MEMORY BARRIERS?
256=========================
257
258As can be seen above, independent memory operations are effectively performed
259in random order, but this can be a problem for CPU-CPU interaction and for I/O.
260What is required is some way of intervening to instruct the compiler and the
261CPU to restrict the order.
262
263Memory barriers are such interventions. They impose a perceived partial
264ordering between the memory operations specified on either side of the barrier.
265They request that the sequence of memory events generated appears to other
266parts of the system as if the barrier is effective on that CPU.
267
268
269VARIETIES OF MEMORY BARRIER
270---------------------------
271
272Memory barriers come in four basic varieties:
273
274 (1) Write (or store) memory barriers.
275
276 A write memory barrier gives a guarantee that all the STORE operations
277 specified before the barrier will appear to happen before all the STORE
278 operations specified after the barrier with respect to the other
279 components of the system.
280
281 A write barrier is a partial ordering on stores only; it is not required
282 to have any effect on loads.
283
284 A CPU can be viewed as as commiting a sequence of store operations to the
285 memory system as time progresses. All stores before a write barrier will
286 occur in the sequence _before_ all the stores after the write barrier.
287
288 [!] Note that write barriers should normally be paired with read or data
289 dependency barriers; see the "SMP barrier pairing" subsection.
290
291
292 (2) Data dependency barriers.
293
294 A data dependency barrier is a weaker form of read barrier. In the case
295 where two loads are performed such that the second depends on the result
296 of the first (eg: the first load retrieves the address to which the second
297 load will be directed), a data dependency barrier would be required to
298 make sure that the target of the second load is updated before the address
299 obtained by the first load is accessed.
300
301 A data dependency barrier is a partial ordering on interdependent loads
302 only; it is not required to have any effect on stores, independent loads
303 or overlapping loads.
304
305 As mentioned in (1), the other CPUs in the system can be viewed as
306 committing sequences of stores to the memory system that the CPU being
307 considered can then perceive. A data dependency barrier issued by the CPU
308 under consideration guarantees that for any load preceding it, if that
309 load touches one of a sequence of stores from another CPU, then by the
310 time the barrier completes, the effects of all the stores prior to that
311 touched by the load will be perceptible to any loads issued after the data
312 dependency barrier.
313
314 See the "Examples of memory barrier sequences" subsection for diagrams
315 showing the ordering constraints.
316
317 [!] Note that the first load really has to have a _data_ dependency and
318 not a control dependency. If the address for the second load is dependent
319 on the first load, but the dependency is through a conditional rather than
320 actually loading the address itself, then it's a _control_ dependency and
321 a full read barrier or better is required. See the "Control dependencies"
322 subsection for more information.
323
324 [!] Note that data dependency barriers should normally be paired with
325 write barriers; see the "SMP barrier pairing" subsection.
326
327
328 (3) Read (or load) memory barriers.
329
330 A read barrier is a data dependency barrier plus a guarantee that all the
331 LOAD operations specified before the barrier will appear to happen before
332 all the LOAD operations specified after the barrier with respect to the
333 other components of the system.
334
335 A read barrier is a partial ordering on loads only; it is not required to
336 have any effect on stores.
337
338 Read memory barriers imply data dependency barriers, and so can substitute
339 for them.
340
341 [!] Note that read barriers should normally be paired with write barriers;
342 see the "SMP barrier pairing" subsection.
343
344
345 (4) General memory barriers.
346
347 A general memory barrier is a combination of both a read memory barrier
348 and a write memory barrier. It is a partial ordering over both loads and
349 stores.
350
351 General memory barriers imply both read and write memory barriers, and so
352 can substitute for either.
353
354
355And a couple of implicit varieties:
356
357 (5) LOCK operations.
358
359 This acts as a one-way permeable barrier. It guarantees that all memory
360 operations after the LOCK operation will appear to happen after the LOCK
361 operation with respect to the other components of the system.
362
363 Memory operations that occur before a LOCK operation may appear to happen
364 after it completes.
365
366 A LOCK operation should almost always be paired with an UNLOCK operation.
367
368
369 (6) UNLOCK operations.
370
371 This also acts as a one-way permeable barrier. It guarantees that all
372 memory operations before the UNLOCK operation will appear to happen before
373 the UNLOCK operation with respect to the other components of the system.
374
375 Memory operations that occur after an UNLOCK operation may appear to
376 happen before it completes.
377
378 LOCK and UNLOCK operations are guaranteed to appear with respect to each
379 other strictly in the order specified.
380
381 The use of LOCK and UNLOCK operations generally precludes the need for
382 other sorts of memory barrier (but note the exceptions mentioned in the
383 subsection "MMIO write barrier").
384
385
386Memory barriers are only required where there's a possibility of interaction
387between two CPUs or between a CPU and a device. If it can be guaranteed that
388there won't be any such interaction in any particular piece of code, then
389memory barriers are unnecessary in that piece of code.
390
391
392Note that these are the _minimum_ guarantees. Different architectures may give
393more substantial guarantees, but they may _not_ be relied upon outside of arch
394specific code.
395
396
397WHAT MAY NOT BE ASSUMED ABOUT MEMORY BARRIERS?
398----------------------------------------------
399
400There are certain things that the Linux kernel memory barriers do not guarantee:
401
402 (*) There is no guarantee that any of the memory accesses specified before a
403 memory barrier will be _complete_ by the completion of a memory barrier
404 instruction; the barrier can be considered to draw a line in that CPU's
405 access queue that accesses of the appropriate type may not cross.
406
407 (*) There is no guarantee that issuing a memory barrier on one CPU will have
408 any direct effect on another CPU or any other hardware in the system. The
409 indirect effect will be the order in which the second CPU sees the effects
410 of the first CPU's accesses occur, but see the next point:
411
412 (*) There is no guarantee that the a CPU will see the correct order of effects
413 from a second CPU's accesses, even _if_ the second CPU uses a memory
414 barrier, unless the first CPU _also_ uses a matching memory barrier (see
415 the subsection on "SMP Barrier Pairing").
416
417 (*) There is no guarantee that some intervening piece of off-the-CPU
418 hardware[*] will not reorder the memory accesses. CPU cache coherency
419 mechanisms should propagate the indirect effects of a memory barrier
420 between CPUs, but might not do so in order.
421
422 [*] For information on bus mastering DMA and coherency please read:
423
424 Documentation/pci.txt
425 Documentation/DMA-mapping.txt
426 Documentation/DMA-API.txt
427
428
429DATA DEPENDENCY BARRIERS
430------------------------
431
432The usage requirements of data dependency barriers are a little subtle, and
433it's not always obvious that they're needed. To illustrate, consider the
434following sequence of events:
435
436 CPU 1 CPU 2
437 =============== ===============
438 { A == 1, B == 2, C = 3, P == &A, Q == &C }
439 B = 4;
440 <write barrier>
441 P = &B
442 Q = P;
443 D = *Q;
444
445There's a clear data dependency here, and it would seem that by the end of the
446sequence, Q must be either &A or &B, and that:
447
448 (Q == &A) implies (D == 1)
449 (Q == &B) implies (D == 4)
450
451But! CPU 2's perception of P may be updated _before_ its perception of B, thus
452leading to the following situation:
453
454 (Q == &B) and (D == 2) ????
455
456Whilst this may seem like a failure of coherency or causality maintenance, it
457isn't, and this behaviour can be observed on certain real CPUs (such as the DEC
458Alpha).
459
460To deal with this, a data dependency barrier must be inserted between the
461address load and the data load:
462
463 CPU 1 CPU 2
464 =============== ===============
465 { A == 1, B == 2, C = 3, P == &A, Q == &C }
466 B = 4;
467 <write barrier>
468 P = &B
469 Q = P;
470 <data dependency barrier>
471 D = *Q;
472
473This enforces the occurrence of one of the two implications, and prevents the
474third possibility from arising.
475
476[!] Note that this extremely counterintuitive situation arises most easily on
477machines with split caches, so that, for example, one cache bank processes
478even-numbered cache lines and the other bank processes odd-numbered cache
479lines. The pointer P might be stored in an odd-numbered cache line, and the
480variable B might be stored in an even-numbered cache line. Then, if the
481even-numbered bank of the reading CPU's cache is extremely busy while the
482odd-numbered bank is idle, one can see the new value of the pointer P (&B),
483but the old value of the variable B (1).
484
485
486Another example of where data dependency barriers might by required is where a
487number is read from memory and then used to calculate the index for an array
488access:
489
490 CPU 1 CPU 2
491 =============== ===============
492 { M[0] == 1, M[1] == 2, M[3] = 3, P == 0, Q == 3 }
493 M[1] = 4;
494 <write barrier>
495 P = 1
496 Q = P;
497 <data dependency barrier>
498 D = M[Q];
499
500
501The data dependency barrier is very important to the RCU system, for example.
502See rcu_dereference() in include/linux/rcupdate.h. This permits the current
503target of an RCU'd pointer to be replaced with a new modified target, without
504the replacement target appearing to be incompletely initialised.
505
506See also the subsection on "Cache Coherency" for a more thorough example.
507
508
509CONTROL DEPENDENCIES
510--------------------
511
512A control dependency requires a full read memory barrier, not simply a data
513dependency barrier to make it work correctly. Consider the following bit of
514code:
515
516 q = &a;
517 if (p)
518 q = &b;
519 <data dependency barrier>
520 x = *q;
521
522This will not have the desired effect because there is no actual data
523dependency, but rather a control dependency that the CPU may short-circuit by
524attempting to predict the outcome in advance. In such a case what's actually
525required is:
526
527 q = &a;
528 if (p)
529 q = &b;
530 <read barrier>
531 x = *q;
532
533
534SMP BARRIER PAIRING
535-------------------
536
537When dealing with CPU-CPU interactions, certain types of memory barrier should
538always be paired. A lack of appropriate pairing is almost certainly an error.
539
540A write barrier should always be paired with a data dependency barrier or read
541barrier, though a general barrier would also be viable. Similarly a read
542barrier or a data dependency barrier should always be paired with at least an
543write barrier, though, again, a general barrier is viable:
544
545 CPU 1 CPU 2
546 =============== ===============
547 a = 1;
548 <write barrier>
549 b = 2; x = a;
550 <read barrier>
551 y = b;
552
553Or:
554
555 CPU 1 CPU 2
556 =============== ===============================
557 a = 1;
558 <write barrier>
559 b = &a; x = b;
560 <data dependency barrier>
561 y = *x;
562
563Basically, the read barrier always has to be there, even though it can be of
564the "weaker" type.
565
566
567EXAMPLES OF MEMORY BARRIER SEQUENCES
568------------------------------------
569
570Firstly, write barriers act as a partial orderings on store operations.
571Consider the following sequence of events:
572
573 CPU 1
574 =======================
575 STORE A = 1
576 STORE B = 2
577 STORE C = 3
578 <write barrier>
579 STORE D = 4
580 STORE E = 5
581
582This sequence of events is committed to the memory coherence system in an order
583that the rest of the system might perceive as the unordered set of { STORE A,
584STORE B, STORE C } all occuring before the unordered set of { STORE D, STORE E
585}:
586
587 +-------+ : :
588 | | +------+
589 | |------>| C=3 | } /\
590 | | : +------+ }----- \ -----> Events perceptible
591 | | : | A=1 | } \/ to rest of system
592 | | : +------+ }
593 | CPU 1 | : | B=2 | }
594 | | +------+ }
595 | | wwwwwwwwwwwwwwww } <--- At this point the write barrier
596 | | +------+ } requires all stores prior to the
597 | | : | E=5 | } barrier to be committed before
598 | | : +------+ } further stores may be take place.
599 | |------>| D=4 | }
600 | | +------+
601 +-------+ : :
602 |
603 | Sequence in which stores committed to memory system
604 | by CPU 1
605 V
606
607
608Secondly, data dependency barriers act as a partial orderings on data-dependent
609loads. Consider the following sequence of events:
610
611 CPU 1 CPU 2
612 ======================= =======================
613 STORE A = 1
614 STORE B = 2
615 <write barrier>
616 STORE C = &B LOAD X
617 STORE D = 4 LOAD C (gets &B)
618 LOAD *C (reads B)
619
620Without intervention, CPU 2 may perceive the events on CPU 1 in some
621effectively random order, despite the write barrier issued by CPU 1:
622
623 +-------+ : : : :
624 | | +------+ +-------+ | Sequence of update
625 | |------>| B=2 |----- --->| Y->8 | | of perception on
626 | | : +------+ \ +-------+ | CPU 2
627 | CPU 1 | : | A=1 | \ --->| C->&Y | V
628 | | +------+ | +-------+
629 | | wwwwwwwwwwwwwwww | : :
630 | | +------+ | : :
631 | | : | C=&B |--- | : : +-------+
632 | | : +------+ \ | +-------+ | |
633 | |------>| D=4 | ----------->| C->&B |------>| |
634 | | +------+ | +-------+ | |
635 +-------+ : : | : : | |
636 | : : | |
637 | : : | CPU 2 |
638 | +-------+ | |
639 Apparently incorrect ---> | | B->7 |------>| |
640 perception of B (!) | +-------+ | |
641 | : : | |
642 | +-------+ | |
643 The load of X holds ---> \ | X->9 |------>| |
644 up the maintenance \ +-------+ | |
645 of coherence of B ----->| B->2 | +-------+
646 +-------+
647 : :
648
649
650In the above example, CPU 2 perceives that B is 7, despite the load of *C
651(which would be B) coming after the the LOAD of C.
652
653If, however, a data dependency barrier were to be placed between the load of C
654and the load of *C (ie: B) on CPU 2, then the following will occur:
655
656 +-------+ : : : :
657 | | +------+ +-------+
658 | |------>| B=2 |----- --->| Y->8 |
659 | | : +------+ \ +-------+
660 | CPU 1 | : | A=1 | \ --->| C->&Y |
661 | | +------+ | +-------+
662 | | wwwwwwwwwwwwwwww | : :
663 | | +------+ | : :
664 | | : | C=&B |--- | : : +-------+
665 | | : +------+ \ | +-------+ | |
666 | |------>| D=4 | ----------->| C->&B |------>| |
667 | | +------+ | +-------+ | |
668 +-------+ : : | : : | |
669 | : : | |
670 | : : | CPU 2 |
671 | +-------+ | |
672 \ | X->9 |------>| |
673 \ +-------+ | |
674 ----->| B->2 | | |
675 +-------+ | |
676 Makes sure all effects ---> ddddddddddddddddd | |
677 prior to the store of C +-------+ | |
678 are perceptible to | B->2 |------>| |
679 successive loads +-------+ | |
680 : : +-------+
681
682
683And thirdly, a read barrier acts as a partial order on loads. Consider the
684following sequence of events:
685
686 CPU 1 CPU 2
687 ======================= =======================
688 STORE A=1
689 STORE B=2
690 STORE C=3
691 <write barrier>
692 STORE D=4
693 STORE E=5
694 LOAD A
695 LOAD B
696 LOAD C
697 LOAD D
698 LOAD E
699
700Without intervention, CPU 2 may then choose to perceive the events on CPU 1 in
701some effectively random order, despite the write barrier issued by CPU 1:
702
703 +-------+ : :
704 | | +------+
705 | |------>| C=3 | }
706 | | : +------+ }
707 | | : | A=1 | }
708 | | : +------+ }
709 | CPU 1 | : | B=2 | }---
710 | | +------+ } \
711 | | wwwwwwwwwwwww} \
712 | | +------+ } \ : : +-------+
713 | | : | E=5 | } \ +-------+ | |
714 | | : +------+ } \ { | C->3 |------>| |
715 | |------>| D=4 | } \ { +-------+ : | |
716 | | +------+ \ { | E->5 | : | |
717 +-------+ : : \ { +-------+ : | |
718 Transfer -->{ | A->1 | : | CPU 2 |
719 from CPU 1 { +-------+ : | |
720 to CPU 2 { | D->4 | : | |
721 { +-------+ : | |
722 { | B->2 |------>| |
723 +-------+ | |
724 : : +-------+
725
726
727If, however, a read barrier were to be placed between the load of C and the
728load of D on CPU 2, then the partial ordering imposed by CPU 1 will be
729perceived correctly by CPU 2.
730
731 +-------+ : :
732 | | +------+
733 | |------>| C=3 | }
734 | | : +------+ }
735 | | : | A=1 | }---
736 | | : +------+ } \
737 | CPU 1 | : | B=2 | } \
738 | | +------+ \
739 | | wwwwwwwwwwwwwwww \
740 | | +------+ \ : : +-------+
741 | | : | E=5 | } \ +-------+ | |
742 | | : +------+ }--- \ { | C->3 |------>| |
743 | |------>| D=4 | } \ \ { +-------+ : | |
744 | | +------+ \ -->{ | B->2 | : | |
745 +-------+ : : \ { +-------+ : | |
746 \ { | A->1 | : | CPU 2 |
747 \ +-------+ | |
748 At this point the read ----> \ rrrrrrrrrrrrrrrrr | |
749 barrier causes all effects \ +-------+ | |
750 prior to the storage of C \ { | E->5 | : | |
751 to be perceptible to CPU 2 -->{ +-------+ : | |
752 { | D->4 |------>| |
753 +-------+ | |
754 : : +-------+
755
756
757========================
758EXPLICIT KERNEL BARRIERS
759========================
760
761The Linux kernel has a variety of different barriers that act at different
762levels:
763
764 (*) Compiler barrier.
765
766 (*) CPU memory barriers.
767
768 (*) MMIO write barrier.
769
770
771COMPILER BARRIER
772----------------
773
774The Linux kernel has an explicit compiler barrier function that prevents the
775compiler from moving the memory accesses either side of it to the other side:
776
777 barrier();
778
779This a general barrier - lesser varieties of compiler barrier do not exist.
780
781The compiler barrier has no direct effect on the CPU, which may then reorder
782things however it wishes.
783
784
785CPU MEMORY BARRIERS
786-------------------
787
788The Linux kernel has eight basic CPU memory barriers:
789
790 TYPE MANDATORY SMP CONDITIONAL
791 =============== ======================= ===========================
792 GENERAL mb() smp_mb()
793 WRITE wmb() smp_wmb()
794 READ rmb() smp_rmb()
795 DATA DEPENDENCY read_barrier_depends() smp_read_barrier_depends()
796
797
798All CPU memory barriers unconditionally imply compiler barriers.
799
800SMP memory barriers are reduced to compiler barriers on uniprocessor compiled
801systems because it is assumed that a CPU will be appear to be self-consistent,
802and will order overlapping accesses correctly with respect to itself.
803
804[!] Note that SMP memory barriers _must_ be used to control the ordering of
805references to shared memory on SMP systems, though the use of locking instead
806is sufficient.
807
808Mandatory barriers should not be used to control SMP effects, since mandatory
809barriers unnecessarily impose overhead on UP systems. They may, however, be
810used to control MMIO effects on accesses through relaxed memory I/O windows.
811These are required even on non-SMP systems as they affect the order in which
812memory operations appear to a device by prohibiting both the compiler and the
813CPU from reordering them.
814
815
816There are some more advanced barrier functions:
817
818 (*) set_mb(var, value)
819 (*) set_wmb(var, value)
820
821 These assign the value to the variable and then insert at least a write
822 barrier after it, depending on the function. They aren't guaranteed to
823 insert anything more than a compiler barrier in a UP compilation.
824
825
826 (*) smp_mb__before_atomic_dec();
827 (*) smp_mb__after_atomic_dec();
828 (*) smp_mb__before_atomic_inc();
829 (*) smp_mb__after_atomic_inc();
830
831 These are for use with atomic add, subtract, increment and decrement
832 functions, especially when used for reference counting. These functions
833 do not imply memory barriers.
834
835 As an example, consider a piece of code that marks an object as being dead
836 and then decrements the object's reference count:
837
838 obj->dead = 1;
839 smp_mb__before_atomic_dec();
840 atomic_dec(&obj->ref_count);
841
842 This makes sure that the death mark on the object is perceived to be set
843 *before* the reference counter is decremented.
844
845 See Documentation/atomic_ops.txt for more information. See the "Atomic
846 operations" subsection for information on where to use these.
847
848
849 (*) smp_mb__before_clear_bit(void);
850 (*) smp_mb__after_clear_bit(void);
851
852 These are for use similar to the atomic inc/dec barriers. These are
853 typically used for bitwise unlocking operations, so care must be taken as
854 there are no implicit memory barriers here either.
855
856 Consider implementing an unlock operation of some nature by clearing a
857 locking bit. The clear_bit() would then need to be barriered like this:
858
859 smp_mb__before_clear_bit();
860 clear_bit( ... );
861
862 This prevents memory operations before the clear leaking to after it. See
863 the subsection on "Locking Functions" with reference to UNLOCK operation
864 implications.
865
866 See Documentation/atomic_ops.txt for more information. See the "Atomic
867 operations" subsection for information on where to use these.
868
869
870MMIO WRITE BARRIER
871------------------
872
873The Linux kernel also has a special barrier for use with memory-mapped I/O
874writes:
875
876 mmiowb();
877
878This is a variation on the mandatory write barrier that causes writes to weakly
879ordered I/O regions to be partially ordered. Its effects may go beyond the
880CPU->Hardware interface and actually affect the hardware at some level.
881
882See the subsection "Locks vs I/O accesses" for more information.
883
884
885===============================
886IMPLICIT KERNEL MEMORY BARRIERS
887===============================
888
889Some of the other functions in the linux kernel imply memory barriers, amongst
890which are locking, scheduling and memory allocation functions.
891
892This specification is a _minimum_ guarantee; any particular architecture may
893provide more substantial guarantees, but these may not be relied upon outside
894of arch specific code.
895
896
897LOCKING FUNCTIONS
898-----------------
899
900The Linux kernel has a number of locking constructs:
901
902 (*) spin locks
903 (*) R/W spin locks
904 (*) mutexes
905 (*) semaphores
906 (*) R/W semaphores
907 (*) RCU
908
909In all cases there are variants on "LOCK" operations and "UNLOCK" operations
910for each construct. These operations all imply certain barriers:
911
912 (1) LOCK operation implication:
913
914 Memory operations issued after the LOCK will be completed after the LOCK
915 operation has completed.
916
917 Memory operations issued before the LOCK may be completed after the LOCK
918 operation has completed.
919
920 (2) UNLOCK operation implication:
921
922 Memory operations issued before the UNLOCK will be completed before the
923 UNLOCK operation has completed.
924
925 Memory operations issued after the UNLOCK may be completed before the
926 UNLOCK operation has completed.
927
928 (3) LOCK vs LOCK implication:
929
930 All LOCK operations issued before another LOCK operation will be completed
931 before that LOCK operation.
932
933 (4) LOCK vs UNLOCK implication:
934
935 All LOCK operations issued before an UNLOCK operation will be completed
936 before the UNLOCK operation.
937
938 All UNLOCK operations issued before a LOCK operation will be completed
939 before the LOCK operation.
940
941 (5) Failed conditional LOCK implication:
942
943 Certain variants of the LOCK operation may fail, either due to being
944 unable to get the lock immediately, or due to receiving an unblocked
945 signal whilst asleep waiting for the lock to become available. Failed
946 locks do not imply any sort of barrier.
947
948Therefore, from (1), (2) and (4) an UNLOCK followed by an unconditional LOCK is
949equivalent to a full barrier, but a LOCK followed by an UNLOCK is not.
950
951[!] Note: one of the consequence of LOCKs and UNLOCKs being only one-way
952 barriers is that the effects instructions outside of a critical section may
953 seep into the inside of the critical section.
954
955Locks and semaphores may not provide any guarantee of ordering on UP compiled
956systems, and so cannot be counted on in such a situation to actually achieve
957anything at all - especially with respect to I/O accesses - unless combined
958with interrupt disabling operations.
959
960See also the section on "Inter-CPU locking barrier effects".
961
962
963As an example, consider the following:
964
965 *A = a;
966 *B = b;
967 LOCK
968 *C = c;
969 *D = d;
970 UNLOCK
971 *E = e;
972 *F = f;
973
974The following sequence of events is acceptable:
975
976 LOCK, {*F,*A}, *E, {*C,*D}, *B, UNLOCK
977
978 [+] Note that {*F,*A} indicates a combined access.
979
980But none of the following are:
981
982 {*F,*A}, *B, LOCK, *C, *D, UNLOCK, *E
983 *A, *B, *C, LOCK, *D, UNLOCK, *E, *F
984 *A, *B, LOCK, *C, UNLOCK, *D, *E, *F
985 *B, LOCK, *C, *D, UNLOCK, {*F,*A}, *E
986
987
988
989INTERRUPT DISABLING FUNCTIONS
990-----------------------------
991
992Functions that disable interrupts (LOCK equivalent) and enable interrupts
993(UNLOCK equivalent) will act as compiler barriers only. So if memory or I/O
994barriers are required in such a situation, they must be provided from some
995other means.
996
997
998MISCELLANEOUS FUNCTIONS
999-----------------------
1000
1001Other functions that imply barriers:
1002
1003 (*) schedule() and similar imply full memory barriers.
1004
1005 (*) Memory allocation and release functions imply full memory barriers.
1006
1007
1008=================================
1009INTER-CPU LOCKING BARRIER EFFECTS
1010=================================
1011
1012On SMP systems locking primitives give a more substantial form of barrier: one
1013that does affect memory access ordering on other CPUs, within the context of
1014conflict on any particular lock.
1015
1016
1017LOCKS VS MEMORY ACCESSES
1018------------------------
1019
1020Consider the following: the system has a pair of spinlocks (N) and (Q), and
1021three CPUs; then should the following sequence of events occur:
1022
1023 CPU 1 CPU 2
1024 =============================== ===============================
1025 *A = a; *E = e;
1026 LOCK M LOCK Q
1027 *B = b; *F = f;
1028 *C = c; *G = g;
1029 UNLOCK M UNLOCK Q
1030 *D = d; *H = h;
1031
1032Then there is no guarantee as to what order CPU #3 will see the accesses to *A
1033through *H occur in, other than the constraints imposed by the separate locks
1034on the separate CPUs. It might, for example, see:
1035
1036 *E, LOCK M, LOCK Q, *G, *C, *F, *A, *B, UNLOCK Q, *D, *H, UNLOCK M
1037
1038But it won't see any of:
1039
1040 *B, *C or *D preceding LOCK M
1041 *A, *B or *C following UNLOCK M
1042 *F, *G or *H preceding LOCK Q
1043 *E, *F or *G following UNLOCK Q
1044
1045
1046However, if the following occurs:
1047
1048 CPU 1 CPU 2
1049 =============================== ===============================
1050 *A = a;
1051 LOCK M [1]
1052 *B = b;
1053 *C = c;
1054 UNLOCK M [1]
1055 *D = d; *E = e;
1056 LOCK M [2]
1057 *F = f;
1058 *G = g;
1059 UNLOCK M [2]
1060 *H = h;
1061
1062CPU #3 might see:
1063
1064 *E, LOCK M [1], *C, *B, *A, UNLOCK M [1],
1065 LOCK M [2], *H, *F, *G, UNLOCK M [2], *D
1066
1067But assuming CPU #1 gets the lock first, it won't see any of:
1068
1069 *B, *C, *D, *F, *G or *H preceding LOCK M [1]
1070 *A, *B or *C following UNLOCK M [1]
1071 *F, *G or *H preceding LOCK M [2]
1072 *A, *B, *C, *E, *F or *G following UNLOCK M [2]
1073
1074
1075LOCKS VS I/O ACCESSES
1076---------------------
1077
1078Under certain circumstances (especially involving NUMA), I/O accesses within
1079two spinlocked sections on two different CPUs may be seen as interleaved by the
1080PCI bridge, because the PCI bridge does not necessarily participate in the
1081cache-coherence protocol, and is therefore incapable of issuing the required
1082read memory barriers.
1083
1084For example:
1085
1086 CPU 1 CPU 2
1087 =============================== ===============================
1088 spin_lock(Q)
1089 writel(0, ADDR)
1090 writel(1, DATA);
1091 spin_unlock(Q);
1092 spin_lock(Q);
1093 writel(4, ADDR);
1094 writel(5, DATA);
1095 spin_unlock(Q);
1096
1097may be seen by the PCI bridge as follows:
1098
1099 STORE *ADDR = 0, STORE *ADDR = 4, STORE *DATA = 1, STORE *DATA = 5
1100
1101which would probably cause the hardware to malfunction.
1102
1103
1104What is necessary here is to intervene with an mmiowb() before dropping the
1105spinlock, for example:
1106
1107 CPU 1 CPU 2
1108 =============================== ===============================
1109 spin_lock(Q)
1110 writel(0, ADDR)
1111 writel(1, DATA);
1112 mmiowb();
1113 spin_unlock(Q);
1114 spin_lock(Q);
1115 writel(4, ADDR);
1116 writel(5, DATA);
1117 mmiowb();
1118 spin_unlock(Q);
1119
1120this will ensure that the two stores issued on CPU #1 appear at the PCI bridge
1121before either of the stores issued on CPU #2.
1122
1123
1124Furthermore, following a store by a load to the same device obviates the need
1125for an mmiowb(), because the load forces the store to complete before the load
1126is performed:
1127
1128 CPU 1 CPU 2
1129 =============================== ===============================
1130 spin_lock(Q)
1131 writel(0, ADDR)
1132 a = readl(DATA);
1133 spin_unlock(Q);
1134 spin_lock(Q);
1135 writel(4, ADDR);
1136 b = readl(DATA);
1137 spin_unlock(Q);
1138
1139
1140See Documentation/DocBook/deviceiobook.tmpl for more information.
1141
1142
1143=================================
1144WHERE ARE MEMORY BARRIERS NEEDED?
1145=================================
1146
1147Under normal operation, memory operation reordering is generally not going to
1148be a problem as a single-threaded linear piece of code will still appear to
1149work correctly, even if it's in an SMP kernel. There are, however, three
1150circumstances in which reordering definitely _could_ be a problem:
1151
1152 (*) Interprocessor interaction.
1153
1154 (*) Atomic operations.
1155
1156 (*) Accessing devices (I/O).
1157
1158 (*) Interrupts.
1159
1160
1161INTERPROCESSOR INTERACTION
1162--------------------------
1163
1164When there's a system with more than one processor, more than one CPU in the
1165system may be working on the same data set at the same time. This can cause
1166synchronisation problems, and the usual way of dealing with them is to use
1167locks. Locks, however, are quite expensive, and so it may be preferable to
1168operate without the use of a lock if at all possible. In such a case
1169operations that affect both CPUs may have to be carefully ordered to prevent
1170a malfunction.
1171
1172Consider, for example, the R/W semaphore slow path. Here a waiting process is
1173queued on the semaphore, by virtue of it having a piece of its stack linked to
1174the semaphore's list of waiting processes:
1175
1176 struct rw_semaphore {
1177 ...
1178 spinlock_t lock;
1179 struct list_head waiters;
1180 };
1181
1182 struct rwsem_waiter {
1183 struct list_head list;
1184 struct task_struct *task;
1185 };
1186
1187To wake up a particular waiter, the up_read() or up_write() functions have to:
1188
1189 (1) read the next pointer from this waiter's record to know as to where the
1190 next waiter record is;
1191
1192 (4) read the pointer to the waiter's task structure;
1193
1194 (3) clear the task pointer to tell the waiter it has been given the semaphore;
1195
1196 (4) call wake_up_process() on the task; and
1197
1198 (5) release the reference held on the waiter's task struct.
1199
1200In otherwords, it has to perform this sequence of events:
1201
1202 LOAD waiter->list.next;
1203 LOAD waiter->task;
1204 STORE waiter->task;
1205 CALL wakeup
1206 RELEASE task
1207
1208and if any of these steps occur out of order, then the whole thing may
1209malfunction.
1210
1211Once it has queued itself and dropped the semaphore lock, the waiter does not
1212get the lock again; it instead just waits for its task pointer to be cleared
1213before proceeding. Since the record is on the waiter's stack, this means that
1214if the task pointer is cleared _before_ the next pointer in the list is read,
1215another CPU might start processing the waiter and might clobber the waiter's
1216stack before the up*() function has a chance to read the next pointer.
1217
1218Consider then what might happen to the above sequence of events:
1219
1220 CPU 1 CPU 2
1221 =============================== ===============================
1222 down_xxx()
1223 Queue waiter
1224 Sleep
1225 up_yyy()
1226 LOAD waiter->task;
1227 STORE waiter->task;
1228 Woken up by other event
1229 <preempt>
1230 Resume processing
1231 down_xxx() returns
1232 call foo()
1233 foo() clobbers *waiter
1234 </preempt>
1235 LOAD waiter->list.next;
1236 --- OOPS ---
1237
1238This could be dealt with using the semaphore lock, but then the down_xxx()
1239function has to needlessly get the spinlock again after being woken up.
1240
1241The way to deal with this is to insert a general SMP memory barrier:
1242
1243 LOAD waiter->list.next;
1244 LOAD waiter->task;
1245 smp_mb();
1246 STORE waiter->task;
1247 CALL wakeup
1248 RELEASE task
1249
1250In this case, the barrier makes a guarantee that all memory accesses before the
1251barrier will appear to happen before all the memory accesses after the barrier
1252with respect to the other CPUs on the system. It does _not_ guarantee that all
1253the memory accesses before the barrier will be complete by the time the barrier
1254instruction itself is complete.
1255
1256On a UP system - where this wouldn't be a problem - the smp_mb() is just a
1257compiler barrier, thus making sure the compiler emits the instructions in the
1258right order without actually intervening in the CPU. Since there there's only
1259one CPU, that CPU's dependency ordering logic will take care of everything
1260else.
1261
1262
1263ATOMIC OPERATIONS
1264-----------------
1265
1266Though they are technically interprocessor interaction considerations, atomic
1267operations are noted specially as they do _not_ generally imply memory
1268barriers. The possible offenders include:
1269
1270 xchg();
1271 cmpxchg();
1272 test_and_set_bit();
1273 test_and_clear_bit();
1274 test_and_change_bit();
1275 atomic_cmpxchg();
1276 atomic_inc_return();
1277 atomic_dec_return();
1278 atomic_add_return();
1279 atomic_sub_return();
1280 atomic_inc_and_test();
1281 atomic_dec_and_test();
1282 atomic_sub_and_test();
1283 atomic_add_negative();
1284 atomic_add_unless();
1285
1286These may be used for such things as implementing LOCK operations or controlling
1287the lifetime of objects by decreasing their reference counts. In such cases
1288they need preceding memory barriers.
1289
1290The following may also be possible offenders as they may be used as UNLOCK
1291operations.
1292
1293 set_bit();
1294 clear_bit();
1295 change_bit();
1296 atomic_set();
1297
1298
1299The following are a little tricky:
1300
1301 atomic_add();
1302 atomic_sub();
1303 atomic_inc();
1304 atomic_dec();
1305
1306If they're used for statistics generation, then they probably don't need memory
1307barriers, unless there's a coupling between statistical data.
1308
1309If they're used for reference counting on an object to control its lifetime,
1310they probably don't need memory barriers because either the reference count
1311will be adjusted inside a locked section, or the caller will already hold
1312sufficient references to make the lock, and thus a memory barrier unnecessary.
1313
1314If they're used for constructing a lock of some description, then they probably
1315do need memory barriers as a lock primitive generally has to do things in a
1316specific order.
1317
1318
1319Basically, each usage case has to be carefully considered as to whether memory
1320barriers are needed or not. The simplest rule is probably: if the atomic
1321operation is protected by a lock, then it does not require a barrier unless
1322there's another operation within the critical section with respect to which an
1323ordering must be maintained.
1324
1325See Documentation/atomic_ops.txt for more information.
1326
1327
1328ACCESSING DEVICES
1329-----------------
1330
1331Many devices can be memory mapped, and so appear to the CPU as if they're just
1332a set of memory locations. To control such a device, the driver usually has to
1333make the right memory accesses in exactly the right order.
1334
1335However, having a clever CPU or a clever compiler creates a potential problem
1336in that the carefully sequenced accesses in the driver code won't reach the
1337device in the requisite order if the CPU or the compiler thinks it is more
1338efficient to reorder, combine or merge accesses - something that would cause
1339the device to malfunction.
1340
1341Inside of the Linux kernel, I/O should be done through the appropriate accessor
1342routines - such as inb() or writel() - which know how to make such accesses
1343appropriately sequential. Whilst this, for the most part, renders the explicit
1344use of memory barriers unnecessary, there are a couple of situations where they
1345might be needed:
1346
1347 (1) On some systems, I/O stores are not strongly ordered across all CPUs, and
1348 so for _all_ general drivers locks should be used and mmiowb() must be
1349 issued prior to unlocking the critical section.
1350
1351 (2) If the accessor functions are used to refer to an I/O memory window with
1352 relaxed memory access properties, then _mandatory_ memory barriers are
1353 required to enforce ordering.
1354
1355See Documentation/DocBook/deviceiobook.tmpl for more information.
1356
1357
1358INTERRUPTS
1359----------
1360
1361A driver may be interrupted by its own interrupt service routine, and thus the
1362two parts of the driver may interfere with each other's attempts to control or
1363access the device.
1364
1365This may be alleviated - at least in part - by disabling local interrupts (a
1366form of locking), such that the critical operations are all contained within
1367the interrupt-disabled section in the driver. Whilst the driver's interrupt
1368routine is executing, the driver's core may not run on the same CPU, and its
1369interrupt is not permitted to happen again until the current interrupt has been
1370handled, thus the interrupt handler does not need to lock against that.
1371
1372However, consider a driver that was talking to an ethernet card that sports an
1373address register and a data register. If that driver's core talks to the card
1374under interrupt-disablement and then the driver's interrupt handler is invoked:
1375
1376 LOCAL IRQ DISABLE
1377 writew(ADDR, 3);
1378 writew(DATA, y);
1379 LOCAL IRQ ENABLE
1380 <interrupt>
1381 writew(ADDR, 4);
1382 q = readw(DATA);
1383 </interrupt>
1384
1385The store to the data register might happen after the second store to the
1386address register if ordering rules are sufficiently relaxed:
1387
1388 STORE *ADDR = 3, STORE *ADDR = 4, STORE *DATA = y, q = LOAD *DATA
1389
1390
1391If ordering rules are relaxed, it must be assumed that accesses done inside an
1392interrupt disabled section may leak outside of it and may interleave with
1393accesses performed in an interrupt - and vice versa - unless implicit or
1394explicit barriers are used.
1395
1396Normally this won't be a problem because the I/O accesses done inside such
1397sections will include synchronous load operations on strictly ordered I/O
1398registers that form implicit I/O barriers. If this isn't sufficient then an
1399mmiowb() may need to be used explicitly.
1400
1401
1402A similar situation may occur between an interrupt routine and two routines
1403running on separate CPUs that communicate with each other. If such a case is
1404likely, then interrupt-disabling locks should be used to guarantee ordering.
1405
1406
1407==========================
1408KERNEL I/O BARRIER EFFECTS
1409==========================
1410
1411When accessing I/O memory, drivers should use the appropriate accessor
1412functions:
1413
1414 (*) inX(), outX():
1415
1416 These are intended to talk to I/O space rather than memory space, but
1417 that's primarily a CPU-specific concept. The i386 and x86_64 processors do
1418 indeed have special I/O space access cycles and instructions, but many
1419 CPUs don't have such a concept.
1420
1421 The PCI bus, amongst others, defines an I/O space concept - which on such
1422 CPUs as i386 and x86_64 cpus readily maps to the CPU's concept of I/O
1423 space. However, it may also mapped as a virtual I/O space in the CPU's
1424 memory map, particularly on those CPUs that don't support alternate
1425 I/O spaces.
1426
1427 Accesses to this space may be fully synchronous (as on i386), but
1428 intermediary bridges (such as the PCI host bridge) may not fully honour
1429 that.
1430
1431 They are guaranteed to be fully ordered with respect to each other.
1432
1433 They are not guaranteed to be fully ordered with respect to other types of
1434 memory and I/O operation.
1435
1436 (*) readX(), writeX():
1437
1438 Whether these are guaranteed to be fully ordered and uncombined with
1439 respect to each other on the issuing CPU depends on the characteristics
1440 defined for the memory window through which they're accessing. On later
1441 i386 architecture machines, for example, this is controlled by way of the
1442 MTRR registers.
1443
1444 Ordinarily, these will be guaranteed to be fully ordered and uncombined,,
1445 provided they're not accessing a prefetchable device.
1446
1447 However, intermediary hardware (such as a PCI bridge) may indulge in
1448 deferral if it so wishes; to flush a store, a load from the same location
1449 is preferred[*], but a load from the same device or from configuration
1450 space should suffice for PCI.
1451
1452 [*] NOTE! attempting to load from the same location as was written to may
1453 cause a malfunction - consider the 16550 Rx/Tx serial registers for
1454 example.
1455
1456 Used with prefetchable I/O memory, an mmiowb() barrier may be required to
1457 force stores to be ordered.
1458
1459 Please refer to the PCI specification for more information on interactions
1460 between PCI transactions.
1461
1462 (*) readX_relaxed()
1463
1464 These are similar to readX(), but are not guaranteed to be ordered in any
1465 way. Be aware that there is no I/O read barrier available.
1466
1467 (*) ioreadX(), iowriteX()
1468
1469 These will perform as appropriate for the type of access they're actually
1470 doing, be it inX()/outX() or readX()/writeX().
1471
1472
1473========================================
1474ASSUMED MINIMUM EXECUTION ORDERING MODEL
1475========================================
1476
1477It has to be assumed that the conceptual CPU is weakly-ordered but that it will
1478maintain the appearance of program causality with respect to itself. Some CPUs
1479(such as i386 or x86_64) are more constrained than others (such as powerpc or
1480frv), and so the most relaxed case (namely DEC Alpha) must be assumed outside
1481of arch-specific code.
1482
1483This means that it must be considered that the CPU will execute its instruction
1484stream in any order it feels like - or even in parallel - provided that if an
1485instruction in the stream depends on the an earlier instruction, then that
1486earlier instruction must be sufficiently complete[*] before the later
1487instruction may proceed; in other words: provided that the appearance of
1488causality is maintained.
1489
1490 [*] Some instructions have more than one effect - such as changing the
1491 condition codes, changing registers or changing memory - and different
1492 instructions may depend on different effects.
1493
1494A CPU may also discard any instruction sequence that winds up having no
1495ultimate effect. For example, if two adjacent instructions both load an
1496immediate value into the same register, the first may be discarded.
1497
1498
1499Similarly, it has to be assumed that compiler might reorder the instruction
1500stream in any way it sees fit, again provided the appearance of causality is
1501maintained.
1502
1503
1504============================
1505THE EFFECTS OF THE CPU CACHE
1506============================
1507
1508The way cached memory operations are perceived across the system is affected to
1509a certain extent by the caches that lie between CPUs and memory, and by the
1510memory coherence system that maintains the consistency of state in the system.
1511
1512As far as the way a CPU interacts with another part of the system through the
1513caches goes, the memory system has to include the CPU's caches, and memory
1514barriers for the most part act at the interface between the CPU and its cache
1515(memory barriers logically act on the dotted line in the following diagram):
1516
1517 <--- CPU ---> : <----------- Memory ----------->
1518 :
1519 +--------+ +--------+ : +--------+ +-----------+
1520 | | | | : | | | | +--------+
1521 | CPU | | Memory | : | CPU | | | | |
1522 | Core |--->| Access |----->| Cache |<-->| | | |
1523 | | | Queue | : | | | |--->| Memory |
1524 | | | | : | | | | | |
1525 +--------+ +--------+ : +--------+ | | | |
1526 : | Cache | +--------+
1527 : | Coherency |
1528 : | Mechanism | +--------+
1529 +--------+ +--------+ : +--------+ | | | |
1530 | | | | : | | | | | |
1531 | CPU | | Memory | : | CPU | | |--->| Device |
1532 | Core |--->| Access |----->| Cache |<-->| | | |
1533 | | | Queue | : | | | | | |
1534 | | | | : | | | | +--------+
1535 +--------+ +--------+ : +--------+ +-----------+
1536 :
1537 :
1538
1539Although any particular load or store may not actually appear outside of the
1540CPU that issued it since it may have been satisfied within the CPU's own cache,
1541it will still appear as if the full memory access had taken place as far as the
1542other CPUs are concerned since the cache coherency mechanisms will migrate the
1543cacheline over to the accessing CPU and propagate the effects upon conflict.
1544
1545The CPU core may execute instructions in any order it deems fit, provided the
1546expected program causality appears to be maintained. Some of the instructions
1547generate load and store operations which then go into the queue of memory
1548accesses to be performed. The core may place these in the queue in any order
1549it wishes, and continue execution until it is forced to wait for an instruction
1550to complete.
1551
1552What memory barriers are concerned with is controlling the order in which
1553accesses cross from the CPU side of things to the memory side of things, and
1554the order in which the effects are perceived to happen by the other observers
1555in the system.
1556
1557[!] Memory barriers are _not_ needed within a given CPU, as CPUs always see
1558their own loads and stores as if they had happened in program order.
1559
1560[!] MMIO or other device accesses may bypass the cache system. This depends on
1561the properties of the memory window through which devices are accessed and/or
1562the use of any special device communication instructions the CPU may have.
1563
1564
1565CACHE COHERENCY
1566---------------
1567
1568Life isn't quite as simple as it may appear above, however: for while the
1569caches are expected to be coherent, there's no guarantee that that coherency
1570will be ordered. This means that whilst changes made on one CPU will
1571eventually become visible on all CPUs, there's no guarantee that they will
1572become apparent in the same order on those other CPUs.
1573
1574
1575Consider dealing with a system that has pair of CPUs (1 & 2), each of which has
1576a pair of parallel data caches (CPU 1 has A/B, and CPU 2 has C/D):
1577
1578 :
1579 : +--------+
1580 : +---------+ | |
1581 +--------+ : +--->| Cache A |<------->| |
1582 | | : | +---------+ | |
1583 | CPU 1 |<---+ | |
1584 | | : | +---------+ | |
1585 +--------+ : +--->| Cache B |<------->| |
1586 : +---------+ | |
1587 : | Memory |
1588 : +---------+ | System |
1589 +--------+ : +--->| Cache C |<------->| |
1590 | | : | +---------+ | |
1591 | CPU 2 |<---+ | |
1592 | | : | +---------+ | |
1593 +--------+ : +--->| Cache D |<------->| |
1594 : +---------+ | |
1595 : +--------+
1596 :
1597
1598Imagine the system has the following properties:
1599
1600 (*) an odd-numbered cache line may be in cache A, cache C or it may still be
1601 resident in memory;
1602
1603 (*) an even-numbered cache line may be in cache B, cache D or it may still be
1604 resident in memory;
1605
1606 (*) whilst the CPU core is interrogating one cache, the other cache may be
1607 making use of the bus to access the rest of the system - perhaps to
1608 displace a dirty cacheline or to do a speculative load;
1609
1610 (*) each cache has a queue of operations that need to be applied to that cache
1611 to maintain coherency with the rest of the system;
1612
1613 (*) the coherency queue is not flushed by normal loads to lines already
1614 present in the cache, even though the contents of the queue may
1615 potentially effect those loads.
1616
1617Imagine, then, that two writes are made on the first CPU, with a write barrier
1618between them to guarantee that they will appear to reach that CPU's caches in
1619the requisite order:
1620
1621 CPU 1 CPU 2 COMMENT
1622 =============== =============== =======================================
1623 u == 0, v == 1 and p == &u, q == &u
1624 v = 2;
1625 smp_wmb(); Make sure change to v visible before
1626 change to p
1627 <A:modify v=2> v is now in cache A exclusively
1628 p = &v;
1629 <B:modify p=&v> p is now in cache B exclusively
1630
1631The write memory barrier forces the other CPUs in the system to perceive that
1632the local CPU's caches have apparently been updated in the correct order. But
1633now imagine that the second CPU that wants to read those values:
1634
1635 CPU 1 CPU 2 COMMENT
1636 =============== =============== =======================================
1637 ...
1638 q = p;
1639 x = *q;
1640
1641The above pair of reads may then fail to happen in expected order, as the
1642cacheline holding p may get updated in one of the second CPU's caches whilst
1643the update to the cacheline holding v is delayed in the other of the second
1644CPU's caches by some other cache event:
1645
1646 CPU 1 CPU 2 COMMENT
1647 =============== =============== =======================================
1648 u == 0, v == 1 and p == &u, q == &u
1649 v = 2;
1650 smp_wmb();
1651 <A:modify v=2> <C:busy>
1652 <C:queue v=2>
1653 p = &b; q = p;
1654 <D:request p>
1655 <B:modify p=&v> <D:commit p=&v>
1656 <D:read p>
1657 x = *q;
1658 <C:read *q> Reads from v before v updated in cache
1659 <C:unbusy>
1660 <C:commit v=2>
1661
1662Basically, whilst both cachelines will be updated on CPU 2 eventually, there's
1663no guarantee that, without intervention, the order of update will be the same
1664as that committed on CPU 1.
1665
1666
1667To intervene, we need to interpolate a data dependency barrier or a read
1668barrier between the loads. This will force the cache to commit its coherency
1669queue before processing any further requests:
1670
1671 CPU 1 CPU 2 COMMENT
1672 =============== =============== =======================================
1673 u == 0, v == 1 and p == &u, q == &u
1674 v = 2;
1675 smp_wmb();
1676 <A:modify v=2> <C:busy>
1677 <C:queue v=2>
1678 p = &b; q = p;
1679 <D:request p>
1680 <B:modify p=&v> <D:commit p=&v>
1681 <D:read p>
1682 smp_read_barrier_depends()
1683 <C:unbusy>
1684 <C:commit v=2>
1685 x = *q;
1686 <C:read *q> Reads from v after v updated in cache
1687
1688
1689This sort of problem can be encountered on DEC Alpha processors as they have a
1690split cache that improves performance by making better use of the data bus.
1691Whilst most CPUs do imply a data dependency barrier on the read when a memory
1692access depends on a read, not all do, so it may not be relied on.
1693
1694Other CPUs may also have split caches, but must coordinate between the various
1695cachelets for normal memory accesss. The semantics of the Alpha removes the
1696need for coordination in absence of memory barriers.
1697
1698
1699CACHE COHERENCY VS DMA
1700----------------------
1701
1702Not all systems maintain cache coherency with respect to devices doing DMA. In
1703such cases, a device attempting DMA may obtain stale data from RAM because
1704dirty cache lines may be resident in the caches of various CPUs, and may not
1705have been written back to RAM yet. To deal with this, the appropriate part of
1706the kernel must flush the overlapping bits of cache on each CPU (and maybe
1707invalidate them as well).
1708
1709In addition, the data DMA'd to RAM by a device may be overwritten by dirty
1710cache lines being written back to RAM from a CPU's cache after the device has
1711installed its own data, or cache lines simply present in a CPUs cache may
1712simply obscure the fact that RAM has been updated, until at such time as the
1713cacheline is discarded from the CPU's cache and reloaded. To deal with this,
1714the appropriate part of the kernel must invalidate the overlapping bits of the
1715cache on each CPU.
1716
1717See Documentation/cachetlb.txt for more information on cache management.
1718
1719
1720CACHE COHERENCY VS MMIO
1721-----------------------
1722
1723Memory mapped I/O usually takes place through memory locations that are part of
1724a window in the CPU's memory space that have different properties assigned than
1725the usual RAM directed window.
1726
1727Amongst these properties is usually the fact that such accesses bypass the
1728caching entirely and go directly to the device buses. This means MMIO accesses
1729may, in effect, overtake accesses to cached memory that were emitted earlier.
1730A memory barrier isn't sufficient in such a case, but rather the cache must be
1731flushed between the cached memory write and the MMIO access if the two are in
1732any way dependent.
1733
1734
1735=========================
1736THE THINGS CPUS GET UP TO
1737=========================
1738
1739A programmer might take it for granted that the CPU will perform memory
1740operations in exactly the order specified, so that if a CPU is, for example,
1741given the following piece of code to execute:
1742
1743 a = *A;
1744 *B = b;
1745 c = *C;
1746 d = *D;
1747 *E = e;
1748
1749They would then expect that the CPU will complete the memory operation for each
1750instruction before moving on to the next one, leading to a definite sequence of
1751operations as seen by external observers in the system:
1752
1753 LOAD *A, STORE *B, LOAD *C, LOAD *D, STORE *E.
1754
1755
1756Reality is, of course, much messier. With many CPUs and compilers, the above
1757assumption doesn't hold because:
1758
1759 (*) loads are more likely to need to be completed immediately to permit
1760 execution progress, whereas stores can often be deferred without a
1761 problem;
1762
1763 (*) loads may be done speculatively, and the result discarded should it prove
1764 to have been unnecessary;
1765
1766 (*) loads may be done speculatively, leading to the result having being
1767 fetched at the wrong time in the expected sequence of events;
1768
1769 (*) the order of the memory accesses may be rearranged to promote better use
1770 of the CPU buses and caches;
1771
1772 (*) loads and stores may be combined to improve performance when talking to
1773 memory or I/O hardware that can do batched accesses of adjacent locations,
1774 thus cutting down on transaction setup costs (memory and PCI devices may
1775 both be able to do this); and
1776
1777 (*) the CPU's data cache may affect the ordering, and whilst cache-coherency
1778 mechanisms may alleviate this - once the store has actually hit the cache
1779 - there's no guarantee that the coherency management will be propagated in
1780 order to other CPUs.
1781
1782So what another CPU, say, might actually observe from the above piece of code
1783is:
1784
1785 LOAD *A, ..., LOAD {*C,*D}, STORE *E, STORE *B
1786
1787 (Where "LOAD {*C,*D}" is a combined load)
1788
1789
1790However, it is guaranteed that a CPU will be self-consistent: it will see its
1791_own_ accesses appear to be correctly ordered, without the need for a memory
1792barrier. For instance with the following code:
1793
1794 U = *A;
1795 *A = V;
1796 *A = W;
1797 X = *A;
1798 *A = Y;
1799 Z = *A;
1800
1801and assuming no intervention by an external influence, it can be assumed that
1802the final result will appear to be:
1803
1804 U == the original value of *A
1805 X == W
1806 Z == Y
1807 *A == Y
1808
1809The code above may cause the CPU to generate the full sequence of memory
1810accesses:
1811
1812 U=LOAD *A, STORE *A=V, STORE *A=W, X=LOAD *A, STORE *A=Y, Z=LOAD *A
1813
1814in that order, but, without intervention, the sequence may have almost any
1815combination of elements combined or discarded, provided the program's view of
1816the world remains consistent.
1817
1818The compiler may also combine, discard or defer elements of the sequence before
1819the CPU even sees them.
1820
1821For instance:
1822
1823 *A = V;
1824 *A = W;
1825
1826may be reduced to:
1827
1828 *A = W;
1829
1830since, without a write barrier, it can be assumed that the effect of the
1831storage of V to *A is lost. Similarly:
1832
1833 *A = Y;
1834 Z = *A;
1835
1836may, without a memory barrier, be reduced to:
1837
1838 *A = Y;
1839 Z = Y;
1840
1841and the LOAD operation never appear outside of the CPU.
1842
1843
1844AND THEN THERE'S THE ALPHA
1845--------------------------
1846
1847The DEC Alpha CPU is one of the most relaxed CPUs there is. Not only that,
1848some versions of the Alpha CPU have a split data cache, permitting them to have
1849two semantically related cache lines updating at separate times. This is where
1850the data dependency barrier really becomes necessary as this synchronises both
1851caches with the memory coherence system, thus making it seem like pointer
1852changes vs new data occur in the right order.
1853
1854The Alpha defines the Linux's kernel's memory barrier model.
1855
1856See the subsection on "Cache Coherency" above.
1857
1858
1859==========
1860REFERENCES
1861==========
1862
1863Alpha AXP Architecture Reference Manual, Second Edition (Sites & Witek,
1864Digital Press)
1865 Chapter 5.2: Physical Address Space Characteristics
1866 Chapter 5.4: Caches and Write Buffers
1867 Chapter 5.5: Data Sharing
1868 Chapter 5.6: Read/Write Ordering
1869
1870AMD64 Architecture Programmer's Manual Volume 2: System Programming
1871 Chapter 7.1: Memory-Access Ordering
1872 Chapter 7.4: Buffering and Combining Memory Writes
1873
1874IA-32 Intel Architecture Software Developer's Manual, Volume 3:
1875System Programming Guide
1876 Chapter 7.1: Locked Atomic Operations
1877 Chapter 7.2: Memory Ordering
1878 Chapter 7.4: Serializing Instructions
1879
1880The SPARC Architecture Manual, Version 9
1881 Chapter 8: Memory Models
1882 Appendix D: Formal Specification of the Memory Models
1883 Appendix J: Programming with the Memory Models
1884
1885UltraSPARC Programmer Reference Manual
1886 Chapter 5: Memory Accesses and Cacheability
1887 Chapter 15: Sparc-V9 Memory Models
1888
1889UltraSPARC III Cu User's Manual
1890 Chapter 9: Memory Models
1891
1892UltraSPARC IIIi Processor User's Manual
1893 Chapter 8: Memory Models
1894
1895UltraSPARC Architecture 2005
1896 Chapter 9: Memory
1897 Appendix D: Formal Specifications of the Memory Models
1898
1899UltraSPARC T1 Supplement to the UltraSPARC Architecture 2005
1900 Chapter 8: Memory Models
1901 Appendix F: Caches and Cache Coherency
1902
1903Solaris Internals, Core Kernel Architecture, p63-68:
1904 Chapter 3.3: Hardware Considerations for Locks and
1905 Synchronization
1906
1907Unix Systems for Modern Architectures, Symmetric Multiprocessing and Caching
1908for Kernel Programmers:
1909 Chapter 13: Other Memory Models
1910
1911Intel Itanium Architecture Software Developer's Manual: Volume 1:
1912 Section 2.6: Speculation
1913 Section 4.4: Memory Access
diff --git a/Documentation/networking/TODO b/Documentation/networking/TODO
deleted file mode 100644
index 66d36ff14bae..000000000000
--- a/Documentation/networking/TODO
+++ /dev/null
@@ -1,18 +0,0 @@
1To-do items for network drivers
2-------------------------------
3
4* Move ethernet crc routine to generic code
5
6* (for 2.5) Integrate Jamal Hadi Salim's netdev Rx polling API change
7
8* Audit all net drivers to make sure magic packet / wake-on-lan /
9 similar features are disabled in the driver by default.
10
11* Audit all net drivers to make sure the module always prints out a
12 version string when loaded as a module, but only prints a version
13 string when built into the kernel if a device is detected.
14
15* Add ETHTOOL_GDRVINFO ioctl support to all ethernet drivers.
16
17* dmfe PCI DMA is totally wrong and only works on x86
18
diff --git a/Documentation/networking/bcm43xx.txt b/Documentation/networking/bcm43xx.txt
new file mode 100644
index 000000000000..28541d2bee1e
--- /dev/null
+++ b/Documentation/networking/bcm43xx.txt
@@ -0,0 +1,36 @@
1
2 BCM43xx Linux Driver Project
3 ============================
4
5About this software
6-------------------
7
8The goal of this project is to develop a linux driver for Broadcom
9BCM43xx chips, based on the specification at
10http://bcm-specs.sipsolutions.net/
11
12The project page is http://bcm43xx.berlios.de/
13
14
15Requirements
16------------
17
181) Linux Kernel 2.6.16 or later
19 http://www.kernel.org/
20
21 You may want to configure your kernel with:
22
23 CONFIG_DEBUG_FS (optional):
24 -> Kernel hacking
25 -> Debug Filesystem
26
272) SoftMAC IEEE 802.11 Networking Stack extension and patched ieee80211
28 modules:
29 http://softmac.sipsolutions.net/
30
313) Firmware Files
32
33 Please try fwcutter. Fwcutter can extract the firmware from various
34 binary driver files. It supports driver files from Windows, MacOS and
35 Linux. You can get fwcutter from http://bcm43xx.berlios.de/.
36 Also, fwcutter comes with a README file for further instructions.
diff --git a/Documentation/powerpc/booting-without-of.txt b/Documentation/powerpc/booting-without-of.txt
index ee551c6ea235..217e51768b87 100644
--- a/Documentation/powerpc/booting-without-of.txt
+++ b/Documentation/powerpc/booting-without-of.txt
@@ -719,6 +719,11 @@ address which can extend beyond that limit.
719 - model : this is your board name/model 719 - model : this is your board name/model
720 - #address-cells : address representation for "root" devices 720 - #address-cells : address representation for "root" devices
721 - #size-cells: the size representation for "root" devices 721 - #size-cells: the size representation for "root" devices
722 - device_type : This property shouldn't be necessary. However, if
723 you decide to create a device_type for your root node, make sure it
724 is _not_ "chrp" unless your platform is a pSeries or PAPR compliant
725 one for 64-bit, or a CHRP-type machine for 32-bit as this will
726 matched by the kernel this way.
722 727
723 Additionally, some recommended properties are: 728 Additionally, some recommended properties are:
724 729
diff --git a/MAINTAINERS b/MAINTAINERS
index e5b051f0e27e..c9465811addc 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1885,6 +1885,7 @@ NETWORKING [GENERAL]
1885P: Networking Team 1885P: Networking Team
1886M: netdev@vger.kernel.org 1886M: netdev@vger.kernel.org
1887L: netdev@vger.kernel.org 1887L: netdev@vger.kernel.org
1888W: http://linux-net.osdl.org/
1888S: Maintained 1889S: Maintained
1889 1890
1890NETWORKING [IPv4/IPv6] 1891NETWORKING [IPv4/IPv6]
diff --git a/arch/alpha/kernel/alpha_ksyms.c b/arch/alpha/kernel/alpha_ksyms.c
index 1898ea79d0e2..9d6186d50245 100644
--- a/arch/alpha/kernel/alpha_ksyms.c
+++ b/arch/alpha/kernel/alpha_ksyms.c
@@ -216,8 +216,6 @@ EXPORT_SYMBOL(memcpy);
216EXPORT_SYMBOL(memset); 216EXPORT_SYMBOL(memset);
217EXPORT_SYMBOL(memchr); 217EXPORT_SYMBOL(memchr);
218 218
219EXPORT_SYMBOL(get_wchan);
220
221#ifdef CONFIG_ALPHA_IRONGATE 219#ifdef CONFIG_ALPHA_IRONGATE
222EXPORT_SYMBOL(irongate_ioremap); 220EXPORT_SYMBOL(irongate_ioremap);
223EXPORT_SYMBOL(irongate_iounmap); 221EXPORT_SYMBOL(irongate_iounmap);
diff --git a/arch/alpha/kernel/core_marvel.c b/arch/alpha/kernel/core_marvel.c
index 44866cb26a80..7f6a98455e74 100644
--- a/arch/alpha/kernel/core_marvel.c
+++ b/arch/alpha/kernel/core_marvel.c
@@ -435,7 +435,7 @@ marvel_specify_io7(char *str)
435 str = pchar; 435 str = pchar;
436 } while(*str); 436 } while(*str);
437 437
438 return 0; 438 return 1;
439} 439}
440__setup("io7=", marvel_specify_io7); 440__setup("io7=", marvel_specify_io7);
441 441
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index ba46d779ede7..dc5a9332c915 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -77,6 +77,14 @@ config FIQ
77config ARCH_MTD_XIP 77config ARCH_MTD_XIP
78 bool 78 bool
79 79
80config VECTORS_BASE
81 hex
82 default 0xffff0000 if MMU
83 default DRAM_BASE if REMAP_VECTORS_TO_RAM
84 default 0x00000000
85 help
86 The base address of exception vectors.
87
80source "init/Kconfig" 88source "init/Kconfig"
81 89
82menu "System Type" 90menu "System Type"
@@ -839,6 +847,8 @@ source "drivers/misc/Kconfig"
839 847
840source "drivers/mfd/Kconfig" 848source "drivers/mfd/Kconfig"
841 849
850source "drivers/leds/Kconfig"
851
842source "drivers/media/Kconfig" 852source "drivers/media/Kconfig"
843 853
844source "drivers/video/Kconfig" 854source "drivers/video/Kconfig"
diff --git a/arch/arm/Kconfig-nommu b/arch/arm/Kconfig-nommu
new file mode 100644
index 000000000000..e1574be2ded6
--- /dev/null
+++ b/arch/arm/Kconfig-nommu
@@ -0,0 +1,44 @@
1#
2# Kconfig for uClinux(non-paged MM) depend configurations
3# Hyok S. Choi <hyok.choi@samsung.com>
4#
5
6config SET_MEM_PARAM
7 bool "Set flash/sdram size and base addr"
8 help
9 Say Y to manually set the base addresses and sizes.
10 otherwise, the default values are assigned.
11
12config DRAM_BASE
13 hex '(S)DRAM Base Address' if SET_MEM_PARAM
14 default 0x00800000
15
16config DRAM_SIZE
17 hex '(S)DRAM SIZE' if SET_MEM_PARAM
18 default 0x00800000
19
20config FLASH_MEM_BASE
21 hex 'FLASH Base Address' if SET_MEM_PARAM
22 default 0x00400000
23
24config FLASH_SIZE
25 hex 'FLASH Size' if SET_MEM_PARAM
26 default 0x00400000
27
28config REMAP_VECTORS_TO_RAM
29 bool 'Install vectors to the begining of RAM' if DRAM_BASE
30 depends on DRAM_BASE
31 help
32 The kernel needs to change the hardware exception vectors.
33 In nommu mode, the hardware exception vectors are normally
34 placed at address 0x00000000. However, this region may be
35 occupied by read-only memory depending on H/W design.
36
37 If the region contains read-write memory, say 'n' here.
38
39 If your CPU provides a remap facility which allows the exception
40 vectors to be mapped to writable memory, say 'n' here.
41
42 Otherwise, say 'y' here. In this case, the kernel will require
43 external support to redirect the hardware exception vectors to
44 the writable versions located at DRAM_BASE.
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index ce3e804ea0f3..95a96275f88a 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -20,6 +20,11 @@ GZFLAGS :=-9
20# Select a platform tht is kept up-to-date 20# Select a platform tht is kept up-to-date
21KBUILD_DEFCONFIG := versatile_defconfig 21KBUILD_DEFCONFIG := versatile_defconfig
22 22
23# defines filename extension depending memory manement type.
24ifeq ($(CONFIG_MMU),)
25MMUEXT := -nommu
26endif
27
23ifeq ($(CONFIG_FRAME_POINTER),y) 28ifeq ($(CONFIG_FRAME_POINTER),y)
24CFLAGS +=-fno-omit-frame-pointer -mapcs -mno-sched-prolog 29CFLAGS +=-fno-omit-frame-pointer -mapcs -mno-sched-prolog
25endif 30endif
@@ -73,7 +78,7 @@ AFLAGS +=$(CFLAGS_ABI) $(arch-y) $(tune-y) -msoft-float
73CHECKFLAGS += -D__arm__ 78CHECKFLAGS += -D__arm__
74 79
75#Default value 80#Default value
76head-y := arch/arm/kernel/head.o arch/arm/kernel/init_task.o 81head-y := arch/arm/kernel/head$(MMUEXT).o arch/arm/kernel/init_task.o
77textofs-y := 0x00008000 82textofs-y := 0x00008000
78 83
79 machine-$(CONFIG_ARCH_RPC) := rpc 84 machine-$(CONFIG_ARCH_RPC) := rpc
@@ -133,7 +138,7 @@ else
133MACHINE := 138MACHINE :=
134endif 139endif
135 140
136export TEXT_OFFSET GZFLAGS 141export TEXT_OFFSET GZFLAGS MMUEXT
137 142
138# Do we have FASTFPE? 143# Do we have FASTFPE?
139FASTFPE :=arch/arm/fastfpe 144FASTFPE :=arch/arm/fastfpe
diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S
index 491c7e4c9ac6..b56f5e691d65 100644
--- a/arch/arm/boot/compressed/head.S
+++ b/arch/arm/boot/compressed/head.S
@@ -2,6 +2,7 @@
2 * linux/arch/arm/boot/compressed/head.S 2 * linux/arch/arm/boot/compressed/head.S
3 * 3 *
4 * Copyright (C) 1996-2002 Russell King 4 * Copyright (C) 1996-2002 Russell King
5 * Copyright (C) 2004 Hyok S. Choi (MPU support)
5 * 6 *
6 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as 8 * it under the terms of the GNU General Public License version 2 as
@@ -320,6 +321,62 @@ params: ldr r0, =params_phys
320cache_on: mov r3, #8 @ cache_on function 321cache_on: mov r3, #8 @ cache_on function
321 b call_cache_fn 322 b call_cache_fn
322 323
324/*
325 * Initialize the highest priority protection region, PR7
326 * to cover all 32bit address and cacheable and bufferable.
327 */
328__armv4_mpu_cache_on:
329 mov r0, #0x3f @ 4G, the whole
330 mcr p15, 0, r0, c6, c7, 0 @ PR7 Area Setting
331 mcr p15, 0, r0, c6, c7, 1
332
333 mov r0, #0x80 @ PR7
334 mcr p15, 0, r0, c2, c0, 0 @ D-cache on
335 mcr p15, 0, r0, c2, c0, 1 @ I-cache on
336 mcr p15, 0, r0, c3, c0, 0 @ write-buffer on
337
338 mov r0, #0xc000
339 mcr p15, 0, r0, c5, c0, 1 @ I-access permission
340 mcr p15, 0, r0, c5, c0, 0 @ D-access permission
341
342 mov r0, #0
343 mcr p15, 0, r0, c7, c10, 4 @ drain write buffer
344 mcr p15, 0, r0, c7, c5, 0 @ flush(inval) I-Cache
345 mcr p15, 0, r0, c7, c6, 0 @ flush(inval) D-Cache
346 mrc p15, 0, r0, c1, c0, 0 @ read control reg
347 @ ...I .... ..D. WC.M
348 orr r0, r0, #0x002d @ .... .... ..1. 11.1
349 orr r0, r0, #0x1000 @ ...1 .... .... ....
350
351 mcr p15, 0, r0, c1, c0, 0 @ write control reg
352
353 mov r0, #0
354 mcr p15, 0, r0, c7, c5, 0 @ flush(inval) I-Cache
355 mcr p15, 0, r0, c7, c6, 0 @ flush(inval) D-Cache
356 mov pc, lr
357
358__armv3_mpu_cache_on:
359 mov r0, #0x3f @ 4G, the whole
360 mcr p15, 0, r0, c6, c7, 0 @ PR7 Area Setting
361
362 mov r0, #0x80 @ PR7
363 mcr p15, 0, r0, c2, c0, 0 @ cache on
364 mcr p15, 0, r0, c3, c0, 0 @ write-buffer on
365
366 mov r0, #0xc000
367 mcr p15, 0, r0, c5, c0, 0 @ access permission
368
369 mov r0, #0
370 mcr p15, 0, r0, c7, c0, 0 @ invalidate whole cache v3
371 mrc p15, 0, r0, c1, c0, 0 @ read control reg
372 @ .... .... .... WC.M
373 orr r0, r0, #0x000d @ .... .... .... 11.1
374 mov r0, #0
375 mcr p15, 0, r0, c1, c0, 0 @ write control reg
376
377 mcr p15, 0, r0, c7, c0, 0 @ invalidate whole cache v3
378 mov pc, lr
379
323__setup_mmu: sub r3, r4, #16384 @ Page directory size 380__setup_mmu: sub r3, r4, #16384 @ Page directory size
324 bic r3, r3, #0xff @ Align the pointer 381 bic r3, r3, #0xff @ Align the pointer
325 bic r3, r3, #0x3f00 382 bic r3, r3, #0x3f00
@@ -496,6 +553,18 @@ proc_types:
496 b __armv4_mmu_cache_off 553 b __armv4_mmu_cache_off
497 mov pc, lr 554 mov pc, lr
498 555
556 .word 0x41007400 @ ARM74x
557 .word 0xff00ff00
558 b __armv3_mpu_cache_on
559 b __armv3_mpu_cache_off
560 b __armv3_mpu_cache_flush
561
562 .word 0x41009400 @ ARM94x
563 .word 0xff00ff00
564 b __armv4_mpu_cache_on
565 b __armv4_mpu_cache_off
566 b __armv4_mpu_cache_flush
567
499 .word 0x00007000 @ ARM7 IDs 568 .word 0x00007000 @ ARM7 IDs
500 .word 0x0000f000 569 .word 0x0000f000
501 mov pc, lr 570 mov pc, lr
@@ -562,6 +631,24 @@ proc_types:
562cache_off: mov r3, #12 @ cache_off function 631cache_off: mov r3, #12 @ cache_off function
563 b call_cache_fn 632 b call_cache_fn
564 633
634__armv4_mpu_cache_off:
635 mrc p15, 0, r0, c1, c0
636 bic r0, r0, #0x000d
637 mcr p15, 0, r0, c1, c0 @ turn MPU and cache off
638 mov r0, #0
639 mcr p15, 0, r0, c7, c10, 4 @ drain write buffer
640 mcr p15, 0, r0, c7, c6, 0 @ flush D-Cache
641 mcr p15, 0, r0, c7, c5, 0 @ flush I-Cache
642 mov pc, lr
643
644__armv3_mpu_cache_off:
645 mrc p15, 0, r0, c1, c0
646 bic r0, r0, #0x000d
647 mcr p15, 0, r0, c1, c0, 0 @ turn MPU and cache off
648 mov r0, #0
649 mcr p15, 0, r0, c7, c0, 0 @ invalidate whole cache v3
650 mov pc, lr
651
565__armv4_mmu_cache_off: 652__armv4_mmu_cache_off:
566 mrc p15, 0, r0, c1, c0 653 mrc p15, 0, r0, c1, c0
567 bic r0, r0, #0x000d 654 bic r0, r0, #0x000d
@@ -601,6 +688,24 @@ cache_clean_flush:
601 mov r3, #16 688 mov r3, #16
602 b call_cache_fn 689 b call_cache_fn
603 690
691__armv4_mpu_cache_flush:
692 mov r2, #1
693 mov r3, #0
694 mcr p15, 0, ip, c7, c6, 0 @ invalidate D cache
695 mov r1, #7 << 5 @ 8 segments
6961: orr r3, r1, #63 << 26 @ 64 entries
6972: mcr p15, 0, r3, c7, c14, 2 @ clean & invalidate D index
698 subs r3, r3, #1 << 26
699 bcs 2b @ entries 63 to 0
700 subs r1, r1, #1 << 5
701 bcs 1b @ segments 7 to 0
702
703 teq r2, #0
704 mcrne p15, 0, ip, c7, c5, 0 @ invalidate I cache
705 mcr p15, 0, ip, c7, c10, 4 @ drain WB
706 mov pc, lr
707
708
604__armv6_mmu_cache_flush: 709__armv6_mmu_cache_flush:
605 mov r1, #0 710 mov r1, #0
606 mcr p15, 0, r1, c7, c14, 0 @ clean+invalidate D 711 mcr p15, 0, r1, c7, c14, 0 @ clean+invalidate D
@@ -638,6 +743,7 @@ no_cache_id:
638 mov pc, lr 743 mov pc, lr
639 744
640__armv3_mmu_cache_flush: 745__armv3_mmu_cache_flush:
746__armv3_mpu_cache_flush:
641 mov r1, #0 747 mov r1, #0
642 mcr p15, 0, r0, c7, c0, 0 @ invalidate whole cache v3 748 mcr p15, 0, r0, c7, c0, 0 @ invalidate whole cache v3
643 mov pc, lr 749 mov pc, lr
diff --git a/arch/arm/common/sharpsl_pm.c b/arch/arm/common/sharpsl_pm.c
index 978d32e82d39..3cd8c9ee4510 100644
--- a/arch/arm/common/sharpsl_pm.c
+++ b/arch/arm/common/sharpsl_pm.c
@@ -22,6 +22,7 @@
22#include <linux/delay.h> 22#include <linux/delay.h>
23#include <linux/interrupt.h> 23#include <linux/interrupt.h>
24#include <linux/platform_device.h> 24#include <linux/platform_device.h>
25#include <linux/leds.h>
25 26
26#include <asm/hardware.h> 27#include <asm/hardware.h>
27#include <asm/mach-types.h> 28#include <asm/mach-types.h>
@@ -75,6 +76,7 @@ static void sharpsl_battery_thread(void *private_);
75struct sharpsl_pm_status sharpsl_pm; 76struct sharpsl_pm_status sharpsl_pm;
76DECLARE_WORK(toggle_charger, sharpsl_charge_toggle, NULL); 77DECLARE_WORK(toggle_charger, sharpsl_charge_toggle, NULL);
77DECLARE_WORK(sharpsl_bat, sharpsl_battery_thread, NULL); 78DECLARE_WORK(sharpsl_bat, sharpsl_battery_thread, NULL);
79DEFINE_LED_TRIGGER(sharpsl_charge_led_trigger);
78 80
79 81
80static int get_percentage(int voltage) 82static int get_percentage(int voltage)
@@ -190,10 +192,10 @@ void sharpsl_pm_led(int val)
190 dev_err(sharpsl_pm.dev, "Charging Error!\n"); 192 dev_err(sharpsl_pm.dev, "Charging Error!\n");
191 } else if (val == SHARPSL_LED_ON) { 193 } else if (val == SHARPSL_LED_ON) {
192 dev_dbg(sharpsl_pm.dev, "Charge LED On\n"); 194 dev_dbg(sharpsl_pm.dev, "Charge LED On\n");
193 195 led_trigger_event(sharpsl_charge_led_trigger, LED_FULL);
194 } else { 196 } else {
195 dev_dbg(sharpsl_pm.dev, "Charge LED Off\n"); 197 dev_dbg(sharpsl_pm.dev, "Charge LED Off\n");
196 198 led_trigger_event(sharpsl_charge_led_trigger, LED_OFF);
197 } 199 }
198} 200}
199 201
@@ -786,6 +788,8 @@ static int __init sharpsl_pm_probe(struct platform_device *pdev)
786 init_timer(&sharpsl_pm.chrg_full_timer); 788 init_timer(&sharpsl_pm.chrg_full_timer);
787 sharpsl_pm.chrg_full_timer.function = sharpsl_chrg_full_timer; 789 sharpsl_pm.chrg_full_timer.function = sharpsl_chrg_full_timer;
788 790
791 led_trigger_register_simple("sharpsl-charge", &sharpsl_charge_led_trigger);
792
789 sharpsl_pm.machinfo->init(); 793 sharpsl_pm.machinfo->init();
790 794
791 device_create_file(&pdev->dev, &dev_attr_battery_percentage); 795 device_create_file(&pdev->dev, &dev_attr_battery_percentage);
@@ -807,6 +811,8 @@ static int sharpsl_pm_remove(struct platform_device *pdev)
807 device_remove_file(&pdev->dev, &dev_attr_battery_percentage); 811 device_remove_file(&pdev->dev, &dev_attr_battery_percentage);
808 device_remove_file(&pdev->dev, &dev_attr_battery_voltage); 812 device_remove_file(&pdev->dev, &dev_attr_battery_voltage);
809 813
814 led_trigger_unregister_simple(sharpsl_charge_led_trigger);
815
810 sharpsl_pm.machinfo->exit(); 816 sharpsl_pm.machinfo->exit();
811 817
812 del_timer_sync(&sharpsl_pm.chrg_full_timer); 818 del_timer_sync(&sharpsl_pm.chrg_full_timer);
diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S
index 355914ffb192..ab8e600c18c8 100644
--- a/arch/arm/kernel/entry-armv.S
+++ b/arch/arm/kernel/entry-armv.S
@@ -666,7 +666,7 @@ __kuser_helper_start:
666 * 666 *
667 * #define __kernel_dmb() \ 667 * #define __kernel_dmb() \
668 * asm volatile ( "mov r0, #0xffff0fff; mov lr, pc; sub pc, r0, #95" \ 668 * asm volatile ( "mov r0, #0xffff0fff; mov lr, pc; sub pc, r0, #95" \
669 * : : : "lr","cc" ) 669 * : : : "r0", "lr","cc" )
670 */ 670 */
671 671
672__kuser_memory_barrier: @ 0xffff0fa0 672__kuser_memory_barrier: @ 0xffff0fa0
diff --git a/arch/arm/kernel/head-common.S b/arch/arm/kernel/head-common.S
new file mode 100644
index 000000000000..a52da0ddb43d
--- /dev/null
+++ b/arch/arm/kernel/head-common.S
@@ -0,0 +1,217 @@
1/*
2 * linux/arch/arm/kernel/head-common.S
3 *
4 * Copyright (C) 1994-2002 Russell King
5 * Copyright (c) 2003 ARM Limited
6 * All Rights Reserved
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 *
12 */
13
14 .type __switch_data, %object
15__switch_data:
16 .long __mmap_switched
17 .long __data_loc @ r4
18 .long __data_start @ r5
19 .long __bss_start @ r6
20 .long _end @ r7
21 .long processor_id @ r4
22 .long __machine_arch_type @ r5
23 .long cr_alignment @ r6
24 .long init_thread_union + THREAD_START_SP @ sp
25
26/*
27 * The following fragment of code is executed with the MMU on in MMU mode,
28 * and uses absolute addresses; this is not position independent.
29 *
30 * r0 = cp#15 control register
31 * r1 = machine ID
32 * r9 = processor ID
33 */
34 .type __mmap_switched, %function
35__mmap_switched:
36 adr r3, __switch_data + 4
37
38 ldmia r3!, {r4, r5, r6, r7}
39 cmp r4, r5 @ Copy data segment if needed
401: cmpne r5, r6
41 ldrne fp, [r4], #4
42 strne fp, [r5], #4
43 bne 1b
44
45 mov fp, #0 @ Clear BSS (and zero fp)
461: cmp r6, r7
47 strcc fp, [r6],#4
48 bcc 1b
49
50 ldmia r3, {r4, r5, r6, sp}
51 str r9, [r4] @ Save processor ID
52 str r1, [r5] @ Save machine type
53 bic r4, r0, #CR_A @ Clear 'A' bit
54 stmia r6, {r0, r4} @ Save control register values
55 b start_kernel
56
57/*
58 * Exception handling. Something went wrong and we can't proceed. We
59 * ought to tell the user, but since we don't have any guarantee that
60 * we're even running on the right architecture, we do virtually nothing.
61 *
62 * If CONFIG_DEBUG_LL is set we try to print out something about the error
63 * and hope for the best (useful if bootloader fails to pass a proper
64 * machine ID for example).
65 */
66
67 .type __error_p, %function
68__error_p:
69#ifdef CONFIG_DEBUG_LL
70 adr r0, str_p1
71 bl printascii
72 b __error
73str_p1: .asciz "\nError: unrecognized/unsupported processor variant.\n"
74 .align
75#endif
76
77 .type __error_a, %function
78__error_a:
79#ifdef CONFIG_DEBUG_LL
80 mov r4, r1 @ preserve machine ID
81 adr r0, str_a1
82 bl printascii
83 mov r0, r4
84 bl printhex8
85 adr r0, str_a2
86 bl printascii
87 adr r3, 3f
88 ldmia r3, {r4, r5, r6} @ get machine desc list
89 sub r4, r3, r4 @ get offset between virt&phys
90 add r5, r5, r4 @ convert virt addresses to
91 add r6, r6, r4 @ physical address space
921: ldr r0, [r5, #MACHINFO_TYPE] @ get machine type
93 bl printhex8
94 mov r0, #'\t'
95 bl printch
96 ldr r0, [r5, #MACHINFO_NAME] @ get machine name
97 add r0, r0, r4
98 bl printascii
99 mov r0, #'\n'
100 bl printch
101 add r5, r5, #SIZEOF_MACHINE_DESC @ next machine_desc
102 cmp r5, r6
103 blo 1b
104 adr r0, str_a3
105 bl printascii
106 b __error
107str_a1: .asciz "\nError: unrecognized/unsupported machine ID (r1 = 0x"
108str_a2: .asciz ").\n\nAvailable machine support:\n\nID (hex)\tNAME\n"
109str_a3: .asciz "\nPlease check your kernel config and/or bootloader.\n"
110 .align
111#endif
112
113 .type __error, %function
114__error:
115#ifdef CONFIG_ARCH_RPC
116/*
117 * Turn the screen red on a error - RiscPC only.
118 */
119 mov r0, #0x02000000
120 mov r3, #0x11
121 orr r3, r3, r3, lsl #8
122 orr r3, r3, r3, lsl #16
123 str r3, [r0], #4
124 str r3, [r0], #4
125 str r3, [r0], #4
126 str r3, [r0], #4
127#endif
1281: mov r0, r0
129 b 1b
130
131
132/*
133 * Read processor ID register (CP#15, CR0), and look up in the linker-built
134 * supported processor list. Note that we can't use the absolute addresses
135 * for the __proc_info lists since we aren't running with the MMU on
136 * (and therefore, we are not in the correct address space). We have to
137 * calculate the offset.
138 *
139 * r9 = cpuid
140 * Returns:
141 * r3, r4, r6 corrupted
142 * r5 = proc_info pointer in physical address space
143 * r9 = cpuid (preserved)
144 */
145 .type __lookup_processor_type, %function
146__lookup_processor_type:
147 adr r3, 3f
148 ldmda r3, {r5 - r7}
149 sub r3, r3, r7 @ get offset between virt&phys
150 add r5, r5, r3 @ convert virt addresses to
151 add r6, r6, r3 @ physical address space
1521: ldmia r5, {r3, r4} @ value, mask
153 and r4, r4, r9 @ mask wanted bits
154 teq r3, r4
155 beq 2f
156 add r5, r5, #PROC_INFO_SZ @ sizeof(proc_info_list)
157 cmp r5, r6
158 blo 1b
159 mov r5, #0 @ unknown processor
1602: mov pc, lr
161
162/*
163 * This provides a C-API version of the above function.
164 */
165ENTRY(lookup_processor_type)
166 stmfd sp!, {r4 - r7, r9, lr}
167 mov r9, r0
168 bl __lookup_processor_type
169 mov r0, r5
170 ldmfd sp!, {r4 - r7, r9, pc}
171
172/*
173 * Look in include/asm-arm/procinfo.h and arch/arm/kernel/arch.[ch] for
174 * more information about the __proc_info and __arch_info structures.
175 */
176 .long __proc_info_begin
177 .long __proc_info_end
1783: .long .
179 .long __arch_info_begin
180 .long __arch_info_end
181
182/*
183 * Lookup machine architecture in the linker-build list of architectures.
184 * Note that we can't use the absolute addresses for the __arch_info
185 * lists since we aren't running with the MMU on (and therefore, we are
186 * not in the correct address space). We have to calculate the offset.
187 *
188 * r1 = machine architecture number
189 * Returns:
190 * r3, r4, r6 corrupted
191 * r5 = mach_info pointer in physical address space
192 */
193 .type __lookup_machine_type, %function
194__lookup_machine_type:
195 adr r3, 3b
196 ldmia r3, {r4, r5, r6}
197 sub r3, r3, r4 @ get offset between virt&phys
198 add r5, r5, r3 @ convert virt addresses to
199 add r6, r6, r3 @ physical address space
2001: ldr r3, [r5, #MACHINFO_TYPE] @ get machine type
201 teq r3, r1 @ matches loader number?
202 beq 2f @ found
203 add r5, r5, #SIZEOF_MACHINE_DESC @ next machine_desc
204 cmp r5, r6
205 blo 1b
206 mov r5, #0 @ unknown machine
2072: mov pc, lr
208
209/*
210 * This provides a C-API version of the above function.
211 */
212ENTRY(lookup_machine_type)
213 stmfd sp!, {r4 - r6, lr}
214 mov r1, r0
215 bl __lookup_machine_type
216 mov r0, r5
217 ldmfd sp!, {r4 - r6, pc}
diff --git a/arch/arm/kernel/head-nommu.S b/arch/arm/kernel/head-nommu.S
new file mode 100644
index 000000000000..b093ab8738b5
--- /dev/null
+++ b/arch/arm/kernel/head-nommu.S
@@ -0,0 +1,83 @@
1/*
2 * linux/arch/arm/kernel/head-nommu.S
3 *
4 * Copyright (C) 1994-2002 Russell King
5 * Copyright (C) 2003-2006 Hyok S. Choi
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 * Common kernel startup code (non-paged MM)
12 * for 32-bit CPUs which has a process ID register(CP15).
13 *
14 */
15#include <linux/config.h>
16#include <linux/linkage.h>
17#include <linux/init.h>
18
19#include <asm/assembler.h>
20#include <asm/mach-types.h>
21#include <asm/procinfo.h>
22#include <asm/ptrace.h>
23#include <asm/constants.h>
24#include <asm/system.h>
25
26#define PROCINFO_INITFUNC 12
27
28/*
29 * Kernel startup entry point.
30 * ---------------------------
31 *
32 * This is normally called from the decompressor code. The requirements
33 * are: MMU = off, D-cache = off, I-cache = dont care, r0 = 0,
34 * r1 = machine nr.
35 *
36 * See linux/arch/arm/tools/mach-types for the complete list of machine
37 * numbers for r1.
38 *
39 */
40 __INIT
41 .type stext, %function
42ENTRY(stext)
43 msr cpsr_c, #PSR_F_BIT | PSR_I_BIT | MODE_SVC @ ensure svc mode
44 @ and irqs disabled
45 mrc p15, 0, r9, c0, c0 @ get processor id
46 bl __lookup_processor_type @ r5=procinfo r9=cpuid
47 movs r10, r5 @ invalid processor (r5=0)?
48 beq __error_p @ yes, error 'p'
49 bl __lookup_machine_type @ r5=machinfo
50 movs r8, r5 @ invalid machine (r5=0)?
51 beq __error_a @ yes, error 'a'
52
53 ldr r13, __switch_data @ address to jump to after
54 @ the initialization is done
55 adr lr, __after_proc_init @ return (PIC) address
56 add pc, r10, #PROCINFO_INITFUNC
57
58/*
59 * Set the Control Register and Read the process ID.
60 */
61 .type __after_proc_init, %function
62__after_proc_init:
63 mrc p15, 0, r0, c1, c0, 0 @ read control reg
64#ifdef CONFIG_ALIGNMENT_TRAP
65 orr r0, r0, #CR_A
66#else
67 bic r0, r0, #CR_A
68#endif
69#ifdef CONFIG_CPU_DCACHE_DISABLE
70 bic r0, r0, #CR_C
71#endif
72#ifdef CONFIG_CPU_BPREDICT_DISABLE
73 bic r0, r0, #CR_Z
74#endif
75#ifdef CONFIG_CPU_ICACHE_DISABLE
76 bic r0, r0, #CR_I
77#endif
78 mcr p15, 0, r0, c1, c0, 0 @ write control reg
79
80 mov pc, r13 @ clear the BSS and jump
81 @ to start_kernel
82
83#include "head-common.S"
diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S
index 53b6901f70a6..04b66a9328ef 100644
--- a/arch/arm/kernel/head.S
+++ b/arch/arm/kernel/head.S
@@ -102,49 +102,6 @@ ENTRY(stext)
102 adr lr, __enable_mmu @ return (PIC) address 102 adr lr, __enable_mmu @ return (PIC) address
103 add pc, r10, #PROCINFO_INITFUNC 103 add pc, r10, #PROCINFO_INITFUNC
104 104
105 .type __switch_data, %object
106__switch_data:
107 .long __mmap_switched
108 .long __data_loc @ r4
109 .long __data_start @ r5
110 .long __bss_start @ r6
111 .long _end @ r7
112 .long processor_id @ r4
113 .long __machine_arch_type @ r5
114 .long cr_alignment @ r6
115 .long init_thread_union + THREAD_START_SP @ sp
116
117/*
118 * The following fragment of code is executed with the MMU on, and uses
119 * absolute addresses; this is not position independent.
120 *
121 * r0 = cp#15 control register
122 * r1 = machine ID
123 * r9 = processor ID
124 */
125 .type __mmap_switched, %function
126__mmap_switched:
127 adr r3, __switch_data + 4
128
129 ldmia r3!, {r4, r5, r6, r7}
130 cmp r4, r5 @ Copy data segment if needed
1311: cmpne r5, r6
132 ldrne fp, [r4], #4
133 strne fp, [r5], #4
134 bne 1b
135
136 mov fp, #0 @ Clear BSS (and zero fp)
1371: cmp r6, r7
138 strcc fp, [r6],#4
139 bcc 1b
140
141 ldmia r3, {r4, r5, r6, sp}
142 str r9, [r4] @ Save processor ID
143 str r1, [r5] @ Save machine type
144 bic r4, r0, #CR_A @ Clear 'A' bit
145 stmia r6, {r0, r4} @ Save control register values
146 b start_kernel
147
148#if defined(CONFIG_SMP) 105#if defined(CONFIG_SMP)
149 .type secondary_startup, #function 106 .type secondary_startup, #function
150ENTRY(secondary_startup) 107ENTRY(secondary_startup)
@@ -367,166 +324,4 @@ __create_page_tables:
367 mov pc, lr 324 mov pc, lr
368 .ltorg 325 .ltorg
369 326
370 327#include "head-common.S"
371
372/*
373 * Exception handling. Something went wrong and we can't proceed. We
374 * ought to tell the user, but since we don't have any guarantee that
375 * we're even running on the right architecture, we do virtually nothing.
376 *
377 * If CONFIG_DEBUG_LL is set we try to print out something about the error
378 * and hope for the best (useful if bootloader fails to pass a proper
379 * machine ID for example).
380 */
381
382 .type __error_p, %function
383__error_p:
384#ifdef CONFIG_DEBUG_LL
385 adr r0, str_p1
386 bl printascii
387 b __error
388str_p1: .asciz "\nError: unrecognized/unsupported processor variant.\n"
389 .align
390#endif
391
392 .type __error_a, %function
393__error_a:
394#ifdef CONFIG_DEBUG_LL
395 mov r4, r1 @ preserve machine ID
396 adr r0, str_a1
397 bl printascii
398 mov r0, r4
399 bl printhex8
400 adr r0, str_a2
401 bl printascii
402 adr r3, 3f
403 ldmia r3, {r4, r5, r6} @ get machine desc list
404 sub r4, r3, r4 @ get offset between virt&phys
405 add r5, r5, r4 @ convert virt addresses to
406 add r6, r6, r4 @ physical address space
4071: ldr r0, [r5, #MACHINFO_TYPE] @ get machine type
408 bl printhex8
409 mov r0, #'\t'
410 bl printch
411 ldr r0, [r5, #MACHINFO_NAME] @ get machine name
412 add r0, r0, r4
413 bl printascii
414 mov r0, #'\n'
415 bl printch
416 add r5, r5, #SIZEOF_MACHINE_DESC @ next machine_desc
417 cmp r5, r6
418 blo 1b
419 adr r0, str_a3
420 bl printascii
421 b __error
422str_a1: .asciz "\nError: unrecognized/unsupported machine ID (r1 = 0x"
423str_a2: .asciz ").\n\nAvailable machine support:\n\nID (hex)\tNAME\n"
424str_a3: .asciz "\nPlease check your kernel config and/or bootloader.\n"
425 .align
426#endif
427
428 .type __error, %function
429__error:
430#ifdef CONFIG_ARCH_RPC
431/*
432 * Turn the screen red on a error - RiscPC only.
433 */
434 mov r0, #0x02000000
435 mov r3, #0x11
436 orr r3, r3, r3, lsl #8
437 orr r3, r3, r3, lsl #16
438 str r3, [r0], #4
439 str r3, [r0], #4
440 str r3, [r0], #4
441 str r3, [r0], #4
442#endif
4431: mov r0, r0
444 b 1b
445
446
447/*
448 * Read processor ID register (CP#15, CR0), and look up in the linker-built
449 * supported processor list. Note that we can't use the absolute addresses
450 * for the __proc_info lists since we aren't running with the MMU on
451 * (and therefore, we are not in the correct address space). We have to
452 * calculate the offset.
453 *
454 * r9 = cpuid
455 * Returns:
456 * r3, r4, r6 corrupted
457 * r5 = proc_info pointer in physical address space
458 * r9 = cpuid (preserved)
459 */
460 .type __lookup_processor_type, %function
461__lookup_processor_type:
462 adr r3, 3f
463 ldmda r3, {r5 - r7}
464 sub r3, r3, r7 @ get offset between virt&phys
465 add r5, r5, r3 @ convert virt addresses to
466 add r6, r6, r3 @ physical address space
4671: ldmia r5, {r3, r4} @ value, mask
468 and r4, r4, r9 @ mask wanted bits
469 teq r3, r4
470 beq 2f
471 add r5, r5, #PROC_INFO_SZ @ sizeof(proc_info_list)
472 cmp r5, r6
473 blo 1b
474 mov r5, #0 @ unknown processor
4752: mov pc, lr
476
477/*
478 * This provides a C-API version of the above function.
479 */
480ENTRY(lookup_processor_type)
481 stmfd sp!, {r4 - r7, r9, lr}
482 mov r9, r0
483 bl __lookup_processor_type
484 mov r0, r5
485 ldmfd sp!, {r4 - r7, r9, pc}
486
487/*
488 * Look in include/asm-arm/procinfo.h and arch/arm/kernel/arch.[ch] for
489 * more information about the __proc_info and __arch_info structures.
490 */
491 .long __proc_info_begin
492 .long __proc_info_end
4933: .long .
494 .long __arch_info_begin
495 .long __arch_info_end
496
497/*
498 * Lookup machine architecture in the linker-build list of architectures.
499 * Note that we can't use the absolute addresses for the __arch_info
500 * lists since we aren't running with the MMU on (and therefore, we are
501 * not in the correct address space). We have to calculate the offset.
502 *
503 * r1 = machine architecture number
504 * Returns:
505 * r3, r4, r6 corrupted
506 * r5 = mach_info pointer in physical address space
507 */
508 .type __lookup_machine_type, %function
509__lookup_machine_type:
510 adr r3, 3b
511 ldmia r3, {r4, r5, r6}
512 sub r3, r3, r4 @ get offset between virt&phys
513 add r5, r5, r3 @ convert virt addresses to
514 add r6, r6, r3 @ physical address space
5151: ldr r3, [r5, #MACHINFO_TYPE] @ get machine type
516 teq r3, r1 @ matches loader number?
517 beq 2f @ found
518 add r5, r5, #SIZEOF_MACHINE_DESC @ next machine_desc
519 cmp r5, r6
520 blo 1b
521 mov r5, #0 @ unknown machine
5222: mov pc, lr
523
524/*
525 * This provides a C-API version of the above function.
526 */
527ENTRY(lookup_machine_type)
528 stmfd sp!, {r4 - r6, lr}
529 mov r1, r0
530 bl __lookup_machine_type
531 mov r0, r5
532 ldmfd sp!, {r4 - r6, pc}
diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c
index 489c069e5c3e..1ff75cee4b0d 100644
--- a/arch/arm/kernel/process.c
+++ b/arch/arm/kernel/process.c
@@ -474,4 +474,3 @@ unsigned long get_wchan(struct task_struct *p)
474 } while (count ++ < 16); 474 } while (count ++ < 16);
475 return 0; 475 return 0;
476} 476}
477EXPORT_SYMBOL(get_wchan);
diff --git a/arch/arm/kernel/signal.h b/arch/arm/kernel/signal.h
index 9991049c522d..27beece15502 100644
--- a/arch/arm/kernel/signal.h
+++ b/arch/arm/kernel/signal.h
@@ -7,6 +7,6 @@
7 * it under the terms of the GNU General Public License version 2 as 7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation. 8 * published by the Free Software Foundation.
9 */ 9 */
10#define KERN_SIGRETURN_CODE 0xffff0500 10#define KERN_SIGRETURN_CODE (CONFIG_VECTORS_BASE + 0x00000500)
11 11
12extern const unsigned long sigreturn_codes[7]; 12extern const unsigned long sigreturn_codes[7];
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c
index d566d5f4574d..35230a060108 100644
--- a/arch/arm/kernel/traps.c
+++ b/arch/arm/kernel/traps.c
@@ -688,6 +688,7 @@ EXPORT_SYMBOL(abort);
688 688
689void __init trap_init(void) 689void __init trap_init(void)
690{ 690{
691 unsigned long vectors = CONFIG_VECTORS_BASE;
691 extern char __stubs_start[], __stubs_end[]; 692 extern char __stubs_start[], __stubs_end[];
692 extern char __vectors_start[], __vectors_end[]; 693 extern char __vectors_start[], __vectors_end[];
693 extern char __kuser_helper_start[], __kuser_helper_end[]; 694 extern char __kuser_helper_start[], __kuser_helper_end[];
@@ -698,9 +699,9 @@ void __init trap_init(void)
698 * into the vector page, mapped at 0xffff0000, and ensure these 699 * into the vector page, mapped at 0xffff0000, and ensure these
699 * are visible to the instruction stream. 700 * are visible to the instruction stream.
700 */ 701 */
701 memcpy((void *)0xffff0000, __vectors_start, __vectors_end - __vectors_start); 702 memcpy((void *)vectors, __vectors_start, __vectors_end - __vectors_start);
702 memcpy((void *)0xffff0200, __stubs_start, __stubs_end - __stubs_start); 703 memcpy((void *)vectors + 0x200, __stubs_start, __stubs_end - __stubs_start);
703 memcpy((void *)0xffff1000 - kuser_sz, __kuser_helper_start, kuser_sz); 704 memcpy((void *)vectors + 0x1000 - kuser_sz, __kuser_helper_start, kuser_sz);
704 705
705 /* 706 /*
706 * Copy signal return handlers into the vector page, and 707 * Copy signal return handlers into the vector page, and
@@ -709,6 +710,6 @@ void __init trap_init(void)
709 memcpy((void *)KERN_SIGRETURN_CODE, sigreturn_codes, 710 memcpy((void *)KERN_SIGRETURN_CODE, sigreturn_codes,
710 sizeof(sigreturn_codes)); 711 sizeof(sigreturn_codes));
711 712
712 flush_icache_range(0xffff0000, 0xffff0000 + PAGE_SIZE); 713 flush_icache_range(vectors, vectors + PAGE_SIZE);
713 modify_domain(DOMAIN_USER, DOMAIN_CLIENT); 714 modify_domain(DOMAIN_USER, DOMAIN_CLIENT);
714} 715}
diff --git a/arch/arm/mach-pxa/corgi.c b/arch/arm/mach-pxa/corgi.c
index 68923b1d2b62..d6d726036361 100644
--- a/arch/arm/mach-pxa/corgi.c
+++ b/arch/arm/mach-pxa/corgi.c
@@ -141,6 +141,8 @@ struct corgissp_machinfo corgi_ssp_machinfo = {
141 */ 141 */
142static struct corgibl_machinfo corgi_bl_machinfo = { 142static struct corgibl_machinfo corgi_bl_machinfo = {
143 .max_intensity = 0x2f, 143 .max_intensity = 0x2f,
144 .default_intensity = 0x1f,
145 .limit_mask = 0x0b,
144 .set_bl_intensity = corgi_bl_set_intensity, 146 .set_bl_intensity = corgi_bl_set_intensity,
145}; 147};
146 148
@@ -164,6 +166,14 @@ static struct platform_device corgikbd_device = {
164 166
165 167
166/* 168/*
169 * Corgi LEDs
170 */
171static struct platform_device corgiled_device = {
172 .name = "corgi-led",
173 .id = -1,
174};
175
176/*
167 * Corgi Touch Screen Device 177 * Corgi Touch Screen Device
168 */ 178 */
169static struct resource corgits_resources[] = { 179static struct resource corgits_resources[] = {
@@ -297,6 +307,7 @@ static struct platform_device *devices[] __initdata = {
297 &corgikbd_device, 307 &corgikbd_device,
298 &corgibl_device, 308 &corgibl_device,
299 &corgits_device, 309 &corgits_device,
310 &corgiled_device,
300}; 311};
301 312
302static void __init corgi_init(void) 313static void __init corgi_init(void)
diff --git a/arch/arm/mach-pxa/spitz.c b/arch/arm/mach-pxa/spitz.c
index 0dbb079ecd25..19b372df544a 100644
--- a/arch/arm/mach-pxa/spitz.c
+++ b/arch/arm/mach-pxa/spitz.c
@@ -220,6 +220,8 @@ struct corgissp_machinfo spitz_ssp_machinfo = {
220 * Spitz Backlight Device 220 * Spitz Backlight Device
221 */ 221 */
222static struct corgibl_machinfo spitz_bl_machinfo = { 222static struct corgibl_machinfo spitz_bl_machinfo = {
223 .default_intensity = 0x1f,
224 .limit_mask = 0x0b,
223 .max_intensity = 0x2f, 225 .max_intensity = 0x2f,
224}; 226};
225 227
@@ -242,6 +244,14 @@ static struct platform_device spitzkbd_device = {
242 244
243 245
244/* 246/*
247 * Spitz LEDs
248 */
249static struct platform_device spitzled_device = {
250 .name = "spitz-led",
251 .id = -1,
252};
253
254/*
245 * Spitz Touch Screen Device 255 * Spitz Touch Screen Device
246 */ 256 */
247static struct resource spitzts_resources[] = { 257static struct resource spitzts_resources[] = {
@@ -418,6 +428,7 @@ static struct platform_device *devices[] __initdata = {
418 &spitzkbd_device, 428 &spitzkbd_device,
419 &spitzts_device, 429 &spitzts_device,
420 &spitzbl_device, 430 &spitzbl_device,
431 &spitzled_device,
421}; 432};
422 433
423static void __init common_init(void) 434static void __init common_init(void)
diff --git a/arch/arm/mach-pxa/tosa.c b/arch/arm/mach-pxa/tosa.c
index 66ec71756d0f..76c0e7f0a219 100644
--- a/arch/arm/mach-pxa/tosa.c
+++ b/arch/arm/mach-pxa/tosa.c
@@ -251,10 +251,19 @@ static struct platform_device tosakbd_device = {
251 .id = -1, 251 .id = -1,
252}; 252};
253 253
254/*
255 * Tosa LEDs
256 */
257static struct platform_device tosaled_device = {
258 .name = "tosa-led",
259 .id = -1,
260};
261
254static struct platform_device *devices[] __initdata = { 262static struct platform_device *devices[] __initdata = {
255 &tosascoop_device, 263 &tosascoop_device,
256 &tosascoop_jc_device, 264 &tosascoop_jc_device,
257 &tosakbd_device, 265 &tosakbd_device,
266 &tosaled_device,
258}; 267};
259 268
260static void __init tosa_init(void) 269static void __init tosa_init(void)
diff --git a/arch/arm/mm/proc-xsc3.S b/arch/arm/mm/proc-xsc3.S
index f90513e9af0c..b9dfce57c272 100644
--- a/arch/arm/mm/proc-xsc3.S
+++ b/arch/arm/mm/proc-xsc3.S
@@ -30,6 +30,7 @@
30#include <asm/procinfo.h> 30#include <asm/procinfo.h>
31#include <asm/hardware.h> 31#include <asm/hardware.h>
32#include <asm/pgtable.h> 32#include <asm/pgtable.h>
33#include <asm/pgtable-hwdef.h>
33#include <asm/page.h> 34#include <asm/page.h>
34#include <asm/ptrace.h> 35#include <asm/ptrace.h>
35#include "proc-macros.S" 36#include "proc-macros.S"
diff --git a/arch/arm26/kernel/armksyms.c b/arch/arm26/kernel/armksyms.c
index 811a6376c624..a6a1b3373444 100644
--- a/arch/arm26/kernel/armksyms.c
+++ b/arch/arm26/kernel/armksyms.c
@@ -212,8 +212,6 @@ EXPORT_SYMBOL(sys_open);
212EXPORT_SYMBOL(sys_exit); 212EXPORT_SYMBOL(sys_exit);
213EXPORT_SYMBOL(sys_wait4); 213EXPORT_SYMBOL(sys_wait4);
214 214
215EXPORT_SYMBOL(get_wchan);
216
217#ifdef CONFIG_PREEMPT 215#ifdef CONFIG_PREEMPT
218EXPORT_SYMBOL(kernel_flag); 216EXPORT_SYMBOL(kernel_flag);
219#endif 217#endif
diff --git a/arch/frv/kernel/frv_ksyms.c b/arch/frv/kernel/frv_ksyms.c
index aa6b7d0a2109..07c8ffa0dd39 100644
--- a/arch/frv/kernel/frv_ksyms.c
+++ b/arch/frv/kernel/frv_ksyms.c
@@ -79,8 +79,6 @@ EXPORT_SYMBOL(memmove);
79EXPORT_SYMBOL(__outsl_ns); 79EXPORT_SYMBOL(__outsl_ns);
80EXPORT_SYMBOL(__insl_ns); 80EXPORT_SYMBOL(__insl_ns);
81 81
82EXPORT_SYMBOL(get_wchan);
83
84#ifdef CONFIG_FRV_OUTOFLINE_ATOMIC_OPS 82#ifdef CONFIG_FRV_OUTOFLINE_ATOMIC_OPS
85EXPORT_SYMBOL(atomic_test_and_ANDNOT_mask); 83EXPORT_SYMBOL(atomic_test_and_ANDNOT_mask);
86EXPORT_SYMBOL(atomic_test_and_OR_mask); 84EXPORT_SYMBOL(atomic_test_and_OR_mask);
diff --git a/arch/h8300/kernel/h8300_ksyms.c b/arch/h8300/kernel/h8300_ksyms.c
index 69d6ad32d56c..b6cd78c972bb 100644
--- a/arch/h8300/kernel/h8300_ksyms.c
+++ b/arch/h8300/kernel/h8300_ksyms.c
@@ -55,8 +55,6 @@ EXPORT_SYMBOL(memcmp);
55EXPORT_SYMBOL(memscan); 55EXPORT_SYMBOL(memscan);
56EXPORT_SYMBOL(memmove); 56EXPORT_SYMBOL(memmove);
57 57
58EXPORT_SYMBOL(get_wchan);
59
60/* 58/*
61 * libgcc functions - functions that are used internally by the 59 * libgcc functions - functions that are used internally by the
62 * compiler... (prototypes are not correct though, but that 60 * compiler... (prototypes are not correct though, but that
diff --git a/arch/i386/kernel/apic.c b/arch/i386/kernel/apic.c
index eb5279d23b7f..6273bf74c203 100644
--- a/arch/i386/kernel/apic.c
+++ b/arch/i386/kernel/apic.c
@@ -415,6 +415,7 @@ void __init init_bsp_APIC(void)
415void __devinit setup_local_APIC(void) 415void __devinit setup_local_APIC(void)
416{ 416{
417 unsigned long oldvalue, value, ver, maxlvt; 417 unsigned long oldvalue, value, ver, maxlvt;
418 int i, j;
418 419
419 /* Pound the ESR really hard over the head with a big hammer - mbligh */ 420 /* Pound the ESR really hard over the head with a big hammer - mbligh */
420 if (esr_disable) { 421 if (esr_disable) {
@@ -452,6 +453,25 @@ void __devinit setup_local_APIC(void)
452 apic_write_around(APIC_TASKPRI, value); 453 apic_write_around(APIC_TASKPRI, value);
453 454
454 /* 455 /*
456 * After a crash, we no longer service the interrupts and a pending
457 * interrupt from previous kernel might still have ISR bit set.
458 *
459 * Most probably by now CPU has serviced that pending interrupt and
460 * it might not have done the ack_APIC_irq() because it thought,
461 * interrupt came from i8259 as ExtInt. LAPIC did not get EOI so it
462 * does not clear the ISR bit and cpu thinks it has already serivced
463 * the interrupt. Hence a vector might get locked. It was noticed
464 * for timer irq (vector 0x31). Issue an extra EOI to clear ISR.
465 */
466 for (i = APIC_ISR_NR - 1; i >= 0; i--) {
467 value = apic_read(APIC_ISR + i*0x10);
468 for (j = 31; j >= 0; j--) {
469 if (value & (1<<j))
470 ack_APIC_irq();
471 }
472 }
473
474 /*
455 * Now that we are all set up, enable the APIC 475 * Now that we are all set up, enable the APIC
456 */ 476 */
457 value = apic_read(APIC_SPIV); 477 value = apic_read(APIC_SPIV);
@@ -732,7 +752,7 @@ static int __init apic_set_verbosity(char *str)
732 printk(KERN_WARNING "APIC Verbosity level %s not recognised" 752 printk(KERN_WARNING "APIC Verbosity level %s not recognised"
733 " use apic=verbose or apic=debug\n", str); 753 " use apic=verbose or apic=debug\n", str);
734 754
735 return 0; 755 return 1;
736} 756}
737 757
738__setup("apic=", apic_set_verbosity); 758__setup("apic=", apic_set_verbosity);
diff --git a/arch/i386/kernel/cpu/mcheck/mce.c b/arch/i386/kernel/cpu/mcheck/mce.c
index 6170af3c271a..afa0888f9a1e 100644
--- a/arch/i386/kernel/cpu/mcheck/mce.c
+++ b/arch/i386/kernel/cpu/mcheck/mce.c
@@ -64,13 +64,13 @@ void mcheck_init(struct cpuinfo_x86 *c)
64static int __init mcheck_disable(char *str) 64static int __init mcheck_disable(char *str)
65{ 65{
66 mce_disabled = 1; 66 mce_disabled = 1;
67 return 0; 67 return 1;
68} 68}
69 69
70static int __init mcheck_enable(char *str) 70static int __init mcheck_enable(char *str)
71{ 71{
72 mce_disabled = -1; 72 mce_disabled = -1;
73 return 0; 73 return 1;
74} 74}
75 75
76__setup("nomce", mcheck_disable); 76__setup("nomce", mcheck_disable);
diff --git a/arch/i386/kernel/io_apic.c b/arch/i386/kernel/io_apic.c
index 3b329af4afc5..f8f132aa5472 100644
--- a/arch/i386/kernel/io_apic.c
+++ b/arch/i386/kernel/io_apic.c
@@ -644,7 +644,7 @@ failed:
644int __init irqbalance_disable(char *str) 644int __init irqbalance_disable(char *str)
645{ 645{
646 irqbalance_disabled = 1; 646 irqbalance_disabled = 1;
647 return 0; 647 return 1;
648} 648}
649 649
650__setup("noirqbalance", irqbalance_disable); 650__setup("noirqbalance", irqbalance_disable);
diff --git a/arch/i386/kernel/process.c b/arch/i386/kernel/process.c
index 24b3e745478b..6259afea46d1 100644
--- a/arch/i386/kernel/process.c
+++ b/arch/i386/kernel/process.c
@@ -781,7 +781,6 @@ unsigned long get_wchan(struct task_struct *p)
781 } while (count++ < 16); 781 } while (count++ < 16);
782 return 0; 782 return 0;
783} 783}
784EXPORT_SYMBOL(get_wchan);
785 784
786/* 785/*
787 * sys_alloc_thread_area: get a yet unused TLS descriptor index. 786 * sys_alloc_thread_area: get a yet unused TLS descriptor index.
diff --git a/arch/i386/kernel/syscall_table.S b/arch/i386/kernel/syscall_table.S
index 326595f3fa4d..4f58b9c0efe3 100644
--- a/arch/i386/kernel/syscall_table.S
+++ b/arch/i386/kernel/syscall_table.S
@@ -312,3 +312,5 @@ ENTRY(sys_call_table)
312 .long sys_unshare /* 310 */ 312 .long sys_unshare /* 310 */
313 .long sys_set_robust_list 313 .long sys_set_robust_list
314 .long sys_get_robust_list 314 .long sys_get_robust_list
315 .long sys_splice
316 .long sys_sync_file_range
diff --git a/arch/i386/kernel/traps.c b/arch/i386/kernel/traps.c
index 6b63a5aa1e46..e38527994590 100644
--- a/arch/i386/kernel/traps.c
+++ b/arch/i386/kernel/traps.c
@@ -1193,6 +1193,6 @@ void __init trap_init(void)
1193static int __init kstack_setup(char *s) 1193static int __init kstack_setup(char *s)
1194{ 1194{
1195 kstack_depth_to_print = simple_strtoul(s, NULL, 0); 1195 kstack_depth_to_print = simple_strtoul(s, NULL, 0);
1196 return 0; 1196 return 1;
1197} 1197}
1198__setup("kstack=", kstack_setup); 1198__setup("kstack=", kstack_setup);
diff --git a/arch/i386/kernel/vsyscall-sigreturn.S b/arch/i386/kernel/vsyscall-sigreturn.S
index fadb5bc3c374..a92262f41659 100644
--- a/arch/i386/kernel/vsyscall-sigreturn.S
+++ b/arch/i386/kernel/vsyscall-sigreturn.S
@@ -44,7 +44,7 @@ __kernel_rt_sigreturn:
44.LSTARTCIEDLSI1: 44.LSTARTCIEDLSI1:
45 .long 0 /* CIE ID */ 45 .long 0 /* CIE ID */
46 .byte 1 /* Version number */ 46 .byte 1 /* Version number */
47 .string "zR" /* NUL-terminated augmentation string */ 47 .string "zRS" /* NUL-terminated augmentation string */
48 .uleb128 1 /* Code alignment factor */ 48 .uleb128 1 /* Code alignment factor */
49 .sleb128 -4 /* Data alignment factor */ 49 .sleb128 -4 /* Data alignment factor */
50 .byte 8 /* Return address register column */ 50 .byte 8 /* Return address register column */
diff --git a/arch/ia64/kernel/entry.S b/arch/ia64/kernel/entry.S
index 0e3eda99e549..750e8e7fbdc3 100644
--- a/arch/ia64/kernel/entry.S
+++ b/arch/ia64/kernel/entry.S
@@ -1605,5 +1605,6 @@ sys_call_table:
1605 data8 sys_ni_syscall // reserved for pselect 1605 data8 sys_ni_syscall // reserved for pselect
1606 data8 sys_ni_syscall // 1295 reserved for ppoll 1606 data8 sys_ni_syscall // 1295 reserved for ppoll
1607 data8 sys_unshare 1607 data8 sys_unshare
1608 data8 sys_splice
1608 1609
1609 .org sys_call_table + 8*NR_syscalls // guard against failures to increase NR_syscalls 1610 .org sys_call_table + 8*NR_syscalls // guard against failures to increase NR_syscalls
diff --git a/arch/ia64/kernel/gate.lds.S b/arch/ia64/kernel/gate.lds.S
index e1e4aba9ecd0..7c99e6ec3daf 100644
--- a/arch/ia64/kernel/gate.lds.S
+++ b/arch/ia64/kernel/gate.lds.S
@@ -59,6 +59,7 @@ SECTIONS
59 *(.dynbss) 59 *(.dynbss)
60 *(.bss .bss.* .gnu.linkonce.b.*) 60 *(.bss .bss.* .gnu.linkonce.b.*)
61 *(__ex_table) 61 *(__ex_table)
62 *(__mca_table)
62 } 63 }
63} 64}
64 65
diff --git a/arch/ia64/kernel/iosapic.c b/arch/ia64/kernel/iosapic.c
index 8832c553230a..7956eb9058fc 100644
--- a/arch/ia64/kernel/iosapic.c
+++ b/arch/ia64/kernel/iosapic.c
@@ -9,54 +9,65 @@
9 * Copyright (C) 1999 VA Linux Systems 9 * Copyright (C) 1999 VA Linux Systems
10 * Copyright (C) 1999,2000 Walt Drummond <drummond@valinux.com> 10 * Copyright (C) 1999,2000 Walt Drummond <drummond@valinux.com>
11 * 11 *
12 * 00/04/19 D. Mosberger Rewritten to mirror more closely the x86 I/O APIC code. 12 * 00/04/19 D. Mosberger Rewritten to mirror more closely the x86 I/O
13 * In particular, we now have separate handlers for edge 13 * APIC code. In particular, we now have separate
14 * and level triggered interrupts. 14 * handlers for edge and level triggered
15 * 00/10/27 Asit Mallick, Goutham Rao <goutham.rao@intel.com> IRQ vector allocation 15 * interrupts.
16 * PCI to vector mapping, shared PCI interrupts. 16 * 00/10/27 Asit Mallick, Goutham Rao <goutham.rao@intel.com> IRQ vector
17 * 00/10/27 D. Mosberger Document things a bit more to make them more understandable. 17 * allocation PCI to vector mapping, shared PCI
18 * Clean up much of the old IOSAPIC cruft. 18 * interrupts.
19 * 01/07/27 J.I. Lee PCI irq routing, Platform/Legacy interrupts and fixes for 19 * 00/10/27 D. Mosberger Document things a bit more to make them more
20 * ACPI S5(SoftOff) support. 20 * understandable. Clean up much of the old
21 * IOSAPIC cruft.
22 * 01/07/27 J.I. Lee PCI irq routing, Platform/Legacy interrupts
23 * and fixes for ACPI S5(SoftOff) support.
21 * 02/01/23 J.I. Lee iosapic pgm fixes for PCI irq routing from _PRT 24 * 02/01/23 J.I. Lee iosapic pgm fixes for PCI irq routing from _PRT
22 * 02/01/07 E. Focht <efocht@ess.nec.de> Redirectable interrupt vectors in 25 * 02/01/07 E. Focht <efocht@ess.nec.de> Redirectable interrupt
23 * iosapic_set_affinity(), initializations for 26 * vectors in iosapic_set_affinity(),
24 * /proc/irq/#/smp_affinity 27 * initializations for /proc/irq/#/smp_affinity
25 * 02/04/02 P. Diefenbaugh Cleaned up ACPI PCI IRQ routing. 28 * 02/04/02 P. Diefenbaugh Cleaned up ACPI PCI IRQ routing.
26 * 02/04/18 J.I. Lee bug fix in iosapic_init_pci_irq 29 * 02/04/18 J.I. Lee bug fix in iosapic_init_pci_irq
27 * 02/04/30 J.I. Lee bug fix in find_iosapic to fix ACPI PCI IRQ to IOSAPIC mapping 30 * 02/04/30 J.I. Lee bug fix in find_iosapic to fix ACPI PCI IRQ to
28 * error 31 * IOSAPIC mapping error
29 * 02/07/29 T. Kochi Allocate interrupt vectors dynamically 32 * 02/07/29 T. Kochi Allocate interrupt vectors dynamically
30 * 02/08/04 T. Kochi Cleaned up terminology (irq, global system interrupt, vector, etc.) 33 * 02/08/04 T. Kochi Cleaned up terminology (irq, global system
31 * 02/09/20 D. Mosberger Simplified by taking advantage of ACPI's pci_irq code. 34 * interrupt, vector, etc.)
35 * 02/09/20 D. Mosberger Simplified by taking advantage of ACPI's
36 * pci_irq code.
32 * 03/02/19 B. Helgaas Make pcat_compat system-wide, not per-IOSAPIC. 37 * 03/02/19 B. Helgaas Make pcat_compat system-wide, not per-IOSAPIC.
33 * Remove iosapic_address & gsi_base from external interfaces. 38 * Remove iosapic_address & gsi_base from
34 * Rationalize __init/__devinit attributes. 39 * external interfaces. Rationalize
40 * __init/__devinit attributes.
35 * 04/12/04 Ashok Raj <ashok.raj@intel.com> Intel Corporation 2004 41 * 04/12/04 Ashok Raj <ashok.raj@intel.com> Intel Corporation 2004
36 * Updated to work with irq migration necessary for CPU Hotplug 42 * Updated to work with irq migration necessary
43 * for CPU Hotplug
37 */ 44 */
38/* 45/*
39 * Here is what the interrupt logic between a PCI device and the kernel looks like: 46 * Here is what the interrupt logic between a PCI device and the kernel looks
47 * like:
40 * 48 *
41 * (1) A PCI device raises one of the four interrupt pins (INTA, INTB, INTC, INTD). The 49 * (1) A PCI device raises one of the four interrupt pins (INTA, INTB, INTC,
42 * device is uniquely identified by its bus--, and slot-number (the function 50 * INTD). The device is uniquely identified by its bus-, and slot-number
43 * number does not matter here because all functions share the same interrupt 51 * (the function number does not matter here because all functions share
44 * lines). 52 * the same interrupt lines).
45 * 53 *
46 * (2) The motherboard routes the interrupt line to a pin on a IOSAPIC controller. 54 * (2) The motherboard routes the interrupt line to a pin on a IOSAPIC
47 * Multiple interrupt lines may have to share the same IOSAPIC pin (if they're level 55 * controller. Multiple interrupt lines may have to share the same
48 * triggered and use the same polarity). Each interrupt line has a unique Global 56 * IOSAPIC pin (if they're level triggered and use the same polarity).
49 * System Interrupt (GSI) number which can be calculated as the sum of the controller's 57 * Each interrupt line has a unique Global System Interrupt (GSI) number
50 * base GSI number and the IOSAPIC pin number to which the line connects. 58 * which can be calculated as the sum of the controller's base GSI number
59 * and the IOSAPIC pin number to which the line connects.
51 * 60 *
52 * (3) The IOSAPIC uses an internal routing table entries (RTEs) to map the IOSAPIC pin 61 * (3) The IOSAPIC uses an internal routing table entries (RTEs) to map the
53 * into the IA-64 interrupt vector. This interrupt vector is then sent to the CPU. 62 * IOSAPIC pin into the IA-64 interrupt vector. This interrupt vector is then
63 * sent to the CPU.
54 * 64 *
55 * (4) The kernel recognizes an interrupt as an IRQ. The IRQ interface is used as 65 * (4) The kernel recognizes an interrupt as an IRQ. The IRQ interface is
56 * architecture-independent interrupt handling mechanism in Linux. As an 66 * used as architecture-independent interrupt handling mechanism in Linux.
57 * IRQ is a number, we have to have IA-64 interrupt vector number <-> IRQ number 67 * As an IRQ is a number, we have to have
58 * mapping. On smaller systems, we use one-to-one mapping between IA-64 vector and 68 * IA-64 interrupt vector number <-> IRQ number mapping. On smaller
59 * IRQ. A platform can implement platform_irq_to_vector(irq) and 69 * systems, we use one-to-one mapping between IA-64 vector and IRQ. A
70 * platform can implement platform_irq_to_vector(irq) and
60 * platform_local_vector_to_irq(vector) APIs to differentiate the mapping. 71 * platform_local_vector_to_irq(vector) APIs to differentiate the mapping.
61 * Please see also include/asm-ia64/hw_irq.h for those APIs. 72 * Please see also include/asm-ia64/hw_irq.h for those APIs.
62 * 73 *
@@ -64,9 +75,9 @@
64 * 75 *
65 * PCI pin -> global system interrupt (GSI) -> IA-64 vector <-> IRQ 76 * PCI pin -> global system interrupt (GSI) -> IA-64 vector <-> IRQ
66 * 77 *
67 * Note: The term "IRQ" is loosely used everywhere in Linux kernel to describe interrupts. 78 * Note: The term "IRQ" is loosely used everywhere in Linux kernel to
68 * Now we use "IRQ" only for Linux IRQ's. ISA IRQ (isa_irq) is the only exception in this 79 * describeinterrupts. Now we use "IRQ" only for Linux IRQ's. ISA IRQ
69 * source code. 80 * (isa_irq) is the only exception in this source code.
70 */ 81 */
71#include <linux/config.h> 82#include <linux/config.h>
72 83
@@ -90,7 +101,6 @@
90#include <asm/ptrace.h> 101#include <asm/ptrace.h>
91#include <asm/system.h> 102#include <asm/system.h>
92 103
93
94#undef DEBUG_INTERRUPT_ROUTING 104#undef DEBUG_INTERRUPT_ROUTING
95 105
96#ifdef DEBUG_INTERRUPT_ROUTING 106#ifdef DEBUG_INTERRUPT_ROUTING
@@ -99,36 +109,46 @@
99#define DBG(fmt...) 109#define DBG(fmt...)
100#endif 110#endif
101 111
102#define NR_PREALLOCATE_RTE_ENTRIES (PAGE_SIZE / sizeof(struct iosapic_rte_info)) 112#define NR_PREALLOCATE_RTE_ENTRIES \
113 (PAGE_SIZE / sizeof(struct iosapic_rte_info))
103#define RTE_PREALLOCATED (1) 114#define RTE_PREALLOCATED (1)
104 115
105static DEFINE_SPINLOCK(iosapic_lock); 116static DEFINE_SPINLOCK(iosapic_lock);
106 117
107/* These tables map IA-64 vectors to the IOSAPIC pin that generates this vector. */ 118/*
119 * These tables map IA-64 vectors to the IOSAPIC pin that generates this
120 * vector.
121 */
108 122
109struct iosapic_rte_info { 123struct iosapic_rte_info {
110 struct list_head rte_list; /* node in list of RTEs sharing the same vector */ 124 struct list_head rte_list; /* node in list of RTEs sharing the
125 * same vector */
111 char __iomem *addr; /* base address of IOSAPIC */ 126 char __iomem *addr; /* base address of IOSAPIC */
112 unsigned int gsi_base; /* first GSI assigned to this IOSAPIC */ 127 unsigned int gsi_base; /* first GSI assigned to this
128 * IOSAPIC */
113 char rte_index; /* IOSAPIC RTE index */ 129 char rte_index; /* IOSAPIC RTE index */
114 int refcnt; /* reference counter */ 130 int refcnt; /* reference counter */
115 unsigned int flags; /* flags */ 131 unsigned int flags; /* flags */
116} ____cacheline_aligned; 132} ____cacheline_aligned;
117 133
118static struct iosapic_intr_info { 134static struct iosapic_intr_info {
119 struct list_head rtes; /* RTEs using this vector (empty => not an IOSAPIC interrupt) */ 135 struct list_head rtes; /* RTEs using this vector (empty =>
136 * not an IOSAPIC interrupt) */
120 int count; /* # of RTEs that shares this vector */ 137 int count; /* # of RTEs that shares this vector */
121 u32 low32; /* current value of low word of Redirection table entry */ 138 u32 low32; /* current value of low word of
139 * Redirection table entry */
122 unsigned int dest; /* destination CPU physical ID */ 140 unsigned int dest; /* destination CPU physical ID */
123 unsigned char dmode : 3; /* delivery mode (see iosapic.h) */ 141 unsigned char dmode : 3; /* delivery mode (see iosapic.h) */
124 unsigned char polarity: 1; /* interrupt polarity (see iosapic.h) */ 142 unsigned char polarity: 1; /* interrupt polarity
143 * (see iosapic.h) */
125 unsigned char trigger : 1; /* trigger mode (see iosapic.h) */ 144 unsigned char trigger : 1; /* trigger mode (see iosapic.h) */
126} iosapic_intr_info[IA64_NUM_VECTORS]; 145} iosapic_intr_info[IA64_NUM_VECTORS];
127 146
128static struct iosapic { 147static struct iosapic {
129 char __iomem *addr; /* base address of IOSAPIC */ 148 char __iomem *addr; /* base address of IOSAPIC */
130 unsigned int gsi_base; /* first GSI assigned to this IOSAPIC */ 149 unsigned int gsi_base; /* first GSI assigned to this
131 unsigned short num_rte; /* number of RTE in this IOSAPIC */ 150 * IOSAPIC */
151 unsigned short num_rte; /* # of RTEs on this IOSAPIC */
132 int rtes_inuse; /* # of RTEs in use on this IOSAPIC */ 152 int rtes_inuse; /* # of RTEs in use on this IOSAPIC */
133#ifdef CONFIG_NUMA 153#ifdef CONFIG_NUMA
134 unsigned short node; /* numa node association via pxm */ 154 unsigned short node; /* numa node association via pxm */
@@ -149,7 +169,8 @@ find_iosapic (unsigned int gsi)
149 int i; 169 int i;
150 170
151 for (i = 0; i < NR_IOSAPICS; i++) { 171 for (i = 0; i < NR_IOSAPICS; i++) {
152 if ((unsigned) (gsi - iosapic_lists[i].gsi_base) < iosapic_lists[i].num_rte) 172 if ((unsigned) (gsi - iosapic_lists[i].gsi_base) <
173 iosapic_lists[i].num_rte)
153 return i; 174 return i;
154 } 175 }
155 176
@@ -162,7 +183,8 @@ _gsi_to_vector (unsigned int gsi)
162 struct iosapic_intr_info *info; 183 struct iosapic_intr_info *info;
163 struct iosapic_rte_info *rte; 184 struct iosapic_rte_info *rte;
164 185
165 for (info = iosapic_intr_info; info < iosapic_intr_info + IA64_NUM_VECTORS; ++info) 186 for (info = iosapic_intr_info; info <
187 iosapic_intr_info + IA64_NUM_VECTORS; ++info)
166 list_for_each_entry(rte, &info->rtes, rte_list) 188 list_for_each_entry(rte, &info->rtes, rte_list)
167 if (rte->gsi_base + rte->rte_index == gsi) 189 if (rte->gsi_base + rte->rte_index == gsi)
168 return info - iosapic_intr_info; 190 return info - iosapic_intr_info;
@@ -185,8 +207,8 @@ gsi_to_irq (unsigned int gsi)
185 unsigned long flags; 207 unsigned long flags;
186 int irq; 208 int irq;
187 /* 209 /*
188 * XXX fix me: this assumes an identity mapping vetween IA-64 vector and Linux irq 210 * XXX fix me: this assumes an identity mapping between IA-64 vector
189 * numbers... 211 * and Linux irq numbers...
190 */ 212 */
191 spin_lock_irqsave(&iosapic_lock, flags); 213 spin_lock_irqsave(&iosapic_lock, flags);
192 { 214 {
@@ -197,7 +219,8 @@ gsi_to_irq (unsigned int gsi)
197 return irq; 219 return irq;
198} 220}
199 221
200static struct iosapic_rte_info *gsi_vector_to_rte(unsigned int gsi, unsigned int vec) 222static struct iosapic_rte_info *gsi_vector_to_rte(unsigned int gsi,
223 unsigned int vec)
201{ 224{
202 struct iosapic_rte_info *rte; 225 struct iosapic_rte_info *rte;
203 226
@@ -237,7 +260,9 @@ set_rte (unsigned int gsi, unsigned int vector, unsigned int dest, int mask)
237 260
238 for (irq = 0; irq < NR_IRQS; ++irq) 261 for (irq = 0; irq < NR_IRQS; ++irq)
239 if (irq_to_vector(irq) == vector) { 262 if (irq_to_vector(irq) == vector) {
240 set_irq_affinity_info(irq, (int)(dest & 0xffff), redir); 263 set_irq_affinity_info(irq,
264 (int)(dest & 0xffff),
265 redir);
241 break; 266 break;
242 } 267 }
243 } 268 }
@@ -259,7 +284,7 @@ set_rte (unsigned int gsi, unsigned int vector, unsigned int dest, int mask)
259} 284}
260 285
261static void 286static void
262nop (unsigned int vector) 287nop (unsigned int irq)
263{ 288{
264 /* do nothing... */ 289 /* do nothing... */
265} 290}
@@ -281,7 +306,8 @@ mask_irq (unsigned int irq)
281 { 306 {
282 /* set only the mask bit */ 307 /* set only the mask bit */
283 low32 = iosapic_intr_info[vec].low32 |= IOSAPIC_MASK; 308 low32 = iosapic_intr_info[vec].low32 |= IOSAPIC_MASK;
284 list_for_each_entry(rte, &iosapic_intr_info[vec].rtes, rte_list) { 309 list_for_each_entry(rte, &iosapic_intr_info[vec].rtes,
310 rte_list) {
285 addr = rte->addr; 311 addr = rte->addr;
286 rte_index = rte->rte_index; 312 rte_index = rte->rte_index;
287 iosapic_write(addr, IOSAPIC_RTE_LOW(rte_index), low32); 313 iosapic_write(addr, IOSAPIC_RTE_LOW(rte_index), low32);
@@ -306,7 +332,8 @@ unmask_irq (unsigned int irq)
306 spin_lock_irqsave(&iosapic_lock, flags); 332 spin_lock_irqsave(&iosapic_lock, flags);
307 { 333 {
308 low32 = iosapic_intr_info[vec].low32 &= ~IOSAPIC_MASK; 334 low32 = iosapic_intr_info[vec].low32 &= ~IOSAPIC_MASK;
309 list_for_each_entry(rte, &iosapic_intr_info[vec].rtes, rte_list) { 335 list_for_each_entry(rte, &iosapic_intr_info[vec].rtes,
336 rte_list) {
310 addr = rte->addr; 337 addr = rte->addr;
311 rte_index = rte->rte_index; 338 rte_index = rte->rte_index;
312 iosapic_write(addr, IOSAPIC_RTE_LOW(rte_index), low32); 339 iosapic_write(addr, IOSAPIC_RTE_LOW(rte_index), low32);
@@ -346,21 +373,25 @@ iosapic_set_affinity (unsigned int irq, cpumask_t mask)
346 373
347 spin_lock_irqsave(&iosapic_lock, flags); 374 spin_lock_irqsave(&iosapic_lock, flags);
348 { 375 {
349 low32 = iosapic_intr_info[vec].low32 & ~(7 << IOSAPIC_DELIVERY_SHIFT); 376 low32 = iosapic_intr_info[vec].low32 &
377 ~(7 << IOSAPIC_DELIVERY_SHIFT);
350 378
351 if (redir) 379 if (redir)
352 /* change delivery mode to lowest priority */ 380 /* change delivery mode to lowest priority */
353 low32 |= (IOSAPIC_LOWEST_PRIORITY << IOSAPIC_DELIVERY_SHIFT); 381 low32 |= (IOSAPIC_LOWEST_PRIORITY <<
382 IOSAPIC_DELIVERY_SHIFT);
354 else 383 else
355 /* change delivery mode to fixed */ 384 /* change delivery mode to fixed */
356 low32 |= (IOSAPIC_FIXED << IOSAPIC_DELIVERY_SHIFT); 385 low32 |= (IOSAPIC_FIXED << IOSAPIC_DELIVERY_SHIFT);
357 386
358 iosapic_intr_info[vec].low32 = low32; 387 iosapic_intr_info[vec].low32 = low32;
359 iosapic_intr_info[vec].dest = dest; 388 iosapic_intr_info[vec].dest = dest;
360 list_for_each_entry(rte, &iosapic_intr_info[vec].rtes, rte_list) { 389 list_for_each_entry(rte, &iosapic_intr_info[vec].rtes,
390 rte_list) {
361 addr = rte->addr; 391 addr = rte->addr;
362 rte_index = rte->rte_index; 392 rte_index = rte->rte_index;
363 iosapic_write(addr, IOSAPIC_RTE_HIGH(rte_index), high32); 393 iosapic_write(addr, IOSAPIC_RTE_HIGH(rte_index),
394 high32);
364 iosapic_write(addr, IOSAPIC_RTE_LOW(rte_index), low32); 395 iosapic_write(addr, IOSAPIC_RTE_LOW(rte_index), low32);
365 } 396 }
366 } 397 }
@@ -433,7 +464,8 @@ iosapic_ack_edge_irq (unsigned int irq)
433 * interrupt for real. This prevents IRQ storms from unhandled 464 * interrupt for real. This prevents IRQ storms from unhandled
434 * devices. 465 * devices.
435 */ 466 */
436 if ((idesc->status & (IRQ_PENDING|IRQ_DISABLED)) == (IRQ_PENDING|IRQ_DISABLED)) 467 if ((idesc->status & (IRQ_PENDING|IRQ_DISABLED)) ==
468 (IRQ_PENDING|IRQ_DISABLED))
437 mask_irq(irq); 469 mask_irq(irq);
438} 470}
439 471
@@ -467,7 +499,8 @@ iosapic_version (char __iomem *addr)
467 return iosapic_read(addr, IOSAPIC_VERSION); 499 return iosapic_read(addr, IOSAPIC_VERSION);
468} 500}
469 501
470static int iosapic_find_sharable_vector (unsigned long trigger, unsigned long pol) 502static int iosapic_find_sharable_vector (unsigned long trigger,
503 unsigned long pol)
471{ 504{
472 int i, vector = -1, min_count = -1; 505 int i, vector = -1, min_count = -1;
473 struct iosapic_intr_info *info; 506 struct iosapic_intr_info *info;
@@ -482,7 +515,8 @@ static int iosapic_find_sharable_vector (unsigned long trigger, unsigned long po
482 for (i = IA64_FIRST_DEVICE_VECTOR; i <= IA64_LAST_DEVICE_VECTOR; i++) { 515 for (i = IA64_FIRST_DEVICE_VECTOR; i <= IA64_LAST_DEVICE_VECTOR; i++) {
483 info = &iosapic_intr_info[i]; 516 info = &iosapic_intr_info[i];
484 if (info->trigger == trigger && info->polarity == pol && 517 if (info->trigger == trigger && info->polarity == pol &&
485 (info->dmode == IOSAPIC_FIXED || info->dmode == IOSAPIC_LOWEST_PRIORITY)) { 518 (info->dmode == IOSAPIC_FIXED || info->dmode ==
519 IOSAPIC_LOWEST_PRIORITY)) {
486 if (min_count == -1 || info->count < min_count) { 520 if (min_count == -1 || info->count < min_count) {
487 vector = i; 521 vector = i;
488 min_count = info->count; 522 min_count = info->count;
@@ -506,12 +540,15 @@ iosapic_reassign_vector (int vector)
506 new_vector = assign_irq_vector(AUTO_ASSIGN); 540 new_vector = assign_irq_vector(AUTO_ASSIGN);
507 if (new_vector < 0) 541 if (new_vector < 0)
508 panic("%s: out of interrupt vectors!\n", __FUNCTION__); 542 panic("%s: out of interrupt vectors!\n", __FUNCTION__);
509 printk(KERN_INFO "Reassigning vector %d to %d\n", vector, new_vector); 543 printk(KERN_INFO "Reassigning vector %d to %d\n",
544 vector, new_vector);
510 memcpy(&iosapic_intr_info[new_vector], &iosapic_intr_info[vector], 545 memcpy(&iosapic_intr_info[new_vector], &iosapic_intr_info[vector],
511 sizeof(struct iosapic_intr_info)); 546 sizeof(struct iosapic_intr_info));
512 INIT_LIST_HEAD(&iosapic_intr_info[new_vector].rtes); 547 INIT_LIST_HEAD(&iosapic_intr_info[new_vector].rtes);
513 list_move(iosapic_intr_info[vector].rtes.next, &iosapic_intr_info[new_vector].rtes); 548 list_move(iosapic_intr_info[vector].rtes.next,
514 memset(&iosapic_intr_info[vector], 0, sizeof(struct iosapic_intr_info)); 549 &iosapic_intr_info[new_vector].rtes);
550 memset(&iosapic_intr_info[vector], 0,
551 sizeof(struct iosapic_intr_info));
515 iosapic_intr_info[vector].low32 = IOSAPIC_MASK; 552 iosapic_intr_info[vector].low32 = IOSAPIC_MASK;
516 INIT_LIST_HEAD(&iosapic_intr_info[vector].rtes); 553 INIT_LIST_HEAD(&iosapic_intr_info[vector].rtes);
517 } 554 }
@@ -524,7 +561,8 @@ static struct iosapic_rte_info *iosapic_alloc_rte (void)
524 int preallocated = 0; 561 int preallocated = 0;
525 562
526 if (!iosapic_kmalloc_ok && list_empty(&free_rte_list)) { 563 if (!iosapic_kmalloc_ok && list_empty(&free_rte_list)) {
527 rte = alloc_bootmem(sizeof(struct iosapic_rte_info) * NR_PREALLOCATE_RTE_ENTRIES); 564 rte = alloc_bootmem(sizeof(struct iosapic_rte_info) *
565 NR_PREALLOCATE_RTE_ENTRIES);
528 if (!rte) 566 if (!rte)
529 return NULL; 567 return NULL;
530 for (i = 0; i < NR_PREALLOCATE_RTE_ENTRIES; i++, rte++) 568 for (i = 0; i < NR_PREALLOCATE_RTE_ENTRIES; i++, rte++)
@@ -532,7 +570,8 @@ static struct iosapic_rte_info *iosapic_alloc_rte (void)
532 } 570 }
533 571
534 if (!list_empty(&free_rte_list)) { 572 if (!list_empty(&free_rte_list)) {
535 rte = list_entry(free_rte_list.next, struct iosapic_rte_info, rte_list); 573 rte = list_entry(free_rte_list.next, struct iosapic_rte_info,
574 rte_list);
536 list_del(&rte->rte_list); 575 list_del(&rte->rte_list);
537 preallocated++; 576 preallocated++;
538 } else { 577 } else {
@@ -575,7 +614,8 @@ register_intr (unsigned int gsi, int vector, unsigned char delivery,
575 614
576 index = find_iosapic(gsi); 615 index = find_iosapic(gsi);
577 if (index < 0) { 616 if (index < 0) {
578 printk(KERN_WARNING "%s: No IOSAPIC for GSI %u\n", __FUNCTION__, gsi); 617 printk(KERN_WARNING "%s: No IOSAPIC for GSI %u\n",
618 __FUNCTION__, gsi);
579 return -ENODEV; 619 return -ENODEV;
580 } 620 }
581 621
@@ -586,7 +626,8 @@ register_intr (unsigned int gsi, int vector, unsigned char delivery,
586 if (!rte) { 626 if (!rte) {
587 rte = iosapic_alloc_rte(); 627 rte = iosapic_alloc_rte();
588 if (!rte) { 628 if (!rte) {
589 printk(KERN_WARNING "%s: cannot allocate memory\n", __FUNCTION__); 629 printk(KERN_WARNING "%s: cannot allocate memory\n",
630 __FUNCTION__);
590 return -ENOMEM; 631 return -ENOMEM;
591 } 632 }
592 633
@@ -602,7 +643,9 @@ register_intr (unsigned int gsi, int vector, unsigned char delivery,
602 else if (vector_is_shared(vector)) { 643 else if (vector_is_shared(vector)) {
603 struct iosapic_intr_info *info = &iosapic_intr_info[vector]; 644 struct iosapic_intr_info *info = &iosapic_intr_info[vector];
604 if (info->trigger != trigger || info->polarity != polarity) { 645 if (info->trigger != trigger || info->polarity != polarity) {
605 printk (KERN_WARNING "%s: cannot override the interrupt\n", __FUNCTION__); 646 printk (KERN_WARNING
647 "%s: cannot override the interrupt\n",
648 __FUNCTION__);
606 return -EINVAL; 649 return -EINVAL;
607 } 650 }
608 } 651 }
@@ -619,8 +662,10 @@ register_intr (unsigned int gsi, int vector, unsigned char delivery,
619 idesc = irq_descp(vector); 662 idesc = irq_descp(vector);
620 if (idesc->handler != irq_type) { 663 if (idesc->handler != irq_type) {
621 if (idesc->handler != &no_irq_type) 664 if (idesc->handler != &no_irq_type)
622 printk(KERN_WARNING "%s: changing vector %d from %s to %s\n", 665 printk(KERN_WARNING
623 __FUNCTION__, vector, idesc->handler->typename, irq_type->typename); 666 "%s: changing vector %d from %s to %s\n",
667 __FUNCTION__, vector,
668 idesc->handler->typename, irq_type->typename);
624 idesc->handler = irq_type; 669 idesc->handler = irq_type;
625 } 670 }
626 return 0; 671 return 0;
@@ -681,7 +726,7 @@ get_target_cpu (unsigned int gsi, int vector)
681 if (!num_cpus) 726 if (!num_cpus)
682 goto skip_numa_setup; 727 goto skip_numa_setup;
683 728
684 /* Use vector assigment to distribute across cpus in node */ 729 /* Use vector assignment to distribute across cpus in node */
685 cpu_index = vector % num_cpus; 730 cpu_index = vector % num_cpus;
686 731
687 for (numa_cpu = first_cpu(cpu_mask) ; i < cpu_index ; i++) 732 for (numa_cpu = first_cpu(cpu_mask) ; i < cpu_index ; i++)
@@ -703,7 +748,7 @@ skip_numa_setup:
703 } while (!cpu_online(cpu)); 748 } while (!cpu_online(cpu));
704 749
705 return cpu_physical_id(cpu); 750 return cpu_physical_id(cpu);
706#else 751#else /* CONFIG_SMP */
707 return cpu_physical_id(smp_processor_id()); 752 return cpu_physical_id(smp_processor_id());
708#endif 753#endif
709} 754}
@@ -755,7 +800,8 @@ again:
755 if (list_empty(&iosapic_intr_info[vector].rtes)) 800 if (list_empty(&iosapic_intr_info[vector].rtes))
756 free_irq_vector(vector); 801 free_irq_vector(vector);
757 spin_unlock(&iosapic_lock); 802 spin_unlock(&iosapic_lock);
758 spin_unlock_irqrestore(&irq_descp(vector)->lock, flags); 803 spin_unlock_irqrestore(&irq_descp(vector)->lock,
804 flags);
759 goto again; 805 goto again;
760 } 806 }
761 807
@@ -764,7 +810,8 @@ again:
764 polarity, trigger); 810 polarity, trigger);
765 if (err < 0) { 811 if (err < 0) {
766 spin_unlock(&iosapic_lock); 812 spin_unlock(&iosapic_lock);
767 spin_unlock_irqrestore(&irq_descp(vector)->lock, flags); 813 spin_unlock_irqrestore(&irq_descp(vector)->lock,
814 flags);
768 return err; 815 return err;
769 } 816 }
770 817
@@ -806,7 +853,8 @@ iosapic_unregister_intr (unsigned int gsi)
806 */ 853 */
807 irq = gsi_to_irq(gsi); 854 irq = gsi_to_irq(gsi);
808 if (irq < 0) { 855 if (irq < 0) {
809 printk(KERN_ERR "iosapic_unregister_intr(%u) unbalanced\n", gsi); 856 printk(KERN_ERR "iosapic_unregister_intr(%u) unbalanced\n",
857 gsi);
810 WARN_ON(1); 858 WARN_ON(1);
811 return; 859 return;
812 } 860 }
@@ -817,7 +865,9 @@ iosapic_unregister_intr (unsigned int gsi)
817 spin_lock(&iosapic_lock); 865 spin_lock(&iosapic_lock);
818 { 866 {
819 if ((rte = gsi_vector_to_rte(gsi, vector)) == NULL) { 867 if ((rte = gsi_vector_to_rte(gsi, vector)) == NULL) {
820 printk(KERN_ERR "iosapic_unregister_intr(%u) unbalanced\n", gsi); 868 printk(KERN_ERR
869 "iosapic_unregister_intr(%u) unbalanced\n",
870 gsi);
821 WARN_ON(1); 871 WARN_ON(1);
822 goto out; 872 goto out;
823 } 873 }
@@ -827,7 +877,8 @@ iosapic_unregister_intr (unsigned int gsi)
827 877
828 /* Mask the interrupt */ 878 /* Mask the interrupt */
829 low32 = iosapic_intr_info[vector].low32 | IOSAPIC_MASK; 879 low32 = iosapic_intr_info[vector].low32 | IOSAPIC_MASK;
830 iosapic_write(rte->addr, IOSAPIC_RTE_LOW(rte->rte_index), low32); 880 iosapic_write(rte->addr, IOSAPIC_RTE_LOW(rte->rte_index),
881 low32);
831 882
832 /* Remove the rte entry from the list */ 883 /* Remove the rte entry from the list */
833 list_del(&rte->rte_list); 884 list_del(&rte->rte_list);
@@ -840,7 +891,9 @@ iosapic_unregister_intr (unsigned int gsi)
840 trigger = iosapic_intr_info[vector].trigger; 891 trigger = iosapic_intr_info[vector].trigger;
841 polarity = iosapic_intr_info[vector].polarity; 892 polarity = iosapic_intr_info[vector].polarity;
842 dest = iosapic_intr_info[vector].dest; 893 dest = iosapic_intr_info[vector].dest;
843 printk(KERN_INFO "GSI %u (%s, %s) -> CPU %d (0x%04x) vector %d unregistered\n", 894 printk(KERN_INFO
895 "GSI %u (%s, %s) -> CPU %d (0x%04x)"
896 " vector %d unregistered\n",
844 gsi, (trigger == IOSAPIC_EDGE ? "edge" : "level"), 897 gsi, (trigger == IOSAPIC_EDGE ? "edge" : "level"),
845 (polarity == IOSAPIC_POL_HIGH ? "high" : "low"), 898 (polarity == IOSAPIC_POL_HIGH ? "high" : "low"),
846 cpu_logical_id(dest), dest, vector); 899 cpu_logical_id(dest), dest, vector);
@@ -853,12 +906,15 @@ iosapic_unregister_intr (unsigned int gsi)
853 idesc->handler = &no_irq_type; 906 idesc->handler = &no_irq_type;
854 907
855 /* Clear the interrupt information */ 908 /* Clear the interrupt information */
856 memset(&iosapic_intr_info[vector], 0, sizeof(struct iosapic_intr_info)); 909 memset(&iosapic_intr_info[vector], 0,
910 sizeof(struct iosapic_intr_info));
857 iosapic_intr_info[vector].low32 |= IOSAPIC_MASK; 911 iosapic_intr_info[vector].low32 |= IOSAPIC_MASK;
858 INIT_LIST_HEAD(&iosapic_intr_info[vector].rtes); 912 INIT_LIST_HEAD(&iosapic_intr_info[vector].rtes);
859 913
860 if (idesc->action) { 914 if (idesc->action) {
861 printk(KERN_ERR "interrupt handlers still exist on IRQ %u\n", irq); 915 printk(KERN_ERR
916 "interrupt handlers still exist on"
917 "IRQ %u\n", irq);
862 WARN_ON(1); 918 WARN_ON(1);
863 } 919 }
864 920
@@ -873,7 +929,6 @@ iosapic_unregister_intr (unsigned int gsi)
873 929
874/* 930/*
875 * ACPI calls this when it finds an entry for a platform interrupt. 931 * ACPI calls this when it finds an entry for a platform interrupt.
876 * Note that the irq_base and IOSAPIC address must be set in iosapic_init().
877 */ 932 */
878int __init 933int __init
879iosapic_register_platform_intr (u32 int_type, unsigned int gsi, 934iosapic_register_platform_intr (u32 int_type, unsigned int gsi,
@@ -907,13 +962,16 @@ iosapic_register_platform_intr (u32 int_type, unsigned int gsi,
907 mask = 1; 962 mask = 1;
908 break; 963 break;
909 default: 964 default:
910 printk(KERN_ERR "iosapic_register_platform_irq(): invalid int type 0x%x\n", int_type); 965 printk(KERN_ERR "%s: invalid int type 0x%x\n", __FUNCTION__,
966 int_type);
911 return -1; 967 return -1;
912 } 968 }
913 969
914 register_intr(gsi, vector, delivery, polarity, trigger); 970 register_intr(gsi, vector, delivery, polarity, trigger);
915 971
916 printk(KERN_INFO "PLATFORM int %s (0x%x): GSI %u (%s, %s) -> CPU %d (0x%04x) vector %d\n", 972 printk(KERN_INFO
973 "PLATFORM int %s (0x%x): GSI %u (%s, %s) -> CPU %d (0x%04x)"
974 " vector %d\n",
917 int_type < ARRAY_SIZE(name) ? name[int_type] : "unknown", 975 int_type < ARRAY_SIZE(name) ? name[int_type] : "unknown",
918 int_type, gsi, (trigger == IOSAPIC_EDGE ? "edge" : "level"), 976 int_type, gsi, (trigger == IOSAPIC_EDGE ? "edge" : "level"),
919 (polarity == IOSAPIC_POL_HIGH ? "high" : "low"), 977 (polarity == IOSAPIC_POL_HIGH ? "high" : "low"),
@@ -923,10 +981,8 @@ iosapic_register_platform_intr (u32 int_type, unsigned int gsi,
923 return vector; 981 return vector;
924} 982}
925 983
926
927/* 984/*
928 * ACPI calls this when it finds an entry for a legacy ISA IRQ override. 985 * ACPI calls this when it finds an entry for a legacy ISA IRQ override.
929 * Note that the gsi_base and IOSAPIC address must be set in iosapic_init().
930 */ 986 */
931void __init 987void __init
932iosapic_override_isa_irq (unsigned int isa_irq, unsigned int gsi, 988iosapic_override_isa_irq (unsigned int isa_irq, unsigned int gsi,
@@ -955,16 +1011,19 @@ iosapic_system_init (int system_pcat_compat)
955 1011
956 for (vector = 0; vector < IA64_NUM_VECTORS; ++vector) { 1012 for (vector = 0; vector < IA64_NUM_VECTORS; ++vector) {
957 iosapic_intr_info[vector].low32 = IOSAPIC_MASK; 1013 iosapic_intr_info[vector].low32 = IOSAPIC_MASK;
958 INIT_LIST_HEAD(&iosapic_intr_info[vector].rtes); /* mark as unused */ 1014 /* mark as unused */
1015 INIT_LIST_HEAD(&iosapic_intr_info[vector].rtes);
959 } 1016 }
960 1017
961 pcat_compat = system_pcat_compat; 1018 pcat_compat = system_pcat_compat;
962 if (pcat_compat) { 1019 if (pcat_compat) {
963 /* 1020 /*
964 * Disable the compatibility mode interrupts (8259 style), needs IN/OUT support 1021 * Disable the compatibility mode interrupts (8259 style),
965 * enabled. 1022 * needs IN/OUT support enabled.
966 */ 1023 */
967 printk(KERN_INFO "%s: Disabling PC-AT compatible 8259 interrupts\n", __FUNCTION__); 1024 printk(KERN_INFO
1025 "%s: Disabling PC-AT compatible 8259 interrupts\n",
1026 __FUNCTION__);
968 outb(0xff, 0xA1); 1027 outb(0xff, 0xA1);
969 outb(0xff, 0x21); 1028 outb(0xff, 0x21);
970 } 1029 }
@@ -1004,10 +1063,7 @@ iosapic_check_gsi_range (unsigned int gsi_base, unsigned int ver)
1004 base = iosapic_lists[index].gsi_base; 1063 base = iosapic_lists[index].gsi_base;
1005 end = base + iosapic_lists[index].num_rte - 1; 1064 end = base + iosapic_lists[index].num_rte - 1;
1006 1065
1007 if (gsi_base < base && gsi_end < base) 1066 if (gsi_end < base || end < gsi_base)
1008 continue;/* OK */
1009
1010 if (gsi_base > end && gsi_end > end)
1011 continue; /* OK */ 1067 continue; /* OK */
1012 1068
1013 return -EBUSY; 1069 return -EBUSY;
@@ -1053,12 +1109,14 @@ iosapic_init (unsigned long phys_addr, unsigned int gsi_base)
1053 1109
1054 if ((gsi_base == 0) && pcat_compat) { 1110 if ((gsi_base == 0) && pcat_compat) {
1055 /* 1111 /*
1056 * Map the legacy ISA devices into the IOSAPIC data. Some of these may 1112 * Map the legacy ISA devices into the IOSAPIC data. Some of
1057 * get reprogrammed later on with data from the ACPI Interrupt Source 1113 * these may get reprogrammed later on with data from the ACPI
1058 * Override table. 1114 * Interrupt Source Override table.
1059 */ 1115 */
1060 for (isa_irq = 0; isa_irq < 16; ++isa_irq) 1116 for (isa_irq = 0; isa_irq < 16; ++isa_irq)
1061 iosapic_override_isa_irq(isa_irq, isa_irq, IOSAPIC_POL_HIGH, IOSAPIC_EDGE); 1117 iosapic_override_isa_irq(isa_irq, isa_irq,
1118 IOSAPIC_POL_HIGH,
1119 IOSAPIC_EDGE);
1062 } 1120 }
1063 return 0; 1121 return 0;
1064} 1122}
@@ -1081,7 +1139,8 @@ iosapic_remove (unsigned int gsi_base)
1081 1139
1082 if (iosapic_lists[index].rtes_inuse) { 1140 if (iosapic_lists[index].rtes_inuse) {
1083 err = -EBUSY; 1141 err = -EBUSY;
1084 printk(KERN_WARNING "%s: IOSAPIC for GSI base %u is busy\n", 1142 printk(KERN_WARNING
1143 "%s: IOSAPIC for GSI base %u is busy\n",
1085 __FUNCTION__, gsi_base); 1144 __FUNCTION__, gsi_base);
1086 goto out; 1145 goto out;
1087 } 1146 }
diff --git a/arch/ia64/kernel/palinfo.c b/arch/ia64/kernel/palinfo.c
index 89faa603c6be..6386f63c413e 100644
--- a/arch/ia64/kernel/palinfo.c
+++ b/arch/ia64/kernel/palinfo.c
@@ -240,7 +240,7 @@ cache_info(char *page)
240 } 240 }
241 p += sprintf(p, 241 p += sprintf(p,
242 "%s Cache level %lu:\n" 242 "%s Cache level %lu:\n"
243 "\tSize : %lu bytes\n" 243 "\tSize : %u bytes\n"
244 "\tAttributes : ", 244 "\tAttributes : ",
245 cache_types[j+cci.pcci_unified], i+1, 245 cache_types[j+cci.pcci_unified], i+1,
246 cci.pcci_cache_size); 246 cci.pcci_cache_size);
@@ -648,9 +648,9 @@ frequency_info(char *page)
648 if (ia64_pal_freq_ratios(&proc, &bus, &itc) != 0) return 0; 648 if (ia64_pal_freq_ratios(&proc, &bus, &itc) != 0) return 0;
649 649
650 p += sprintf(p, 650 p += sprintf(p,
651 "Processor/Clock ratio : %ld/%ld\n" 651 "Processor/Clock ratio : %d/%d\n"
652 "Bus/Clock ratio : %ld/%ld\n" 652 "Bus/Clock ratio : %d/%d\n"
653 "ITC/Clock ratio : %ld/%ld\n", 653 "ITC/Clock ratio : %d/%d\n",
654 proc.num, proc.den, bus.num, bus.den, itc.num, itc.den); 654 proc.num, proc.den, bus.num, bus.den, itc.num, itc.den);
655 655
656 return p - page; 656 return p - page;
diff --git a/arch/ia64/kernel/time.c b/arch/ia64/kernel/time.c
index ac167436e936..49958904045b 100644
--- a/arch/ia64/kernel/time.c
+++ b/arch/ia64/kernel/time.c
@@ -188,7 +188,7 @@ ia64_init_itm (void)
188 itc_freq = (platform_base_freq*itc_ratio.num)/itc_ratio.den; 188 itc_freq = (platform_base_freq*itc_ratio.num)/itc_ratio.den;
189 189
190 local_cpu_data->itm_delta = (itc_freq + HZ/2) / HZ; 190 local_cpu_data->itm_delta = (itc_freq + HZ/2) / HZ;
191 printk(KERN_DEBUG "CPU %d: base freq=%lu.%03luMHz, ITC ratio=%lu/%lu, " 191 printk(KERN_DEBUG "CPU %d: base freq=%lu.%03luMHz, ITC ratio=%u/%u, "
192 "ITC freq=%lu.%03luMHz", smp_processor_id(), 192 "ITC freq=%lu.%03luMHz", smp_processor_id(),
193 platform_base_freq / 1000000, (platform_base_freq / 1000) % 1000, 193 platform_base_freq / 1000000, (platform_base_freq / 1000) % 1000,
194 itc_ratio.num, itc_ratio.den, itc_freq / 1000000, (itc_freq / 1000) % 1000); 194 itc_ratio.num, itc_ratio.den, itc_freq / 1000000, (itc_freq / 1000) % 1000);
diff --git a/arch/ia64/kernel/topology.c b/arch/ia64/kernel/topology.c
index 3b6fd798c4d6..b47476d655f1 100644
--- a/arch/ia64/kernel/topology.c
+++ b/arch/ia64/kernel/topology.c
@@ -9,6 +9,8 @@
9 * 2002/08/07 Erich Focht <efocht@ess.nec.de> 9 * 2002/08/07 Erich Focht <efocht@ess.nec.de>
10 * Populate cpu entries in sysfs for non-numa systems as well 10 * Populate cpu entries in sysfs for non-numa systems as well
11 * Intel Corporation - Ashok Raj 11 * Intel Corporation - Ashok Raj
12 * 02/27/2006 Zhang, Yanmin
13 * Populate cpu cache entries in sysfs for cpu cache info
12 */ 14 */
13 15
14#include <linux/config.h> 16#include <linux/config.h>
@@ -19,6 +21,7 @@
19#include <linux/init.h> 21#include <linux/init.h>
20#include <linux/bootmem.h> 22#include <linux/bootmem.h>
21#include <linux/nodemask.h> 23#include <linux/nodemask.h>
24#include <linux/notifier.h>
22#include <asm/mmzone.h> 25#include <asm/mmzone.h>
23#include <asm/numa.h> 26#include <asm/numa.h>
24#include <asm/cpu.h> 27#include <asm/cpu.h>
@@ -101,3 +104,367 @@ out:
101} 104}
102 105
103subsys_initcall(topology_init); 106subsys_initcall(topology_init);
107
108
109/*
110 * Export cpu cache information through sysfs
111 */
112
113/*
114 * A bunch of string array to get pretty printing
115 */
116static const char *cache_types[] = {
117 "", /* not used */
118 "Instruction",
119 "Data",
120 "Unified" /* unified */
121};
122
123static const char *cache_mattrib[]={
124 "WriteThrough",
125 "WriteBack",
126 "", /* reserved */
127 "" /* reserved */
128};
129
130struct cache_info {
131 pal_cache_config_info_t cci;
132 cpumask_t shared_cpu_map;
133 int level;
134 int type;
135 struct kobject kobj;
136};
137
138struct cpu_cache_info {
139 struct cache_info *cache_leaves;
140 int num_cache_leaves;
141 struct kobject kobj;
142};
143
144static struct cpu_cache_info all_cpu_cache_info[NR_CPUS];
145#define LEAF_KOBJECT_PTR(x,y) (&all_cpu_cache_info[x].cache_leaves[y])
146
147#ifdef CONFIG_SMP
148static void cache_shared_cpu_map_setup( unsigned int cpu,
149 struct cache_info * this_leaf)
150{
151 pal_cache_shared_info_t csi;
152 int num_shared, i = 0;
153 unsigned int j;
154
155 if (cpu_data(cpu)->threads_per_core <= 1 &&
156 cpu_data(cpu)->cores_per_socket <= 1) {
157 cpu_set(cpu, this_leaf->shared_cpu_map);
158 return;
159 }
160
161 if (ia64_pal_cache_shared_info(this_leaf->level,
162 this_leaf->type,
163 0,
164 &csi) != PAL_STATUS_SUCCESS)
165 return;
166
167 num_shared = (int) csi.num_shared;
168 do {
169 for_each_cpu(j)
170 if (cpu_data(cpu)->socket_id == cpu_data(j)->socket_id
171 && cpu_data(j)->core_id == csi.log1_cid
172 && cpu_data(j)->thread_id == csi.log1_tid)
173 cpu_set(j, this_leaf->shared_cpu_map);
174
175 i++;
176 } while (i < num_shared &&
177 ia64_pal_cache_shared_info(this_leaf->level,
178 this_leaf->type,
179 i,
180 &csi) == PAL_STATUS_SUCCESS);
181}
182#else
183static void cache_shared_cpu_map_setup(unsigned int cpu,
184 struct cache_info * this_leaf)
185{
186 cpu_set(cpu, this_leaf->shared_cpu_map);
187 return;
188}
189#endif
190
191static ssize_t show_coherency_line_size(struct cache_info *this_leaf,
192 char *buf)
193{
194 return sprintf(buf, "%u\n", 1 << this_leaf->cci.pcci_line_size);
195}
196
197static ssize_t show_ways_of_associativity(struct cache_info *this_leaf,
198 char *buf)
199{
200 return sprintf(buf, "%u\n", this_leaf->cci.pcci_assoc);
201}
202
203static ssize_t show_attributes(struct cache_info *this_leaf, char *buf)
204{
205 return sprintf(buf,
206 "%s\n",
207 cache_mattrib[this_leaf->cci.pcci_cache_attr]);
208}
209
210static ssize_t show_size(struct cache_info *this_leaf, char *buf)
211{
212 return sprintf(buf, "%uK\n", this_leaf->cci.pcci_cache_size / 1024);
213}
214
215static ssize_t show_number_of_sets(struct cache_info *this_leaf, char *buf)
216{
217 unsigned number_of_sets = this_leaf->cci.pcci_cache_size;
218 number_of_sets /= this_leaf->cci.pcci_assoc;
219 number_of_sets /= 1 << this_leaf->cci.pcci_line_size;
220
221 return sprintf(buf, "%u\n", number_of_sets);
222}
223
224static ssize_t show_shared_cpu_map(struct cache_info *this_leaf, char *buf)
225{
226 ssize_t len;
227 cpumask_t shared_cpu_map;
228
229 cpus_and(shared_cpu_map, this_leaf->shared_cpu_map, cpu_online_map);
230 len = cpumask_scnprintf(buf, NR_CPUS+1, shared_cpu_map);
231 len += sprintf(buf+len, "\n");
232 return len;
233}
234
235static ssize_t show_type(struct cache_info *this_leaf, char *buf)
236{
237 int type = this_leaf->type + this_leaf->cci.pcci_unified;
238 return sprintf(buf, "%s\n", cache_types[type]);
239}
240
241static ssize_t show_level(struct cache_info *this_leaf, char *buf)
242{
243 return sprintf(buf, "%u\n", this_leaf->level);
244}
245
246struct cache_attr {
247 struct attribute attr;
248 ssize_t (*show)(struct cache_info *, char *);
249 ssize_t (*store)(struct cache_info *, const char *, size_t count);
250};
251
252#ifdef define_one_ro
253 #undef define_one_ro
254#endif
255#define define_one_ro(_name) \
256 static struct cache_attr _name = \
257__ATTR(_name, 0444, show_##_name, NULL)
258
259define_one_ro(level);
260define_one_ro(type);
261define_one_ro(coherency_line_size);
262define_one_ro(ways_of_associativity);
263define_one_ro(size);
264define_one_ro(number_of_sets);
265define_one_ro(shared_cpu_map);
266define_one_ro(attributes);
267
268static struct attribute * cache_default_attrs[] = {
269 &type.attr,
270 &level.attr,
271 &coherency_line_size.attr,
272 &ways_of_associativity.attr,
273 &attributes.attr,
274 &size.attr,
275 &number_of_sets.attr,
276 &shared_cpu_map.attr,
277 NULL
278};
279
280#define to_object(k) container_of(k, struct cache_info, kobj)
281#define to_attr(a) container_of(a, struct cache_attr, attr)
282
283static ssize_t cache_show(struct kobject * kobj, struct attribute * attr, char * buf)
284{
285 struct cache_attr *fattr = to_attr(attr);
286 struct cache_info *this_leaf = to_object(kobj);
287 ssize_t ret;
288
289 ret = fattr->show ? fattr->show(this_leaf, buf) : 0;
290 return ret;
291}
292
293static struct sysfs_ops cache_sysfs_ops = {
294 .show = cache_show
295};
296
297static struct kobj_type cache_ktype = {
298 .sysfs_ops = &cache_sysfs_ops,
299 .default_attrs = cache_default_attrs,
300};
301
302static struct kobj_type cache_ktype_percpu_entry = {
303 .sysfs_ops = &cache_sysfs_ops,
304};
305
306static void __cpuinit cpu_cache_sysfs_exit(unsigned int cpu)
307{
308 if (all_cpu_cache_info[cpu].cache_leaves) {
309 kfree(all_cpu_cache_info[cpu].cache_leaves);
310 all_cpu_cache_info[cpu].cache_leaves = NULL;
311 }
312 all_cpu_cache_info[cpu].num_cache_leaves = 0;
313 memset(&all_cpu_cache_info[cpu].kobj, 0, sizeof(struct kobject));
314
315 return;
316}
317
318static int __cpuinit cpu_cache_sysfs_init(unsigned int cpu)
319{
320 u64 i, levels, unique_caches;
321 pal_cache_config_info_t cci;
322 int j;
323 s64 status;
324 struct cache_info *this_cache;
325 int num_cache_leaves = 0;
326
327 if ((status = ia64_pal_cache_summary(&levels, &unique_caches)) != 0) {
328 printk(KERN_ERR "ia64_pal_cache_summary=%ld\n", status);
329 return -1;
330 }
331
332 this_cache=kzalloc(sizeof(struct cache_info)*unique_caches,
333 GFP_KERNEL);
334 if (this_cache == NULL)
335 return -ENOMEM;
336
337 for (i=0; i < levels; i++) {
338 for (j=2; j >0 ; j--) {
339 if ((status=ia64_pal_cache_config_info(i,j, &cci)) !=
340 PAL_STATUS_SUCCESS)
341 continue;
342
343 this_cache[num_cache_leaves].cci = cci;
344 this_cache[num_cache_leaves].level = i + 1;
345 this_cache[num_cache_leaves].type = j;
346
347 cache_shared_cpu_map_setup(cpu,
348 &this_cache[num_cache_leaves]);
349 num_cache_leaves ++;
350 }
351 }
352
353 all_cpu_cache_info[cpu].cache_leaves = this_cache;
354 all_cpu_cache_info[cpu].num_cache_leaves = num_cache_leaves;
355
356 memset(&all_cpu_cache_info[cpu].kobj, 0, sizeof(struct kobject));
357
358 return 0;
359}
360
361/* Add cache interface for CPU device */
362static int __cpuinit cache_add_dev(struct sys_device * sys_dev)
363{
364 unsigned int cpu = sys_dev->id;
365 unsigned long i, j;
366 struct cache_info *this_object;
367 int retval = 0;
368 cpumask_t oldmask;
369
370 if (all_cpu_cache_info[cpu].kobj.parent)
371 return 0;
372
373 oldmask = current->cpus_allowed;
374 retval = set_cpus_allowed(current, cpumask_of_cpu(cpu));
375 if (unlikely(retval))
376 return retval;
377
378 retval = cpu_cache_sysfs_init(cpu);
379 set_cpus_allowed(current, oldmask);
380 if (unlikely(retval < 0))
381 return retval;
382
383 all_cpu_cache_info[cpu].kobj.parent = &sys_dev->kobj;
384 kobject_set_name(&all_cpu_cache_info[cpu].kobj, "%s", "cache");
385 all_cpu_cache_info[cpu].kobj.ktype = &cache_ktype_percpu_entry;
386 retval = kobject_register(&all_cpu_cache_info[cpu].kobj);
387
388 for (i = 0; i < all_cpu_cache_info[cpu].num_cache_leaves; i++) {
389 this_object = LEAF_KOBJECT_PTR(cpu,i);
390 this_object->kobj.parent = &all_cpu_cache_info[cpu].kobj;
391 kobject_set_name(&(this_object->kobj), "index%1lu", i);
392 this_object->kobj.ktype = &cache_ktype;
393 retval = kobject_register(&(this_object->kobj));
394 if (unlikely(retval)) {
395 for (j = 0; j < i; j++) {
396 kobject_unregister(
397 &(LEAF_KOBJECT_PTR(cpu,j)->kobj));
398 }
399 kobject_unregister(&all_cpu_cache_info[cpu].kobj);
400 cpu_cache_sysfs_exit(cpu);
401 break;
402 }
403 }
404 return retval;
405}
406
407/* Remove cache interface for CPU device */
408static int __cpuinit cache_remove_dev(struct sys_device * sys_dev)
409{
410 unsigned int cpu = sys_dev->id;
411 unsigned long i;
412
413 for (i = 0; i < all_cpu_cache_info[cpu].num_cache_leaves; i++)
414 kobject_unregister(&(LEAF_KOBJECT_PTR(cpu,i)->kobj));
415
416 if (all_cpu_cache_info[cpu].kobj.parent) {
417 kobject_unregister(&all_cpu_cache_info[cpu].kobj);
418 memset(&all_cpu_cache_info[cpu].kobj,
419 0,
420 sizeof(struct kobject));
421 }
422
423 cpu_cache_sysfs_exit(cpu);
424
425 return 0;
426}
427
428/*
429 * When a cpu is hot-plugged, do a check and initiate
430 * cache kobject if necessary
431 */
432static int __cpuinit cache_cpu_callback(struct notifier_block *nfb,
433 unsigned long action, void *hcpu)
434{
435 unsigned int cpu = (unsigned long)hcpu;
436 struct sys_device *sys_dev;
437
438 sys_dev = get_cpu_sysdev(cpu);
439 switch (action) {
440 case CPU_ONLINE:
441 cache_add_dev(sys_dev);
442 break;
443 case CPU_DEAD:
444 cache_remove_dev(sys_dev);
445 break;
446 }
447 return NOTIFY_OK;
448}
449
450static struct notifier_block cache_cpu_notifier =
451{
452 .notifier_call = cache_cpu_callback
453};
454
455static int __cpuinit cache_sysfs_init(void)
456{
457 int i;
458
459 for_each_online_cpu(i) {
460 cache_cpu_callback(&cache_cpu_notifier, CPU_ONLINE,
461 (void *)(long)i);
462 }
463
464 register_cpu_notifier(&cache_cpu_notifier);
465
466 return 0;
467}
468
469device_initcall(cache_sysfs_init);
470
diff --git a/arch/ia64/kernel/vmlinux.lds.S b/arch/ia64/kernel/vmlinux.lds.S
index 0b9e56dd7f05..783600fe52b2 100644
--- a/arch/ia64/kernel/vmlinux.lds.S
+++ b/arch/ia64/kernel/vmlinux.lds.S
@@ -70,6 +70,15 @@ SECTIONS
70 __stop___ex_table = .; 70 __stop___ex_table = .;
71 } 71 }
72 72
73 /* MCA table */
74 . = ALIGN(16);
75 __mca_table : AT(ADDR(__mca_table) - LOAD_OFFSET)
76 {
77 __start___mca_table = .;
78 *(__mca_table)
79 __stop___mca_table = .;
80 }
81
73 /* Global data */ 82 /* Global data */
74 _data = .; 83 _data = .;
75 84
@@ -130,15 +139,6 @@ SECTIONS
130 __initcall_end = .; 139 __initcall_end = .;
131 } 140 }
132 141
133 /* MCA table */
134 . = ALIGN(16);
135 __mca_table : AT(ADDR(__mca_table) - LOAD_OFFSET)
136 {
137 __start___mca_table = .;
138 *(__mca_table)
139 __stop___mca_table = .;
140 }
141
142 .data.patch.vtop : AT(ADDR(.data.patch.vtop) - LOAD_OFFSET) 142 .data.patch.vtop : AT(ADDR(.data.patch.vtop) - LOAD_OFFSET)
143 { 143 {
144 __start___vtop_patchlist = .; 144 __start___vtop_patchlist = .;
diff --git a/arch/ia64/mm/init.c b/arch/ia64/mm/init.c
index 2ef1151cde90..cafa8776a53d 100644
--- a/arch/ia64/mm/init.c
+++ b/arch/ia64/mm/init.c
@@ -109,6 +109,7 @@ lazy_mmu_prot_update (pte_t pte)
109{ 109{
110 unsigned long addr; 110 unsigned long addr;
111 struct page *page; 111 struct page *page;
112 unsigned long order;
112 113
113 if (!pte_exec(pte)) 114 if (!pte_exec(pte))
114 return; /* not an executable page... */ 115 return; /* not an executable page... */
@@ -119,7 +120,12 @@ lazy_mmu_prot_update (pte_t pte)
119 if (test_bit(PG_arch_1, &page->flags)) 120 if (test_bit(PG_arch_1, &page->flags))
120 return; /* i-cache is already coherent with d-cache */ 121 return; /* i-cache is already coherent with d-cache */
121 122
122 flush_icache_range(addr, addr + PAGE_SIZE); 123 if (PageCompound(page)) {
124 order = (unsigned long) (page[1].lru.prev);
125 flush_icache_range(addr, addr + (1UL << order << PAGE_SHIFT));
126 }
127 else
128 flush_icache_range(addr, addr + PAGE_SIZE);
123 set_bit(PG_arch_1, &page->flags); /* mark page as clean */ 129 set_bit(PG_arch_1, &page->flags); /* mark page as clean */
124} 130}
125 131
diff --git a/arch/ia64/mm/ioremap.c b/arch/ia64/mm/ioremap.c
index 62328621f99c..643ccc6960ce 100644
--- a/arch/ia64/mm/ioremap.c
+++ b/arch/ia64/mm/ioremap.c
@@ -21,12 +21,12 @@ __ioremap (unsigned long offset, unsigned long size)
21void __iomem * 21void __iomem *
22ioremap (unsigned long offset, unsigned long size) 22ioremap (unsigned long offset, unsigned long size)
23{ 23{
24 if (efi_mem_attribute_range(offset, size, EFI_MEMORY_UC))
25 return __ioremap(offset, size);
26
27 if (efi_mem_attribute_range(offset, size, EFI_MEMORY_WB)) 24 if (efi_mem_attribute_range(offset, size, EFI_MEMORY_WB))
28 return phys_to_virt(offset); 25 return phys_to_virt(offset);
29 26
27 if (efi_mem_attribute_range(offset, size, EFI_MEMORY_UC))
28 return __ioremap(offset, size);
29
30 /* 30 /*
31 * Someday this should check ACPI resources so we 31 * Someday this should check ACPI resources so we
32 * can do the right thing for hot-plugged regions. 32 * can do the right thing for hot-plugged regions.
diff --git a/arch/ia64/mm/tlb.c b/arch/ia64/mm/tlb.c
index 6a4eec9113e8..4dbbca0b5e9c 100644
--- a/arch/ia64/mm/tlb.c
+++ b/arch/ia64/mm/tlb.c
@@ -156,17 +156,19 @@ flush_tlb_range (struct vm_area_struct *vma, unsigned long start,
156 nbits = purge.max_bits; 156 nbits = purge.max_bits;
157 start &= ~((1UL << nbits) - 1); 157 start &= ~((1UL << nbits) - 1);
158 158
159# ifdef CONFIG_SMP
160 platform_global_tlb_purge(mm, start, end, nbits);
161# else
162 preempt_disable(); 159 preempt_disable();
160#ifdef CONFIG_SMP
161 if (mm != current->active_mm || cpus_weight(mm->cpu_vm_mask) != 1) {
162 platform_global_tlb_purge(mm, start, end, nbits);
163 preempt_enable();
164 return;
165 }
166#endif
163 do { 167 do {
164 ia64_ptcl(start, (nbits<<2)); 168 ia64_ptcl(start, (nbits<<2));
165 start += (1UL << nbits); 169 start += (1UL << nbits);
166 } while (start < end); 170 } while (start < end);
167 preempt_enable(); 171 preempt_enable();
168# endif
169
170 ia64_srlz_i(); /* srlz.i implies srlz.d */ 172 ia64_srlz_i(); /* srlz.i implies srlz.d */
171} 173}
172EXPORT_SYMBOL(flush_tlb_range); 174EXPORT_SYMBOL(flush_tlb_range);
diff --git a/arch/ia64/sn/kernel/sn2/sn_hwperf.c b/arch/ia64/sn/kernel/sn2/sn_hwperf.c
index 70db21f3df21..d917afa30b27 100644
--- a/arch/ia64/sn/kernel/sn2/sn_hwperf.c
+++ b/arch/ia64/sn/kernel/sn2/sn_hwperf.c
@@ -110,7 +110,11 @@ static int sn_hwperf_geoid_to_cnode(char *location)
110 if (sn_hwperf_location_to_bpos(location, &rack, &bay, &slot, &slab)) 110 if (sn_hwperf_location_to_bpos(location, &rack, &bay, &slot, &slab))
111 return -1; 111 return -1;
112 112
113 for_each_node(cnode) { 113 /*
114 * FIXME: replace with cleaner for_each_XXX macro which addresses
115 * both compute and IO nodes once ACPI3.0 is available.
116 */
117 for (cnode = 0; cnode < num_cnodes; cnode++) {
114 geoid = cnodeid_get_geoid(cnode); 118 geoid = cnodeid_get_geoid(cnode);
115 module_id = geo_module(geoid); 119 module_id = geo_module(geoid);
116 this_rack = MODULE_GET_RACK(module_id); 120 this_rack = MODULE_GET_RACK(module_id);
@@ -605,7 +609,7 @@ static int sn_hwperf_op_cpu(struct sn_hwperf_op_info *op_info)
605 op_info->a->arg &= SN_HWPERF_ARG_OBJID_MASK; 609 op_info->a->arg &= SN_HWPERF_ARG_OBJID_MASK;
606 610
607 if (cpu != SN_HWPERF_ARG_ANY_CPU) { 611 if (cpu != SN_HWPERF_ARG_ANY_CPU) {
608 if (cpu >= num_online_cpus() || !cpu_online(cpu)) { 612 if (cpu >= NR_CPUS || !cpu_online(cpu)) {
609 r = -EINVAL; 613 r = -EINVAL;
610 goto out; 614 goto out;
611 } 615 }
diff --git a/arch/m68k/kernel/m68k_ksyms.c b/arch/m68k/kernel/m68k_ksyms.c
index 3d7f2000b714..c3319514a85e 100644
--- a/arch/m68k/kernel/m68k_ksyms.c
+++ b/arch/m68k/kernel/m68k_ksyms.c
@@ -79,4 +79,3 @@ EXPORT_SYMBOL(__down_failed_interruptible);
79EXPORT_SYMBOL(__down_failed_trylock); 79EXPORT_SYMBOL(__down_failed_trylock);
80EXPORT_SYMBOL(__up_wakeup); 80EXPORT_SYMBOL(__up_wakeup);
81 81
82EXPORT_SYMBOL(get_wchan);
diff --git a/arch/m68knommu/kernel/m68k_ksyms.c b/arch/m68knommu/kernel/m68k_ksyms.c
index d844c755945a..f9b4ea16c099 100644
--- a/arch/m68knommu/kernel/m68k_ksyms.c
+++ b/arch/m68knommu/kernel/m68k_ksyms.c
@@ -57,8 +57,6 @@ EXPORT_SYMBOL(__down_failed_interruptible);
57EXPORT_SYMBOL(__down_failed_trylock); 57EXPORT_SYMBOL(__down_failed_trylock);
58EXPORT_SYMBOL(__up_wakeup); 58EXPORT_SYMBOL(__up_wakeup);
59 59
60EXPORT_SYMBOL(get_wchan);
61
62/* 60/*
63 * libgcc functions - functions that are used internally by the 61 * libgcc functions - functions that are used internally by the
64 * compiler... (prototypes are not correct though, but that 62 * compiler... (prototypes are not correct though, but that
diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c
index a8f435d82940..c66db5e5ab62 100644
--- a/arch/mips/kernel/process.c
+++ b/arch/mips/kernel/process.c
@@ -419,4 +419,3 @@ unsigned long get_wchan(struct task_struct *p)
419 return pc; 419 return pc;
420} 420}
421 421
422EXPORT_SYMBOL(get_wchan);
diff --git a/arch/parisc/Kconfig b/arch/parisc/Kconfig
index 6b3c50964ca9..2fdf21989dc2 100644
--- a/arch/parisc/Kconfig
+++ b/arch/parisc/Kconfig
@@ -177,14 +177,10 @@ config ARCH_DISCONTIGMEM_DEFAULT
177 def_bool y 177 def_bool y
178 depends on ARCH_DISCONTIGMEM_ENABLE 178 depends on ARCH_DISCONTIGMEM_ENABLE
179 179
180source "kernel/Kconfig.preempt"
180source "kernel/Kconfig.hz" 181source "kernel/Kconfig.hz"
181source "mm/Kconfig" 182source "mm/Kconfig"
182 183
183config PREEMPT
184 bool
185# bool "Preemptible Kernel"
186 default n
187
188config COMPAT 184config COMPAT
189 def_bool y 185 def_bool y
190 depends on 64BIT 186 depends on 64BIT
diff --git a/arch/parisc/configs/712_defconfig b/arch/parisc/configs/712_defconfig
index 3e013f55df64..41fd0696bbe7 100644
--- a/arch/parisc/configs/712_defconfig
+++ b/arch/parisc/configs/712_defconfig
@@ -1,7 +1,7 @@
1# 1#
2# Automatically generated make config: don't edit 2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.14-rc5-pa1 3# Linux kernel version: 2.6.16-pa6
4# Fri Oct 21 23:04:34 2005 4# Sun Mar 26 19:59:51 2006
5# 5#
6CONFIG_PARISC=y 6CONFIG_PARISC=y
7CONFIG_MMU=y 7CONFIG_MMU=y
@@ -10,14 +10,11 @@ CONFIG_RWSEM_GENERIC_SPINLOCK=y
10CONFIG_GENERIC_CALIBRATE_DELAY=y 10CONFIG_GENERIC_CALIBRATE_DELAY=y
11CONFIG_GENERIC_HARDIRQS=y 11CONFIG_GENERIC_HARDIRQS=y
12CONFIG_GENERIC_IRQ_PROBE=y 12CONFIG_GENERIC_IRQ_PROBE=y
13CONFIG_ARCH_MAY_HAVE_PC_FDC=y
14 13
15# 14#
16# Code maturity level options 15# Code maturity level options
17# 16#
18CONFIG_EXPERIMENTAL=y 17CONFIG_EXPERIMENTAL=y
19# CONFIG_CLEAN_COMPILE is not set
20CONFIG_BROKEN=y
21CONFIG_BROKEN_ON_SMP=y 18CONFIG_BROKEN_ON_SMP=y
22CONFIG_INIT_ENV_ARG_LIMIT=32 19CONFIG_INIT_ENV_ARG_LIMIT=32
23 20
@@ -32,17 +29,18 @@ CONFIG_POSIX_MQUEUE=y
32# CONFIG_BSD_PROCESS_ACCT is not set 29# CONFIG_BSD_PROCESS_ACCT is not set
33CONFIG_SYSCTL=y 30CONFIG_SYSCTL=y
34# CONFIG_AUDIT is not set 31# CONFIG_AUDIT is not set
35CONFIG_HOTPLUG=y
36CONFIG_KOBJECT_UEVENT=y
37CONFIG_IKCONFIG=y 32CONFIG_IKCONFIG=y
38CONFIG_IKCONFIG_PROC=y 33CONFIG_IKCONFIG_PROC=y
39CONFIG_INITRAMFS_SOURCE="" 34CONFIG_INITRAMFS_SOURCE=""
35CONFIG_CC_OPTIMIZE_FOR_SIZE=y
40# CONFIG_EMBEDDED is not set 36# CONFIG_EMBEDDED is not set
41CONFIG_KALLSYMS=y 37CONFIG_KALLSYMS=y
42CONFIG_KALLSYMS_ALL=y 38CONFIG_KALLSYMS_ALL=y
43# CONFIG_KALLSYMS_EXTRA_PASS is not set 39# CONFIG_KALLSYMS_EXTRA_PASS is not set
40CONFIG_HOTPLUG=y
44CONFIG_PRINTK=y 41CONFIG_PRINTK=y
45CONFIG_BUG=y 42CONFIG_BUG=y
43CONFIG_ELF_CORE=y
46CONFIG_BASE_FULL=y 44CONFIG_BASE_FULL=y
47CONFIG_FUTEX=y 45CONFIG_FUTEX=y
48CONFIG_EPOLL=y 46CONFIG_EPOLL=y
@@ -51,8 +49,10 @@ CONFIG_CC_ALIGN_FUNCTIONS=0
51CONFIG_CC_ALIGN_LABELS=0 49CONFIG_CC_ALIGN_LABELS=0
52CONFIG_CC_ALIGN_LOOPS=0 50CONFIG_CC_ALIGN_LOOPS=0
53CONFIG_CC_ALIGN_JUMPS=0 51CONFIG_CC_ALIGN_JUMPS=0
52CONFIG_SLAB=y
54# CONFIG_TINY_SHMEM is not set 53# CONFIG_TINY_SHMEM is not set
55CONFIG_BASE_SMALL=0 54CONFIG_BASE_SMALL=0
55# CONFIG_SLOB is not set
56 56
57# 57#
58# Loadable module support 58# Loadable module support
@@ -66,6 +66,23 @@ CONFIG_OBSOLETE_MODPARM=y
66CONFIG_KMOD=y 66CONFIG_KMOD=y
67 67
68# 68#
69# Block layer
70#
71
72#
73# IO Schedulers
74#
75CONFIG_IOSCHED_NOOP=y
76CONFIG_IOSCHED_AS=y
77CONFIG_IOSCHED_DEADLINE=y
78CONFIG_IOSCHED_CFQ=y
79CONFIG_DEFAULT_AS=y
80# CONFIG_DEFAULT_DEADLINE is not set
81# CONFIG_DEFAULT_CFQ is not set
82# CONFIG_DEFAULT_NOOP is not set
83CONFIG_DEFAULT_IOSCHED="anticipatory"
84
85#
69# Processor type and features 86# Processor type and features
70# 87#
71# CONFIG_PA7000 is not set 88# CONFIG_PA7000 is not set
@@ -75,6 +92,10 @@ CONFIG_PA7100LC=y
75# CONFIG_PA8X00 is not set 92# CONFIG_PA8X00 is not set
76CONFIG_PA11=y 93CONFIG_PA11=y
77# CONFIG_SMP is not set 94# CONFIG_SMP is not set
95CONFIG_ARCH_FLATMEM_ENABLE=y
96# CONFIG_PREEMPT_NONE is not set
97CONFIG_PREEMPT_VOLUNTARY=y
98# CONFIG_PREEMPT is not set
78# CONFIG_HZ_100 is not set 99# CONFIG_HZ_100 is not set
79CONFIG_HZ_250=y 100CONFIG_HZ_250=y
80# CONFIG_HZ_1000 is not set 101# CONFIG_HZ_1000 is not set
@@ -86,7 +107,7 @@ CONFIG_FLATMEM_MANUAL=y
86CONFIG_FLATMEM=y 107CONFIG_FLATMEM=y
87CONFIG_FLAT_NODE_MEM_MAP=y 108CONFIG_FLAT_NODE_MEM_MAP=y
88# CONFIG_SPARSEMEM_STATIC is not set 109# CONFIG_SPARSEMEM_STATIC is not set
89# CONFIG_PREEMPT is not set 110CONFIG_SPLIT_PTLOCK_CPUS=4096
90# CONFIG_HPUX is not set 111# CONFIG_HPUX is not set
91 112
92# 113#
@@ -130,6 +151,7 @@ CONFIG_NET=y
130# 151#
131# Networking options 152# Networking options
132# 153#
154# CONFIG_NETDEBUG is not set
133CONFIG_PACKET=y 155CONFIG_PACKET=y
134CONFIG_PACKET_MMAP=y 156CONFIG_PACKET_MMAP=y
135CONFIG_UNIX=y 157CONFIG_UNIX=y
@@ -165,7 +187,12 @@ CONFIG_TCP_CONG_BIC=y
165# CONFIG_IPV6 is not set 187# CONFIG_IPV6 is not set
166CONFIG_NETFILTER=y 188CONFIG_NETFILTER=y
167# CONFIG_NETFILTER_DEBUG is not set 189# CONFIG_NETFILTER_DEBUG is not set
190
191#
192# Core Netfilter Configuration
193#
168# CONFIG_NETFILTER_NETLINK is not set 194# CONFIG_NETFILTER_NETLINK is not set
195# CONFIG_NETFILTER_XTABLES is not set
169 196
170# 197#
171# IP: Netfilter Configuration 198# IP: Netfilter Configuration
@@ -182,64 +209,6 @@ CONFIG_IP_NF_TFTP=m
182CONFIG_IP_NF_AMANDA=m 209CONFIG_IP_NF_AMANDA=m
183# CONFIG_IP_NF_PPTP is not set 210# CONFIG_IP_NF_PPTP is not set
184CONFIG_IP_NF_QUEUE=m 211CONFIG_IP_NF_QUEUE=m
185CONFIG_IP_NF_IPTABLES=m
186CONFIG_IP_NF_MATCH_LIMIT=m
187CONFIG_IP_NF_MATCH_IPRANGE=m
188CONFIG_IP_NF_MATCH_MAC=m
189CONFIG_IP_NF_MATCH_PKTTYPE=m
190CONFIG_IP_NF_MATCH_MARK=m
191CONFIG_IP_NF_MATCH_MULTIPORT=m
192CONFIG_IP_NF_MATCH_TOS=m
193CONFIG_IP_NF_MATCH_RECENT=m
194CONFIG_IP_NF_MATCH_ECN=m
195CONFIG_IP_NF_MATCH_DSCP=m
196CONFIG_IP_NF_MATCH_AH_ESP=m
197CONFIG_IP_NF_MATCH_LENGTH=m
198CONFIG_IP_NF_MATCH_TTL=m
199CONFIG_IP_NF_MATCH_TCPMSS=m
200CONFIG_IP_NF_MATCH_HELPER=m
201CONFIG_IP_NF_MATCH_STATE=m
202CONFIG_IP_NF_MATCH_CONNTRACK=m
203CONFIG_IP_NF_MATCH_OWNER=m
204# CONFIG_IP_NF_MATCH_ADDRTYPE is not set
205# CONFIG_IP_NF_MATCH_REALM is not set
206CONFIG_IP_NF_MATCH_SCTP=m
207# CONFIG_IP_NF_MATCH_DCCP is not set
208CONFIG_IP_NF_MATCH_COMMENT=m
209CONFIG_IP_NF_MATCH_CONNMARK=m
210CONFIG_IP_NF_MATCH_HASHLIMIT=m
211# CONFIG_IP_NF_MATCH_STRING is not set
212CONFIG_IP_NF_FILTER=m
213CONFIG_IP_NF_TARGET_REJECT=m
214CONFIG_IP_NF_TARGET_LOG=m
215CONFIG_IP_NF_TARGET_ULOG=m
216CONFIG_IP_NF_TARGET_TCPMSS=m
217# CONFIG_IP_NF_TARGET_NFQUEUE is not set
218CONFIG_IP_NF_NAT=m
219CONFIG_IP_NF_NAT_NEEDED=y
220CONFIG_IP_NF_TARGET_MASQUERADE=m
221CONFIG_IP_NF_TARGET_REDIRECT=m
222CONFIG_IP_NF_TARGET_NETMAP=m
223CONFIG_IP_NF_TARGET_SAME=m
224CONFIG_IP_NF_NAT_SNMP_BASIC=m
225CONFIG_IP_NF_NAT_IRC=m
226CONFIG_IP_NF_NAT_FTP=m
227CONFIG_IP_NF_NAT_TFTP=m
228CONFIG_IP_NF_NAT_AMANDA=m
229CONFIG_IP_NF_MANGLE=m
230CONFIG_IP_NF_TARGET_TOS=m
231CONFIG_IP_NF_TARGET_ECN=m
232CONFIG_IP_NF_TARGET_DSCP=m
233CONFIG_IP_NF_TARGET_MARK=m
234CONFIG_IP_NF_TARGET_CLASSIFY=m
235# CONFIG_IP_NF_TARGET_TTL is not set
236CONFIG_IP_NF_TARGET_CONNMARK=m
237CONFIG_IP_NF_TARGET_CLUSTERIP=m
238CONFIG_IP_NF_RAW=m
239CONFIG_IP_NF_TARGET_NOTRACK=m
240CONFIG_IP_NF_ARPTABLES=m
241CONFIG_IP_NF_ARPFILTER=m
242CONFIG_IP_NF_ARP_MANGLE=m
243 212
244# 213#
245# DCCP Configuration (EXPERIMENTAL) 214# DCCP Configuration (EXPERIMENTAL)
@@ -250,6 +219,11 @@ CONFIG_IP_NF_ARP_MANGLE=m
250# SCTP Configuration (EXPERIMENTAL) 219# SCTP Configuration (EXPERIMENTAL)
251# 220#
252# CONFIG_IP_SCTP is not set 221# CONFIG_IP_SCTP is not set
222
223#
224# TIPC Configuration (EXPERIMENTAL)
225#
226# CONFIG_TIPC is not set
253# CONFIG_ATM is not set 227# CONFIG_ATM is not set
254# CONFIG_BRIDGE is not set 228# CONFIG_BRIDGE is not set
255# CONFIG_VLAN_8021Q is not set 229# CONFIG_VLAN_8021Q is not set
@@ -263,8 +237,11 @@ CONFIG_LLC2=m
263# CONFIG_NET_DIVERT is not set 237# CONFIG_NET_DIVERT is not set
264# CONFIG_ECONET is not set 238# CONFIG_ECONET is not set
265# CONFIG_WAN_ROUTER is not set 239# CONFIG_WAN_ROUTER is not set
240
241#
242# QoS and/or fair queueing
243#
266# CONFIG_NET_SCHED is not set 244# CONFIG_NET_SCHED is not set
267# CONFIG_NET_CLS_ROUTE is not set
268 245
269# 246#
270# Network testing 247# Network testing
@@ -304,6 +281,7 @@ CONFIG_PARPORT=y
304CONFIG_PARPORT_PC=m 281CONFIG_PARPORT_PC=m
305# CONFIG_PARPORT_PC_FIFO is not set 282# CONFIG_PARPORT_PC_FIFO is not set
306# CONFIG_PARPORT_PC_SUPERIO is not set 283# CONFIG_PARPORT_PC_SUPERIO is not set
284CONFIG_PARPORT_NOT_PC=y
307CONFIG_PARPORT_GSC=y 285CONFIG_PARPORT_GSC=y
308# CONFIG_PARPORT_1284 is not set 286# CONFIG_PARPORT_1284 is not set
309 287
@@ -314,7 +292,6 @@ CONFIG_PARPORT_GSC=y
314# 292#
315# Block devices 293# Block devices
316# 294#
317# CONFIG_BLK_DEV_FD is not set
318# CONFIG_PARIDE is not set 295# CONFIG_PARIDE is not set
319# CONFIG_BLK_DEV_COW_COMMON is not set 296# CONFIG_BLK_DEV_COW_COMMON is not set
320CONFIG_BLK_DEV_LOOP=y 297CONFIG_BLK_DEV_LOOP=y
@@ -325,14 +302,6 @@ CONFIG_BLK_DEV_RAM_COUNT=16
325CONFIG_BLK_DEV_RAM_SIZE=6144 302CONFIG_BLK_DEV_RAM_SIZE=6144
326CONFIG_BLK_DEV_INITRD=y 303CONFIG_BLK_DEV_INITRD=y
327# CONFIG_CDROM_PKTCDVD is not set 304# CONFIG_CDROM_PKTCDVD is not set
328
329#
330# IO Schedulers
331#
332CONFIG_IOSCHED_NOOP=y
333CONFIG_IOSCHED_AS=y
334CONFIG_IOSCHED_DEADLINE=y
335CONFIG_IOSCHED_CFQ=y
336CONFIG_ATA_OVER_ETH=m 305CONFIG_ATA_OVER_ETH=m
337 306
338# 307#
@@ -376,6 +345,7 @@ CONFIG_SCSI_ISCSI_ATTRS=m
376# 345#
377# SCSI low-level drivers 346# SCSI low-level drivers
378# 347#
348# CONFIG_ISCSI_TCP is not set
379# CONFIG_SCSI_SATA is not set 349# CONFIG_SCSI_SATA is not set
380# CONFIG_SCSI_PPA is not set 350# CONFIG_SCSI_PPA is not set
381# CONFIG_SCSI_IMM is not set 351# CONFIG_SCSI_IMM is not set
@@ -407,7 +377,6 @@ CONFIG_MD_RAID1=m
407# 377#
408# IEEE 1394 (FireWire) support 378# IEEE 1394 (FireWire) support
409# 379#
410# CONFIG_IEEE1394 is not set
411 380
412# 381#
413# I2O device support 382# I2O device support
@@ -471,6 +440,7 @@ CONFIG_PPP_ASYNC=m
471CONFIG_PPP_SYNC_TTY=m 440CONFIG_PPP_SYNC_TTY=m
472CONFIG_PPP_DEFLATE=m 441CONFIG_PPP_DEFLATE=m
473CONFIG_PPP_BSDCOMP=m 442CONFIG_PPP_BSDCOMP=m
443CONFIG_PPP_MPPE=m
474CONFIG_PPPOE=m 444CONFIG_PPPOE=m
475# CONFIG_SLIP is not set 445# CONFIG_SLIP is not set
476# CONFIG_SHAPER is not set 446# CONFIG_SHAPER is not set
@@ -516,8 +486,8 @@ CONFIG_KEYBOARD_ATKBD_HP_KEYCODES=y
516# CONFIG_KEYBOARD_LKKBD is not set 486# CONFIG_KEYBOARD_LKKBD is not set
517# CONFIG_KEYBOARD_XTKBD is not set 487# CONFIG_KEYBOARD_XTKBD is not set
518# CONFIG_KEYBOARD_NEWTON is not set 488# CONFIG_KEYBOARD_NEWTON is not set
519CONFIG_KEYBOARD_HIL_OLD=y 489# CONFIG_KEYBOARD_HIL_OLD is not set
520# CONFIG_KEYBOARD_HIL is not set 490CONFIG_KEYBOARD_HIL=y
521CONFIG_INPUT_MOUSE=y 491CONFIG_INPUT_MOUSE=y
522CONFIG_MOUSE_PS2=y 492CONFIG_MOUSE_PS2=y
523CONFIG_MOUSE_SERIAL=m 493CONFIG_MOUSE_SERIAL=m
@@ -554,6 +524,7 @@ CONFIG_HW_CONSOLE=y
554CONFIG_SERIAL_8250=y 524CONFIG_SERIAL_8250=y
555CONFIG_SERIAL_8250_CONSOLE=y 525CONFIG_SERIAL_8250_CONSOLE=y
556CONFIG_SERIAL_8250_NR_UARTS=17 526CONFIG_SERIAL_8250_NR_UARTS=17
527CONFIG_SERIAL_8250_RUNTIME_UARTS=4
557CONFIG_SERIAL_8250_EXTENDED=y 528CONFIG_SERIAL_8250_EXTENDED=y
558CONFIG_SERIAL_8250_MANY_PORTS=y 529CONFIG_SERIAL_8250_MANY_PORTS=y
559CONFIG_SERIAL_8250_SHARE_IRQ=y 530CONFIG_SERIAL_8250_SHARE_IRQ=y
@@ -598,6 +569,8 @@ CONFIG_MAX_RAW_DEVS=256
598# 569#
599# TPM devices 570# TPM devices
600# 571#
572# CONFIG_TCG_TPM is not set
573# CONFIG_TELCLOCK is not set
601 574
602# 575#
603# I2C support 576# I2C support
@@ -605,6 +578,12 @@ CONFIG_MAX_RAW_DEVS=256
605# CONFIG_I2C is not set 578# CONFIG_I2C is not set
606 579
607# 580#
581# SPI support
582#
583# CONFIG_SPI is not set
584# CONFIG_SPI_MASTER is not set
585
586#
608# Dallas's 1-wire bus 587# Dallas's 1-wire bus
609# 588#
610# CONFIG_W1 is not set 589# CONFIG_W1 is not set
@@ -640,7 +619,6 @@ CONFIG_FB=y
640CONFIG_FB_CFB_FILLRECT=y 619CONFIG_FB_CFB_FILLRECT=y
641CONFIG_FB_CFB_COPYAREA=y 620CONFIG_FB_CFB_COPYAREA=y
642CONFIG_FB_CFB_IMAGEBLIT=y 621CONFIG_FB_CFB_IMAGEBLIT=y
643CONFIG_FB_SOFT_CURSOR=y
644# CONFIG_FB_MACMODES is not set 622# CONFIG_FB_MACMODES is not set
645CONFIG_FB_MODE_HELPERS=y 623CONFIG_FB_MODE_HELPERS=y
646CONFIG_FB_TILEBLITTING=y 624CONFIG_FB_TILEBLITTING=y
@@ -655,6 +633,7 @@ CONFIG_DUMMY_CONSOLE=y
655CONFIG_DUMMY_CONSOLE_COLUMNS=128 633CONFIG_DUMMY_CONSOLE_COLUMNS=128
656CONFIG_DUMMY_CONSOLE_ROWS=48 634CONFIG_DUMMY_CONSOLE_ROWS=48
657CONFIG_FRAMEBUFFER_CONSOLE=y 635CONFIG_FRAMEBUFFER_CONSOLE=y
636# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
658CONFIG_STI_CONSOLE=y 637CONFIG_STI_CONSOLE=y
659CONFIG_FONTS=y 638CONFIG_FONTS=y
660CONFIG_FONT_8x8=y 639CONFIG_FONT_8x8=y
@@ -695,6 +674,8 @@ CONFIG_SND_OSSEMUL=y
695CONFIG_SND_MIXER_OSS=y 674CONFIG_SND_MIXER_OSS=y
696CONFIG_SND_PCM_OSS=y 675CONFIG_SND_PCM_OSS=y
697CONFIG_SND_SEQUENCER_OSS=y 676CONFIG_SND_SEQUENCER_OSS=y
677# CONFIG_SND_DYNAMIC_MINORS is not set
678CONFIG_SND_SUPPORT_OLD_API=y
698# CONFIG_SND_VERBOSE_PRINTK is not set 679# CONFIG_SND_VERBOSE_PRINTK is not set
699# CONFIG_SND_DEBUG is not set 680# CONFIG_SND_DEBUG is not set
700 681
@@ -724,6 +705,10 @@ CONFIG_SND_HARMONY=y
724# CONFIG_USB_ARCH_HAS_OHCI is not set 705# CONFIG_USB_ARCH_HAS_OHCI is not set
725 706
726# 707#
708# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
709#
710
711#
727# USB Gadget Support 712# USB Gadget Support
728# 713#
729# CONFIG_USB_GADGET is not set 714# CONFIG_USB_GADGET is not set
@@ -736,10 +721,9 @@ CONFIG_SND_HARMONY=y
736# 721#
737# InfiniBand support 722# InfiniBand support
738# 723#
739# CONFIG_INFINIBAND is not set
740 724
741# 725#
742# SN Devices 726# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
743# 727#
744 728
745# 729#
@@ -765,6 +749,7 @@ CONFIG_XFS_EXPORT=y
765# CONFIG_XFS_SECURITY is not set 749# CONFIG_XFS_SECURITY is not set
766# CONFIG_XFS_POSIX_ACL is not set 750# CONFIG_XFS_POSIX_ACL is not set
767# CONFIG_XFS_RT is not set 751# CONFIG_XFS_RT is not set
752# CONFIG_OCFS2_FS is not set
768# CONFIG_MINIX_FS is not set 753# CONFIG_MINIX_FS is not set
769# CONFIG_ROMFS_FS is not set 754# CONFIG_ROMFS_FS is not set
770CONFIG_INOTIFY=y 755CONFIG_INOTIFY=y
@@ -800,10 +785,10 @@ CONFIG_PROC_FS=y
800CONFIG_PROC_KCORE=y 785CONFIG_PROC_KCORE=y
801CONFIG_SYSFS=y 786CONFIG_SYSFS=y
802CONFIG_TMPFS=y 787CONFIG_TMPFS=y
803# CONFIG_HUGETLBFS is not set
804# CONFIG_HUGETLB_PAGE is not set 788# CONFIG_HUGETLB_PAGE is not set
805CONFIG_RAMFS=y 789CONFIG_RAMFS=y
806# CONFIG_RELAYFS_FS is not set 790# CONFIG_RELAYFS_FS is not set
791# CONFIG_CONFIGFS_FS is not set
807 792
808# 793#
809# Miscellaneous filesystems 794# Miscellaneous filesystems
@@ -821,7 +806,6 @@ CONFIG_RAMFS=y
821# CONFIG_QNX4FS_FS is not set 806# CONFIG_QNX4FS_FS is not set
822# CONFIG_SYSV_FS is not set 807# CONFIG_SYSV_FS is not set
823CONFIG_UFS_FS=m 808CONFIG_UFS_FS=m
824# CONFIG_UFS_FS_WRITE is not set
825 809
826# 810#
827# Network File Systems 811# Network File Systems
@@ -917,18 +901,22 @@ CONFIG_OPROFILE=m
917# Kernel hacking 901# Kernel hacking
918# 902#
919# CONFIG_PRINTK_TIME is not set 903# CONFIG_PRINTK_TIME is not set
920CONFIG_DEBUG_KERNEL=y
921CONFIG_MAGIC_SYSRQ=y 904CONFIG_MAGIC_SYSRQ=y
905CONFIG_DEBUG_KERNEL=y
922CONFIG_LOG_BUF_SHIFT=16 906CONFIG_LOG_BUF_SHIFT=16
923CONFIG_DETECT_SOFTLOCKUP=y 907CONFIG_DETECT_SOFTLOCKUP=y
924# CONFIG_SCHEDSTATS is not set 908# CONFIG_SCHEDSTATS is not set
925# CONFIG_DEBUG_SLAB is not set 909# CONFIG_DEBUG_SLAB is not set
910CONFIG_DEBUG_MUTEXES=y
926# CONFIG_DEBUG_SPINLOCK is not set 911# CONFIG_DEBUG_SPINLOCK is not set
927# CONFIG_DEBUG_SPINLOCK_SLEEP is not set 912# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
928# CONFIG_DEBUG_KOBJECT is not set 913# CONFIG_DEBUG_KOBJECT is not set
929# CONFIG_DEBUG_INFO is not set 914# CONFIG_DEBUG_INFO is not set
930# CONFIG_DEBUG_IOREMAP is not set
931# CONFIG_DEBUG_FS is not set 915# CONFIG_DEBUG_FS is not set
916# CONFIG_DEBUG_VM is not set
917CONFIG_FORCED_INLINING=y
918# CONFIG_RCU_TORTURE_TEST is not set
919CONFIG_DEBUG_RODATA=y
932 920
933# 921#
934# Security options 922# Security options
diff --git a/arch/parisc/configs/a500_defconfig b/arch/parisc/configs/a500_defconfig
index 959ad3c4e372..f3b812f04592 100644
--- a/arch/parisc/configs/a500_defconfig
+++ b/arch/parisc/configs/a500_defconfig
@@ -1031,8 +1031,8 @@ CONFIG_NLS_CODEPAGE_850=m
1031# CONFIG_NLS_ISO8859_8 is not set 1031# CONFIG_NLS_ISO8859_8 is not set
1032# CONFIG_NLS_CODEPAGE_1250 is not set 1032# CONFIG_NLS_CODEPAGE_1250 is not set
1033# CONFIG_NLS_CODEPAGE_1251 is not set 1033# CONFIG_NLS_CODEPAGE_1251 is not set
1034# CONFIG_NLS_ASCII is not set 1034CONFIG_NLS_ASCII=m
1035# CONFIG_NLS_ISO8859_1 is not set 1035CONFIG_NLS_ISO8859_1=m
1036# CONFIG_NLS_ISO8859_2 is not set 1036# CONFIG_NLS_ISO8859_2 is not set
1037# CONFIG_NLS_ISO8859_3 is not set 1037# CONFIG_NLS_ISO8859_3 is not set
1038# CONFIG_NLS_ISO8859_4 is not set 1038# CONFIG_NLS_ISO8859_4 is not set
diff --git a/arch/parisc/configs/b180_defconfig b/arch/parisc/configs/b180_defconfig
index 37e98241ce4b..35093612ad2c 100644
--- a/arch/parisc/configs/b180_defconfig
+++ b/arch/parisc/configs/b180_defconfig
@@ -939,10 +939,10 @@ CONFIG_MSDOS_PARTITION=y
939# 939#
940CONFIG_NLS=y 940CONFIG_NLS=y
941CONFIG_NLS_DEFAULT="iso8859-1" 941CONFIG_NLS_DEFAULT="iso8859-1"
942# CONFIG_NLS_CODEPAGE_437 is not set 942CONFIG_NLS_CODEPAGE_437=m
943# CONFIG_NLS_CODEPAGE_737 is not set 943# CONFIG_NLS_CODEPAGE_737 is not set
944# CONFIG_NLS_CODEPAGE_775 is not set 944# CONFIG_NLS_CODEPAGE_775 is not set
945# CONFIG_NLS_CODEPAGE_850 is not set 945CONFIG_NLS_CODEPAGE_850=m
946# CONFIG_NLS_CODEPAGE_852 is not set 946# CONFIG_NLS_CODEPAGE_852 is not set
947# CONFIG_NLS_CODEPAGE_855 is not set 947# CONFIG_NLS_CODEPAGE_855 is not set
948# CONFIG_NLS_CODEPAGE_857 is not set 948# CONFIG_NLS_CODEPAGE_857 is not set
@@ -962,8 +962,8 @@ CONFIG_NLS_DEFAULT="iso8859-1"
962# CONFIG_NLS_ISO8859_8 is not set 962# CONFIG_NLS_ISO8859_8 is not set
963# CONFIG_NLS_CODEPAGE_1250 is not set 963# CONFIG_NLS_CODEPAGE_1250 is not set
964# CONFIG_NLS_CODEPAGE_1251 is not set 964# CONFIG_NLS_CODEPAGE_1251 is not set
965# CONFIG_NLS_ASCII is not set 965CONFIG_NLS_ASCII=m
966# CONFIG_NLS_ISO8859_1 is not set 966CONFIG_NLS_ISO8859_1=m
967# CONFIG_NLS_ISO8859_2 is not set 967# CONFIG_NLS_ISO8859_2 is not set
968# CONFIG_NLS_ISO8859_3 is not set 968# CONFIG_NLS_ISO8859_3 is not set
969# CONFIG_NLS_ISO8859_4 is not set 969# CONFIG_NLS_ISO8859_4 is not set
@@ -973,10 +973,10 @@ CONFIG_NLS_DEFAULT="iso8859-1"
973# CONFIG_NLS_ISO8859_9 is not set 973# CONFIG_NLS_ISO8859_9 is not set
974# CONFIG_NLS_ISO8859_13 is not set 974# CONFIG_NLS_ISO8859_13 is not set
975# CONFIG_NLS_ISO8859_14 is not set 975# CONFIG_NLS_ISO8859_14 is not set
976# CONFIG_NLS_ISO8859_15 is not set 976CONFIG_NLS_ISO8859_15=m
977# CONFIG_NLS_KOI8_R is not set 977# CONFIG_NLS_KOI8_R is not set
978# CONFIG_NLS_KOI8_U is not set 978# CONFIG_NLS_KOI8_U is not set
979# CONFIG_NLS_UTF8 is not set 979CONFIG_NLS_UTF8=m
980 980
981# 981#
982# Kernel hacking 982# Kernel hacking
diff --git a/arch/parisc/configs/c3000_defconfig b/arch/parisc/configs/c3000_defconfig
index 0b1c8c1fa8a3..782906b644dd 100644
--- a/arch/parisc/configs/c3000_defconfig
+++ b/arch/parisc/configs/c3000_defconfig
@@ -1,7 +1,7 @@
1# 1#
2# Automatically generated make config: don't edit 2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.14-rc5-pa1 3# Linux kernel version: 2.6.16-pa6
4# Fri Oct 21 23:06:31 2005 4# Sun Mar 26 20:03:29 2006
5# 5#
6CONFIG_PARISC=y 6CONFIG_PARISC=y
7CONFIG_MMU=y 7CONFIG_MMU=y
@@ -10,14 +10,11 @@ CONFIG_RWSEM_GENERIC_SPINLOCK=y
10CONFIG_GENERIC_CALIBRATE_DELAY=y 10CONFIG_GENERIC_CALIBRATE_DELAY=y
11CONFIG_GENERIC_HARDIRQS=y 11CONFIG_GENERIC_HARDIRQS=y
12CONFIG_GENERIC_IRQ_PROBE=y 12CONFIG_GENERIC_IRQ_PROBE=y
13CONFIG_ARCH_MAY_HAVE_PC_FDC=y
14 13
15# 14#
16# Code maturity level options 15# Code maturity level options
17# 16#
18CONFIG_EXPERIMENTAL=y 17CONFIG_EXPERIMENTAL=y
19# CONFIG_CLEAN_COMPILE is not set
20CONFIG_BROKEN=y
21CONFIG_BROKEN_ON_SMP=y 18CONFIG_BROKEN_ON_SMP=y
22CONFIG_INIT_ENV_ARG_LIMIT=32 19CONFIG_INIT_ENV_ARG_LIMIT=32
23 20
@@ -32,28 +29,30 @@ CONFIG_SYSVIPC=y
32# CONFIG_BSD_PROCESS_ACCT is not set 29# CONFIG_BSD_PROCESS_ACCT is not set
33CONFIG_SYSCTL=y 30CONFIG_SYSCTL=y
34# CONFIG_AUDIT is not set 31# CONFIG_AUDIT is not set
35CONFIG_HOTPLUG=y
36CONFIG_KOBJECT_UEVENT=y
37CONFIG_IKCONFIG=y 32CONFIG_IKCONFIG=y
38CONFIG_IKCONFIG_PROC=y 33CONFIG_IKCONFIG_PROC=y
39CONFIG_INITRAMFS_SOURCE="" 34CONFIG_INITRAMFS_SOURCE=""
35# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
40CONFIG_EMBEDDED=y 36CONFIG_EMBEDDED=y
41CONFIG_KALLSYMS=y 37CONFIG_KALLSYMS=y
42CONFIG_KALLSYMS_ALL=y 38CONFIG_KALLSYMS_ALL=y
43# CONFIG_KALLSYMS_EXTRA_PASS is not set 39# CONFIG_KALLSYMS_EXTRA_PASS is not set
40CONFIG_HOTPLUG=y
44CONFIG_PRINTK=y 41CONFIG_PRINTK=y
45CONFIG_BUG=y 42CONFIG_BUG=y
43CONFIG_ELF_CORE=y
46CONFIG_BASE_FULL=y 44CONFIG_BASE_FULL=y
47CONFIG_FUTEX=y 45CONFIG_FUTEX=y
48CONFIG_EPOLL=y 46CONFIG_EPOLL=y
49# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
50CONFIG_SHMEM=y 47CONFIG_SHMEM=y
51CONFIG_CC_ALIGN_FUNCTIONS=0 48CONFIG_CC_ALIGN_FUNCTIONS=0
52CONFIG_CC_ALIGN_LABELS=0 49CONFIG_CC_ALIGN_LABELS=0
53CONFIG_CC_ALIGN_LOOPS=0 50CONFIG_CC_ALIGN_LOOPS=0
54CONFIG_CC_ALIGN_JUMPS=0 51CONFIG_CC_ALIGN_JUMPS=0
52CONFIG_SLAB=y
55# CONFIG_TINY_SHMEM is not set 53# CONFIG_TINY_SHMEM is not set
56CONFIG_BASE_SMALL=0 54CONFIG_BASE_SMALL=0
55# CONFIG_SLOB is not set
57 56
58# 57#
59# Loadable module support 58# Loadable module support
@@ -67,6 +66,23 @@ CONFIG_OBSOLETE_MODPARM=y
67CONFIG_KMOD=y 66CONFIG_KMOD=y
68 67
69# 68#
69# Block layer
70#
71
72#
73# IO Schedulers
74#
75CONFIG_IOSCHED_NOOP=y
76CONFIG_IOSCHED_AS=y
77CONFIG_IOSCHED_DEADLINE=y
78CONFIG_IOSCHED_CFQ=y
79CONFIG_DEFAULT_AS=y
80# CONFIG_DEFAULT_DEADLINE is not set
81# CONFIG_DEFAULT_CFQ is not set
82# CONFIG_DEFAULT_NOOP is not set
83CONFIG_DEFAULT_IOSCHED="anticipatory"
84
85#
70# Processor type and features 86# Processor type and features
71# 87#
72# CONFIG_PA7000 is not set 88# CONFIG_PA7000 is not set
@@ -78,6 +94,10 @@ CONFIG_PA20=y
78CONFIG_PREFETCH=y 94CONFIG_PREFETCH=y
79# CONFIG_64BIT is not set 95# CONFIG_64BIT is not set
80# CONFIG_SMP is not set 96# CONFIG_SMP is not set
97CONFIG_ARCH_FLATMEM_ENABLE=y
98# CONFIG_PREEMPT_NONE is not set
99CONFIG_PREEMPT_VOLUNTARY=y
100# CONFIG_PREEMPT is not set
81# CONFIG_HZ_100 is not set 101# CONFIG_HZ_100 is not set
82CONFIG_HZ_250=y 102CONFIG_HZ_250=y
83# CONFIG_HZ_1000 is not set 103# CONFIG_HZ_1000 is not set
@@ -89,7 +109,7 @@ CONFIG_FLATMEM_MANUAL=y
89CONFIG_FLATMEM=y 109CONFIG_FLATMEM=y
90CONFIG_FLAT_NODE_MEM_MAP=y 110CONFIG_FLAT_NODE_MEM_MAP=y
91# CONFIG_SPARSEMEM_STATIC is not set 111# CONFIG_SPARSEMEM_STATIC is not set
92# CONFIG_PREEMPT is not set 112CONFIG_SPLIT_PTLOCK_CPUS=4
93# CONFIG_HPUX is not set 113# CONFIG_HPUX is not set
94 114
95# 115#
@@ -135,6 +155,7 @@ CONFIG_NET=y
135# 155#
136# Networking options 156# Networking options
137# 157#
158# CONFIG_NETDEBUG is not set
138CONFIG_PACKET=y 159CONFIG_PACKET=y
139CONFIG_PACKET_MMAP=y 160CONFIG_PACKET_MMAP=y
140CONFIG_UNIX=y 161CONFIG_UNIX=y
@@ -175,7 +196,12 @@ CONFIG_INET6_TUNNEL=m
175CONFIG_IPV6_TUNNEL=m 196CONFIG_IPV6_TUNNEL=m
176CONFIG_NETFILTER=y 197CONFIG_NETFILTER=y
177CONFIG_NETFILTER_DEBUG=y 198CONFIG_NETFILTER_DEBUG=y
199
200#
201# Core Netfilter Configuration
202#
178# CONFIG_NETFILTER_NETLINK is not set 203# CONFIG_NETFILTER_NETLINK is not set
204# CONFIG_NETFILTER_XTABLES is not set
179 205
180# 206#
181# IP: Netfilter Configuration 207# IP: Netfilter Configuration
@@ -192,87 +218,11 @@ CONFIG_IP_NF_TFTP=m
192CONFIG_IP_NF_AMANDA=m 218CONFIG_IP_NF_AMANDA=m
193# CONFIG_IP_NF_PPTP is not set 219# CONFIG_IP_NF_PPTP is not set
194CONFIG_IP_NF_QUEUE=m 220CONFIG_IP_NF_QUEUE=m
195CONFIG_IP_NF_IPTABLES=m
196CONFIG_IP_NF_MATCH_LIMIT=m
197CONFIG_IP_NF_MATCH_IPRANGE=m
198CONFIG_IP_NF_MATCH_MAC=m
199CONFIG_IP_NF_MATCH_PKTTYPE=m
200CONFIG_IP_NF_MATCH_MARK=m
201CONFIG_IP_NF_MATCH_MULTIPORT=m
202CONFIG_IP_NF_MATCH_TOS=m
203CONFIG_IP_NF_MATCH_RECENT=m
204CONFIG_IP_NF_MATCH_ECN=m
205CONFIG_IP_NF_MATCH_DSCP=m
206CONFIG_IP_NF_MATCH_AH_ESP=m
207CONFIG_IP_NF_MATCH_LENGTH=m
208CONFIG_IP_NF_MATCH_TTL=m
209CONFIG_IP_NF_MATCH_TCPMSS=m
210CONFIG_IP_NF_MATCH_HELPER=m
211CONFIG_IP_NF_MATCH_STATE=m
212CONFIG_IP_NF_MATCH_CONNTRACK=m
213CONFIG_IP_NF_MATCH_OWNER=m
214# CONFIG_IP_NF_MATCH_ADDRTYPE is not set
215# CONFIG_IP_NF_MATCH_REALM is not set
216# CONFIG_IP_NF_MATCH_SCTP is not set
217# CONFIG_IP_NF_MATCH_DCCP is not set
218# CONFIG_IP_NF_MATCH_COMMENT is not set
219# CONFIG_IP_NF_MATCH_HASHLIMIT is not set
220# CONFIG_IP_NF_MATCH_STRING is not set
221CONFIG_IP_NF_FILTER=m
222CONFIG_IP_NF_TARGET_REJECT=m
223CONFIG_IP_NF_TARGET_LOG=m
224CONFIG_IP_NF_TARGET_ULOG=m
225CONFIG_IP_NF_TARGET_TCPMSS=m
226# CONFIG_IP_NF_TARGET_NFQUEUE is not set
227CONFIG_IP_NF_NAT=m
228CONFIG_IP_NF_NAT_NEEDED=y
229CONFIG_IP_NF_TARGET_MASQUERADE=m
230CONFIG_IP_NF_TARGET_REDIRECT=m
231CONFIG_IP_NF_TARGET_NETMAP=m
232CONFIG_IP_NF_TARGET_SAME=m
233CONFIG_IP_NF_NAT_SNMP_BASIC=m
234CONFIG_IP_NF_NAT_IRC=m
235CONFIG_IP_NF_NAT_FTP=m
236CONFIG_IP_NF_NAT_TFTP=m
237CONFIG_IP_NF_NAT_AMANDA=m
238CONFIG_IP_NF_MANGLE=m
239CONFIG_IP_NF_TARGET_TOS=m
240CONFIG_IP_NF_TARGET_ECN=m
241CONFIG_IP_NF_TARGET_DSCP=m
242CONFIG_IP_NF_TARGET_MARK=m
243CONFIG_IP_NF_TARGET_CLASSIFY=m
244# CONFIG_IP_NF_TARGET_TTL is not set
245# CONFIG_IP_NF_RAW is not set
246CONFIG_IP_NF_ARPTABLES=m
247CONFIG_IP_NF_ARPFILTER=m
248CONFIG_IP_NF_ARP_MANGLE=m
249 221
250# 222#
251# IPv6: Netfilter Configuration (EXPERIMENTAL) 223# IPv6: Netfilter Configuration (EXPERIMENTAL)
252# 224#
253# CONFIG_IP6_NF_QUEUE is not set 225# CONFIG_IP6_NF_QUEUE is not set
254CONFIG_IP6_NF_IPTABLES=m
255# CONFIG_IP6_NF_MATCH_LIMIT is not set
256CONFIG_IP6_NF_MATCH_MAC=m
257CONFIG_IP6_NF_MATCH_RT=m
258# CONFIG_IP6_NF_MATCH_OPTS is not set
259# CONFIG_IP6_NF_MATCH_FRAG is not set
260# CONFIG_IP6_NF_MATCH_HL is not set
261# CONFIG_IP6_NF_MATCH_MULTIPORT is not set
262CONFIG_IP6_NF_MATCH_OWNER=m
263# CONFIG_IP6_NF_MATCH_MARK is not set
264CONFIG_IP6_NF_MATCH_IPV6HEADER=m
265# CONFIG_IP6_NF_MATCH_AHESP is not set
266CONFIG_IP6_NF_MATCH_LENGTH=m
267# CONFIG_IP6_NF_MATCH_EUI64 is not set
268CONFIG_IP6_NF_FILTER=m
269CONFIG_IP6_NF_TARGET_LOG=m
270CONFIG_IP6_NF_TARGET_REJECT=m
271# CONFIG_IP6_NF_TARGET_NFQUEUE is not set
272CONFIG_IP6_NF_MANGLE=m
273# CONFIG_IP6_NF_TARGET_MARK is not set
274# CONFIG_IP6_NF_TARGET_HL is not set
275# CONFIG_IP6_NF_RAW is not set
276 226
277# 227#
278# DCCP Configuration (EXPERIMENTAL) 228# DCCP Configuration (EXPERIMENTAL)
@@ -283,6 +233,11 @@ CONFIG_IP6_NF_MANGLE=m
283# SCTP Configuration (EXPERIMENTAL) 233# SCTP Configuration (EXPERIMENTAL)
284# 234#
285# CONFIG_IP_SCTP is not set 235# CONFIG_IP_SCTP is not set
236
237#
238# TIPC Configuration (EXPERIMENTAL)
239#
240# CONFIG_TIPC is not set
286# CONFIG_ATM is not set 241# CONFIG_ATM is not set
287# CONFIG_BRIDGE is not set 242# CONFIG_BRIDGE is not set
288# CONFIG_VLAN_8021Q is not set 243# CONFIG_VLAN_8021Q is not set
@@ -295,8 +250,11 @@ CONFIG_IP6_NF_MANGLE=m
295# CONFIG_NET_DIVERT is not set 250# CONFIG_NET_DIVERT is not set
296# CONFIG_ECONET is not set 251# CONFIG_ECONET is not set
297# CONFIG_WAN_ROUTER is not set 252# CONFIG_WAN_ROUTER is not set
253
254#
255# QoS and/or fair queueing
256#
298# CONFIG_NET_SCHED is not set 257# CONFIG_NET_SCHED is not set
299# CONFIG_NET_CLS_ROUTE is not set
300 258
301# 259#
302# Network testing 260# Network testing
@@ -341,7 +299,6 @@ CONFIG_FW_LOADER=y
341# 299#
342# Block devices 300# Block devices
343# 301#
344# CONFIG_BLK_DEV_FD is not set
345# CONFIG_BLK_CPQ_DA is not set 302# CONFIG_BLK_CPQ_DA is not set
346# CONFIG_BLK_CPQ_CISS_DA is not set 303# CONFIG_BLK_CPQ_CISS_DA is not set
347# CONFIG_BLK_DEV_DAC960 is not set 304# CONFIG_BLK_DEV_DAC960 is not set
@@ -355,14 +312,6 @@ CONFIG_BLK_DEV_CRYPTOLOOP=m
355# CONFIG_BLK_DEV_RAM is not set 312# CONFIG_BLK_DEV_RAM is not set
356CONFIG_BLK_DEV_RAM_COUNT=16 313CONFIG_BLK_DEV_RAM_COUNT=16
357# CONFIG_CDROM_PKTCDVD is not set 314# CONFIG_CDROM_PKTCDVD is not set
358
359#
360# IO Schedulers
361#
362CONFIG_IOSCHED_NOOP=y
363CONFIG_IOSCHED_AS=y
364CONFIG_IOSCHED_DEADLINE=y
365CONFIG_IOSCHED_CFQ=y
366# CONFIG_ATA_OVER_ETH is not set 315# CONFIG_ATA_OVER_ETH is not set
367 316
368# 317#
@@ -458,6 +407,7 @@ CONFIG_SCSI_ISCSI_ATTRS=m
458# 407#
459# SCSI low-level drivers 408# SCSI low-level drivers
460# 409#
410# CONFIG_ISCSI_TCP is not set
461# CONFIG_BLK_DEV_3W_XXXX_RAID is not set 411# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
462# CONFIG_SCSI_3W_9XXX is not set 412# CONFIG_SCSI_3W_9XXX is not set
463# CONFIG_SCSI_ACARD is not set 413# CONFIG_SCSI_ACARD is not set
@@ -466,7 +416,6 @@ CONFIG_SCSI_ISCSI_ATTRS=m
466# CONFIG_SCSI_AIC7XXX_OLD is not set 416# CONFIG_SCSI_AIC7XXX_OLD is not set
467# CONFIG_SCSI_AIC79XX is not set 417# CONFIG_SCSI_AIC79XX is not set
468# CONFIG_SCSI_DPT_I2O is not set 418# CONFIG_SCSI_DPT_I2O is not set
469# CONFIG_SCSI_ADVANSYS is not set
470# CONFIG_MEGARAID_NEWGEN is not set 419# CONFIG_MEGARAID_NEWGEN is not set
471# CONFIG_MEGARAID_LEGACY is not set 420# CONFIG_MEGARAID_LEGACY is not set
472# CONFIG_MEGARAID_SAS is not set 421# CONFIG_MEGARAID_SAS is not set
@@ -476,18 +425,18 @@ CONFIG_SCSI_SATA=y
476CONFIG_SCSI_ATA_PIIX=m 425CONFIG_SCSI_ATA_PIIX=m
477# CONFIG_SCSI_SATA_MV is not set 426# CONFIG_SCSI_SATA_MV is not set
478# CONFIG_SCSI_SATA_NV is not set 427# CONFIG_SCSI_SATA_NV is not set
479CONFIG_SCSI_SATA_PROMISE=m 428# CONFIG_SCSI_PDC_ADMA is not set
480# CONFIG_SCSI_SATA_QSTOR is not set 429# CONFIG_SCSI_SATA_QSTOR is not set
430CONFIG_SCSI_SATA_PROMISE=m
481# CONFIG_SCSI_SATA_SX4 is not set 431# CONFIG_SCSI_SATA_SX4 is not set
482CONFIG_SCSI_SATA_SIL=m 432CONFIG_SCSI_SATA_SIL=m
433# CONFIG_SCSI_SATA_SIL24 is not set
483# CONFIG_SCSI_SATA_SIS is not set 434# CONFIG_SCSI_SATA_SIS is not set
484# CONFIG_SCSI_SATA_ULI is not set 435# CONFIG_SCSI_SATA_ULI is not set
485CONFIG_SCSI_SATA_VIA=m 436CONFIG_SCSI_SATA_VIA=m
486# CONFIG_SCSI_SATA_VITESSE is not set 437# CONFIG_SCSI_SATA_VITESSE is not set
487CONFIG_SCSI_SATA_INTEL_COMBINED=y 438CONFIG_SCSI_SATA_INTEL_COMBINED=y
488# CONFIG_SCSI_CPQFCTS is not set
489# CONFIG_SCSI_DMX3191D is not set 439# CONFIG_SCSI_DMX3191D is not set
490# CONFIG_SCSI_EATA_PIO is not set
491# CONFIG_SCSI_FUTURE_DOMAIN is not set 440# CONFIG_SCSI_FUTURE_DOMAIN is not set
492# CONFIG_SCSI_IPS is not set 441# CONFIG_SCSI_IPS is not set
493# CONFIG_SCSI_INITIO is not set 442# CONFIG_SCSI_INITIO is not set
@@ -496,18 +445,11 @@ CONFIG_SCSI_SYM53C8XX_2=y
496CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=0 445CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=0
497CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16 446CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16
498CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64 447CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64
499# CONFIG_SCSI_SYM53C8XX_IOMAPPED is not set 448CONFIG_SCSI_SYM53C8XX_MMIO=y
500# CONFIG_SCSI_IPR is not set 449# CONFIG_SCSI_IPR is not set
501# CONFIG_SCSI_QLOGIC_ISP is not set
502# CONFIG_SCSI_QLOGIC_FC is not set 450# CONFIG_SCSI_QLOGIC_FC is not set
503# CONFIG_SCSI_QLOGIC_1280 is not set 451# CONFIG_SCSI_QLOGIC_1280 is not set
504CONFIG_SCSI_QLA2XXX=y 452# CONFIG_SCSI_QLA_FC is not set
505# CONFIG_SCSI_QLA21XX is not set
506# CONFIG_SCSI_QLA22XX is not set
507# CONFIG_SCSI_QLA2300 is not set
508# CONFIG_SCSI_QLA2322 is not set
509# CONFIG_SCSI_QLA6312 is not set
510# CONFIG_SCSI_QLA24XX is not set
511# CONFIG_SCSI_LPFC is not set 453# CONFIG_SCSI_LPFC is not set
512# CONFIG_SCSI_DC395x is not set 454# CONFIG_SCSI_DC395x is not set
513# CONFIG_SCSI_DC390T is not set 455# CONFIG_SCSI_DC390T is not set
@@ -633,6 +575,7 @@ CONFIG_E1000=m
633# CONFIG_R8169 is not set 575# CONFIG_R8169 is not set
634# CONFIG_SIS190 is not set 576# CONFIG_SIS190 is not set
635# CONFIG_SKGE is not set 577# CONFIG_SKGE is not set
578# CONFIG_SKY2 is not set
636# CONFIG_SK98LIN is not set 579# CONFIG_SK98LIN is not set
637# CONFIG_VIA_VELOCITY is not set 580# CONFIG_VIA_VELOCITY is not set
638CONFIG_TIGON3=m 581CONFIG_TIGON3=m
@@ -668,6 +611,7 @@ CONFIG_PPP_ASYNC=m
668CONFIG_PPP_SYNC_TTY=m 611CONFIG_PPP_SYNC_TTY=m
669CONFIG_PPP_DEFLATE=m 612CONFIG_PPP_DEFLATE=m
670CONFIG_PPP_BSDCOMP=m 613CONFIG_PPP_BSDCOMP=m
614# CONFIG_PPP_MPPE is not set
671CONFIG_PPPOE=m 615CONFIG_PPPOE=m
672# CONFIG_SLIP is not set 616# CONFIG_SLIP is not set
673# CONFIG_NET_FC is not set 617# CONFIG_NET_FC is not set
@@ -744,6 +688,7 @@ CONFIG_HW_CONSOLE=y
744CONFIG_SERIAL_8250=y 688CONFIG_SERIAL_8250=y
745CONFIG_SERIAL_8250_CONSOLE=y 689CONFIG_SERIAL_8250_CONSOLE=y
746CONFIG_SERIAL_8250_NR_UARTS=13 690CONFIG_SERIAL_8250_NR_UARTS=13
691CONFIG_SERIAL_8250_RUNTIME_UARTS=4
747CONFIG_SERIAL_8250_EXTENDED=y 692CONFIG_SERIAL_8250_EXTENDED=y
748CONFIG_SERIAL_8250_MANY_PORTS=y 693CONFIG_SERIAL_8250_MANY_PORTS=y
749CONFIG_SERIAL_8250_SHARE_IRQ=y 694CONFIG_SERIAL_8250_SHARE_IRQ=y
@@ -753,7 +698,6 @@ CONFIG_SERIAL_8250_SHARE_IRQ=y
753# 698#
754# Non-8250 serial port support 699# Non-8250 serial port support
755# 700#
756# CONFIG_SERIAL_MUX is not set
757# CONFIG_PDC_CONSOLE is not set 701# CONFIG_PDC_CONSOLE is not set
758CONFIG_SERIAL_CORE=y 702CONFIG_SERIAL_CORE=y
759CONFIG_SERIAL_CORE_CONSOLE=y 703CONFIG_SERIAL_CORE_CONSOLE=y
@@ -788,6 +732,7 @@ CONFIG_MAX_RAW_DEVS=256
788# TPM devices 732# TPM devices
789# 733#
790# CONFIG_TCG_TPM is not set 734# CONFIG_TCG_TPM is not set
735# CONFIG_TELCLOCK is not set
791 736
792# 737#
793# I2C support 738# I2C support
@@ -795,6 +740,12 @@ CONFIG_MAX_RAW_DEVS=256
795# CONFIG_I2C is not set 740# CONFIG_I2C is not set
796 741
797# 742#
743# SPI support
744#
745# CONFIG_SPI is not set
746# CONFIG_SPI_MASTER is not set
747
748#
798# Dallas's 1-wire bus 749# Dallas's 1-wire bus
799# 750#
800# CONFIG_W1 is not set 751# CONFIG_W1 is not set
@@ -830,7 +781,6 @@ CONFIG_FB=y
830CONFIG_FB_CFB_FILLRECT=y 781CONFIG_FB_CFB_FILLRECT=y
831CONFIG_FB_CFB_COPYAREA=y 782CONFIG_FB_CFB_COPYAREA=y
832CONFIG_FB_CFB_IMAGEBLIT=y 783CONFIG_FB_CFB_IMAGEBLIT=y
833CONFIG_FB_SOFT_CURSOR=y
834# CONFIG_FB_MACMODES is not set 784# CONFIG_FB_MACMODES is not set
835# CONFIG_FB_MODE_HELPERS is not set 785# CONFIG_FB_MODE_HELPERS is not set
836# CONFIG_FB_TILEBLITTING is not set 786# CONFIG_FB_TILEBLITTING is not set
@@ -840,6 +790,7 @@ CONFIG_FB_SOFT_CURSOR=y
840# CONFIG_FB_ASILIANT is not set 790# CONFIG_FB_ASILIANT is not set
841# CONFIG_FB_IMSTT is not set 791# CONFIG_FB_IMSTT is not set
842CONFIG_FB_STI=y 792CONFIG_FB_STI=y
793# CONFIG_FB_S1D13XXX is not set
843# CONFIG_FB_NVIDIA is not set 794# CONFIG_FB_NVIDIA is not set
844# CONFIG_FB_RIVA is not set 795# CONFIG_FB_RIVA is not set
845# CONFIG_FB_MATROX is not set 796# CONFIG_FB_MATROX is not set
@@ -853,10 +804,7 @@ CONFIG_FB_STI=y
853# CONFIG_FB_KYRO is not set 804# CONFIG_FB_KYRO is not set
854# CONFIG_FB_3DFX is not set 805# CONFIG_FB_3DFX is not set
855# CONFIG_FB_VOODOO1 is not set 806# CONFIG_FB_VOODOO1 is not set
856# CONFIG_FB_CYBLA is not set
857# CONFIG_FB_TRIDENT is not set 807# CONFIG_FB_TRIDENT is not set
858# CONFIG_FB_PM3 is not set
859# CONFIG_FB_S1D13XXX is not set
860# CONFIG_FB_VIRTUAL is not set 808# CONFIG_FB_VIRTUAL is not set
861 809
862# 810#
@@ -866,6 +814,7 @@ CONFIG_DUMMY_CONSOLE=y
866CONFIG_DUMMY_CONSOLE_COLUMNS=160 814CONFIG_DUMMY_CONSOLE_COLUMNS=160
867CONFIG_DUMMY_CONSOLE_ROWS=64 815CONFIG_DUMMY_CONSOLE_ROWS=64
868CONFIG_FRAMEBUFFER_CONSOLE=y 816CONFIG_FRAMEBUFFER_CONSOLE=y
817# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
869CONFIG_STI_CONSOLE=y 818CONFIG_STI_CONSOLE=y
870# CONFIG_FONTS is not set 819# CONFIG_FONTS is not set
871CONFIG_FONT_8x8=y 820CONFIG_FONT_8x8=y
@@ -898,23 +847,27 @@ CONFIG_SND_OSSEMUL=y
898CONFIG_SND_MIXER_OSS=y 847CONFIG_SND_MIXER_OSS=y
899CONFIG_SND_PCM_OSS=y 848CONFIG_SND_PCM_OSS=y
900CONFIG_SND_SEQUENCER_OSS=y 849CONFIG_SND_SEQUENCER_OSS=y
850# CONFIG_SND_DYNAMIC_MINORS is not set
851CONFIG_SND_SUPPORT_OLD_API=y
901# CONFIG_SND_VERBOSE_PRINTK is not set 852# CONFIG_SND_VERBOSE_PRINTK is not set
902# CONFIG_SND_DEBUG is not set 853# CONFIG_SND_DEBUG is not set
903 854
904# 855#
905# Generic devices 856# Generic devices
906# 857#
858CONFIG_SND_AC97_CODEC=y
859CONFIG_SND_AC97_BUS=y
907# CONFIG_SND_DUMMY is not set 860# CONFIG_SND_DUMMY is not set
908# CONFIG_SND_VIRMIDI is not set 861# CONFIG_SND_VIRMIDI is not set
909# CONFIG_SND_MTPAV is not set 862# CONFIG_SND_MTPAV is not set
910# CONFIG_SND_SERIAL_U16550 is not set 863# CONFIG_SND_SERIAL_U16550 is not set
911# CONFIG_SND_MPU401 is not set 864# CONFIG_SND_MPU401 is not set
912CONFIG_SND_AC97_CODEC=y
913CONFIG_SND_AC97_BUS=y
914 865
915# 866#
916# PCI devices 867# PCI devices
917# 868#
869CONFIG_SND_AD1889=y
870# CONFIG_SND_AD1889_OPL3 is not set
918# CONFIG_SND_ALI5451 is not set 871# CONFIG_SND_ALI5451 is not set
919# CONFIG_SND_ATIIXP is not set 872# CONFIG_SND_ATIIXP is not set
920# CONFIG_SND_ATIIXP_MODEM is not set 873# CONFIG_SND_ATIIXP_MODEM is not set
@@ -923,39 +876,38 @@ CONFIG_SND_AC97_BUS=y
923# CONFIG_SND_AU8830 is not set 876# CONFIG_SND_AU8830 is not set
924# CONFIG_SND_AZT3328 is not set 877# CONFIG_SND_AZT3328 is not set
925# CONFIG_SND_BT87X is not set 878# CONFIG_SND_BT87X is not set
926# CONFIG_SND_CS46XX is not set 879# CONFIG_SND_CA0106 is not set
880# CONFIG_SND_CMIPCI is not set
927# CONFIG_SND_CS4281 is not set 881# CONFIG_SND_CS4281 is not set
882# CONFIG_SND_CS46XX is not set
928# CONFIG_SND_EMU10K1 is not set 883# CONFIG_SND_EMU10K1 is not set
929# CONFIG_SND_EMU10K1X is not set 884# CONFIG_SND_EMU10K1X is not set
930# CONFIG_SND_CA0106 is not set
931# CONFIG_SND_KORG1212 is not set
932# CONFIG_SND_MIXART is not set
933# CONFIG_SND_NM256 is not set
934# CONFIG_SND_RME32 is not set
935# CONFIG_SND_RME96 is not set
936# CONFIG_SND_RME9652 is not set
937# CONFIG_SND_HDSP is not set
938# CONFIG_SND_HDSPM is not set
939# CONFIG_SND_TRIDENT is not set
940# CONFIG_SND_YMFPCI is not set
941CONFIG_SND_AD1889=y
942# CONFIG_SND_AD1889_OPL3 is not set
943# CONFIG_SND_CMIPCI is not set
944# CONFIG_SND_ENS1370 is not set 885# CONFIG_SND_ENS1370 is not set
945# CONFIG_SND_ENS1371 is not set 886# CONFIG_SND_ENS1371 is not set
946# CONFIG_SND_ES1938 is not set 887# CONFIG_SND_ES1938 is not set
947# CONFIG_SND_ES1968 is not set 888# CONFIG_SND_ES1968 is not set
948# CONFIG_SND_MAESTRO3 is not set
949# CONFIG_SND_FM801 is not set 889# CONFIG_SND_FM801 is not set
890# CONFIG_SND_HDA_INTEL is not set
891# CONFIG_SND_HDSP is not set
892# CONFIG_SND_HDSPM is not set
950# CONFIG_SND_ICE1712 is not set 893# CONFIG_SND_ICE1712 is not set
951# CONFIG_SND_ICE1724 is not set 894# CONFIG_SND_ICE1724 is not set
952# CONFIG_SND_INTEL8X0 is not set 895# CONFIG_SND_INTEL8X0 is not set
953# CONFIG_SND_INTEL8X0M is not set 896# CONFIG_SND_INTEL8X0M is not set
897# CONFIG_SND_KORG1212 is not set
898# CONFIG_SND_MAESTRO3 is not set
899# CONFIG_SND_MIXART is not set
900# CONFIG_SND_NM256 is not set
901# CONFIG_SND_PCXHR is not set
902# CONFIG_SND_RME32 is not set
903# CONFIG_SND_RME96 is not set
904# CONFIG_SND_RME9652 is not set
954# CONFIG_SND_SONICVIBES is not set 905# CONFIG_SND_SONICVIBES is not set
906# CONFIG_SND_TRIDENT is not set
955# CONFIG_SND_VIA82XX is not set 907# CONFIG_SND_VIA82XX is not set
956# CONFIG_SND_VIA82XX_MODEM is not set 908# CONFIG_SND_VIA82XX_MODEM is not set
957# CONFIG_SND_VX222 is not set 909# CONFIG_SND_VX222 is not set
958# CONFIG_SND_HDA_INTEL is not set 910# CONFIG_SND_YMFPCI is not set
959 911
960# 912#
961# USB devices 913# USB devices
@@ -998,12 +950,15 @@ CONFIG_USB_OHCI_LITTLE_ENDIAN=y
998# USB Device Class drivers 950# USB Device Class drivers
999# 951#
1000# CONFIG_OBSOLETE_OSS_USB_DRIVER is not set 952# CONFIG_OBSOLETE_OSS_USB_DRIVER is not set
1001# CONFIG_USB_BLUETOOTH_TTY is not set
1002# CONFIG_USB_ACM is not set 953# CONFIG_USB_ACM is not set
1003CONFIG_USB_PRINTER=m 954CONFIG_USB_PRINTER=m
1004 955
1005# 956#
1006# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information 957# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
958#
959
960#
961# may also be needed; see USB_STORAGE Help for more information
1007# 962#
1008CONFIG_USB_STORAGE=m 963CONFIG_USB_STORAGE=m
1009# CONFIG_USB_STORAGE_DEBUG is not set 964# CONFIG_USB_STORAGE_DEBUG is not set
@@ -1015,12 +970,15 @@ CONFIG_USB_STORAGE_USBAT=y
1015CONFIG_USB_STORAGE_SDDR09=y 970CONFIG_USB_STORAGE_SDDR09=y
1016CONFIG_USB_STORAGE_SDDR55=y 971CONFIG_USB_STORAGE_SDDR55=y
1017CONFIG_USB_STORAGE_JUMPSHOT=y 972CONFIG_USB_STORAGE_JUMPSHOT=y
973# CONFIG_USB_STORAGE_ALAUDA is not set
974# CONFIG_USB_LIBUSUAL is not set
1018 975
1019# 976#
1020# USB Input Devices 977# USB Input Devices
1021# 978#
1022CONFIG_USB_HID=y 979CONFIG_USB_HID=y
1023CONFIG_USB_HIDINPUT=y 980CONFIG_USB_HIDINPUT=y
981# CONFIG_USB_HIDINPUT_POWERBOOK is not set
1024# CONFIG_HID_FF is not set 982# CONFIG_HID_FF is not set
1025CONFIG_USB_HIDDEV=y 983CONFIG_USB_HIDDEV=y
1026# CONFIG_USB_AIPTEK is not set 984# CONFIG_USB_AIPTEK is not set
@@ -1034,6 +992,7 @@ CONFIG_USB_HIDDEV=y
1034# CONFIG_USB_YEALINK is not set 992# CONFIG_USB_YEALINK is not set
1035# CONFIG_USB_XPAD is not set 993# CONFIG_USB_XPAD is not set
1036# CONFIG_USB_ATI_REMOTE is not set 994# CONFIG_USB_ATI_REMOTE is not set
995# CONFIG_USB_ATI_REMOTE2 is not set
1037# CONFIG_USB_KEYSPAN_REMOTE is not set 996# CONFIG_USB_KEYSPAN_REMOTE is not set
1038# CONFIG_USB_APPLETOUCH is not set 997# CONFIG_USB_APPLETOUCH is not set
1039 998
@@ -1108,7 +1067,7 @@ CONFIG_USB_LEGOTOWER=m
1108# CONFIG_INFINIBAND is not set 1067# CONFIG_INFINIBAND is not set
1109 1068
1110# 1069#
1111# SN Devices 1070# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
1112# 1071#
1113 1072
1114# 1073#
@@ -1130,6 +1089,7 @@ CONFIG_XFS_EXPORT=y
1130# CONFIG_XFS_SECURITY is not set 1089# CONFIG_XFS_SECURITY is not set
1131# CONFIG_XFS_POSIX_ACL is not set 1090# CONFIG_XFS_POSIX_ACL is not set
1132# CONFIG_XFS_RT is not set 1091# CONFIG_XFS_RT is not set
1092# CONFIG_OCFS2_FS is not set
1133# CONFIG_MINIX_FS is not set 1093# CONFIG_MINIX_FS is not set
1134# CONFIG_ROMFS_FS is not set 1094# CONFIG_ROMFS_FS is not set
1135CONFIG_INOTIFY=y 1095CONFIG_INOTIFY=y
@@ -1164,10 +1124,10 @@ CONFIG_PROC_FS=y
1164CONFIG_PROC_KCORE=y 1124CONFIG_PROC_KCORE=y
1165CONFIG_SYSFS=y 1125CONFIG_SYSFS=y
1166CONFIG_TMPFS=y 1126CONFIG_TMPFS=y
1167# CONFIG_HUGETLBFS is not set
1168# CONFIG_HUGETLB_PAGE is not set 1127# CONFIG_HUGETLB_PAGE is not set
1169CONFIG_RAMFS=y 1128CONFIG_RAMFS=y
1170# CONFIG_RELAYFS_FS is not set 1129# CONFIG_RELAYFS_FS is not set
1130# CONFIG_CONFIGFS_FS is not set
1171 1131
1172# 1132#
1173# Miscellaneous filesystems 1133# Miscellaneous filesystems
@@ -1225,10 +1185,10 @@ CONFIG_MSDOS_PARTITION=y
1225# 1185#
1226CONFIG_NLS=y 1186CONFIG_NLS=y
1227CONFIG_NLS_DEFAULT="iso8859-1" 1187CONFIG_NLS_DEFAULT="iso8859-1"
1228# CONFIG_NLS_CODEPAGE_437 is not set 1188CONFIG_NLS_CODEPAGE_437=m
1229# CONFIG_NLS_CODEPAGE_737 is not set 1189# CONFIG_NLS_CODEPAGE_737 is not set
1230# CONFIG_NLS_CODEPAGE_775 is not set 1190# CONFIG_NLS_CODEPAGE_775 is not set
1231# CONFIG_NLS_CODEPAGE_850 is not set 1191CONFIG_NLS_CODEPAGE_850=m
1232# CONFIG_NLS_CODEPAGE_852 is not set 1192# CONFIG_NLS_CODEPAGE_852 is not set
1233# CONFIG_NLS_CODEPAGE_855 is not set 1193# CONFIG_NLS_CODEPAGE_855 is not set
1234# CONFIG_NLS_CODEPAGE_857 is not set 1194# CONFIG_NLS_CODEPAGE_857 is not set
@@ -1248,8 +1208,8 @@ CONFIG_NLS_DEFAULT="iso8859-1"
1248# CONFIG_NLS_ISO8859_8 is not set 1208# CONFIG_NLS_ISO8859_8 is not set
1249# CONFIG_NLS_CODEPAGE_1250 is not set 1209# CONFIG_NLS_CODEPAGE_1250 is not set
1250# CONFIG_NLS_CODEPAGE_1251 is not set 1210# CONFIG_NLS_CODEPAGE_1251 is not set
1251# CONFIG_NLS_ASCII is not set 1211CONFIG_NLS_ASCII=m
1252# CONFIG_NLS_ISO8859_1 is not set 1212CONFIG_NLS_ISO8859_1=m
1253# CONFIG_NLS_ISO8859_2 is not set 1213# CONFIG_NLS_ISO8859_2 is not set
1254# CONFIG_NLS_ISO8859_3 is not set 1214# CONFIG_NLS_ISO8859_3 is not set
1255# CONFIG_NLS_ISO8859_4 is not set 1215# CONFIG_NLS_ISO8859_4 is not set
@@ -1259,10 +1219,10 @@ CONFIG_NLS_DEFAULT="iso8859-1"
1259# CONFIG_NLS_ISO8859_9 is not set 1219# CONFIG_NLS_ISO8859_9 is not set
1260# CONFIG_NLS_ISO8859_13 is not set 1220# CONFIG_NLS_ISO8859_13 is not set
1261# CONFIG_NLS_ISO8859_14 is not set 1221# CONFIG_NLS_ISO8859_14 is not set
1262# CONFIG_NLS_ISO8859_15 is not set 1222CONFIG_NLS_ISO8859_15=m
1263# CONFIG_NLS_KOI8_R is not set 1223# CONFIG_NLS_KOI8_R is not set
1264# CONFIG_NLS_KOI8_U is not set 1224# CONFIG_NLS_KOI8_U is not set
1265# CONFIG_NLS_UTF8 is not set 1225CONFIG_NLS_UTF8=m
1266 1226
1267# 1227#
1268# Profiling support 1228# Profiling support
@@ -1274,18 +1234,22 @@ CONFIG_OPROFILE=m
1274# Kernel hacking 1234# Kernel hacking
1275# 1235#
1276# CONFIG_PRINTK_TIME is not set 1236# CONFIG_PRINTK_TIME is not set
1277CONFIG_DEBUG_KERNEL=y
1278CONFIG_MAGIC_SYSRQ=y 1237CONFIG_MAGIC_SYSRQ=y
1238CONFIG_DEBUG_KERNEL=y
1279CONFIG_LOG_BUF_SHIFT=16 1239CONFIG_LOG_BUF_SHIFT=16
1280CONFIG_DETECT_SOFTLOCKUP=y 1240CONFIG_DETECT_SOFTLOCKUP=y
1281# CONFIG_SCHEDSTATS is not set 1241# CONFIG_SCHEDSTATS is not set
1282# CONFIG_DEBUG_SLAB is not set 1242# CONFIG_DEBUG_SLAB is not set
1243CONFIG_DEBUG_MUTEXES=y
1283# CONFIG_DEBUG_SPINLOCK is not set 1244# CONFIG_DEBUG_SPINLOCK is not set
1284# CONFIG_DEBUG_SPINLOCK_SLEEP is not set 1245# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
1285# CONFIG_DEBUG_KOBJECT is not set 1246# CONFIG_DEBUG_KOBJECT is not set
1286# CONFIG_DEBUG_INFO is not set 1247# CONFIG_DEBUG_INFO is not set
1287# CONFIG_DEBUG_IOREMAP is not set
1288# CONFIG_DEBUG_FS is not set 1248# CONFIG_DEBUG_FS is not set
1249# CONFIG_DEBUG_VM is not set
1250CONFIG_FORCED_INLINING=y
1251# CONFIG_RCU_TORTURE_TEST is not set
1252CONFIG_DEBUG_RODATA=y
1289 1253
1290# 1254#
1291# Security options 1255# Security options
diff --git a/arch/parisc/defconfig b/arch/parisc/defconfig
index f38a4620d24f..59f7bc38e72e 100644
--- a/arch/parisc/defconfig
+++ b/arch/parisc/defconfig
@@ -1,7 +1,7 @@
1# 1#
2# Automatically generated make config: don't edit 2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.14-rc5-pa1 3# Linux kernel version: 2.6.16-pa6
4# Fri Oct 21 23:01:33 2005 4# Sun Mar 26 19:50:07 2006
5# 5#
6CONFIG_PARISC=y 6CONFIG_PARISC=y
7CONFIG_MMU=y 7CONFIG_MMU=y
@@ -15,7 +15,6 @@ CONFIG_GENERIC_IRQ_PROBE=y
15# Code maturity level options 15# Code maturity level options
16# 16#
17CONFIG_EXPERIMENTAL=y 17CONFIG_EXPERIMENTAL=y
18CONFIG_CLEAN_COMPILE=y
19CONFIG_BROKEN_ON_SMP=y 18CONFIG_BROKEN_ON_SMP=y
20CONFIG_INIT_ENV_ARG_LIMIT=32 19CONFIG_INIT_ENV_ARG_LIMIT=32
21 20
@@ -30,17 +29,18 @@ CONFIG_SYSVIPC=y
30# CONFIG_BSD_PROCESS_ACCT is not set 29# CONFIG_BSD_PROCESS_ACCT is not set
31CONFIG_SYSCTL=y 30CONFIG_SYSCTL=y
32# CONFIG_AUDIT is not set 31# CONFIG_AUDIT is not set
33# CONFIG_HOTPLUG is not set
34CONFIG_KOBJECT_UEVENT=y
35CONFIG_IKCONFIG=y 32CONFIG_IKCONFIG=y
36CONFIG_IKCONFIG_PROC=y 33CONFIG_IKCONFIG_PROC=y
37CONFIG_INITRAMFS_SOURCE="" 34CONFIG_INITRAMFS_SOURCE=""
35CONFIG_CC_OPTIMIZE_FOR_SIZE=y
38# CONFIG_EMBEDDED is not set 36# CONFIG_EMBEDDED is not set
39CONFIG_KALLSYMS=y 37CONFIG_KALLSYMS=y
40# CONFIG_KALLSYMS_ALL is not set 38# CONFIG_KALLSYMS_ALL is not set
41# CONFIG_KALLSYMS_EXTRA_PASS is not set 39# CONFIG_KALLSYMS_EXTRA_PASS is not set
40CONFIG_HOTPLUG=y
42CONFIG_PRINTK=y 41CONFIG_PRINTK=y
43CONFIG_BUG=y 42CONFIG_BUG=y
43CONFIG_ELF_CORE=y
44CONFIG_BASE_FULL=y 44CONFIG_BASE_FULL=y
45CONFIG_FUTEX=y 45CONFIG_FUTEX=y
46CONFIG_EPOLL=y 46CONFIG_EPOLL=y
@@ -49,8 +49,10 @@ CONFIG_CC_ALIGN_FUNCTIONS=0
49CONFIG_CC_ALIGN_LABELS=0 49CONFIG_CC_ALIGN_LABELS=0
50CONFIG_CC_ALIGN_LOOPS=0 50CONFIG_CC_ALIGN_LOOPS=0
51CONFIG_CC_ALIGN_JUMPS=0 51CONFIG_CC_ALIGN_JUMPS=0
52CONFIG_SLAB=y
52# CONFIG_TINY_SHMEM is not set 53# CONFIG_TINY_SHMEM is not set
53CONFIG_BASE_SMALL=0 54CONFIG_BASE_SMALL=0
55# CONFIG_SLOB is not set
54 56
55# 57#
56# Loadable module support 58# Loadable module support
@@ -58,6 +60,23 @@ CONFIG_BASE_SMALL=0
58# CONFIG_MODULES is not set 60# CONFIG_MODULES is not set
59 61
60# 62#
63# Block layer
64#
65
66#
67# IO Schedulers
68#
69CONFIG_IOSCHED_NOOP=y
70CONFIG_IOSCHED_AS=y
71CONFIG_IOSCHED_DEADLINE=y
72CONFIG_IOSCHED_CFQ=y
73CONFIG_DEFAULT_AS=y
74# CONFIG_DEFAULT_DEADLINE is not set
75# CONFIG_DEFAULT_CFQ is not set
76# CONFIG_DEFAULT_NOOP is not set
77CONFIG_DEFAULT_IOSCHED="anticipatory"
78
79#
61# Processor type and features 80# Processor type and features
62# 81#
63CONFIG_PA7000=y 82CONFIG_PA7000=y
@@ -67,6 +86,10 @@ CONFIG_PA7000=y
67# CONFIG_PA8X00 is not set 86# CONFIG_PA8X00 is not set
68CONFIG_PA11=y 87CONFIG_PA11=y
69# CONFIG_SMP is not set 88# CONFIG_SMP is not set
89CONFIG_ARCH_FLATMEM_ENABLE=y
90CONFIG_PREEMPT_NONE=y
91# CONFIG_PREEMPT_VOLUNTARY is not set
92# CONFIG_PREEMPT is not set
70# CONFIG_HZ_100 is not set 93# CONFIG_HZ_100 is not set
71CONFIG_HZ_250=y 94CONFIG_HZ_250=y
72# CONFIG_HZ_1000 is not set 95# CONFIG_HZ_1000 is not set
@@ -78,7 +101,7 @@ CONFIG_FLATMEM_MANUAL=y
78CONFIG_FLATMEM=y 101CONFIG_FLATMEM=y
79CONFIG_FLAT_NODE_MEM_MAP=y 102CONFIG_FLAT_NODE_MEM_MAP=y
80# CONFIG_SPARSEMEM_STATIC is not set 103# CONFIG_SPARSEMEM_STATIC is not set
81# CONFIG_PREEMPT is not set 104CONFIG_SPLIT_PTLOCK_CPUS=4096
82# CONFIG_HPUX is not set 105# CONFIG_HPUX is not set
83 106
84# 107#
@@ -132,6 +155,7 @@ CONFIG_NET=y
132# 155#
133# Networking options 156# Networking options
134# 157#
158# CONFIG_NETDEBUG is not set
135CONFIG_PACKET=y 159CONFIG_PACKET=y
136CONFIG_PACKET_MMAP=y 160CONFIG_PACKET_MMAP=y
137CONFIG_UNIX=y 161CONFIG_UNIX=y
@@ -174,6 +198,11 @@ CONFIG_IPV6=y
174# SCTP Configuration (EXPERIMENTAL) 198# SCTP Configuration (EXPERIMENTAL)
175# 199#
176# CONFIG_IP_SCTP is not set 200# CONFIG_IP_SCTP is not set
201
202#
203# TIPC Configuration (EXPERIMENTAL)
204#
205# CONFIG_TIPC is not set
177# CONFIG_ATM is not set 206# CONFIG_ATM is not set
178# CONFIG_BRIDGE is not set 207# CONFIG_BRIDGE is not set
179# CONFIG_VLAN_8021Q is not set 208# CONFIG_VLAN_8021Q is not set
@@ -186,8 +215,11 @@ CONFIG_IPV6=y
186# CONFIG_NET_DIVERT is not set 215# CONFIG_NET_DIVERT is not set
187# CONFIG_ECONET is not set 216# CONFIG_ECONET is not set
188# CONFIG_WAN_ROUTER is not set 217# CONFIG_WAN_ROUTER is not set
218
219#
220# QoS and/or fair queueing
221#
189# CONFIG_NET_SCHED is not set 222# CONFIG_NET_SCHED is not set
190# CONFIG_NET_CLS_ROUTE is not set
191 223
192# 224#
193# Network testing 225# Network testing
@@ -228,6 +260,7 @@ CONFIG_PARPORT_PC=y
228# CONFIG_PARPORT_SERIAL is not set 260# CONFIG_PARPORT_SERIAL is not set
229# CONFIG_PARPORT_PC_FIFO is not set 261# CONFIG_PARPORT_PC_FIFO is not set
230# CONFIG_PARPORT_PC_SUPERIO is not set 262# CONFIG_PARPORT_PC_SUPERIO is not set
263CONFIG_PARPORT_NOT_PC=y
231CONFIG_PARPORT_GSC=y 264CONFIG_PARPORT_GSC=y
232# CONFIG_PARPORT_1284 is not set 265# CONFIG_PARPORT_1284 is not set
233 266
@@ -254,14 +287,6 @@ CONFIG_BLK_DEV_RAM_COUNT=16
254CONFIG_BLK_DEV_RAM_SIZE=4096 287CONFIG_BLK_DEV_RAM_SIZE=4096
255CONFIG_BLK_DEV_INITRD=y 288CONFIG_BLK_DEV_INITRD=y
256# CONFIG_CDROM_PKTCDVD is not set 289# CONFIG_CDROM_PKTCDVD is not set
257
258#
259# IO Schedulers
260#
261CONFIG_IOSCHED_NOOP=y
262CONFIG_IOSCHED_AS=y
263CONFIG_IOSCHED_DEADLINE=y
264CONFIG_IOSCHED_CFQ=y
265# CONFIG_ATA_OVER_ETH is not set 290# CONFIG_ATA_OVER_ETH is not set
266 291
267# 292#
@@ -305,6 +330,7 @@ CONFIG_SCSI_SPI_ATTRS=y
305# 330#
306# SCSI low-level drivers 331# SCSI low-level drivers
307# 332#
333# CONFIG_ISCSI_TCP is not set
308# CONFIG_BLK_DEV_3W_XXXX_RAID is not set 334# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
309# CONFIG_SCSI_3W_9XXX is not set 335# CONFIG_SCSI_3W_9XXX is not set
310# CONFIG_SCSI_ACARD is not set 336# CONFIG_SCSI_ACARD is not set
@@ -331,7 +357,7 @@ CONFIG_SCSI_SYM53C8XX_2=y
331CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=1 357CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=1
332CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16 358CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16
333CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64 359CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64
334# CONFIG_SCSI_SYM53C8XX_IOMAPPED is not set 360CONFIG_SCSI_SYM53C8XX_MMIO=y
335# CONFIG_SCSI_IPR is not set 361# CONFIG_SCSI_IPR is not set
336CONFIG_SCSI_ZALON=y 362CONFIG_SCSI_ZALON=y
337CONFIG_SCSI_NCR53C8XX_DEFAULT_TAGS=8 363CONFIG_SCSI_NCR53C8XX_DEFAULT_TAGS=8
@@ -340,13 +366,7 @@ CONFIG_SCSI_NCR53C8XX_SYNC=20
340# CONFIG_SCSI_NCR53C8XX_PROFILE is not set 366# CONFIG_SCSI_NCR53C8XX_PROFILE is not set
341# CONFIG_SCSI_QLOGIC_FC is not set 367# CONFIG_SCSI_QLOGIC_FC is not set
342# CONFIG_SCSI_QLOGIC_1280 is not set 368# CONFIG_SCSI_QLOGIC_1280 is not set
343CONFIG_SCSI_QLA2XXX=y 369# CONFIG_SCSI_QLA_FC is not set
344# CONFIG_SCSI_QLA21XX is not set
345# CONFIG_SCSI_QLA22XX is not set
346# CONFIG_SCSI_QLA2300 is not set
347# CONFIG_SCSI_QLA2322 is not set
348# CONFIG_SCSI_QLA6312 is not set
349# CONFIG_SCSI_QLA24XX is not set
350# CONFIG_SCSI_LPFC is not set 370# CONFIG_SCSI_LPFC is not set
351# CONFIG_SCSI_SIM710 is not set 371# CONFIG_SCSI_SIM710 is not set
352# CONFIG_SCSI_DC395x is not set 372# CONFIG_SCSI_DC395x is not set
@@ -471,6 +491,7 @@ CONFIG_ACENIC=y
471# CONFIG_R8169 is not set 491# CONFIG_R8169 is not set
472# CONFIG_SIS190 is not set 492# CONFIG_SIS190 is not set
473# CONFIG_SKGE is not set 493# CONFIG_SKGE is not set
494# CONFIG_SKY2 is not set
474# CONFIG_SK98LIN is not set 495# CONFIG_SK98LIN is not set
475# CONFIG_VIA_VELOCITY is not set 496# CONFIG_VIA_VELOCITY is not set
476CONFIG_TIGON3=y 497CONFIG_TIGON3=y
@@ -562,13 +583,13 @@ CONFIG_INPUT_KEYBOARD=y
562# CONFIG_KEYBOARD_LKKBD is not set 583# CONFIG_KEYBOARD_LKKBD is not set
563# CONFIG_KEYBOARD_XTKBD is not set 584# CONFIG_KEYBOARD_XTKBD is not set
564# CONFIG_KEYBOARD_NEWTON is not set 585# CONFIG_KEYBOARD_NEWTON is not set
565CONFIG_KEYBOARD_HIL_OLD=y 586# CONFIG_KEYBOARD_HIL_OLD is not set
566CONFIG_KEYBOARD_HIL=y 587CONFIG_KEYBOARD_HIL=y
567CONFIG_INPUT_MOUSE=y 588CONFIG_INPUT_MOUSE=y
568# CONFIG_MOUSE_PS2 is not set 589# CONFIG_MOUSE_PS2 is not set
569# CONFIG_MOUSE_SERIAL is not set 590# CONFIG_MOUSE_SERIAL is not set
570# CONFIG_MOUSE_VSXXXAA is not set 591# CONFIG_MOUSE_VSXXXAA is not set
571# CONFIG_MOUSE_HIL is not set 592CONFIG_MOUSE_HIL=y
572CONFIG_INPUT_JOYSTICK=y 593CONFIG_INPUT_JOYSTICK=y
573# CONFIG_JOYSTICK_ANALOG is not set 594# CONFIG_JOYSTICK_ANALOG is not set
574# CONFIG_JOYSTICK_A3D is not set 595# CONFIG_JOYSTICK_A3D is not set
@@ -628,6 +649,7 @@ CONFIG_HW_CONSOLE=y
628CONFIG_SERIAL_8250=y 649CONFIG_SERIAL_8250=y
629CONFIG_SERIAL_8250_CONSOLE=y 650CONFIG_SERIAL_8250_CONSOLE=y
630CONFIG_SERIAL_8250_NR_UARTS=13 651CONFIG_SERIAL_8250_NR_UARTS=13
652CONFIG_SERIAL_8250_RUNTIME_UARTS=4
631CONFIG_SERIAL_8250_EXTENDED=y 653CONFIG_SERIAL_8250_EXTENDED=y
632CONFIG_SERIAL_8250_MANY_PORTS=y 654CONFIG_SERIAL_8250_MANY_PORTS=y
633CONFIG_SERIAL_8250_SHARE_IRQ=y 655CONFIG_SERIAL_8250_SHARE_IRQ=y
@@ -675,6 +697,7 @@ CONFIG_GEN_RTC=y
675# TPM devices 697# TPM devices
676# 698#
677# CONFIG_TCG_TPM is not set 699# CONFIG_TCG_TPM is not set
700# CONFIG_TELCLOCK is not set
678 701
679# 702#
680# I2C support 703# I2C support
@@ -682,6 +705,12 @@ CONFIG_GEN_RTC=y
682# CONFIG_I2C is not set 705# CONFIG_I2C is not set
683 706
684# 707#
708# SPI support
709#
710# CONFIG_SPI is not set
711# CONFIG_SPI_MASTER is not set
712
713#
685# Dallas's 1-wire bus 714# Dallas's 1-wire bus
686# 715#
687# CONFIG_W1 is not set 716# CONFIG_W1 is not set
@@ -691,6 +720,7 @@ CONFIG_GEN_RTC=y
691# 720#
692CONFIG_HWMON=y 721CONFIG_HWMON=y
693# CONFIG_HWMON_VID is not set 722# CONFIG_HWMON_VID is not set
723# CONFIG_SENSORS_F71805F is not set
694# CONFIG_HWMON_DEBUG_CHIP is not set 724# CONFIG_HWMON_DEBUG_CHIP is not set
695 725
696# 726#
@@ -718,7 +748,6 @@ CONFIG_FB=y
718CONFIG_FB_CFB_FILLRECT=y 748CONFIG_FB_CFB_FILLRECT=y
719CONFIG_FB_CFB_COPYAREA=y 749CONFIG_FB_CFB_COPYAREA=y
720CONFIG_FB_CFB_IMAGEBLIT=y 750CONFIG_FB_CFB_IMAGEBLIT=y
721CONFIG_FB_SOFT_CURSOR=y
722# CONFIG_FB_MACMODES is not set 751# CONFIG_FB_MACMODES is not set
723# CONFIG_FB_MODE_HELPERS is not set 752# CONFIG_FB_MODE_HELPERS is not set
724# CONFIG_FB_TILEBLITTING is not set 753# CONFIG_FB_TILEBLITTING is not set
@@ -728,6 +757,7 @@ CONFIG_FB_SOFT_CURSOR=y
728# CONFIG_FB_ASILIANT is not set 757# CONFIG_FB_ASILIANT is not set
729# CONFIG_FB_IMSTT is not set 758# CONFIG_FB_IMSTT is not set
730CONFIG_FB_STI=y 759CONFIG_FB_STI=y
760# CONFIG_FB_S1D13XXX is not set
731# CONFIG_FB_NVIDIA is not set 761# CONFIG_FB_NVIDIA is not set
732# CONFIG_FB_RIVA is not set 762# CONFIG_FB_RIVA is not set
733# CONFIG_FB_MATROX is not set 763# CONFIG_FB_MATROX is not set
@@ -741,9 +771,7 @@ CONFIG_FB_STI=y
741# CONFIG_FB_KYRO is not set 771# CONFIG_FB_KYRO is not set
742# CONFIG_FB_3DFX is not set 772# CONFIG_FB_3DFX is not set
743# CONFIG_FB_VOODOO1 is not set 773# CONFIG_FB_VOODOO1 is not set
744# CONFIG_FB_CYBLA is not set
745# CONFIG_FB_TRIDENT is not set 774# CONFIG_FB_TRIDENT is not set
746# CONFIG_FB_S1D13XXX is not set
747# CONFIG_FB_VIRTUAL is not set 775# CONFIG_FB_VIRTUAL is not set
748 776
749# 777#
@@ -753,15 +781,28 @@ CONFIG_DUMMY_CONSOLE=y
753CONFIG_DUMMY_CONSOLE_COLUMNS=160 781CONFIG_DUMMY_CONSOLE_COLUMNS=160
754CONFIG_DUMMY_CONSOLE_ROWS=64 782CONFIG_DUMMY_CONSOLE_ROWS=64
755CONFIG_FRAMEBUFFER_CONSOLE=y 783CONFIG_FRAMEBUFFER_CONSOLE=y
784# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
756CONFIG_STI_CONSOLE=y 785CONFIG_STI_CONSOLE=y
757# CONFIG_FONTS is not set 786CONFIG_FONTS=y
758CONFIG_FONT_8x8=y 787# CONFIG_FONT_8x8 is not set
759CONFIG_FONT_8x16=y 788CONFIG_FONT_8x16=y
789# CONFIG_FONT_6x11 is not set
790# CONFIG_FONT_7x14 is not set
791# CONFIG_FONT_PEARL_8x8 is not set
792# CONFIG_FONT_ACORN_8x8 is not set
793# CONFIG_FONT_MINI_4x6 is not set
794# CONFIG_FONT_SUN8x16 is not set
795# CONFIG_FONT_SUN12x22 is not set
796# CONFIG_FONT_10x18 is not set
760 797
761# 798#
762# Logo configuration 799# Logo configuration
763# 800#
764# CONFIG_LOGO is not set 801CONFIG_LOGO=y
802# CONFIG_LOGO_LINUX_MONO is not set
803# CONFIG_LOGO_LINUX_VGA16 is not set
804# CONFIG_LOGO_LINUX_CLUT224 is not set
805CONFIG_LOGO_PARISC_CLUT224=y
765# CONFIG_BACKLIGHT_LCD_SUPPORT is not set 806# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
766 807
767# 808#
@@ -781,23 +822,27 @@ CONFIG_SND_OSSEMUL=y
781CONFIG_SND_MIXER_OSS=y 822CONFIG_SND_MIXER_OSS=y
782CONFIG_SND_PCM_OSS=y 823CONFIG_SND_PCM_OSS=y
783CONFIG_SND_SEQUENCER_OSS=y 824CONFIG_SND_SEQUENCER_OSS=y
825# CONFIG_SND_DYNAMIC_MINORS is not set
826CONFIG_SND_SUPPORT_OLD_API=y
784# CONFIG_SND_VERBOSE_PRINTK is not set 827# CONFIG_SND_VERBOSE_PRINTK is not set
785# CONFIG_SND_DEBUG is not set 828# CONFIG_SND_DEBUG is not set
786 829
787# 830#
788# Generic devices 831# Generic devices
789# 832#
833CONFIG_SND_AC97_CODEC=y
834CONFIG_SND_AC97_BUS=y
790# CONFIG_SND_DUMMY is not set 835# CONFIG_SND_DUMMY is not set
791# CONFIG_SND_VIRMIDI is not set 836# CONFIG_SND_VIRMIDI is not set
792# CONFIG_SND_MTPAV is not set 837# CONFIG_SND_MTPAV is not set
793# CONFIG_SND_SERIAL_U16550 is not set 838# CONFIG_SND_SERIAL_U16550 is not set
794# CONFIG_SND_MPU401 is not set 839# CONFIG_SND_MPU401 is not set
795CONFIG_SND_AC97_CODEC=y
796CONFIG_SND_AC97_BUS=y
797 840
798# 841#
799# PCI devices 842# PCI devices
800# 843#
844CONFIG_SND_AD1889=y
845# CONFIG_SND_AD1889_OPL3 is not set
801# CONFIG_SND_ALI5451 is not set 846# CONFIG_SND_ALI5451 is not set
802# CONFIG_SND_ATIIXP is not set 847# CONFIG_SND_ATIIXP is not set
803# CONFIG_SND_ATIIXP_MODEM is not set 848# CONFIG_SND_ATIIXP_MODEM is not set
@@ -806,39 +851,38 @@ CONFIG_SND_AC97_BUS=y
806# CONFIG_SND_AU8830 is not set 851# CONFIG_SND_AU8830 is not set
807# CONFIG_SND_AZT3328 is not set 852# CONFIG_SND_AZT3328 is not set
808# CONFIG_SND_BT87X is not set 853# CONFIG_SND_BT87X is not set
809# CONFIG_SND_CS46XX is not set 854# CONFIG_SND_CA0106 is not set
855# CONFIG_SND_CMIPCI is not set
810# CONFIG_SND_CS4281 is not set 856# CONFIG_SND_CS4281 is not set
857# CONFIG_SND_CS46XX is not set
811# CONFIG_SND_EMU10K1 is not set 858# CONFIG_SND_EMU10K1 is not set
812# CONFIG_SND_EMU10K1X is not set 859# CONFIG_SND_EMU10K1X is not set
813# CONFIG_SND_CA0106 is not set
814# CONFIG_SND_KORG1212 is not set
815# CONFIG_SND_MIXART is not set
816# CONFIG_SND_NM256 is not set
817# CONFIG_SND_RME32 is not set
818# CONFIG_SND_RME96 is not set
819# CONFIG_SND_RME9652 is not set
820# CONFIG_SND_HDSP is not set
821# CONFIG_SND_HDSPM is not set
822# CONFIG_SND_TRIDENT is not set
823# CONFIG_SND_YMFPCI is not set
824CONFIG_SND_AD1889=y
825# CONFIG_SND_AD1889_OPL3 is not set
826# CONFIG_SND_CMIPCI is not set
827# CONFIG_SND_ENS1370 is not set 860# CONFIG_SND_ENS1370 is not set
828# CONFIG_SND_ENS1371 is not set 861# CONFIG_SND_ENS1371 is not set
829# CONFIG_SND_ES1938 is not set 862# CONFIG_SND_ES1938 is not set
830# CONFIG_SND_ES1968 is not set 863# CONFIG_SND_ES1968 is not set
831# CONFIG_SND_MAESTRO3 is not set
832# CONFIG_SND_FM801 is not set 864# CONFIG_SND_FM801 is not set
865# CONFIG_SND_HDA_INTEL is not set
866# CONFIG_SND_HDSP is not set
867# CONFIG_SND_HDSPM is not set
833# CONFIG_SND_ICE1712 is not set 868# CONFIG_SND_ICE1712 is not set
834# CONFIG_SND_ICE1724 is not set 869# CONFIG_SND_ICE1724 is not set
835# CONFIG_SND_INTEL8X0 is not set 870# CONFIG_SND_INTEL8X0 is not set
836# CONFIG_SND_INTEL8X0M is not set 871# CONFIG_SND_INTEL8X0M is not set
872# CONFIG_SND_KORG1212 is not set
873# CONFIG_SND_MAESTRO3 is not set
874# CONFIG_SND_MIXART is not set
875# CONFIG_SND_NM256 is not set
876# CONFIG_SND_PCXHR is not set
877# CONFIG_SND_RME32 is not set
878# CONFIG_SND_RME96 is not set
879# CONFIG_SND_RME9652 is not set
837# CONFIG_SND_SONICVIBES is not set 880# CONFIG_SND_SONICVIBES is not set
881# CONFIG_SND_TRIDENT is not set
838# CONFIG_SND_VIA82XX is not set 882# CONFIG_SND_VIA82XX is not set
839# CONFIG_SND_VIA82XX_MODEM is not set 883# CONFIG_SND_VIA82XX_MODEM is not set
840# CONFIG_SND_VX222 is not set 884# CONFIG_SND_VX222 is not set
841# CONFIG_SND_HDA_INTEL is not set 885# CONFIG_SND_YMFPCI is not set
842 886
843# 887#
844# USB devices 888# USB devices
@@ -888,14 +932,18 @@ CONFIG_USB_OHCI_LITTLE_ENDIAN=y
888# USB Device Class drivers 932# USB Device Class drivers
889# 933#
890# CONFIG_OBSOLETE_OSS_USB_DRIVER is not set 934# CONFIG_OBSOLETE_OSS_USB_DRIVER is not set
891# CONFIG_USB_BLUETOOTH_TTY is not set
892# CONFIG_USB_ACM is not set 935# CONFIG_USB_ACM is not set
893# CONFIG_USB_PRINTER is not set 936# CONFIG_USB_PRINTER is not set
894 937
895# 938#
896# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information 939# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
940#
941
942#
943# may also be needed; see USB_STORAGE Help for more information
897# 944#
898# CONFIG_USB_STORAGE is not set 945# CONFIG_USB_STORAGE is not set
946# CONFIG_USB_LIBUSUAL is not set
899 947
900# 948#
901# USB Input Devices 949# USB Input Devices
@@ -918,6 +966,7 @@ CONFIG_USB_OHCI_LITTLE_ENDIAN=y
918# CONFIG_USB_YEALINK is not set 966# CONFIG_USB_YEALINK is not set
919# CONFIG_USB_XPAD is not set 967# CONFIG_USB_XPAD is not set
920# CONFIG_USB_ATI_REMOTE is not set 968# CONFIG_USB_ATI_REMOTE is not set
969# CONFIG_USB_ATI_REMOTE2 is not set
921# CONFIG_USB_KEYSPAN_REMOTE is not set 970# CONFIG_USB_KEYSPAN_REMOTE is not set
922# CONFIG_USB_APPLETOUCH is not set 971# CONFIG_USB_APPLETOUCH is not set
923 972
@@ -994,7 +1043,7 @@ CONFIG_USB_MON=y
994# CONFIG_INFINIBAND is not set 1043# CONFIG_INFINIBAND is not set
995 1044
996# 1045#
997# SN Devices 1046# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
998# 1047#
999 1048
1000# 1049#
@@ -1011,6 +1060,7 @@ CONFIG_JBD=y
1011# CONFIG_JFS_FS is not set 1060# CONFIG_JFS_FS is not set
1012# CONFIG_FS_POSIX_ACL is not set 1061# CONFIG_FS_POSIX_ACL is not set
1013# CONFIG_XFS_FS is not set 1062# CONFIG_XFS_FS is not set
1063# CONFIG_OCFS2_FS is not set
1014# CONFIG_MINIX_FS is not set 1064# CONFIG_MINIX_FS is not set
1015# CONFIG_ROMFS_FS is not set 1065# CONFIG_ROMFS_FS is not set
1016CONFIG_INOTIFY=y 1066CONFIG_INOTIFY=y
@@ -1045,6 +1095,7 @@ CONFIG_TMPFS=y
1045# CONFIG_HUGETLB_PAGE is not set 1095# CONFIG_HUGETLB_PAGE is not set
1046CONFIG_RAMFS=y 1096CONFIG_RAMFS=y
1047# CONFIG_RELAYFS_FS is not set 1097# CONFIG_RELAYFS_FS is not set
1098# CONFIG_CONFIGFS_FS is not set
1048 1099
1049# 1100#
1050# Miscellaneous filesystems 1101# Miscellaneous filesystems
@@ -1151,18 +1202,22 @@ CONFIG_OPROFILE=y
1151# Kernel hacking 1202# Kernel hacking
1152# 1203#
1153# CONFIG_PRINTK_TIME is not set 1204# CONFIG_PRINTK_TIME is not set
1154CONFIG_DEBUG_KERNEL=y
1155CONFIG_MAGIC_SYSRQ=y 1205CONFIG_MAGIC_SYSRQ=y
1206CONFIG_DEBUG_KERNEL=y
1156CONFIG_LOG_BUF_SHIFT=15 1207CONFIG_LOG_BUF_SHIFT=15
1157CONFIG_DETECT_SOFTLOCKUP=y 1208CONFIG_DETECT_SOFTLOCKUP=y
1158# CONFIG_SCHEDSTATS is not set 1209# CONFIG_SCHEDSTATS is not set
1159# CONFIG_DEBUG_SLAB is not set 1210# CONFIG_DEBUG_SLAB is not set
1211CONFIG_DEBUG_MUTEXES=y
1160# CONFIG_DEBUG_SPINLOCK is not set 1212# CONFIG_DEBUG_SPINLOCK is not set
1161# CONFIG_DEBUG_SPINLOCK_SLEEP is not set 1213# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
1162# CONFIG_DEBUG_KOBJECT is not set 1214# CONFIG_DEBUG_KOBJECT is not set
1163# CONFIG_DEBUG_INFO is not set 1215# CONFIG_DEBUG_INFO is not set
1164# CONFIG_DEBUG_IOREMAP is not set
1165# CONFIG_DEBUG_FS is not set 1216# CONFIG_DEBUG_FS is not set
1217# CONFIG_DEBUG_VM is not set
1218CONFIG_FORCED_INLINING=y
1219# CONFIG_RCU_TORTURE_TEST is not set
1220CONFIG_DEBUG_RODATA=y
1166 1221
1167# 1222#
1168# Security options 1223# Security options
diff --git a/arch/parisc/kernel/cache.c b/arch/parisc/kernel/cache.c
index d8a4ca021aac..360b7391cb8c 100644
--- a/arch/parisc/kernel/cache.c
+++ b/arch/parisc/kernel/cache.c
@@ -89,7 +89,7 @@ update_mmu_cache(struct vm_area_struct *vma, unsigned long address, pte_t pte)
89 if (pfn_valid(page_to_pfn(page)) && page_mapping(page) && 89 if (pfn_valid(page_to_pfn(page)) && page_mapping(page) &&
90 test_bit(PG_dcache_dirty, &page->flags)) { 90 test_bit(PG_dcache_dirty, &page->flags)) {
91 91
92 flush_kernel_dcache_page(page_address(page)); 92 flush_kernel_dcache_page(page);
93 clear_bit(PG_dcache_dirty, &page->flags); 93 clear_bit(PG_dcache_dirty, &page->flags);
94 } 94 }
95} 95}
@@ -278,7 +278,7 @@ void flush_dcache_page(struct page *page)
278 return; 278 return;
279 } 279 }
280 280
281 flush_kernel_dcache_page(page_address(page)); 281 flush_kernel_dcache_page(page);
282 282
283 if (!mapping) 283 if (!mapping)
284 return; 284 return;
@@ -317,7 +317,7 @@ EXPORT_SYMBOL(flush_dcache_page);
317 317
318/* Defined in arch/parisc/kernel/pacache.S */ 318/* Defined in arch/parisc/kernel/pacache.S */
319EXPORT_SYMBOL(flush_kernel_dcache_range_asm); 319EXPORT_SYMBOL(flush_kernel_dcache_range_asm);
320EXPORT_SYMBOL(flush_kernel_dcache_page); 320EXPORT_SYMBOL(flush_kernel_dcache_page_asm);
321EXPORT_SYMBOL(flush_data_cache_local); 321EXPORT_SYMBOL(flush_data_cache_local);
322EXPORT_SYMBOL(flush_kernel_icache_range_asm); 322EXPORT_SYMBOL(flush_kernel_icache_range_asm);
323 323
diff --git a/arch/parisc/kernel/entry.S b/arch/parisc/kernel/entry.S
index 9af4b22a6d77..7c95d7663c29 100644
--- a/arch/parisc/kernel/entry.S
+++ b/arch/parisc/kernel/entry.S
@@ -563,10 +563,10 @@
563 extrd,u,*= \pte,_PAGE_GATEWAY_BIT+32,1,%r0 563 extrd,u,*= \pte,_PAGE_GATEWAY_BIT+32,1,%r0
564 depd %r0,11,2,\prot /* If Gateway, Set PL2 to 0 */ 564 depd %r0,11,2,\prot /* If Gateway, Set PL2 to 0 */
565 565
566 /* Get rid of prot bits and convert to page addr for iitlbt */ 566 /* Get rid of prot bits and convert to page addr for iitlbt and idtlbt */
567 567
568 depd %r0,63,PAGE_SHIFT,\pte 568 depd %r0,63,PAGE_SHIFT,\pte
569 extrd,u \pte,56,32,\pte 569 extrd,s \pte,(63-PAGE_SHIFT)+(63-58),64-PAGE_SHIFT,\pte
570 .endm 570 .endm
571 571
572 /* Identical macro to make_insert_tlb above, except it 572 /* Identical macro to make_insert_tlb above, except it
@@ -584,7 +584,7 @@
584 584
585 /* Get rid of prot bits and convert to page addr for iitlba */ 585 /* Get rid of prot bits and convert to page addr for iitlba */
586 586
587 depi 0,31,12,\pte 587 depi 0,31,PAGE_SHIFT,\pte
588 extru \pte,24,25,\pte 588 extru \pte,24,25,\pte
589 589
590 .endm 590 .endm
@@ -1014,14 +1014,21 @@ intr_restore:
1014 nop 1014 nop
1015 nop 1015 nop
1016 1016
1017#ifndef CONFIG_PREEMPT
1018# define intr_do_preempt intr_restore
1019#endif /* !CONFIG_PREEMPT */
1020
1017 .import schedule,code 1021 .import schedule,code
1018intr_do_resched: 1022intr_do_resched:
1019 /* Only do reschedule if we are returning to user space */ 1023 /* Only call schedule on return to userspace. If we're returning
1024 * to kernel space, we may schedule if CONFIG_PREEMPT, otherwise
1025 * we jump back to intr_restore.
1026 */
1020 LDREG PT_IASQ0(%r16), %r20 1027 LDREG PT_IASQ0(%r16), %r20
1021 CMPIB= 0,%r20,intr_restore /* backward */ 1028 CMPIB= 0, %r20, intr_do_preempt
1022 nop 1029 nop
1023 LDREG PT_IASQ1(%r16), %r20 1030 LDREG PT_IASQ1(%r16), %r20
1024 CMPIB= 0,%r20,intr_restore /* backward */ 1031 CMPIB= 0, %r20, intr_do_preempt
1025 nop 1032 nop
1026 1033
1027#ifdef CONFIG_64BIT 1034#ifdef CONFIG_64BIT
@@ -1037,6 +1044,32 @@ intr_do_resched:
1037#endif 1044#endif
1038 ldo R%intr_check_sig(%r2), %r2 1045 ldo R%intr_check_sig(%r2), %r2
1039 1046
1047 /* preempt the current task on returning to kernel
1048 * mode from an interrupt, iff need_resched is set,
1049 * and preempt_count is 0. otherwise, we continue on
1050 * our merry way back to the current running task.
1051 */
1052#ifdef CONFIG_PREEMPT
1053 .import preempt_schedule_irq,code
1054intr_do_preempt:
1055 rsm PSW_SM_I, %r0 /* disable interrupts */
1056
1057 /* current_thread_info()->preempt_count */
1058 mfctl %cr30, %r1
1059 LDREG TI_PRE_COUNT(%r1), %r19
1060 CMPIB<> 0, %r19, intr_restore /* if preempt_count > 0 */
1061 nop /* prev insn branched backwards */
1062
1063 /* check if we interrupted a critical path */
1064 LDREG PT_PSW(%r16), %r20
1065 bb,<,n %r20, 31 - PSW_SM_I, intr_restore
1066 nop
1067
1068 BL preempt_schedule_irq, %r2
1069 nop
1070
1071 b intr_restore /* ssm PSW_SM_I done by intr_restore */
1072#endif /* CONFIG_PREEMPT */
1040 1073
1041 .import do_signal,code 1074 .import do_signal,code
1042intr_do_signal: 1075intr_do_signal:
diff --git a/arch/parisc/kernel/pacache.S b/arch/parisc/kernel/pacache.S
index 9534ee17b9be..7a4f07e8d3c3 100644
--- a/arch/parisc/kernel/pacache.S
+++ b/arch/parisc/kernel/pacache.S
@@ -621,9 +621,9 @@ __clear_user_page_asm:
621 621
622 .procend 622 .procend
623 623
624 .export flush_kernel_dcache_page 624 .export flush_kernel_dcache_page_asm
625 625
626flush_kernel_dcache_page: 626flush_kernel_dcache_page_asm:
627 .proc 627 .proc
628 .callinfo NO_CALLS 628 .callinfo NO_CALLS
629 .entry 629 .entry
diff --git a/arch/parisc/kernel/parisc_ksyms.c b/arch/parisc/kernel/parisc_ksyms.c
index 1d00c365f2b1..47ca5c0a323b 100644
--- a/arch/parisc/kernel/parisc_ksyms.c
+++ b/arch/parisc/kernel/parisc_ksyms.c
@@ -30,22 +30,7 @@
30#include <linux/syscalls.h> 30#include <linux/syscalls.h>
31 31
32#include <linux/string.h> 32#include <linux/string.h>
33EXPORT_SYMBOL(memchr);
34EXPORT_SYMBOL(memcmp);
35EXPORT_SYMBOL(memmove);
36EXPORT_SYMBOL(memscan);
37EXPORT_SYMBOL(memset); 33EXPORT_SYMBOL(memset);
38EXPORT_SYMBOL(strcat);
39EXPORT_SYMBOL(strchr);
40EXPORT_SYMBOL(strcmp);
41EXPORT_SYMBOL(strcpy);
42EXPORT_SYMBOL(strlen);
43EXPORT_SYMBOL(strncat);
44EXPORT_SYMBOL(strncmp);
45EXPORT_SYMBOL(strncpy);
46EXPORT_SYMBOL(strnlen);
47EXPORT_SYMBOL(strrchr);
48EXPORT_SYMBOL(strstr);
49EXPORT_SYMBOL(strpbrk); 34EXPORT_SYMBOL(strpbrk);
50 35
51#include <asm/atomic.h> 36#include <asm/atomic.h>
@@ -82,16 +67,12 @@ EXPORT_SYMBOL($global$);
82#endif 67#endif
83 68
84#include <asm/io.h> 69#include <asm/io.h>
85EXPORT_SYMBOL(__ioremap);
86EXPORT_SYMBOL(iounmap);
87EXPORT_SYMBOL(memcpy_toio); 70EXPORT_SYMBOL(memcpy_toio);
88EXPORT_SYMBOL(memcpy_fromio); 71EXPORT_SYMBOL(memcpy_fromio);
89EXPORT_SYMBOL(memset_io); 72EXPORT_SYMBOL(memset_io);
90 73
91#include <asm/unistd.h> 74#include <asm/unistd.h>
92EXPORT_SYMBOL(sys_open);
93EXPORT_SYMBOL(sys_lseek); 75EXPORT_SYMBOL(sys_lseek);
94EXPORT_SYMBOL(sys_read);
95EXPORT_SYMBOL(sys_write); 76EXPORT_SYMBOL(sys_write);
96 77
97#include <asm/semaphore.h> 78#include <asm/semaphore.h>
diff --git a/arch/parisc/kernel/pdc_chassis.c b/arch/parisc/kernel/pdc_chassis.c
index 0cea6958f427..a45e2e2ffd9f 100644
--- a/arch/parisc/kernel/pdc_chassis.c
+++ b/arch/parisc/kernel/pdc_chassis.c
@@ -5,9 +5,8 @@
5 * Copyright (C) 2002-2004 Thibaut VARENE <varenet@parisc-linux.org> 5 * Copyright (C) 2002-2004 Thibaut VARENE <varenet@parisc-linux.org>
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by 8 * it under the terms of the GNU General Public License, version 2, as
9 * the Free Software Foundation; either version 2 of the License, or 9 * published by the Free Software Foundation.
10 * (at your option) any later version.
11 * 10 *
12 * This program is distributed in the hope that it will be useful, 11 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
diff --git a/arch/parisc/kernel/perf.c b/arch/parisc/kernel/perf.c
index 53f861c82f93..ac8ee205c351 100644
--- a/arch/parisc/kernel/perf.c
+++ b/arch/parisc/kernel/perf.c
@@ -805,7 +805,7 @@ static int perf_write_image(uint64_t *memaddr)
805 return -1; 805 return -1;
806 } 806 }
807 807
808 runway = ioremap(cpu_device->hpa.start, 4096); 808 runway = ioremap_nocache(cpu_device->hpa.start, 4096);
809 809
810 /* Merge intrigue bits into Runway STATUS 0 */ 810 /* Merge intrigue bits into Runway STATUS 0 */
811 tmp64 = __raw_readq(runway + RUNWAY_STATUS) & 0xffecfffffffffffful; 811 tmp64 = __raw_readq(runway + RUNWAY_STATUS) & 0xffecfffffffffffful;
diff --git a/arch/parisc/kernel/syscall_table.S b/arch/parisc/kernel/syscall_table.S
index 89b6c56ea0a8..bbeeb614cfab 100644
--- a/arch/parisc/kernel/syscall_table.S
+++ b/arch/parisc/kernel/syscall_table.S
@@ -287,7 +287,7 @@
287 ENTRY_SAME(chown) /* 180 */ 287 ENTRY_SAME(chown) /* 180 */
288 /* setsockopt() used by iptables: SO_SET_REPLACE/SO_SET_ADD_COUNTERS */ 288 /* setsockopt() used by iptables: SO_SET_REPLACE/SO_SET_ADD_COUNTERS */
289 ENTRY_COMP(setsockopt) 289 ENTRY_COMP(setsockopt)
290 ENTRY_SAME(getsockopt) 290 ENTRY_COMP(getsockopt)
291 ENTRY_COMP(sendmsg) 291 ENTRY_COMP(sendmsg)
292 ENTRY_COMP(recvmsg) 292 ENTRY_COMP(recvmsg)
293 ENTRY_SAME(semop) /* 185 */ 293 ENTRY_SAME(semop) /* 185 */
diff --git a/arch/parisc/lib/iomap.c b/arch/parisc/lib/iomap.c
index 01bec8fcbd0d..f4a811690ab3 100644
--- a/arch/parisc/lib/iomap.c
+++ b/arch/parisc/lib/iomap.c
@@ -263,11 +263,7 @@ static const struct iomap_ops iomem_ops = {
263 263
264const struct iomap_ops *iomap_ops[8] = { 264const struct iomap_ops *iomap_ops[8] = {
265 [0] = &ioport_ops, 265 [0] = &ioport_ops,
266#ifdef CONFIG_DEBUG_IOREMAP
267 [6] = &iomem_ops,
268#else
269 [7] = &iomem_ops 266 [7] = &iomem_ops
270#endif
271}; 267};
272 268
273 269
diff --git a/arch/parisc/mm/init.c b/arch/parisc/mm/init.c
index 852eda3953dc..3796be67cd53 100644
--- a/arch/parisc/mm/init.c
+++ b/arch/parisc/mm/init.c
@@ -1013,9 +1013,9 @@ void flush_tlb_all(void)
1013#ifdef CONFIG_BLK_DEV_INITRD 1013#ifdef CONFIG_BLK_DEV_INITRD
1014void free_initrd_mem(unsigned long start, unsigned long end) 1014void free_initrd_mem(unsigned long start, unsigned long end)
1015{ 1015{
1016#if 0 1016 if (start >= end)
1017 if (start < end) 1017 return;
1018 printk(KERN_INFO "Freeing initrd memory: %ldk freed\n", (end - start) >> 10); 1018 printk(KERN_INFO "Freeing initrd memory: %ldk freed\n", (end - start) >> 10);
1019 for (; start < end; start += PAGE_SIZE) { 1019 for (; start < end; start += PAGE_SIZE) {
1020 ClearPageReserved(virt_to_page(start)); 1020 ClearPageReserved(virt_to_page(start));
1021 init_page_count(virt_to_page(start)); 1021 init_page_count(virt_to_page(start));
@@ -1023,6 +1023,5 @@ void free_initrd_mem(unsigned long start, unsigned long end)
1023 num_physpages++; 1023 num_physpages++;
1024 totalram_pages++; 1024 totalram_pages++;
1025 } 1025 }
1026#endif
1027} 1026}
1028#endif 1027#endif
diff --git a/arch/parisc/mm/ioremap.c b/arch/parisc/mm/ioremap.c
index edd9a9559cba..0db12818d7bc 100644
--- a/arch/parisc/mm/ioremap.c
+++ b/arch/parisc/mm/ioremap.c
@@ -72,7 +72,6 @@ remap_area_pmd(pmd_t *pmd, unsigned long address, unsigned long size,
72 return 0; 72 return 0;
73} 73}
74 74
75#if USE_HPPA_IOREMAP
76static int 75static int
77remap_area_pages(unsigned long address, unsigned long phys_addr, 76remap_area_pages(unsigned long address, unsigned long phys_addr,
78 unsigned long size, unsigned long flags) 77 unsigned long size, unsigned long flags)
@@ -114,31 +113,6 @@ remap_area_pages(unsigned long address, unsigned long phys_addr,
114 113
115 return error; 114 return error;
116} 115}
117#endif /* USE_HPPA_IOREMAP */
118
119#ifdef CONFIG_DEBUG_IOREMAP
120static unsigned long last = 0;
121
122void gsc_bad_addr(unsigned long addr)
123{
124 if (time_after(jiffies, last + HZ*10)) {
125 printk("gsc_foo() called with bad address 0x%lx\n", addr);
126 dump_stack();
127 last = jiffies;
128 }
129}
130EXPORT_SYMBOL(gsc_bad_addr);
131
132void __raw_bad_addr(const volatile void __iomem *addr)
133{
134 if (time_after(jiffies, last + HZ*10)) {
135 printk("__raw_foo() called with bad address 0x%p\n", addr);
136 dump_stack();
137 last = jiffies;
138 }
139}
140EXPORT_SYMBOL(__raw_bad_addr);
141#endif
142 116
143/* 117/*
144 * Generic mapping function (not visible outside): 118 * Generic mapping function (not visible outside):
@@ -154,26 +128,19 @@ EXPORT_SYMBOL(__raw_bad_addr);
154 */ 128 */
155void __iomem * __ioremap(unsigned long phys_addr, unsigned long size, unsigned long flags) 129void __iomem * __ioremap(unsigned long phys_addr, unsigned long size, unsigned long flags)
156{ 130{
157#if !(USE_HPPA_IOREMAP) 131 void *addr;
132 struct vm_struct *area;
133 unsigned long offset, last_addr;
158 134
135#ifdef CONFIG_EISA
159 unsigned long end = phys_addr + size - 1; 136 unsigned long end = phys_addr + size - 1;
160 /* Support EISA addresses */ 137 /* Support EISA addresses */
161 if ((phys_addr >= 0x00080000 && end < 0x000fffff) 138 if ((phys_addr >= 0x00080000 && end < 0x000fffff) ||
162 || (phys_addr >= 0x00500000 && end < 0x03bfffff)) { 139 (phys_addr >= 0x00500000 && end < 0x03bfffff)) {
163 phys_addr |= 0xfc000000; 140 phys_addr |= F_EXTEND(0xfc000000);
164 } 141 }
165
166#ifdef CONFIG_DEBUG_IOREMAP
167 return (void __iomem *)(phys_addr - (0x1UL << NYBBLE_SHIFT));
168#else
169 return (void __iomem *)phys_addr;
170#endif 142#endif
171 143
172#else
173 void *addr;
174 struct vm_struct *area;
175 unsigned long offset, last_addr;
176
177 /* Don't allow wraparound or zero size */ 144 /* Don't allow wraparound or zero size */
178 last_addr = phys_addr + size - 1; 145 last_addr = phys_addr + size - 1;
179 if (!size || last_addr < phys_addr) 146 if (!size || last_addr < phys_addr)
@@ -217,15 +184,12 @@ void __iomem * __ioremap(unsigned long phys_addr, unsigned long size, unsigned l
217 } 184 }
218 185
219 return (void __iomem *) (offset + (char *)addr); 186 return (void __iomem *) (offset + (char *)addr);
220#endif
221} 187}
188EXPORT_SYMBOL(__ioremap);
222 189
223void iounmap(void __iomem *addr) 190void iounmap(void __iomem *addr)
224{ 191{
225#if !(USE_HPPA_IOREMAP)
226 return;
227#else
228 if (addr > high_memory) 192 if (addr > high_memory)
229 return vfree((void *) (PAGE_MASK & (unsigned long __force) addr)); 193 return vfree((void *) (PAGE_MASK & (unsigned long __force) addr));
230#endif
231} 194}
195EXPORT_SYMBOL(iounmap);
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index a433b7126d33..2cdc35ce8045 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -491,7 +491,7 @@ config PPC601_SYNC_FIX
491 If in doubt, say Y here. 491 If in doubt, say Y here.
492 492
493config TAU 493config TAU
494 bool "Thermal Management Support" 494 bool "On-chip CPU temperature sensor support"
495 depends on 6xx 495 depends on 6xx
496 help 496 help
497 G3 and G4 processors have an on-chip temperature sensor called the 497 G3 and G4 processors have an on-chip temperature sensor called the
@@ -500,7 +500,7 @@ config TAU
500 on-die temperature in /proc/cpuinfo if the cpu supports it. 500 on-die temperature in /proc/cpuinfo if the cpu supports it.
501 501
502 Unfortunately, on some chip revisions, this sensor is very inaccurate 502 Unfortunately, on some chip revisions, this sensor is very inaccurate
503 and in some cases, does not work at all, so don't assume the cpu 503 and in many cases, does not work at all, so don't assume the cpu
504 temp is actually what /proc/cpuinfo says it is. 504 temp is actually what /proc/cpuinfo says it is.
505 505
506config TAU_INT 506config TAU_INT
diff --git a/arch/powerpc/Kconfig.debug b/arch/powerpc/Kconfig.debug
index 9254806f7032..8d48e9e7162a 100644
--- a/arch/powerpc/Kconfig.debug
+++ b/arch/powerpc/Kconfig.debug
@@ -110,11 +110,6 @@ config SERIAL_TEXT_DEBUG
110 depends on 4xx || LOPEC || MV64X60 || PPLUS || PRPMC800 || \ 110 depends on 4xx || LOPEC || MV64X60 || PPLUS || PRPMC800 || \
111 PPC_GEN550 || PPC_MPC52xx 111 PPC_GEN550 || PPC_MPC52xx
112 112
113config PPC_OCP
114 bool
115 depends on IBM_OCP || XILINX_OCP
116 default y
117
118choice 113choice
119 prompt "Early debugging (dangerous)" 114 prompt "Early debugging (dangerous)"
120 bool 115 bool
diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile
index 829e017b8a54..6ec84d37a337 100644
--- a/arch/powerpc/Makefile
+++ b/arch/powerpc/Makefile
@@ -129,13 +129,8 @@ core-y += arch/powerpc/kernel/ \
129 arch/powerpc/lib/ \ 129 arch/powerpc/lib/ \
130 arch/powerpc/sysdev/ \ 130 arch/powerpc/sysdev/ \
131 arch/powerpc/platforms/ 131 arch/powerpc/platforms/
132core-$(CONFIG_PPC32) += arch/ppc/kernel/ 132core-$(CONFIG_MATH_EMULATION) += arch/powerpc/math-emu/
133core-$(CONFIG_MATH_EMULATION) += arch/ppc/math-emu/
134core-$(CONFIG_XMON) += arch/powerpc/xmon/ 133core-$(CONFIG_XMON) += arch/powerpc/xmon/
135core-$(CONFIG_APUS) += arch/ppc/amiga/
136drivers-$(CONFIG_8xx) += arch/ppc/8xx_io/
137drivers-$(CONFIG_4xx) += arch/ppc/4xx_io/
138drivers-$(CONFIG_CPM2) += arch/ppc/8260_io/
139 134
140drivers-$(CONFIG_OPROFILE) += arch/powerpc/oprofile/ 135drivers-$(CONFIG_OPROFILE) += arch/powerpc/oprofile/
141 136
diff --git a/arch/powerpc/configs/cell_defconfig b/arch/powerpc/configs/cell_defconfig
index 3c2acab63736..fe22e54ab2b0 100644
--- a/arch/powerpc/configs/cell_defconfig
+++ b/arch/powerpc/configs/cell_defconfig
@@ -1,7 +1,7 @@
1# 1#
2# Automatically generated make config: don't edit 2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.16-rc6 3# Linux kernel version: 2.6.16
4# Wed Mar 15 16:19:48 2006 4# Thu Mar 23 20:48:09 2006
5# 5#
6CONFIG_PPC64=y 6CONFIG_PPC64=y
7CONFIG_64BIT=y 7CONFIG_64BIT=y
@@ -30,6 +30,7 @@ CONFIG_POWER4=y
30CONFIG_PPC_FPU=y 30CONFIG_PPC_FPU=y
31CONFIG_ALTIVEC=y 31CONFIG_ALTIVEC=y
32CONFIG_PPC_STD_MMU=y 32CONFIG_PPC_STD_MMU=y
33CONFIG_VIRT_CPU_ACCOUNTING=y
33CONFIG_SMP=y 34CONFIG_SMP=y
34CONFIG_NR_CPUS=4 35CONFIG_NR_CPUS=4
35 36
@@ -51,7 +52,8 @@ CONFIG_SYSVIPC=y
51# CONFIG_BSD_PROCESS_ACCT is not set 52# CONFIG_BSD_PROCESS_ACCT is not set
52CONFIG_SYSCTL=y 53CONFIG_SYSCTL=y
53# CONFIG_AUDIT is not set 54# CONFIG_AUDIT is not set
54# CONFIG_IKCONFIG is not set 55CONFIG_IKCONFIG=y
56CONFIG_IKCONFIG_PROC=y
55# CONFIG_CPUSETS is not set 57# CONFIG_CPUSETS is not set
56CONFIG_INITRAMFS_SOURCE="" 58CONFIG_INITRAMFS_SOURCE=""
57CONFIG_CC_OPTIMIZE_FOR_SIZE=y 59CONFIG_CC_OPTIMIZE_FOR_SIZE=y
@@ -85,7 +87,7 @@ CONFIG_MODULE_UNLOAD=y
85CONFIG_OBSOLETE_MODPARM=y 87CONFIG_OBSOLETE_MODPARM=y
86# CONFIG_MODVERSIONS is not set 88# CONFIG_MODVERSIONS is not set
87# CONFIG_MODULE_SRCVERSION_ALL is not set 89# CONFIG_MODULE_SRCVERSION_ALL is not set
88# CONFIG_KMOD is not set 90CONFIG_KMOD=y
89CONFIG_STOP_MACHINE=y 91CONFIG_STOP_MACHINE=y
90 92
91# 93#
@@ -130,7 +132,8 @@ CONFIG_CELL_IIC=y
130# 132#
131# Cell Broadband Engine options 133# Cell Broadband Engine options
132# 134#
133CONFIG_SPU_FS=y 135CONFIG_SPU_FS=m
136CONFIG_SPUFS_MMAP=y
134 137
135# 138#
136# Kernel options 139# Kernel options
@@ -144,7 +147,7 @@ CONFIG_PREEMPT_NONE=y
144# CONFIG_PREEMPT is not set 147# CONFIG_PREEMPT is not set
145CONFIG_PREEMPT_BKL=y 148CONFIG_PREEMPT_BKL=y
146CONFIG_BINFMT_ELF=y 149CONFIG_BINFMT_ELF=y
147# CONFIG_BINFMT_MISC is not set 150CONFIG_BINFMT_MISC=m
148CONFIG_FORCE_MAX_ZONEORDER=13 151CONFIG_FORCE_MAX_ZONEORDER=13
149# CONFIG_IOMMU_VMERGE is not set 152# CONFIG_IOMMU_VMERGE is not set
150CONFIG_KEXEC=y 153CONFIG_KEXEC=y
@@ -155,13 +158,16 @@ CONFIG_ARCH_SELECT_MEMORY_MODEL=y
155CONFIG_ARCH_FLATMEM_ENABLE=y 158CONFIG_ARCH_FLATMEM_ENABLE=y
156CONFIG_ARCH_SPARSEMEM_ENABLE=y 159CONFIG_ARCH_SPARSEMEM_ENABLE=y
157CONFIG_SELECT_MEMORY_MODEL=y 160CONFIG_SELECT_MEMORY_MODEL=y
158CONFIG_FLATMEM_MANUAL=y 161# CONFIG_FLATMEM_MANUAL is not set
159# CONFIG_DISCONTIGMEM_MANUAL is not set 162# CONFIG_DISCONTIGMEM_MANUAL is not set
160# CONFIG_SPARSEMEM_MANUAL is not set 163CONFIG_SPARSEMEM_MANUAL=y
161CONFIG_FLATMEM=y 164CONFIG_SPARSEMEM=y
162CONFIG_FLAT_NODE_MEM_MAP=y 165CONFIG_HAVE_MEMORY_PRESENT=y
163# CONFIG_SPARSEMEM_STATIC is not set 166# CONFIG_SPARSEMEM_STATIC is not set
167CONFIG_SPARSEMEM_EXTREME=y
168# CONFIG_MEMORY_HOTPLUG is not set
164CONFIG_SPLIT_PTLOCK_CPUS=4 169CONFIG_SPLIT_PTLOCK_CPUS=4
170CONFIG_MIGRATION=y
165# CONFIG_PPC_64K_PAGES is not set 171# CONFIG_PPC_64K_PAGES is not set
166CONFIG_SCHED_SMT=y 172CONFIG_SCHED_SMT=y
167CONFIG_PROC_DEVICETREE=y 173CONFIG_PROC_DEVICETREE=y
@@ -232,6 +238,7 @@ CONFIG_TCP_CONG_BIC=y
232# CONFIG_IP_VS is not set 238# CONFIG_IP_VS is not set
233CONFIG_IPV6=y 239CONFIG_IPV6=y
234# CONFIG_IPV6_PRIVACY is not set 240# CONFIG_IPV6_PRIVACY is not set
241# CONFIG_IPV6_ROUTER_PREF is not set
235CONFIG_INET6_AH=m 242CONFIG_INET6_AH=m
236CONFIG_INET6_ESP=m 243CONFIG_INET6_ESP=m
237CONFIG_INET6_IPCOMP=m 244CONFIG_INET6_IPCOMP=m
@@ -244,25 +251,7 @@ CONFIG_NETFILTER=y
244# Core Netfilter Configuration 251# Core Netfilter Configuration
245# 252#
246# CONFIG_NETFILTER_NETLINK is not set 253# CONFIG_NETFILTER_NETLINK is not set
247CONFIG_NETFILTER_XTABLES=m 254# CONFIG_NETFILTER_XTABLES is not set
248CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
249CONFIG_NETFILTER_XT_TARGET_MARK=m
250CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
251CONFIG_NETFILTER_XT_TARGET_NOTRACK=m
252CONFIG_NETFILTER_XT_MATCH_COMMENT=m
253CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
254# CONFIG_NETFILTER_XT_MATCH_DCCP is not set
255CONFIG_NETFILTER_XT_MATCH_HELPER=m
256CONFIG_NETFILTER_XT_MATCH_LENGTH=m
257CONFIG_NETFILTER_XT_MATCH_LIMIT=m
258CONFIG_NETFILTER_XT_MATCH_MAC=m
259CONFIG_NETFILTER_XT_MATCH_MARK=m
260CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m
261CONFIG_NETFILTER_XT_MATCH_REALM=m
262CONFIG_NETFILTER_XT_MATCH_SCTP=m
263CONFIG_NETFILTER_XT_MATCH_STATE=m
264CONFIG_NETFILTER_XT_MATCH_STRING=m
265CONFIG_NETFILTER_XT_MATCH_TCPMSS=m
266 255
267# 256#
268# IP: Netfilter Configuration 257# IP: Netfilter Configuration
@@ -278,51 +267,13 @@ CONFIG_IP_NF_IRC=m
278CONFIG_IP_NF_TFTP=m 267CONFIG_IP_NF_TFTP=m
279CONFIG_IP_NF_AMANDA=m 268CONFIG_IP_NF_AMANDA=m
280# CONFIG_IP_NF_PPTP is not set 269# CONFIG_IP_NF_PPTP is not set
270# CONFIG_IP_NF_H323 is not set
281CONFIG_IP_NF_QUEUE=m 271CONFIG_IP_NF_QUEUE=m
282CONFIG_IP_NF_IPTABLES=m
283CONFIG_IP_NF_MATCH_IPRANGE=m
284CONFIG_IP_NF_MATCH_MULTIPORT=m
285CONFIG_IP_NF_MATCH_TOS=m
286CONFIG_IP_NF_MATCH_RECENT=m
287CONFIG_IP_NF_MATCH_ECN=m
288CONFIG_IP_NF_MATCH_DSCP=m
289CONFIG_IP_NF_MATCH_AH_ESP=m
290CONFIG_IP_NF_MATCH_TTL=m
291CONFIG_IP_NF_MATCH_OWNER=m
292CONFIG_IP_NF_MATCH_ADDRTYPE=m
293CONFIG_IP_NF_MATCH_HASHLIMIT=m
294CONFIG_IP_NF_MATCH_POLICY=m
295CONFIG_IP_NF_FILTER=m
296CONFIG_IP_NF_TARGET_REJECT=m
297CONFIG_IP_NF_TARGET_LOG=m
298CONFIG_IP_NF_TARGET_ULOG=m
299CONFIG_IP_NF_TARGET_TCPMSS=m
300CONFIG_IP_NF_NAT=m
301CONFIG_IP_NF_NAT_NEEDED=y
302CONFIG_IP_NF_TARGET_MASQUERADE=m
303CONFIG_IP_NF_TARGET_REDIRECT=m
304CONFIG_IP_NF_TARGET_NETMAP=m
305CONFIG_IP_NF_TARGET_SAME=m
306CONFIG_IP_NF_NAT_SNMP_BASIC=m
307CONFIG_IP_NF_NAT_IRC=m
308CONFIG_IP_NF_NAT_FTP=m
309CONFIG_IP_NF_NAT_TFTP=m
310CONFIG_IP_NF_NAT_AMANDA=m
311CONFIG_IP_NF_MANGLE=m
312CONFIG_IP_NF_TARGET_TOS=m
313CONFIG_IP_NF_TARGET_ECN=m
314CONFIG_IP_NF_TARGET_DSCP=m
315CONFIG_IP_NF_TARGET_TTL=m
316CONFIG_IP_NF_RAW=m
317CONFIG_IP_NF_ARPTABLES=m
318CONFIG_IP_NF_ARPFILTER=m
319CONFIG_IP_NF_ARP_MANGLE=m
320 272
321# 273#
322# IPv6: Netfilter Configuration (EXPERIMENTAL) 274# IPv6: Netfilter Configuration (EXPERIMENTAL)
323# 275#
324# CONFIG_IP6_NF_QUEUE is not set 276# CONFIG_IP6_NF_QUEUE is not set
325# CONFIG_IP6_NF_IPTABLES is not set
326 277
327# 278#
328# DCCP Configuration (EXPERIMENTAL) 279# DCCP Configuration (EXPERIMENTAL)
@@ -355,7 +306,6 @@ CONFIG_IP_NF_ARP_MANGLE=m
355# QoS and/or fair queueing 306# QoS and/or fair queueing
356# 307#
357# CONFIG_NET_SCHED is not set 308# CONFIG_NET_SCHED is not set
358CONFIG_NET_CLS_ROUTE=y
359 309
360# 310#
361# Network testing 311# Network testing
@@ -408,7 +358,7 @@ CONFIG_FW_LOADER=y
408# CONFIG_BLK_DEV_COW_COMMON is not set 358# CONFIG_BLK_DEV_COW_COMMON is not set
409CONFIG_BLK_DEV_LOOP=y 359CONFIG_BLK_DEV_LOOP=y
410# CONFIG_BLK_DEV_CRYPTOLOOP is not set 360# CONFIG_BLK_DEV_CRYPTOLOOP is not set
411CONFIG_BLK_DEV_NBD=y 361# CONFIG_BLK_DEV_NBD is not set
412# CONFIG_BLK_DEV_SX8 is not set 362# CONFIG_BLK_DEV_SX8 is not set
413CONFIG_BLK_DEV_RAM=y 363CONFIG_BLK_DEV_RAM=y
414CONFIG_BLK_DEV_RAM_COUNT=16 364CONFIG_BLK_DEV_RAM_COUNT=16
@@ -484,7 +434,23 @@ CONFIG_IDEDMA_AUTO=y
484# 434#
485# Multi-device support (RAID and LVM) 435# Multi-device support (RAID and LVM)
486# 436#
487# CONFIG_MD is not set 437CONFIG_MD=y
438CONFIG_BLK_DEV_MD=m
439CONFIG_MD_LINEAR=m
440CONFIG_MD_RAID0=m
441CONFIG_MD_RAID1=m
442# CONFIG_MD_RAID10 is not set
443# CONFIG_MD_RAID5 is not set
444# CONFIG_MD_RAID6 is not set
445# CONFIG_MD_MULTIPATH is not set
446# CONFIG_MD_FAULTY is not set
447CONFIG_BLK_DEV_DM=m
448CONFIG_DM_CRYPT=m
449CONFIG_DM_SNAPSHOT=m
450CONFIG_DM_MIRROR=m
451CONFIG_DM_ZERO=m
452CONFIG_DM_MULTIPATH=m
453# CONFIG_DM_MULTIPATH_EMC is not set
488 454
489# 455#
490# Fusion MPT device support 456# Fusion MPT device support
@@ -548,7 +514,7 @@ CONFIG_MII=y
548# CONFIG_ACENIC is not set 514# CONFIG_ACENIC is not set
549# CONFIG_DL2K is not set 515# CONFIG_DL2K is not set
550CONFIG_E1000=m 516CONFIG_E1000=m
551# CONFIG_E1000_NAPI is not set 517CONFIG_E1000_NAPI=y
552# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set 518# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set
553# CONFIG_NS83820 is not set 519# CONFIG_NS83820 is not set
554# CONFIG_HAMACHI is not set 520# CONFIG_HAMACHI is not set
@@ -560,7 +526,7 @@ CONFIG_SKGE=m
560# CONFIG_SK98LIN is not set 526# CONFIG_SK98LIN is not set
561# CONFIG_TIGON3 is not set 527# CONFIG_TIGON3 is not set
562# CONFIG_BNX2 is not set 528# CONFIG_BNX2 is not set
563CONFIG_SPIDER_NET=y 529CONFIG_SPIDER_NET=m
564# CONFIG_MV643XX_ETH is not set 530# CONFIG_MV643XX_ETH is not set
565 531
566# 532#
@@ -678,6 +644,8 @@ CONFIG_SERIAL_CORE_CONSOLE=y
678# CONFIG_SERIAL_JSM is not set 644# CONFIG_SERIAL_JSM is not set
679CONFIG_UNIX98_PTYS=y 645CONFIG_UNIX98_PTYS=y
680# CONFIG_LEGACY_PTYS is not set 646# CONFIG_LEGACY_PTYS is not set
647CONFIG_HVC_DRIVER=y
648CONFIG_HVC_RTAS=y
681 649
682# 650#
683# IPMI 651# IPMI
@@ -694,14 +662,13 @@ CONFIG_WATCHDOG=y
694# Watchdog Device Drivers 662# Watchdog Device Drivers
695# 663#
696# CONFIG_SOFT_WATCHDOG is not set 664# CONFIG_SOFT_WATCHDOG is not set
697# CONFIG_WATCHDOG_RTAS is not set 665CONFIG_WATCHDOG_RTAS=y
698 666
699# 667#
700# PCI-based Watchdog Cards 668# PCI-based Watchdog Cards
701# 669#
702# CONFIG_PCIPCWATCHDOG is not set 670# CONFIG_PCIPCWATCHDOG is not set
703# CONFIG_WDTPCI is not set 671# CONFIG_WDTPCI is not set
704# CONFIG_RTC is not set
705CONFIG_GEN_RTC=y 672CONFIG_GEN_RTC=y
706# CONFIG_GEN_RTC_X is not set 673# CONFIG_GEN_RTC_X is not set
707# CONFIG_DTLK is not set 674# CONFIG_DTLK is not set
@@ -833,6 +800,7 @@ CONFIG_DUMMY_CONSOLE=y
833# 800#
834CONFIG_USB_ARCH_HAS_HCD=y 801CONFIG_USB_ARCH_HAS_HCD=y
835CONFIG_USB_ARCH_HAS_OHCI=y 802CONFIG_USB_ARCH_HAS_OHCI=y
803CONFIG_USB_ARCH_HAS_EHCI=y
836# CONFIG_USB is not set 804# CONFIG_USB is not set
837 805
838# 806#
@@ -852,7 +820,14 @@ CONFIG_USB_ARCH_HAS_OHCI=y
852# 820#
853# InfiniBand support 821# InfiniBand support
854# 822#
855# CONFIG_INFINIBAND is not set 823CONFIG_INFINIBAND=y
824CONFIG_INFINIBAND_USER_MAD=m
825CONFIG_INFINIBAND_USER_ACCESS=m
826CONFIG_INFINIBAND_MTHCA=m
827CONFIG_INFINIBAND_MTHCA_DEBUG=y
828CONFIG_INFINIBAND_IPOIB=m
829CONFIG_INFINIBAND_IPOIB_DEBUG=y
830CONFIG_INFINIBAND_IPOIB_DEBUG_DATA=y
856 831
857# 832#
858# EDAC - error detection and reporting (RAS) (EXPERIMENTAL) 833# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
@@ -1037,10 +1012,6 @@ CONFIG_CRC32=y
1037# CONFIG_LIBCRC32C is not set 1012# CONFIG_LIBCRC32C is not set
1038CONFIG_ZLIB_INFLATE=m 1013CONFIG_ZLIB_INFLATE=m
1039CONFIG_ZLIB_DEFLATE=m 1014CONFIG_ZLIB_DEFLATE=m
1040CONFIG_TEXTSEARCH=y
1041CONFIG_TEXTSEARCH_KMP=m
1042CONFIG_TEXTSEARCH_BM=m
1043CONFIG_TEXTSEARCH_FSM=m
1044 1015
1045# 1016#
1046# Instrumentation Support 1017# Instrumentation Support
@@ -1058,7 +1029,7 @@ CONFIG_LOG_BUF_SHIFT=15
1058CONFIG_DETECT_SOFTLOCKUP=y 1029CONFIG_DETECT_SOFTLOCKUP=y
1059# CONFIG_SCHEDSTATS is not set 1030# CONFIG_SCHEDSTATS is not set
1060# CONFIG_DEBUG_SLAB is not set 1031# CONFIG_DEBUG_SLAB is not set
1061# CONFIG_DEBUG_MUTEXES is not set 1032CONFIG_DEBUG_MUTEXES=y
1062# CONFIG_DEBUG_SPINLOCK is not set 1033# CONFIG_DEBUG_SPINLOCK is not set
1063CONFIG_DEBUG_SPINLOCK_SLEEP=y 1034CONFIG_DEBUG_SPINLOCK_SLEEP=y
1064# CONFIG_DEBUG_KOBJECT is not set 1035# CONFIG_DEBUG_KOBJECT is not set
diff --git a/arch/powerpc/configs/mpc8540_ads_defconfig b/arch/powerpc/configs/mpc8540_ads_defconfig
index 2a8290ee15c6..7f0780f1aa39 100644
--- a/arch/powerpc/configs/mpc8540_ads_defconfig
+++ b/arch/powerpc/configs/mpc8540_ads_defconfig
@@ -1,7 +1,7 @@
1# 1#
2# Automatically generated make config: don't edit 2# Automatically generated make config: don't edit
3# Linux kernel version: 3# Linux kernel version: 2.6.16
4# Sat Jan 14 15:57:54 2006 4# Mon Mar 27 23:37:36 2006
5# 5#
6# CONFIG_PPC64 is not set 6# CONFIG_PPC64 is not set
7CONFIG_PPC32=y 7CONFIG_PPC32=y
@@ -9,6 +9,7 @@ CONFIG_PPC_MERGE=y
9CONFIG_MMU=y 9CONFIG_MMU=y
10CONFIG_GENERIC_HARDIRQS=y 10CONFIG_GENERIC_HARDIRQS=y
11CONFIG_RWSEM_XCHGADD_ALGORITHM=y 11CONFIG_RWSEM_XCHGADD_ALGORITHM=y
12CONFIG_GENERIC_HWEIGHT=y
12CONFIG_GENERIC_CALIBRATE_DELAY=y 13CONFIG_GENERIC_CALIBRATE_DELAY=y
13CONFIG_PPC=y 14CONFIG_PPC=y
14CONFIG_EARLY_PRINTK=y 15CONFIG_EARLY_PRINTK=y
@@ -18,6 +19,7 @@ CONFIG_ARCH_MAY_HAVE_PC_FDC=y
18CONFIG_PPC_OF=y 19CONFIG_PPC_OF=y
19CONFIG_PPC_UDBG_16550=y 20CONFIG_PPC_UDBG_16550=y
20# CONFIG_GENERIC_TBSYNC is not set 21# CONFIG_GENERIC_TBSYNC is not set
22CONFIG_DEFAULT_UIMAGE=y
21 23
22# 24#
23# Processor support 25# Processor support
@@ -42,7 +44,6 @@ CONFIG_SPE=y
42# Code maturity level options 44# Code maturity level options
43# 45#
44CONFIG_EXPERIMENTAL=y 46CONFIG_EXPERIMENTAL=y
45CONFIG_CLEAN_COMPILE=y
46CONFIG_BROKEN_ON_SMP=y 47CONFIG_BROKEN_ON_SMP=y
47CONFIG_INIT_ENV_ARG_LIMIT=32 48CONFIG_INIT_ENV_ARG_LIMIT=32
48 49
@@ -58,6 +59,7 @@ CONFIG_SYSVIPC=y
58CONFIG_SYSCTL=y 59CONFIG_SYSCTL=y
59# CONFIG_AUDIT is not set 60# CONFIG_AUDIT is not set
60# CONFIG_IKCONFIG is not set 61# CONFIG_IKCONFIG is not set
62# CONFIG_RELAY is not set
61CONFIG_INITRAMFS_SOURCE="" 63CONFIG_INITRAMFS_SOURCE=""
62# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set 64# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
63CONFIG_EMBEDDED=y 65CONFIG_EMBEDDED=y
@@ -72,10 +74,6 @@ CONFIG_BASE_FULL=y
72CONFIG_FUTEX=y 74CONFIG_FUTEX=y
73CONFIG_EPOLL=y 75CONFIG_EPOLL=y
74CONFIG_SHMEM=y 76CONFIG_SHMEM=y
75CONFIG_CC_ALIGN_FUNCTIONS=0
76CONFIG_CC_ALIGN_LABELS=0
77CONFIG_CC_ALIGN_LOOPS=0
78CONFIG_CC_ALIGN_JUMPS=0
79CONFIG_SLAB=y 77CONFIG_SLAB=y
80# CONFIG_TINY_SHMEM is not set 78# CONFIG_TINY_SHMEM is not set
81CONFIG_BASE_SMALL=0 79CONFIG_BASE_SMALL=0
@@ -90,6 +88,8 @@ CONFIG_BASE_SMALL=0
90# Block layer 88# Block layer
91# 89#
92# CONFIG_LBD is not set 90# CONFIG_LBD is not set
91# CONFIG_BLK_DEV_IO_TRACE is not set
92# CONFIG_LSF is not set
93 93
94# 94#
95# IO Schedulers 95# IO Schedulers
@@ -183,6 +183,7 @@ CONFIG_NET=y
183# 183#
184# Networking options 184# Networking options
185# 185#
186# CONFIG_NETDEBUG is not set
186CONFIG_PACKET=y 187CONFIG_PACKET=y
187# CONFIG_PACKET_MMAP is not set 188# CONFIG_PACKET_MMAP is not set
188CONFIG_UNIX=y 189CONFIG_UNIX=y
@@ -220,6 +221,11 @@ CONFIG_TCP_CONG_BIC=y
220# SCTP Configuration (EXPERIMENTAL) 221# SCTP Configuration (EXPERIMENTAL)
221# 222#
222# CONFIG_IP_SCTP is not set 223# CONFIG_IP_SCTP is not set
224
225#
226# TIPC Configuration (EXPERIMENTAL)
227#
228# CONFIG_TIPC is not set
223# CONFIG_ATM is not set 229# CONFIG_ATM is not set
224# CONFIG_BRIDGE is not set 230# CONFIG_BRIDGE is not set
225# CONFIG_VLAN_8021Q is not set 231# CONFIG_VLAN_8021Q is not set
@@ -229,11 +235,6 @@ CONFIG_TCP_CONG_BIC=y
229# CONFIG_ATALK is not set 235# CONFIG_ATALK is not set
230# CONFIG_X25 is not set 236# CONFIG_X25 is not set
231# CONFIG_LAPB is not set 237# CONFIG_LAPB is not set
232
233#
234# TIPC Configuration (EXPERIMENTAL)
235#
236# CONFIG_TIPC is not set
237# CONFIG_NET_DIVERT is not set 238# CONFIG_NET_DIVERT is not set
238# CONFIG_ECONET is not set 239# CONFIG_ECONET is not set
239# CONFIG_WAN_ROUTER is not set 240# CONFIG_WAN_ROUTER is not set
@@ -487,6 +488,12 @@ CONFIG_GEN_RTC=y
487# CONFIG_I2C is not set 488# CONFIG_I2C is not set
488 489
489# 490#
491# SPI support
492#
493# CONFIG_SPI is not set
494# CONFIG_SPI_MASTER is not set
495
496#
490# Dallas's 1-wire bus 497# Dallas's 1-wire bus
491# 498#
492# CONFIG_W1 is not set 499# CONFIG_W1 is not set
@@ -496,6 +503,7 @@ CONFIG_GEN_RTC=y
496# 503#
497CONFIG_HWMON=y 504CONFIG_HWMON=y
498# CONFIG_HWMON_VID is not set 505# CONFIG_HWMON_VID is not set
506# CONFIG_SENSORS_F71805F is not set
499# CONFIG_HWMON_DEBUG_CHIP is not set 507# CONFIG_HWMON_DEBUG_CHIP is not set
500 508
501# 509#
@@ -503,10 +511,6 @@ CONFIG_HWMON=y
503# 511#
504 512
505# 513#
506# Multimedia Capabilities Port drivers
507#
508
509#
510# Multimedia devices 514# Multimedia devices
511# 515#
512# CONFIG_VIDEO_DEV is not set 516# CONFIG_VIDEO_DEV is not set
@@ -531,6 +535,7 @@ CONFIG_HWMON=y
531# 535#
532# CONFIG_USB_ARCH_HAS_HCD is not set 536# CONFIG_USB_ARCH_HAS_HCD is not set
533# CONFIG_USB_ARCH_HAS_OHCI is not set 537# CONFIG_USB_ARCH_HAS_OHCI is not set
538# CONFIG_USB_ARCH_HAS_EHCI is not set
534 539
535# 540#
536# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' 541# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
@@ -551,7 +556,7 @@ CONFIG_HWMON=y
551# 556#
552 557
553# 558#
554# SN Devices 559# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
555# 560#
556 561
557# 562#
@@ -603,7 +608,6 @@ CONFIG_SYSFS=y
603CONFIG_TMPFS=y 608CONFIG_TMPFS=y
604# CONFIG_HUGETLB_PAGE is not set 609# CONFIG_HUGETLB_PAGE is not set
605CONFIG_RAMFS=y 610CONFIG_RAMFS=y
606# CONFIG_RELAYFS_FS is not set
607# CONFIG_CONFIGFS_FS is not set 611# CONFIG_CONFIGFS_FS is not set
608 612
609# 613#
@@ -658,6 +662,7 @@ CONFIG_PARTITION_ADVANCED=y
658# CONFIG_SGI_PARTITION is not set 662# CONFIG_SGI_PARTITION is not set
659# CONFIG_ULTRIX_PARTITION is not set 663# CONFIG_ULTRIX_PARTITION is not set
660# CONFIG_SUN_PARTITION is not set 664# CONFIG_SUN_PARTITION is not set
665# CONFIG_KARMA_PARTITION is not set
661# CONFIG_EFI_PARTITION is not set 666# CONFIG_EFI_PARTITION is not set
662 667
663# 668#
@@ -695,6 +700,8 @@ CONFIG_DEBUG_MUTEXES=y
695# CONFIG_DEBUG_INFO is not set 700# CONFIG_DEBUG_INFO is not set
696# CONFIG_DEBUG_FS is not set 701# CONFIG_DEBUG_FS is not set
697# CONFIG_DEBUG_VM is not set 702# CONFIG_DEBUG_VM is not set
703# CONFIG_UNWIND_INFO is not set
704CONFIG_FORCED_INLINING=y
698# CONFIG_RCU_TORTURE_TEST is not set 705# CONFIG_RCU_TORTURE_TEST is not set
699# CONFIG_DEBUGGER is not set 706# CONFIG_DEBUGGER is not set
700# CONFIG_BDI_SWITCH is not set 707# CONFIG_BDI_SWITCH is not set
diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile
index 80e9fe2632b8..0cc0995b81b0 100644
--- a/arch/powerpc/kernel/Makefile
+++ b/arch/powerpc/kernel/Makefile
@@ -12,12 +12,12 @@ endif
12 12
13obj-y := semaphore.o cputable.o ptrace.o syscalls.o \ 13obj-y := semaphore.o cputable.o ptrace.o syscalls.o \
14 irq.o align.o signal_32.o pmc.o vdso.o \ 14 irq.o align.o signal_32.o pmc.o vdso.o \
15 init_task.o process.o systbl.o 15 init_task.o process.o systbl.o idle.o
16obj-y += vdso32/ 16obj-y += vdso32/
17obj-$(CONFIG_PPC64) += setup_64.o binfmt_elf32.o sys_ppc32.o \ 17obj-$(CONFIG_PPC64) += setup_64.o binfmt_elf32.o sys_ppc32.o \
18 signal_64.o ptrace32.o \ 18 signal_64.o ptrace32.o \
19 paca.o cpu_setup_power4.o \ 19 paca.o cpu_setup_power4.o \
20 firmware.o sysfs.o idle_64.o 20 firmware.o sysfs.o
21obj-$(CONFIG_PPC64) += vdso64/ 21obj-$(CONFIG_PPC64) += vdso64/
22obj-$(CONFIG_ALTIVEC) += vecemu.o vector.o 22obj-$(CONFIG_ALTIVEC) += vecemu.o vector.o
23obj-$(CONFIG_POWER4) += idle_power4.o 23obj-$(CONFIG_POWER4) += idle_power4.o
@@ -34,6 +34,11 @@ obj-$(CONFIG_IBMEBUS) += ibmebus.o
34obj-$(CONFIG_GENERIC_TBSYNC) += smp-tbsync.o 34obj-$(CONFIG_GENERIC_TBSYNC) += smp-tbsync.o
35obj64-$(CONFIG_PPC_MULTIPLATFORM) += nvram_64.o 35obj64-$(CONFIG_PPC_MULTIPLATFORM) += nvram_64.o
36obj-$(CONFIG_CRASH_DUMP) += crash_dump.o 36obj-$(CONFIG_CRASH_DUMP) += crash_dump.o
37obj-$(CONFIG_6xx) += idle_6xx.o l2cr_6xx.o cpu_setup_6xx.o
38obj-$(CONFIG_TAU) += tau_6xx.o
39obj32-$(CONFIG_SOFTWARE_SUSPEND) += swsusp_32.o
40obj32-$(CONFIG_MODULES) += module_32.o
41obj-$(CONFIG_E500) += perfmon_fsl_booke.o
37 42
38ifeq ($(CONFIG_PPC_MERGE),y) 43ifeq ($(CONFIG_PPC_MERGE),y)
39 44
@@ -51,7 +56,6 @@ obj-$(CONFIG_PPC64) += misc_64.o dma_64.o iommu.o
51obj-$(CONFIG_PPC_MULTIPLATFORM) += prom_init.o 56obj-$(CONFIG_PPC_MULTIPLATFORM) += prom_init.o
52obj-$(CONFIG_MODULES) += ppc_ksyms.o 57obj-$(CONFIG_MODULES) += ppc_ksyms.o
53obj-$(CONFIG_BOOTX_TEXT) += btext.o 58obj-$(CONFIG_BOOTX_TEXT) += btext.o
54obj-$(CONFIG_6xx) += idle_6xx.o
55obj-$(CONFIG_SMP) += smp.o 59obj-$(CONFIG_SMP) += smp.o
56obj-$(CONFIG_KPROBES) += kprobes.o 60obj-$(CONFIG_KPROBES) += kprobes.o
57obj-$(CONFIG_PPC_UDBG_16550) += legacy_serial.o udbg_16550.o 61obj-$(CONFIG_PPC_UDBG_16550) += legacy_serial.o udbg_16550.o
@@ -77,6 +81,7 @@ smpobj-$(CONFIG_SMP) += smp.o
77 81
78endif 82endif
79 83
84obj-$(CONFIG_PPC32) += $(obj32-y)
80obj-$(CONFIG_PPC64) += $(obj64-y) 85obj-$(CONFIG_PPC64) += $(obj64-y)
81 86
82extra-$(CONFIG_PPC_FPU) += fpu.o 87extra-$(CONFIG_PPC_FPU) += fpu.o
diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c
index 882889b15926..54b48f330051 100644
--- a/arch/powerpc/kernel/asm-offsets.c
+++ b/arch/powerpc/kernel/asm-offsets.c
@@ -105,8 +105,6 @@ int main(void)
105 DEFINE(ICACHEL1LINESIZE, offsetof(struct ppc64_caches, iline_size)); 105 DEFINE(ICACHEL1LINESIZE, offsetof(struct ppc64_caches, iline_size));
106 DEFINE(ICACHEL1LOGLINESIZE, offsetof(struct ppc64_caches, log_iline_size)); 106 DEFINE(ICACHEL1LOGLINESIZE, offsetof(struct ppc64_caches, log_iline_size));
107 DEFINE(ICACHEL1LINESPERPAGE, offsetof(struct ppc64_caches, ilines_per_page)); 107 DEFINE(ICACHEL1LINESPERPAGE, offsetof(struct ppc64_caches, ilines_per_page));
108 DEFINE(PLATFORM_LPAR, PLATFORM_LPAR);
109
110 /* paca */ 108 /* paca */
111 DEFINE(PACA_SIZE, sizeof(struct paca_struct)); 109 DEFINE(PACA_SIZE, sizeof(struct paca_struct));
112 DEFINE(PACAPACAINDEX, offsetof(struct paca_struct, paca_index)); 110 DEFINE(PACAPACAINDEX, offsetof(struct paca_struct, paca_index));
diff --git a/arch/ppc/kernel/cpu_setup_6xx.S b/arch/powerpc/kernel/cpu_setup_6xx.S
index 55ed7716636f..55ed7716636f 100644
--- a/arch/ppc/kernel/cpu_setup_6xx.S
+++ b/arch/powerpc/kernel/cpu_setup_6xx.S
diff --git a/arch/powerpc/kernel/crash_dump.c b/arch/powerpc/kernel/crash_dump.c
index 211d72653ea6..764d07329716 100644
--- a/arch/powerpc/kernel/crash_dump.c
+++ b/arch/powerpc/kernel/crash_dump.c
@@ -61,7 +61,7 @@ static int __init parse_elfcorehdr(char *p)
61 if (p) 61 if (p)
62 elfcorehdr_addr = memparse(p, &p); 62 elfcorehdr_addr = memparse(p, &p);
63 63
64 return 0; 64 return 1;
65} 65}
66__setup("elfcorehdr=", parse_elfcorehdr); 66__setup("elfcorehdr=", parse_elfcorehdr);
67#endif 67#endif
@@ -71,7 +71,7 @@ static int __init parse_savemaxmem(char *p)
71 if (p) 71 if (p)
72 saved_max_pfn = (memparse(p, &p) >> PAGE_SHIFT) - 1; 72 saved_max_pfn = (memparse(p, &p) >> PAGE_SHIFT) - 1;
73 73
74 return 0; 74 return 1;
75} 75}
76__setup("savemaxmem=", parse_savemaxmem); 76__setup("savemaxmem=", parse_savemaxmem);
77 77
diff --git a/arch/powerpc/kernel/entry_32.S b/arch/powerpc/kernel/entry_32.S
index 4827ca1ec89b..b3a979467225 100644
--- a/arch/powerpc/kernel/entry_32.S
+++ b/arch/powerpc/kernel/entry_32.S
@@ -135,10 +135,10 @@ transfer_to_handler:
135 mfspr r11,SPRN_HID0 135 mfspr r11,SPRN_HID0
136 mtcr r11 136 mtcr r11
137BEGIN_FTR_SECTION 137BEGIN_FTR_SECTION
138 bt- 8,power_save_6xx_restore /* Check DOZE */ 138 bt- 8,4f /* Check DOZE */
139END_FTR_SECTION_IFSET(CPU_FTR_CAN_DOZE) 139END_FTR_SECTION_IFSET(CPU_FTR_CAN_DOZE)
140BEGIN_FTR_SECTION 140BEGIN_FTR_SECTION
141 bt- 9,power_save_6xx_restore /* Check NAP */ 141 bt- 9,4f /* Check NAP */
142END_FTR_SECTION_IFSET(CPU_FTR_CAN_NAP) 142END_FTR_SECTION_IFSET(CPU_FTR_CAN_NAP)
143#endif /* CONFIG_6xx */ 143#endif /* CONFIG_6xx */
144 .globl transfer_to_handler_cont 144 .globl transfer_to_handler_cont
@@ -157,6 +157,10 @@ transfer_to_handler_cont:
157 SYNC 157 SYNC
158 RFI /* jump to handler, enable MMU */ 158 RFI /* jump to handler, enable MMU */
159 159
160#ifdef CONFIG_6xx
1614: b power_save_6xx_restore
162#endif
163
160/* 164/*
161 * On kernel stack overflow, load up an initial stack pointer 165 * On kernel stack overflow, load up an initial stack pointer
162 * and call StackOverflow(regs), which should not return. 166 * and call StackOverflow(regs), which should not return.
diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S
index 1060155d84c3..19ad5c6b1818 100644
--- a/arch/powerpc/kernel/entry_64.S
+++ b/arch/powerpc/kernel/entry_64.S
@@ -617,6 +617,12 @@ _GLOBAL(enter_rtas)
617 mfsrr1 r10 617 mfsrr1 r10
618 std r10,_SRR1(r1) 618 std r10,_SRR1(r1)
619 619
620 /* Temporary workaround to clear CR until RTAS can be modified to
621 * ignore all bits.
622 */
623 li r0,0
624 mtcr r0
625
620 /* There is no way it is acceptable to get here with interrupts enabled, 626 /* There is no way it is acceptable to get here with interrupts enabled,
621 * check it with the asm equivalent of WARN_ON 627 * check it with the asm equivalent of WARN_ON
622 */ 628 */
diff --git a/arch/powerpc/kernel/firmware.c b/arch/powerpc/kernel/firmware.c
index 4d37a3cb80f6..0bfe9061720a 100644
--- a/arch/powerpc/kernel/firmware.c
+++ b/arch/powerpc/kernel/firmware.c
@@ -14,7 +14,9 @@
14 */ 14 */
15 15
16#include <linux/config.h> 16#include <linux/config.h>
17#include <linux/module.h>
17 18
18#include <asm/firmware.h> 19#include <asm/firmware.h>
19 20
20unsigned long ppc64_firmware_features; 21unsigned long powerpc_firmware_features;
22EXPORT_SYMBOL_GPL(powerpc_firmware_features);
diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S
index 35084f3a841b..a5ae04a57c78 100644
--- a/arch/powerpc/kernel/head_64.S
+++ b/arch/powerpc/kernel/head_64.S
@@ -1544,7 +1544,11 @@ _STATIC(__boot_from_prom)
1544 mr r28,r6 1544 mr r28,r6
1545 mr r27,r7 1545 mr r27,r7
1546 1546
1547 /* Align the stack to 16-byte boundary for broken yaboot */ 1547 /*
1548 * Align the stack to 16-byte boundary
1549 * Depending on the size and layout of the ELF sections in the initial
1550 * boot binary, the stack pointer will be unalignet on PowerMac
1551 */
1548 rldicr r1,r1,0,59 1552 rldicr r1,r1,0,59
1549 1553
1550 /* Make sure we are running in 64 bits mode */ 1554 /* Make sure we are running in 64 bits mode */
@@ -1847,21 +1851,6 @@ _STATIC(start_here_multiplatform)
1847 bl .__save_cpu_setup 1851 bl .__save_cpu_setup
1848 sync 1852 sync
1849 1853
1850 /* Setup a valid physical PACA pointer in SPRG3 for early_setup
1851 * note that boot_cpuid can always be 0 nowadays since there is
1852 * nowhere it can be initialized differently before we reach this
1853 * code
1854 */
1855 LOAD_REG_IMMEDIATE(r27, boot_cpuid)
1856 add r27,r27,r26
1857 lwz r27,0(r27)
1858
1859 LOAD_REG_IMMEDIATE(r24, paca) /* Get base vaddr of paca array */
1860 mulli r13,r27,PACA_SIZE /* Calculate vaddr of right paca */
1861 add r13,r13,r24 /* for this processor. */
1862 add r13,r13,r26 /* convert to physical addr */
1863 mtspr SPRN_SPRG3,r13
1864
1865 /* Do very early kernel initializations, including initial hash table, 1854 /* Do very early kernel initializations, including initial hash table,
1866 * stab and slb setup before we turn on relocation. */ 1855 * stab and slb setup before we turn on relocation. */
1867 1856
@@ -1930,6 +1919,17 @@ _STATIC(start_here_common)
1930 /* Not reached */ 1919 /* Not reached */
1931 BUG_OPCODE 1920 BUG_OPCODE
1932 1921
1922/* Put the paca pointer into r13 and SPRG3 */
1923_GLOBAL(setup_boot_paca)
1924 LOAD_REG_IMMEDIATE(r3, boot_cpuid)
1925 lwz r3,0(r3)
1926 LOAD_REG_IMMEDIATE(r4, paca) /* Get base vaddr of paca array */
1927 mulli r3,r3,PACA_SIZE /* Calculate vaddr of right paca */
1928 add r13,r3,r4 /* for this processor. */
1929 mtspr SPRN_SPRG3,r13
1930
1931 blr
1932
1933/* 1933/*
1934 * We put a few things here that have to be page-aligned. 1934 * We put a few things here that have to be page-aligned.
1935 * This stuff goes at the beginning of the bss, which is page-aligned. 1935 * This stuff goes at the beginning of the bss, which is page-aligned.
diff --git a/arch/powerpc/kernel/idle_64.c b/arch/powerpc/kernel/idle.c
index b879d3057ef8..e9f321d74d85 100644
--- a/arch/powerpc/kernel/idle_64.c
+++ b/arch/powerpc/kernel/idle.c
@@ -2,13 +2,17 @@
2 * Idle daemon for PowerPC. Idle daemon will handle any action 2 * Idle daemon for PowerPC. Idle daemon will handle any action
3 * that needs to be taken when the system becomes idle. 3 * that needs to be taken when the system becomes idle.
4 * 4 *
5 * Originally Written by Cort Dougan (cort@cs.nmt.edu) 5 * Originally written by Cort Dougan (cort@cs.nmt.edu).
6 * Subsequent 32-bit hacking by Tom Rini, Armin Kuster,
7 * Paul Mackerras and others.
6 * 8 *
7 * iSeries supported added by Mike Corrigan <mikejc@us.ibm.com> 9 * iSeries supported added by Mike Corrigan <mikejc@us.ibm.com>
8 * 10 *
9 * Additional shared processor, SMT, and firmware support 11 * Additional shared processor, SMT, and firmware support
10 * Copyright (c) 2003 Dave Engebretsen <engebret@us.ibm.com> 12 * Copyright (c) 2003 Dave Engebretsen <engebret@us.ibm.com>
11 * 13 *
14 * 32-bit and 64-bit versions merged by Paul Mackerras <paulus@samba.org>
15 *
12 * This program is free software; you can redistribute it and/or 16 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License 17 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 18 * as published by the Free Software Foundation; either version
@@ -29,18 +33,43 @@
29#include <asm/machdep.h> 33#include <asm/machdep.h>
30#include <asm/smp.h> 34#include <asm/smp.h>
31 35
32extern void power4_idle(void); 36#ifdef CONFIG_HOTPLUG_CPU
37#define cpu_should_die() (cpu_is_offline(smp_processor_id()) && \
38 system_state == SYSTEM_RUNNING)
39#else
40#define cpu_should_die() 0
41#endif
33 42
34void default_idle(void) 43/*
44 * The body of the idle task.
45 */
46void cpu_idle(void)
35{ 47{
36 unsigned int cpu = smp_processor_id(); 48 if (ppc_md.idle_loop)
37 set_thread_flag(TIF_POLLING_NRFLAG); 49 ppc_md.idle_loop(); /* doesn't return */
38 50
51 set_thread_flag(TIF_POLLING_NRFLAG);
39 while (1) { 52 while (1) {
40 if (!need_resched()) { 53 ppc64_runlatch_off();
41 while (!need_resched() && !cpu_is_offline(cpu)) {
42 ppc64_runlatch_off();
43 54
55 while (!need_resched() && !cpu_should_die()) {
56 if (ppc_md.power_save) {
57 clear_thread_flag(TIF_POLLING_NRFLAG);
58 /*
59 * smp_mb is so clearing of TIF_POLLING_NRFLAG
60 * is ordered w.r.t. need_resched() test.
61 */
62 smp_mb();
63 local_irq_disable();
64
65 /* check again after disabling irqs */
66 if (!need_resched() && !cpu_should_die())
67 ppc_md.power_save();
68
69 local_irq_enable();
70 set_thread_flag(TIF_POLLING_NRFLAG);
71
72 } else {
44 /* 73 /*
45 * Go into low thread priority and possibly 74 * Go into low thread priority and possibly
46 * low power mode. 75 * low power mode.
@@ -48,46 +77,18 @@ void default_idle(void)
48 HMT_low(); 77 HMT_low();
49 HMT_very_low(); 78 HMT_very_low();
50 } 79 }
51
52 HMT_medium();
53 } 80 }
54 81
82 HMT_medium();
55 ppc64_runlatch_on(); 83 ppc64_runlatch_on();
84 if (cpu_should_die())
85 cpu_die();
56 preempt_enable_no_resched(); 86 preempt_enable_no_resched();
57 schedule(); 87 schedule();
58 preempt_disable(); 88 preempt_disable();
59 if (cpu_is_offline(cpu) && system_state == SYSTEM_RUNNING)
60 cpu_die();
61 } 89 }
62} 90}
63 91
64void native_idle(void)
65{
66 while (1) {
67 ppc64_runlatch_off();
68
69 if (!need_resched())
70 power4_idle();
71
72 if (need_resched()) {
73 ppc64_runlatch_on();
74 preempt_enable_no_resched();
75 schedule();
76 preempt_disable();
77 }
78
79 if (cpu_is_offline(smp_processor_id()) &&
80 system_state == SYSTEM_RUNNING)
81 cpu_die();
82 }
83}
84
85void cpu_idle(void)
86{
87 BUG_ON(NULL == ppc_md.idle_loop);
88 ppc_md.idle_loop();
89}
90
91int powersave_nap; 92int powersave_nap;
92 93
93#ifdef CONFIG_SYSCTL 94#ifdef CONFIG_SYSCTL
diff --git a/arch/powerpc/kernel/idle_6xx.S b/arch/powerpc/kernel/idle_6xx.S
index 444fdcc769f1..12a4efbaa08f 100644
--- a/arch/powerpc/kernel/idle_6xx.S
+++ b/arch/powerpc/kernel/idle_6xx.S
@@ -87,19 +87,6 @@ END_FTR_SECTION_IFSET(CPU_FTR_CAN_NAP)
87 cmpwi 0,r3,0 87 cmpwi 0,r3,0
88 beqlr 88 beqlr
89 89
90 /* Clear MSR:EE */
91 mfmsr r7
92 rlwinm r0,r7,0,17,15
93 mtmsr r0
94
95 /* Check current_thread_info()->flags */
96 rlwinm r4,r1,0,0,18
97 lwz r4,TI_FLAGS(r4)
98 andi. r0,r4,_TIF_NEED_RESCHED
99 beq 1f
100 mtmsr r7 /* out of line this ? */
101 blr
1021:
103 /* Some pre-nap cleanups needed on some CPUs */ 90 /* Some pre-nap cleanups needed on some CPUs */
104 andis. r0,r3,HID0_NAP@h 91 andis. r0,r3,HID0_NAP@h
105 beq 2f 92 beq 2f
@@ -157,7 +144,8 @@ BEGIN_FTR_SECTION
157 DSSALL 144 DSSALL
158 sync 145 sync
159END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) 146END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
160 ori r7,r7,MSR_EE /* Could be ommited (already set) */ 147 mfmsr r7
148 ori r7,r7,MSR_EE
161 oris r7,r7,MSR_POW@h 149 oris r7,r7,MSR_POW@h
162 sync 150 sync
163 isync 151 isync
@@ -220,8 +208,6 @@ _GLOBAL(nap_save_msscr0)
220_GLOBAL(nap_save_hid1) 208_GLOBAL(nap_save_hid1)
221 .space 4*NR_CPUS 209 .space 4*NR_CPUS
222 210
223_GLOBAL(powersave_nap)
224 .long 0
225_GLOBAL(powersave_lowspeed) 211_GLOBAL(powersave_lowspeed)
226 .long 0 212 .long 0
227 213
diff --git a/arch/powerpc/kernel/idle_power4.S b/arch/powerpc/kernel/idle_power4.S
index c16b4afab582..6dad1c02496e 100644
--- a/arch/powerpc/kernel/idle_power4.S
+++ b/arch/powerpc/kernel/idle_power4.S
@@ -1,11 +1,5 @@
1/* 1/*
2 * This file contains the power_save function for 6xx & 7xxx CPUs 2 * This file contains the power_save function for 970-family CPUs.
3 * rewritten in assembler
4 *
5 * Warning ! This code assumes that if your machine has a 750fx
6 * it will have PLL 1 set to low speed mode (used during NAP/DOZE).
7 * if this is not the case some additional changes will have to
8 * be done to check a runtime var (a bit like powersave-nap)
9 * 3 *
10 * This program is free software; you can redistribute it and/or 4 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License 5 * modify it under the terms of the GNU General Public License
@@ -26,49 +20,23 @@
26 20
27 .text 21 .text
28 22
29/*
30 * Here is the power_save_6xx function. This could eventually be
31 * split into several functions & changing the function pointer
32 * depending on the various features.
33 */
34_GLOBAL(power4_idle) 23_GLOBAL(power4_idle)
35BEGIN_FTR_SECTION 24BEGIN_FTR_SECTION
36 blr 25 blr
37END_FTR_SECTION_IFCLR(CPU_FTR_CAN_NAP) 26END_FTR_SECTION_IFCLR(CPU_FTR_CAN_NAP)
38 /* We must dynamically check for the NAP feature as it
39 * can be cleared by CPU init after the fixups are done
40 */
41 LOAD_REG_ADDRBASE(r3,cur_cpu_spec)
42 ld r4,ADDROFF(cur_cpu_spec)(r3)
43 ld r4,CPU_SPEC_FEATURES(r4)
44 andi. r0,r4,CPU_FTR_CAN_NAP
45 beqlr
46 /* Now check if user or arch enabled NAP mode */ 27 /* Now check if user or arch enabled NAP mode */
47 LOAD_REG_ADDRBASE(r3,powersave_nap) 28 LOAD_REG_ADDRBASE(r3,powersave_nap)
48 lwz r4,ADDROFF(powersave_nap)(r3) 29 lwz r4,ADDROFF(powersave_nap)(r3)
49 cmpwi 0,r4,0 30 cmpwi 0,r4,0
50 beqlr 31 beqlr
51 32
52 /* Clear MSR:EE */
53 mfmsr r7
54 li r4,0
55 ori r4,r4,MSR_EE
56 andc r0,r7,r4
57 mtmsrd r0
58
59 /* Check current_thread_info()->flags */
60 clrrdi r4,r1,THREAD_SHIFT
61 ld r4,TI_FLAGS(r4)
62 andi. r0,r4,_TIF_NEED_RESCHED
63 beq 1f
64 mtmsrd r7 /* out of line this ? */
65 blr
661:
67 /* Go to NAP now */ 33 /* Go to NAP now */
68BEGIN_FTR_SECTION 34BEGIN_FTR_SECTION
69 DSSALL 35 DSSALL
70 sync 36 sync
71END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) 37END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
38 mfmsr r7
39 ori r7,r7,MSR_EE
72 oris r7,r7,MSR_POW@h 40 oris r7,r7,MSR_POW@h
73 sync 41 sync
74 isync 42 isync
diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c
index 771a59cbd213..bb5c9501234c 100644
--- a/arch/powerpc/kernel/irq.c
+++ b/arch/powerpc/kernel/irq.c
@@ -379,7 +379,7 @@ void irq_ctx_init(void)
379 struct thread_info *tp; 379 struct thread_info *tp;
380 int i; 380 int i;
381 381
382 for_each_cpu(i) { 382 for_each_possible_cpu(i) {
383 memset((void *)softirq_ctx[i], 0, THREAD_SIZE); 383 memset((void *)softirq_ctx[i], 0, THREAD_SIZE);
384 tp = softirq_ctx[i]; 384 tp = softirq_ctx[i];
385 tp->cpu = i; 385 tp->cpu = i;
diff --git a/arch/ppc/kernel/l2cr.S b/arch/powerpc/kernel/l2cr_6xx.S
index d7f4e982b539..d7f4e982b539 100644
--- a/arch/ppc/kernel/l2cr.S
+++ b/arch/powerpc/kernel/l2cr_6xx.S
diff --git a/arch/powerpc/kernel/legacy_serial.c b/arch/powerpc/kernel/legacy_serial.c
index c7a799a09516..6e67b5b49ba1 100644
--- a/arch/powerpc/kernel/legacy_serial.c
+++ b/arch/powerpc/kernel/legacy_serial.c
@@ -37,7 +37,7 @@ static int legacy_serial_console = -1;
37static int __init add_legacy_port(struct device_node *np, int want_index, 37static int __init add_legacy_port(struct device_node *np, int want_index,
38 int iotype, phys_addr_t base, 38 int iotype, phys_addr_t base,
39 phys_addr_t taddr, unsigned long irq, 39 phys_addr_t taddr, unsigned long irq,
40 unsigned int flags) 40 upf_t flags)
41{ 41{
42 u32 *clk, *spd, clock = BASE_BAUD * 16; 42 u32 *clk, *spd, clock = BASE_BAUD * 16;
43 int index; 43 int index;
@@ -113,7 +113,7 @@ static int __init add_legacy_soc_port(struct device_node *np,
113{ 113{
114 phys_addr_t addr; 114 phys_addr_t addr;
115 u32 *addrp; 115 u32 *addrp;
116 unsigned int flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_SHARE_IRQ; 116 upf_t flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_SHARE_IRQ;
117 117
118 /* We only support ports that have a clock frequency properly 118 /* We only support ports that have a clock frequency properly
119 * encoded in the device-tree. 119 * encoded in the device-tree.
@@ -236,6 +236,23 @@ static int __init add_legacy_pci_port(struct device_node *np,
236} 236}
237#endif 237#endif
238 238
239static void __init setup_legacy_serial_console(int console)
240{
241 struct legacy_serial_info *info =
242 &legacy_serial_infos[console];
243 void __iomem *addr;
244
245 if (info->taddr == 0)
246 return;
247 addr = ioremap(info->taddr, 0x1000);
248 if (addr == NULL)
249 return;
250 if (info->speed == 0)
251 info->speed = udbg_probe_uart_speed(addr, info->clock);
252 DBG("default console speed = %d\n", info->speed);
253 udbg_init_uart(addr, info->speed, info->clock);
254}
255
239/* 256/*
240 * This is called very early, as part of setup_system() or eventually 257 * This is called very early, as part of setup_system() or eventually
241 * setup_arch(), basically before anything else in this file. This function 258 * setup_arch(), basically before anything else in this file. This function
@@ -318,25 +335,8 @@ void __init find_legacy_serial_ports(void)
318#endif 335#endif
319 336
320 DBG("legacy_serial_console = %d\n", legacy_serial_console); 337 DBG("legacy_serial_console = %d\n", legacy_serial_console);
321 338 if (legacy_serial_console >= 0)
322 /* udbg is 64 bits only for now, that will change soon though ... */ 339 setup_legacy_serial_console(legacy_serial_console);
323 while (legacy_serial_console >= 0) {
324 struct legacy_serial_info *info =
325 &legacy_serial_infos[legacy_serial_console];
326 void __iomem *addr;
327
328 if (info->taddr == 0)
329 break;
330 addr = ioremap(info->taddr, 0x1000);
331 if (addr == NULL)
332 break;
333 if (info->speed == 0)
334 info->speed = udbg_probe_uart_speed(addr, info->clock);
335 DBG("default console speed = %d\n", info->speed);
336 udbg_init_uart(addr, info->speed, info->clock);
337 break;
338 }
339
340 DBG(" <- find_legacy_serial_port()\n"); 340 DBG(" <- find_legacy_serial_port()\n");
341} 341}
342 342
diff --git a/arch/powerpc/kernel/lparcfg.c b/arch/powerpc/kernel/lparcfg.c
index e789fef4eb8a..1b73508ecb2b 100644
--- a/arch/powerpc/kernel/lparcfg.c
+++ b/arch/powerpc/kernel/lparcfg.c
@@ -56,7 +56,7 @@ static unsigned long get_purr(void)
56 unsigned long sum_purr = 0; 56 unsigned long sum_purr = 0;
57 int cpu; 57 int cpu;
58 58
59 for_each_cpu(cpu) { 59 for_each_possible_cpu(cpu) {
60 sum_purr += lppaca[cpu].emulated_time_base; 60 sum_purr += lppaca[cpu].emulated_time_base;
61 61
62#ifdef PURR_DEBUG 62#ifdef PURR_DEBUG
@@ -222,7 +222,7 @@ static unsigned long get_purr(void)
222 int cpu; 222 int cpu;
223 struct cpu_usage *cu; 223 struct cpu_usage *cu;
224 224
225 for_each_cpu(cpu) { 225 for_each_possible_cpu(cpu) {
226 cu = &per_cpu(cpu_usage_array, cpu); 226 cu = &per_cpu(cpu_usage_array, cpu);
227 sum_purr += cu->current_tb; 227 sum_purr += cu->current_tb;
228 } 228 }
diff --git a/arch/ppc/kernel/module.c b/arch/powerpc/kernel/module_32.c
index 92f4e5f64f02..92f4e5f64f02 100644
--- a/arch/ppc/kernel/module.c
+++ b/arch/powerpc/kernel/module_32.c
diff --git a/arch/powerpc/kernel/nvram_64.c b/arch/powerpc/kernel/nvram_64.c
index fd7db8d542db..ada50aa5b600 100644
--- a/arch/powerpc/kernel/nvram_64.c
+++ b/arch/powerpc/kernel/nvram_64.c
@@ -160,7 +160,7 @@ static int dev_nvram_ioctl(struct inode *inode, struct file *file,
160 case IOC_NVRAM_GET_OFFSET: { 160 case IOC_NVRAM_GET_OFFSET: {
161 int part, offset; 161 int part, offset;
162 162
163 if (_machine != PLATFORM_POWERMAC) 163 if (!machine_is(powermac))
164 return -EINVAL; 164 return -EINVAL;
165 if (copy_from_user(&part, (void __user*)arg, sizeof(part)) != 0) 165 if (copy_from_user(&part, (void __user*)arg, sizeof(part)) != 0)
166 return -EFAULT; 166 return -EFAULT;
@@ -174,8 +174,9 @@ static int dev_nvram_ioctl(struct inode *inode, struct file *file,
174 return 0; 174 return 0;
175 } 175 }
176#endif /* CONFIG_PPC_PMAC */ 176#endif /* CONFIG_PPC_PMAC */
177 default:
178 return -EINVAL;
177 } 179 }
178 return -EINVAL;
179} 180}
180 181
181struct file_operations nvram_fops = { 182struct file_operations nvram_fops = {
@@ -443,7 +444,7 @@ static int nvram_setup_partition(void)
443 * in our nvram, as Apple defined partitions use pretty much 444 * in our nvram, as Apple defined partitions use pretty much
444 * all of the space 445 * all of the space
445 */ 446 */
446 if (_machine == PLATFORM_POWERMAC) 447 if (machine_is(powermac))
447 return -ENOSPC; 448 return -ENOSPC;
448 449
449 /* see if we have an OS partition that meets our needs. 450 /* see if we have an OS partition that meets our needs.
diff --git a/arch/powerpc/kernel/paca.c b/arch/powerpc/kernel/paca.c
index 5d1b708086bd..f505a8827e3e 100644
--- a/arch/powerpc/kernel/paca.c
+++ b/arch/powerpc/kernel/paca.c
@@ -56,14 +56,11 @@ struct lppaca lppaca[] = {
56 * processors. The processor VPD array needs one entry per physical 56 * processors. The processor VPD array needs one entry per physical
57 * processor (not thread). 57 * processor (not thread).
58 */ 58 */
59#define PACA_INIT_COMMON(number, start, asrr, asrv) \ 59#define PACA_INIT_COMMON(number) \
60 .lppaca_ptr = &lppaca[number], \ 60 .lppaca_ptr = &lppaca[number], \
61 .lock_token = 0x8000, \ 61 .lock_token = 0x8000, \
62 .paca_index = (number), /* Paca Index */ \ 62 .paca_index = (number), /* Paca Index */ \
63 .kernel_toc = (unsigned long)(&__toc_start) + 0x8000UL, \ 63 .kernel_toc = (unsigned long)(&__toc_start) + 0x8000UL, \
64 .stab_real = (asrr), /* Real pointer to segment table */ \
65 .stab_addr = (asrv), /* Virt pointer to segment table */ \
66 .cpu_start = (start), /* Processor start */ \
67 .hw_cpu_id = 0xffff, 64 .hw_cpu_id = 0xffff,
68 65
69#ifdef CONFIG_PPC_ISERIES 66#ifdef CONFIG_PPC_ISERIES
@@ -72,30 +69,20 @@ struct lppaca lppaca[] = {
72 69
73#define PACA_INIT(number) \ 70#define PACA_INIT(number) \
74{ \ 71{ \
75 PACA_INIT_COMMON(number, 0, 0, 0) \ 72 PACA_INIT_COMMON(number) \
76 PACA_INIT_ISERIES(number) \
77}
78
79#define BOOTCPU_PACA_INIT(number) \
80{ \
81 PACA_INIT_COMMON(number, 1, 0, (u64)&initial_stab) \
82 PACA_INIT_ISERIES(number) \ 73 PACA_INIT_ISERIES(number) \
83} 74}
84 75
85#else 76#else
86#define PACA_INIT(number) \ 77#define PACA_INIT(number) \
87{ \ 78{ \
88 PACA_INIT_COMMON(number, 0, 0, 0) \ 79 PACA_INIT_COMMON(number) \
89} 80}
90 81
91#define BOOTCPU_PACA_INIT(number) \
92{ \
93 PACA_INIT_COMMON(number, 1, STAB0_PHYS_ADDR, (u64)&initial_stab) \
94}
95#endif 82#endif
96 83
97struct paca_struct paca[] = { 84struct paca_struct paca[] = {
98 BOOTCPU_PACA_INIT(0), 85 PACA_INIT(0),
99#if NR_CPUS > 1 86#if NR_CPUS > 1
100 PACA_INIT( 1), PACA_INIT( 2), PACA_INIT( 3), 87 PACA_INIT( 1), PACA_INIT( 2), PACA_INIT( 3),
101#if NR_CPUS > 4 88#if NR_CPUS > 4
diff --git a/arch/powerpc/kernel/pci_32.c b/arch/powerpc/kernel/pci_32.c
index 704c846b2b0f..b129d2e4b759 100644
--- a/arch/powerpc/kernel/pci_32.c
+++ b/arch/powerpc/kernel/pci_32.c
@@ -787,7 +787,7 @@ pci_busdev_to_OF_node(struct pci_bus *bus, int devfn)
787 * fix has to be done by making the remapping per-host and always 787 * fix has to be done by making the remapping per-host and always
788 * filling the pci_to_OF map. --BenH 788 * filling the pci_to_OF map. --BenH
789 */ 789 */
790 if (_machine == _MACH_Pmac && busnr >= 0xf0) 790 if (machine_is(powermac) && busnr >= 0xf0)
791 busnr -= 0xf0; 791 busnr -= 0xf0;
792 else 792 else
793#endif 793#endif
@@ -1728,7 +1728,7 @@ long sys_pciconfig_iobase(long which, unsigned long bus, unsigned long devfn)
1728 * (bus 0 is HT root), we return the AGP one instead. 1728 * (bus 0 is HT root), we return the AGP one instead.
1729 */ 1729 */
1730#ifdef CONFIG_PPC_PMAC 1730#ifdef CONFIG_PPC_PMAC
1731 if (_machine == _MACH_Pmac && machine_is_compatible("MacRISC4")) 1731 if (machine_is(powermac) && machine_is_compatible("MacRISC4"))
1732 if (bus == 0) 1732 if (bus == 0)
1733 bus = 0xf0; 1733 bus = 0xf0;
1734#endif /* CONFIG_PPC_PMAC */ 1734#endif /* CONFIG_PPC_PMAC */
diff --git a/arch/powerpc/kernel/pci_64.c b/arch/powerpc/kernel/pci_64.c
index ba92bab7cc2c..4c4449be81ce 100644
--- a/arch/powerpc/kernel/pci_64.c
+++ b/arch/powerpc/kernel/pci_64.c
@@ -78,6 +78,7 @@ int global_phb_number; /* Global phb counter */
78 78
79/* Cached ISA bridge dev. */ 79/* Cached ISA bridge dev. */
80struct pci_dev *ppc64_isabridge_dev = NULL; 80struct pci_dev *ppc64_isabridge_dev = NULL;
81EXPORT_SYMBOL_GPL(ppc64_isabridge_dev);
81 82
82static void fixup_broken_pcnet32(struct pci_dev* dev) 83static void fixup_broken_pcnet32(struct pci_dev* dev)
83{ 84{
diff --git a/arch/ppc/kernel/perfmon_fsl_booke.c b/arch/powerpc/kernel/perfmon_fsl_booke.c
index 32455dfcc36b..32455dfcc36b 100644
--- a/arch/ppc/kernel/perfmon_fsl_booke.c
+++ b/arch/powerpc/kernel/perfmon_fsl_booke.c
diff --git a/arch/powerpc/kernel/proc_ppc64.c b/arch/powerpc/kernel/proc_ppc64.c
index 7ba42a405f41..3c2cf661f6d9 100644
--- a/arch/powerpc/kernel/proc_ppc64.c
+++ b/arch/powerpc/kernel/proc_ppc64.c
@@ -23,6 +23,7 @@
23#include <linux/slab.h> 23#include <linux/slab.h>
24#include <linux/kernel.h> 24#include <linux/kernel.h>
25 25
26#include <asm/machdep.h>
26#include <asm/vdso_datapage.h> 27#include <asm/vdso_datapage.h>
27#include <asm/rtas.h> 28#include <asm/rtas.h>
28#include <asm/uaccess.h> 29#include <asm/uaccess.h>
@@ -51,7 +52,7 @@ static int __init proc_ppc64_create(void)
51 if (!root) 52 if (!root)
52 return 1; 53 return 1;
53 54
54 if (!(platform_is_pseries() || _machine == PLATFORM_CELL)) 55 if (!machine_is(pseries) && !machine_is(cell))
55 return 0; 56 return 0;
56 57
57 if (!proc_mkdir("rtas", root)) 58 if (!proc_mkdir("rtas", root))
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
index f698aa77127e..2dd47d2dd998 100644
--- a/arch/powerpc/kernel/process.c
+++ b/arch/powerpc/kernel/process.c
@@ -45,6 +45,7 @@
45#include <asm/prom.h> 45#include <asm/prom.h>
46#include <asm/machdep.h> 46#include <asm/machdep.h>
47#include <asm/time.h> 47#include <asm/time.h>
48#include <asm/syscalls.h>
48#ifdef CONFIG_PPC64 49#ifdef CONFIG_PPC64
49#include <asm/firmware.h> 50#include <asm/firmware.h>
50#endif 51#endif
@@ -362,7 +363,11 @@ static void show_instructions(struct pt_regs *regs)
362 if (!(i % 8)) 363 if (!(i % 8))
363 printk("\n"); 364 printk("\n");
364 365
365 if (BAD_PC(pc) || __get_user(instr, (unsigned int *)pc)) { 366 /* We use __get_user here *only* to avoid an OOPS on a
367 * bad address because the pc *should* only be a
368 * kernel address.
369 */
370 if (BAD_PC(pc) || __get_user(instr, (unsigned int __user *)pc)) {
366 printk("XXXXXXXX "); 371 printk("XXXXXXXX ");
367 } else { 372 } else {
368 if (regs->nip == pc) 373 if (regs->nip == pc)
@@ -765,7 +770,7 @@ out:
765 return error; 770 return error;
766} 771}
767 772
768static int validate_sp(unsigned long sp, struct task_struct *p, 773int validate_sp(unsigned long sp, struct task_struct *p,
769 unsigned long nbytes) 774 unsigned long nbytes)
770{ 775{
771 unsigned long stack_page = (unsigned long)task_stack_page(p); 776 unsigned long stack_page = (unsigned long)task_stack_page(p);
@@ -803,6 +808,8 @@ static int validate_sp(unsigned long sp, struct task_struct *p,
803#define FRAME_MARKER 2 808#define FRAME_MARKER 2
804#endif 809#endif
805 810
811EXPORT_SYMBOL(validate_sp);
812
806unsigned long get_wchan(struct task_struct *p) 813unsigned long get_wchan(struct task_struct *p)
807{ 814{
808 unsigned long ip, sp; 815 unsigned long ip, sp;
@@ -827,7 +834,6 @@ unsigned long get_wchan(struct task_struct *p)
827 } while (count++ < 16); 834 } while (count++ < 16);
828 return 0; 835 return 0;
829} 836}
830EXPORT_SYMBOL(get_wchan);
831 837
832static int kstack_depth_to_print = 64; 838static int kstack_depth_to_print = 64;
833 839
diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c
index d63cd562d9d5..4336390bcf34 100644
--- a/arch/powerpc/kernel/prom.c
+++ b/arch/powerpc/kernel/prom.c
@@ -383,14 +383,14 @@ static int __devinit finish_node_interrupts(struct device_node *np,
383 /* Apple uses bits in there in a different way, let's 383 /* Apple uses bits in there in a different way, let's
384 * only keep the real sense bit on macs 384 * only keep the real sense bit on macs
385 */ 385 */
386 if (_machine == PLATFORM_POWERMAC) 386 if (machine_is(powermac))
387 sense &= 0x1; 387 sense &= 0x1;
388 np->intrs[intrcount].sense = map_mpic_senses[sense]; 388 np->intrs[intrcount].sense = map_mpic_senses[sense];
389 } 389 }
390 390
391#ifdef CONFIG_PPC64 391#ifdef CONFIG_PPC64
392 /* We offset irq numbers for the u3 MPIC by 128 in PowerMac */ 392 /* We offset irq numbers for the u3 MPIC by 128 in PowerMac */
393 if (_machine == PLATFORM_POWERMAC && ic && ic->parent) { 393 if (machine_is(powermac) && ic && ic->parent) {
394 char *name = get_property(ic->parent, "name", NULL); 394 char *name = get_property(ic->parent, "name", NULL);
395 if (name && !strcmp(name, "u3")) 395 if (name && !strcmp(name, "u3"))
396 np->intrs[intrcount].line += 128; 396 np->intrs[intrcount].line += 128;
@@ -570,6 +570,18 @@ int __init of_scan_flat_dt(int (*it)(unsigned long node,
570 return rc; 570 return rc;
571} 571}
572 572
573unsigned long __init of_get_flat_dt_root(void)
574{
575 unsigned long p = ((unsigned long)initial_boot_params) +
576 initial_boot_params->off_dt_struct;
577
578 while(*((u32 *)p) == OF_DT_NOP)
579 p += 4;
580 BUG_ON (*((u32 *)p) != OF_DT_BEGIN_NODE);
581 p += 4;
582 return _ALIGN(p + strlen((char *)p) + 1, 4);
583}
584
573/** 585/**
574 * This function can be used within scan_flattened_dt callback to get 586 * This function can be used within scan_flattened_dt callback to get
575 * access to properties 587 * access to properties
@@ -612,6 +624,25 @@ void* __init of_get_flat_dt_prop(unsigned long node, const char *name,
612 } while(1); 624 } while(1);
613} 625}
614 626
627int __init of_flat_dt_is_compatible(unsigned long node, const char *compat)
628{
629 const char* cp;
630 unsigned long cplen, l;
631
632 cp = of_get_flat_dt_prop(node, "compatible", &cplen);
633 if (cp == NULL)
634 return 0;
635 while (cplen > 0) {
636 if (strncasecmp(cp, compat, strlen(compat)) == 0)
637 return 1;
638 l = strlen(cp) + 1;
639 cp += l;
640 cplen -= l;
641 }
642
643 return 0;
644}
645
615static void *__init unflatten_dt_alloc(unsigned long *mem, unsigned long size, 646static void *__init unflatten_dt_alloc(unsigned long *mem, unsigned long size,
616 unsigned long align) 647 unsigned long align)
617{ 648{
@@ -686,7 +717,7 @@ static unsigned long __init unflatten_dt_node(unsigned long mem,
686#ifdef DEBUG 717#ifdef DEBUG
687 if ((strlen(p) + l + 1) != allocl) { 718 if ((strlen(p) + l + 1) != allocl) {
688 DBG("%s: p: %d, l: %d, a: %d\n", 719 DBG("%s: p: %d, l: %d, a: %d\n",
689 pathp, strlen(p), l, allocl); 720 pathp, (int)strlen(p), l, allocl);
690 } 721 }
691#endif 722#endif
692 p += strlen(p); 723 p += strlen(p);
@@ -854,35 +885,73 @@ void __init unflatten_device_tree(void)
854 DBG(" <- unflatten_device_tree()\n"); 885 DBG(" <- unflatten_device_tree()\n");
855} 886}
856 887
857
858static int __init early_init_dt_scan_cpus(unsigned long node, 888static int __init early_init_dt_scan_cpus(unsigned long node,
859 const char *uname, int depth, void *data) 889 const char *uname, int depth,
890 void *data)
860{ 891{
892 static int logical_cpuid = 0;
893 char *type = of_get_flat_dt_prop(node, "device_type", NULL);
894#ifdef CONFIG_ALTIVEC
861 u32 *prop; 895 u32 *prop;
862 unsigned long size; 896#endif
863 char *type = of_get_flat_dt_prop(node, "device_type", &size); 897 u32 *intserv;
898 int i, nthreads;
899 unsigned long len;
900 int found = 0;
864 901
865 /* We are scanning "cpu" nodes only */ 902 /* We are scanning "cpu" nodes only */
866 if (type == NULL || strcmp(type, "cpu") != 0) 903 if (type == NULL || strcmp(type, "cpu") != 0)
867 return 0; 904 return 0;
868 905
869 boot_cpuid = 0; 906 /* Get physical cpuid */
870 boot_cpuid_phys = 0; 907 intserv = of_get_flat_dt_prop(node, "ibm,ppc-interrupt-server#s", &len);
871 if (initial_boot_params && initial_boot_params->version >= 2) { 908 if (intserv) {
872 /* version 2 of the kexec param format adds the phys cpuid 909 nthreads = len / sizeof(int);
873 * of booted proc.
874 */
875 boot_cpuid_phys = initial_boot_params->boot_cpuid_phys;
876 } else { 910 } else {
877 /* Check if it's the boot-cpu, set it's hw index now */ 911 intserv = of_get_flat_dt_prop(node, "reg", NULL);
878 if (of_get_flat_dt_prop(node, 912 nthreads = 1;
913 }
914
915 /*
916 * Now see if any of these threads match our boot cpu.
917 * NOTE: This must match the parsing done in smp_setup_cpu_maps.
918 */
919 for (i = 0; i < nthreads; i++) {
920 /*
921 * version 2 of the kexec param format adds the phys cpuid of
922 * booted proc.
923 */
924 if (initial_boot_params && initial_boot_params->version >= 2) {
925 if (intserv[i] ==
926 initial_boot_params->boot_cpuid_phys) {
927 found = 1;
928 break;
929 }
930 } else {
931 /*
932 * Check if it's the boot-cpu, set it's hw index now,
933 * unfortunately this format did not support booting
934 * off secondary threads.
935 */
936 if (of_get_flat_dt_prop(node,
879 "linux,boot-cpu", NULL) != NULL) { 937 "linux,boot-cpu", NULL) != NULL) {
880 prop = of_get_flat_dt_prop(node, "reg", NULL); 938 found = 1;
881 if (prop != NULL) 939 break;
882 boot_cpuid_phys = *prop; 940 }
883 } 941 }
942
943#ifdef CONFIG_SMP
944 /* logical cpu id is always 0 on UP kernels */
945 logical_cpuid++;
946#endif
947 }
948
949 if (found) {
950 DBG("boot cpu: logical %d physical %d\n", logical_cpuid,
951 intserv[i]);
952 boot_cpuid = logical_cpuid;
953 set_hard_smp_processor_id(boot_cpuid, intserv[i]);
884 } 954 }
885 set_hard_smp_processor_id(0, boot_cpuid_phys);
886 955
887#ifdef CONFIG_ALTIVEC 956#ifdef CONFIG_ALTIVEC
888 /* Check if we have a VMX and eventually update CPU features */ 957 /* Check if we have a VMX and eventually update CPU features */
@@ -901,16 +970,10 @@ static int __init early_init_dt_scan_cpus(unsigned long node,
901#endif /* CONFIG_ALTIVEC */ 970#endif /* CONFIG_ALTIVEC */
902 971
903#ifdef CONFIG_PPC_PSERIES 972#ifdef CONFIG_PPC_PSERIES
904 /* 973 if (nthreads > 1)
905 * Check for an SMT capable CPU and set the CPU feature. We do
906 * this by looking at the size of the ibm,ppc-interrupt-server#s
907 * property
908 */
909 prop = (u32 *)of_get_flat_dt_prop(node, "ibm,ppc-interrupt-server#s",
910 &size);
911 cur_cpu_spec->cpu_features &= ~CPU_FTR_SMT;
912 if (prop && ((size / sizeof(u32)) > 1))
913 cur_cpu_spec->cpu_features |= CPU_FTR_SMT; 974 cur_cpu_spec->cpu_features |= CPU_FTR_SMT;
975 else
976 cur_cpu_spec->cpu_features &= ~CPU_FTR_SMT;
914#endif 977#endif
915 978
916 return 0; 979 return 0;
@@ -919,7 +982,6 @@ static int __init early_init_dt_scan_cpus(unsigned long node,
919static int __init early_init_dt_scan_chosen(unsigned long node, 982static int __init early_init_dt_scan_chosen(unsigned long node,
920 const char *uname, int depth, void *data) 983 const char *uname, int depth, void *data)
921{ 984{
922 u32 *prop;
923 unsigned long *lprop; 985 unsigned long *lprop;
924 unsigned long l; 986 unsigned long l;
925 char *p; 987 char *p;
@@ -930,14 +992,6 @@ static int __init early_init_dt_scan_chosen(unsigned long node,
930 (strcmp(uname, "chosen") != 0 && strcmp(uname, "chosen@0") != 0)) 992 (strcmp(uname, "chosen") != 0 && strcmp(uname, "chosen@0") != 0))
931 return 0; 993 return 0;
932 994
933 /* get platform type */
934 prop = (u32 *)of_get_flat_dt_prop(node, "linux,platform", NULL);
935 if (prop == NULL)
936 return 0;
937#ifdef CONFIG_PPC_MULTIPLATFORM
938 _machine = *prop;
939#endif
940
941#ifdef CONFIG_PPC64 995#ifdef CONFIG_PPC64
942 /* check if iommu is forced on or off */ 996 /* check if iommu is forced on or off */
943 if (of_get_flat_dt_prop(node, "linux,iommu-off", NULL) != NULL) 997 if (of_get_flat_dt_prop(node, "linux,iommu-off", NULL) != NULL)
@@ -964,15 +1018,15 @@ static int __init early_init_dt_scan_chosen(unsigned long node,
964 * set of RTAS infos now if available 1018 * set of RTAS infos now if available
965 */ 1019 */
966 { 1020 {
967 u64 *basep, *entryp; 1021 u64 *basep, *entryp, *sizep;
968 1022
969 basep = of_get_flat_dt_prop(node, "linux,rtas-base", NULL); 1023 basep = of_get_flat_dt_prop(node, "linux,rtas-base", NULL);
970 entryp = of_get_flat_dt_prop(node, "linux,rtas-entry", NULL); 1024 entryp = of_get_flat_dt_prop(node, "linux,rtas-entry", NULL);
971 prop = of_get_flat_dt_prop(node, "linux,rtas-size", NULL); 1025 sizep = of_get_flat_dt_prop(node, "linux,rtas-size", NULL);
972 if (basep && entryp && prop) { 1026 if (basep && entryp && sizep) {
973 rtas.base = *basep; 1027 rtas.base = *basep;
974 rtas.entry = *entryp; 1028 rtas.entry = *entryp;
975 rtas.size = *prop; 1029 rtas.size = *sizep;
976 } 1030 }
977 } 1031 }
978#endif /* CONFIG_PPC_RTAS */ 1032#endif /* CONFIG_PPC_RTAS */
@@ -1001,25 +1055,13 @@ static int __init early_init_dt_scan_chosen(unsigned long node,
1001 1055
1002 if (strstr(cmd_line, "mem=")) { 1056 if (strstr(cmd_line, "mem=")) {
1003 char *p, *q; 1057 char *p, *q;
1004 unsigned long maxmem = 0;
1005 1058
1006 for (q = cmd_line; (p = strstr(q, "mem=")) != 0; ) { 1059 for (q = cmd_line; (p = strstr(q, "mem=")) != 0; ) {
1007 q = p + 4; 1060 q = p + 4;
1008 if (p > cmd_line && p[-1] != ' ') 1061 if (p > cmd_line && p[-1] != ' ')
1009 continue; 1062 continue;
1010 maxmem = simple_strtoul(q, &q, 0); 1063 memory_limit = memparse(q, &q);
1011 if (*q == 'k' || *q == 'K') {
1012 maxmem <<= 10;
1013 ++q;
1014 } else if (*q == 'm' || *q == 'M') {
1015 maxmem <<= 20;
1016 ++q;
1017 } else if (*q == 'g' || *q == 'G') {
1018 maxmem <<= 30;
1019 ++q;
1020 }
1021 } 1064 }
1022 memory_limit = maxmem;
1023 } 1065 }
1024 1066
1025 /* break now */ 1067 /* break now */
@@ -1755,7 +1797,7 @@ static int of_finish_dynamic_node(struct device_node *node)
1755 /* We don't support that function on PowerMac, at least 1797 /* We don't support that function on PowerMac, at least
1756 * not yet 1798 * not yet
1757 */ 1799 */
1758 if (_machine == PLATFORM_POWERMAC) 1800 if (machine_is(powermac))
1759 return -ENODEV; 1801 return -ENODEV;
1760 1802
1761 /* fix up new node's linux_phandle field */ 1803 /* fix up new node's linux_phandle field */
diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c
index 813c2cd194c2..d66c5e77fcff 100644
--- a/arch/powerpc/kernel/prom_init.c
+++ b/arch/powerpc/kernel/prom_init.c
@@ -180,6 +180,16 @@ static unsigned long __initdata prom_tce_alloc_start;
180static unsigned long __initdata prom_tce_alloc_end; 180static unsigned long __initdata prom_tce_alloc_end;
181#endif 181#endif
182 182
183/* Platforms codes are now obsolete in the kernel. Now only used within this
184 * file and ultimately gone too. Feel free to change them if you need, they
185 * are not shared with anything outside of this file anymore
186 */
187#define PLATFORM_PSERIES 0x0100
188#define PLATFORM_PSERIES_LPAR 0x0101
189#define PLATFORM_LPAR 0x0001
190#define PLATFORM_POWERMAC 0x0400
191#define PLATFORM_GENERIC 0x0500
192
183static int __initdata of_platform; 193static int __initdata of_platform;
184 194
185static char __initdata prom_cmd_line[COMMAND_LINE_SIZE]; 195static char __initdata prom_cmd_line[COMMAND_LINE_SIZE];
@@ -397,6 +407,11 @@ static void __init __attribute__((noreturn)) prom_panic(const char *reason)
397 reason = PTRRELOC(reason); 407 reason = PTRRELOC(reason);
398#endif 408#endif
399 prom_print(reason); 409 prom_print(reason);
410 /* Do not call exit because it clears the screen on pmac
411 * it also causes some sort of double-fault on early pmacs */
412 if (RELOC(of_platform) == PLATFORM_POWERMAC)
413 asm("trap\n");
414
400 /* ToDo: should put up an SRC here on p/iSeries */ 415 /* ToDo: should put up an SRC here on p/iSeries */
401 call_prom("exit", 0, 0); 416 call_prom("exit", 0, 0);
402 417
@@ -1487,7 +1502,10 @@ static int __init prom_find_machine_type(void)
1487 int len, i = 0; 1502 int len, i = 0;
1488#ifdef CONFIG_PPC64 1503#ifdef CONFIG_PPC64
1489 phandle rtas; 1504 phandle rtas;
1505 int x;
1490#endif 1506#endif
1507
1508 /* Look for a PowerMac */
1491 len = prom_getprop(_prom->root, "compatible", 1509 len = prom_getprop(_prom->root, "compatible",
1492 compat, sizeof(compat)-1); 1510 compat, sizeof(compat)-1);
1493 if (len > 0) { 1511 if (len > 0) {
@@ -1500,28 +1518,36 @@ static int __init prom_find_machine_type(void)
1500 if (strstr(p, RELOC("Power Macintosh")) || 1518 if (strstr(p, RELOC("Power Macintosh")) ||
1501 strstr(p, RELOC("MacRISC"))) 1519 strstr(p, RELOC("MacRISC")))
1502 return PLATFORM_POWERMAC; 1520 return PLATFORM_POWERMAC;
1503#ifdef CONFIG_PPC64
1504 if (strstr(p, RELOC("Momentum,Maple")))
1505 return PLATFORM_MAPLE;
1506 if (strstr(p, RELOC("IBM,CPB")))
1507 return PLATFORM_CELL;
1508#endif
1509 i += sl + 1; 1521 i += sl + 1;
1510 } 1522 }
1511 } 1523 }
1512#ifdef CONFIG_PPC64 1524#ifdef CONFIG_PPC64
1525 /* If not a mac, try to figure out if it's an IBM pSeries or any other
1526 * PAPR compliant platform. We assume it is if :
1527 * - /device_type is "chrp" (please, do NOT use that for future
1528 * non-IBM designs !
1529 * - it has /rtas
1530 */
1531 len = prom_getprop(_prom->root, "model",
1532 compat, sizeof(compat)-1);
1533 if (len <= 0)
1534 return PLATFORM_GENERIC;
1535 compat[len] = 0;
1536 if (strcmp(compat, "chrp"))
1537 return PLATFORM_GENERIC;
1538
1513 /* Default to pSeries. We need to know if we are running LPAR */ 1539 /* Default to pSeries. We need to know if we are running LPAR */
1514 rtas = call_prom("finddevice", 1, 1, ADDR("/rtas")); 1540 rtas = call_prom("finddevice", 1, 1, ADDR("/rtas"));
1515 if (PHANDLE_VALID(rtas)) { 1541 if (!PHANDLE_VALID(rtas))
1516 int x = prom_getproplen(rtas, "ibm,hypertas-functions"); 1542 return PLATFORM_GENERIC;
1517 if (x != PROM_ERROR) { 1543 x = prom_getproplen(rtas, "ibm,hypertas-functions");
1518 prom_printf("Hypertas detected, assuming LPAR !\n"); 1544 if (x != PROM_ERROR) {
1519 return PLATFORM_PSERIES_LPAR; 1545 prom_printf("Hypertas detected, assuming LPAR !\n");
1520 } 1546 return PLATFORM_PSERIES_LPAR;
1521 } 1547 }
1522 return PLATFORM_PSERIES; 1548 return PLATFORM_PSERIES;
1523#else 1549#else
1524 return PLATFORM_CHRP; 1550 return PLATFORM_GENERIC;
1525#endif 1551#endif
1526} 1552}
1527 1553
@@ -2029,7 +2055,6 @@ unsigned long __init prom_init(unsigned long r3, unsigned long r4,
2029{ 2055{
2030 struct prom_t *_prom; 2056 struct prom_t *_prom;
2031 unsigned long hdr; 2057 unsigned long hdr;
2032 u32 getprop_rval;
2033 unsigned long offset = reloc_offset(); 2058 unsigned long offset = reloc_offset();
2034 2059
2035#ifdef CONFIG_PPC32 2060#ifdef CONFIG_PPC32
@@ -2060,6 +2085,12 @@ unsigned long __init prom_init(unsigned long r3, unsigned long r4,
2060 */ 2085 */
2061 prom_init_stdout(); 2086 prom_init_stdout();
2062 2087
2088 /*
2089 * Get default machine type. At this point, we do not differentiate
2090 * between pSeries SMP and pSeries LPAR
2091 */
2092 RELOC(of_platform) = prom_find_machine_type();
2093
2063 /* Bail if this is a kdump kernel. */ 2094 /* Bail if this is a kdump kernel. */
2064 if (PHYSICAL_START > 0) 2095 if (PHYSICAL_START > 0)
2065 prom_panic("Error: You can't boot a kdump kernel from OF!\n"); 2096 prom_panic("Error: You can't boot a kdump kernel from OF!\n");
@@ -2069,15 +2100,6 @@ unsigned long __init prom_init(unsigned long r3, unsigned long r4,
2069 */ 2100 */
2070 prom_check_initrd(r3, r4); 2101 prom_check_initrd(r3, r4);
2071 2102
2072 /*
2073 * Get default machine type. At this point, we do not differentiate
2074 * between pSeries SMP and pSeries LPAR
2075 */
2076 RELOC(of_platform) = prom_find_machine_type();
2077 getprop_rval = RELOC(of_platform);
2078 prom_setprop(_prom->chosen, "/chosen", "linux,platform",
2079 &getprop_rval, sizeof(getprop_rval));
2080
2081#ifdef CONFIG_PPC_PSERIES 2103#ifdef CONFIG_PPC_PSERIES
2082 /* 2104 /*
2083 * On pSeries, inform the firmware about our capabilities 2105 * On pSeries, inform the firmware about our capabilities
diff --git a/arch/powerpc/kernel/rtas-proc.c b/arch/powerpc/kernel/rtas-proc.c
index 1f03fb28cc0a..456286cf1d14 100644
--- a/arch/powerpc/kernel/rtas-proc.c
+++ b/arch/powerpc/kernel/rtas-proc.c
@@ -257,7 +257,7 @@ static int __init proc_rtas_init(void)
257{ 257{
258 struct proc_dir_entry *entry; 258 struct proc_dir_entry *entry;
259 259
260 if (_machine != PLATFORM_PSERIES && _machine != PLATFORM_PSERIES_LPAR) 260 if (!machine_is(pseries))
261 return 1; 261 return 1;
262 262
263 rtas_node = of_find_node_by_name(NULL, "rtas"); 263 rtas_node = of_find_node_by_name(NULL, "rtas");
diff --git a/arch/powerpc/kernel/rtas.c b/arch/powerpc/kernel/rtas.c
index b5b2add7ad1e..06636c927a7e 100644
--- a/arch/powerpc/kernel/rtas.c
+++ b/arch/powerpc/kernel/rtas.c
@@ -25,6 +25,7 @@
25#include <asm/hvcall.h> 25#include <asm/hvcall.h>
26#include <asm/semaphore.h> 26#include <asm/semaphore.h>
27#include <asm/machdep.h> 27#include <asm/machdep.h>
28#include <asm/firmware.h>
28#include <asm/page.h> 29#include <asm/page.h>
29#include <asm/param.h> 30#include <asm/param.h>
30#include <asm/system.h> 31#include <asm/system.h>
@@ -32,6 +33,7 @@
32#include <asm/uaccess.h> 33#include <asm/uaccess.h>
33#include <asm/lmb.h> 34#include <asm/lmb.h>
34#include <asm/udbg.h> 35#include <asm/udbg.h>
36#include <asm/syscalls.h>
35 37
36struct rtas_t rtas = { 38struct rtas_t rtas = {
37 .lock = SPIN_LOCK_UNLOCKED 39 .lock = SPIN_LOCK_UNLOCKED
@@ -591,7 +593,7 @@ static void rtas_percpu_suspend_me(void *info)
591 data->waiting = 0; 593 data->waiting = 0;
592 data->args->args[data->args->nargs] = 594 data->args->args[data->args->nargs] =
593 rtas_call(ibm_suspend_me_token, 0, 1, NULL); 595 rtas_call(ibm_suspend_me_token, 0, 1, NULL);
594 for_each_cpu(i) 596 for_each_possible_cpu(i)
595 plpar_hcall_norets(H_PROD,i); 597 plpar_hcall_norets(H_PROD,i);
596 } else { 598 } else {
597 data->waiting = -EBUSY; 599 data->waiting = -EBUSY;
@@ -624,7 +626,7 @@ static int rtas_ibm_suspend_me(struct rtas_args *args)
624 /* Prod each CPU. This won't hurt, and will wake 626 /* Prod each CPU. This won't hurt, and will wake
625 * anyone we successfully put to sleep with H_Join 627 * anyone we successfully put to sleep with H_Join
626 */ 628 */
627 for_each_cpu(i) 629 for_each_possible_cpu(i)
628 plpar_hcall_norets(H_PROD, i); 630 plpar_hcall_norets(H_PROD, i);
629 631
630 return data.waiting; 632 return data.waiting;
@@ -767,7 +769,7 @@ void __init rtas_initialize(void)
767 * the stop-self token if any 769 * the stop-self token if any
768 */ 770 */
769#ifdef CONFIG_PPC64 771#ifdef CONFIG_PPC64
770 if (_machine == PLATFORM_PSERIES_LPAR) { 772 if (machine_is(pseries) && firmware_has_feature(FW_FEATURE_LPAR)) {
771 rtas_region = min(lmb.rmo_size, RTAS_INSTANTIATE_MAX); 773 rtas_region = min(lmb.rmo_size, RTAS_INSTANTIATE_MAX);
772 ibm_suspend_me_token = rtas_token("ibm,suspend-me"); 774 ibm_suspend_me_token = rtas_token("ibm,suspend-me");
773 } 775 }
diff --git a/arch/powerpc/kernel/setup-common.c b/arch/powerpc/kernel/setup-common.c
index c1d62bf11f29..c607f3b9ca17 100644
--- a/arch/powerpc/kernel/setup-common.c
+++ b/arch/powerpc/kernel/setup-common.c
@@ -9,6 +9,9 @@
9 * as published by the Free Software Foundation; either version 9 * as published by the Free Software Foundation; either version
10 * 2 of the License, or (at your option) any later version. 10 * 2 of the License, or (at your option) any later version.
11 */ 11 */
12
13#undef DEBUG
14
12#include <linux/config.h> 15#include <linux/config.h>
13#include <linux/module.h> 16#include <linux/module.h>
14#include <linux/string.h> 17#include <linux/string.h>
@@ -41,6 +44,7 @@
41#include <asm/time.h> 44#include <asm/time.h>
42#include <asm/cputable.h> 45#include <asm/cputable.h>
43#include <asm/sections.h> 46#include <asm/sections.h>
47#include <asm/firmware.h>
44#include <asm/btext.h> 48#include <asm/btext.h>
45#include <asm/nvram.h> 49#include <asm/nvram.h>
46#include <asm/setup.h> 50#include <asm/setup.h>
@@ -56,8 +60,6 @@
56 60
57#include "setup.h" 61#include "setup.h"
58 62
59#undef DEBUG
60
61#ifdef DEBUG 63#ifdef DEBUG
62#include <asm/udbg.h> 64#include <asm/udbg.h>
63#define DBG(fmt...) udbg_printf(fmt) 65#define DBG(fmt...) udbg_printf(fmt)
@@ -65,10 +67,12 @@
65#define DBG(fmt...) 67#define DBG(fmt...)
66#endif 68#endif
67 69
68#ifdef CONFIG_PPC_MULTIPLATFORM 70/* The main machine-dep calls structure
69int _machine = 0; 71 */
70EXPORT_SYMBOL(_machine); 72struct machdep_calls ppc_md;
71#endif 73EXPORT_SYMBOL(ppc_md);
74struct machdep_calls *machine_id;
75EXPORT_SYMBOL(machine_id);
72 76
73unsigned long klimit = (unsigned long) _end; 77unsigned long klimit = (unsigned long) _end;
74 78
@@ -168,7 +172,8 @@ static int show_cpuinfo(struct seq_file *m, void *v)
168 bogosum/(500000/HZ), bogosum/(5000/HZ) % 100); 172 bogosum/(500000/HZ), bogosum/(5000/HZ) % 100);
169#endif /* CONFIG_SMP && CONFIG_PPC32 */ 173#endif /* CONFIG_SMP && CONFIG_PPC32 */
170 seq_printf(m, "timebase\t: %lu\n", ppc_tb_freq); 174 seq_printf(m, "timebase\t: %lu\n", ppc_tb_freq);
171 175 if (ppc_md.name)
176 seq_printf(m, "platform\t: %s\n", ppc_md.name);
172 if (ppc_md.show_cpuinfo != NULL) 177 if (ppc_md.show_cpuinfo != NULL)
173 ppc_md.show_cpuinfo(m); 178 ppc_md.show_cpuinfo(m);
174 179
@@ -352,12 +357,13 @@ void __init check_for_initrd(void)
352 * must be called before using this. 357 * must be called before using this.
353 * 358 *
354 * While we're here, we may as well set the "physical" cpu ids in the paca. 359 * While we're here, we may as well set the "physical" cpu ids in the paca.
360 *
361 * NOTE: This must match the parsing done in early_init_dt_scan_cpus.
355 */ 362 */
356void __init smp_setup_cpu_maps(void) 363void __init smp_setup_cpu_maps(void)
357{ 364{
358 struct device_node *dn = NULL; 365 struct device_node *dn = NULL;
359 int cpu = 0; 366 int cpu = 0;
360 int swap_cpuid = 0;
361 367
362 while ((dn = of_find_node_by_type(dn, "cpu")) && cpu < NR_CPUS) { 368 while ((dn = of_find_node_by_type(dn, "cpu")) && cpu < NR_CPUS) {
363 int *intserv; 369 int *intserv;
@@ -376,30 +382,17 @@ void __init smp_setup_cpu_maps(void)
376 for (j = 0; j < nthreads && cpu < NR_CPUS; j++) { 382 for (j = 0; j < nthreads && cpu < NR_CPUS; j++) {
377 cpu_set(cpu, cpu_present_map); 383 cpu_set(cpu, cpu_present_map);
378 set_hard_smp_processor_id(cpu, intserv[j]); 384 set_hard_smp_processor_id(cpu, intserv[j]);
379
380 if (intserv[j] == boot_cpuid_phys)
381 swap_cpuid = cpu;
382 cpu_set(cpu, cpu_possible_map); 385 cpu_set(cpu, cpu_possible_map);
383 cpu++; 386 cpu++;
384 } 387 }
385 } 388 }
386 389
387 /* Swap CPU id 0 with boot_cpuid_phys, so we can always assume that
388 * boot cpu is logical 0.
389 */
390 if (boot_cpuid_phys != get_hard_smp_processor_id(0)) {
391 u32 tmp;
392 tmp = get_hard_smp_processor_id(0);
393 set_hard_smp_processor_id(0, boot_cpuid_phys);
394 set_hard_smp_processor_id(swap_cpuid, tmp);
395 }
396
397#ifdef CONFIG_PPC64 390#ifdef CONFIG_PPC64
398 /* 391 /*
399 * On pSeries LPAR, we need to know how many cpus 392 * On pSeries LPAR, we need to know how many cpus
400 * could possibly be added to this partition. 393 * could possibly be added to this partition.
401 */ 394 */
402 if (_machine == PLATFORM_PSERIES_LPAR && 395 if (machine_is(pseries) && firmware_has_feature(FW_FEATURE_LPAR) &&
403 (dn = of_find_node_by_path("/rtas"))) { 396 (dn = of_find_node_by_path("/rtas"))) {
404 int num_addr_cell, num_size_cell, maxcpus; 397 int num_addr_cell, num_size_cell, maxcpus;
405 unsigned int *ireg; 398 unsigned int *ireg;
@@ -438,7 +431,7 @@ void __init smp_setup_cpu_maps(void)
438 /* 431 /*
439 * Do the sibling map; assume only two threads per processor. 432 * Do the sibling map; assume only two threads per processor.
440 */ 433 */
441 for_each_cpu(cpu) { 434 for_each_possible_cpu(cpu) {
442 cpu_set(cpu, cpu_sibling_map[cpu]); 435 cpu_set(cpu, cpu_sibling_map[cpu]);
443 if (cpu_has_feature(CPU_FTR_SMT)) 436 if (cpu_has_feature(CPU_FTR_SMT))
444 cpu_set(cpu ^ 0x1, cpu_sibling_map[cpu]); 437 cpu_set(cpu ^ 0x1, cpu_sibling_map[cpu]);
@@ -468,3 +461,34 @@ static int __init early_xmon(char *p)
468} 461}
469early_param("xmon", early_xmon); 462early_param("xmon", early_xmon);
470#endif 463#endif
464
465void probe_machine(void)
466{
467 extern struct machdep_calls __machine_desc_start;
468 extern struct machdep_calls __machine_desc_end;
469
470 /*
471 * Iterate all ppc_md structures until we find the proper
472 * one for the current machine type
473 */
474 DBG("Probing machine type ...\n");
475
476 for (machine_id = &__machine_desc_start;
477 machine_id < &__machine_desc_end;
478 machine_id++) {
479 DBG(" %s ...", machine_id->name);
480 memcpy(&ppc_md, machine_id, sizeof(struct machdep_calls));
481 if (ppc_md.probe()) {
482 DBG(" match !\n");
483 break;
484 }
485 DBG("\n");
486 }
487 /* What can we do if we didn't find ? */
488 if (machine_id >= &__machine_desc_end) {
489 DBG("No suitable machine found !\n");
490 for (;;);
491 }
492
493 printk(KERN_INFO "Using %s machine description\n", ppc_md.name);
494}
diff --git a/arch/powerpc/kernel/setup_32.c b/arch/powerpc/kernel/setup_32.c
index dc2770df25b3..a72bf5dceeee 100644
--- a/arch/powerpc/kernel/setup_32.c
+++ b/arch/powerpc/kernel/setup_32.c
@@ -53,9 +53,6 @@
53extern void platform_init(void); 53extern void platform_init(void);
54extern void bootx_init(unsigned long r4, unsigned long phys); 54extern void bootx_init(unsigned long r4, unsigned long phys);
55 55
56extern void ppc6xx_idle(void);
57extern void power4_idle(void);
58
59boot_infos_t *boot_infos; 56boot_infos_t *boot_infos;
60struct ide_machdep_calls ppc_ide_md; 57struct ide_machdep_calls ppc_ide_md;
61 58
@@ -70,10 +67,6 @@ unsigned int DMA_MODE_WRITE;
70int have_of = 1; 67int have_of = 1;
71 68
72#ifdef CONFIG_PPC_MULTIPLATFORM 69#ifdef CONFIG_PPC_MULTIPLATFORM
73extern void prep_init(void);
74extern void pmac_init(void);
75extern void chrp_init(void);
76
77dev_t boot_dev; 70dev_t boot_dev;
78#endif /* CONFIG_PPC_MULTIPLATFORM */ 71#endif /* CONFIG_PPC_MULTIPLATFORM */
79 72
@@ -85,9 +78,6 @@ unsigned long SYSRQ_KEY = 0x54;
85unsigned long vgacon_remap_base; 78unsigned long vgacon_remap_base;
86#endif 79#endif
87 80
88struct machdep_calls ppc_md;
89EXPORT_SYMBOL(ppc_md);
90
91/* 81/*
92 * These are used in binfmt_elf.c to put aux entries on the stack 82 * These are used in binfmt_elf.c to put aux entries on the stack
93 * for each elf executable being started. 83 * for each elf executable being started.
@@ -111,7 +101,7 @@ unsigned long __init early_init(unsigned long dt_ptr)
111 101
112 /* First zero the BSS -- use memset_io, some platforms don't have 102 /* First zero the BSS -- use memset_io, some platforms don't have
113 * caches on yet */ 103 * caches on yet */
114 memset_io(PTRRELOC(&__bss_start), 0, _end - __bss_start); 104 memset_io((void __iomem *)PTRRELOC(&__bss_start), 0, _end - __bss_start);
115 105
116 /* 106 /*
117 * Identify the CPU type and fix up code sections 107 * Identify the CPU type and fix up code sections
@@ -123,48 +113,6 @@ unsigned long __init early_init(unsigned long dt_ptr)
123 return KERNELBASE + offset; 113 return KERNELBASE + offset;
124} 114}
125 115
126#ifdef CONFIG_PPC_MULTIPLATFORM
127/*
128 * The PPC_MULTIPLATFORM version of platform_init...
129 */
130void __init platform_init(void)
131{
132 /* if we didn't get any bootinfo telling us what we are... */
133 if (_machine == 0) {
134 /* prep boot loader tells us if we're prep or not */
135 if ( *(unsigned long *)(KERNELBASE) == (0xdeadc0de) )
136 _machine = _MACH_prep;
137 }
138
139#ifdef CONFIG_PPC_PREP
140 /* not much more to do here, if prep */
141 if (_machine == _MACH_prep) {
142 prep_init();
143 return;
144 }
145#endif
146
147#ifdef CONFIG_ADB
148 if (strstr(cmd_line, "adb_sync")) {
149 extern int __adb_probe_sync;
150 __adb_probe_sync = 1;
151 }
152#endif /* CONFIG_ADB */
153
154 switch (_machine) {
155#ifdef CONFIG_PPC_PMAC
156 case _MACH_Pmac:
157 pmac_init();
158 break;
159#endif
160#ifdef CONFIG_PPC_CHRP
161 case _MACH_chrp:
162 chrp_init();
163 break;
164#endif
165 }
166}
167#endif
168 116
169/* 117/*
170 * Find out what kind of machine we're on and save any data we need 118 * Find out what kind of machine we're on and save any data we need
@@ -190,11 +138,17 @@ void __init machine_init(unsigned long dt_ptr, unsigned long phys)
190 strlcpy(cmd_line, CONFIG_CMDLINE, sizeof(cmd_line)); 138 strlcpy(cmd_line, CONFIG_CMDLINE, sizeof(cmd_line));
191#endif /* CONFIG_CMDLINE */ 139#endif /* CONFIG_CMDLINE */
192 140
193 /* Base init based on machine type */ 141#ifdef CONFIG_PPC_MULTIPLATFORM
142 probe_machine();
143#else
144 /* Base init based on machine type. Obsoloete, please kill ! */
194 platform_init(); 145 platform_init();
146#endif
195 147
196#ifdef CONFIG_6xx 148#ifdef CONFIG_6xx
197 ppc_md.power_save = ppc6xx_idle; 149 if (cpu_has_feature(CPU_FTR_CAN_DOZE) ||
150 cpu_has_feature(CPU_FTR_CAN_NAP))
151 ppc_md.power_save = ppc6xx_idle;
198#endif 152#endif
199 153
200 if (ppc_md.progress) 154 if (ppc_md.progress)
@@ -272,7 +226,7 @@ int __init ppc_init(void)
272 if ( ppc_md.progress ) ppc_md.progress(" ", 0xffff); 226 if ( ppc_md.progress ) ppc_md.progress(" ", 0xffff);
273 227
274 /* register CPU devices */ 228 /* register CPU devices */
275 for_each_cpu(i) 229 for_each_possible_cpu(i)
276 register_cpu(&cpu_devices[i], i, NULL); 230 register_cpu(&cpu_devices[i], i, NULL);
277 231
278 /* call platform init */ 232 /* call platform init */
@@ -352,12 +306,6 @@ void __init setup_arch(char **cmdline_p)
352 do_init_bootmem(); 306 do_init_bootmem();
353 if ( ppc_md.progress ) ppc_md.progress("setup_arch: bootmem", 0x3eab); 307 if ( ppc_md.progress ) ppc_md.progress("setup_arch: bootmem", 0x3eab);
354 308
355#ifdef CONFIG_PPC_OCP
356 /* Initialize OCP device list */
357 ocp_early_init();
358 if ( ppc_md.progress ) ppc_md.progress("ocp: exit", 0x3eab);
359#endif
360
361#ifdef CONFIG_DUMMY_CONSOLE 309#ifdef CONFIG_DUMMY_CONSOLE
362 conswitchp = &dummy_con; 310 conswitchp = &dummy_con;
363#endif 311#endif
@@ -366,7 +314,4 @@ void __init setup_arch(char **cmdline_p)
366 if ( ppc_md.progress ) ppc_md.progress("arch: exit", 0x3eab); 314 if ( ppc_md.progress ) ppc_md.progress("arch: exit", 0x3eab);
367 315
368 paging_init(); 316 paging_init();
369
370 /* this is for modules since _machine can be a define -- Cort */
371 ppc_md.ppc_machine = _machine;
372} 317}
diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c
index e20c1fae3423..59aa92cd6fa4 100644
--- a/arch/powerpc/kernel/setup_64.c
+++ b/arch/powerpc/kernel/setup_64.c
@@ -73,7 +73,6 @@
73 73
74int have_of = 1; 74int have_of = 1;
75int boot_cpuid = 0; 75int boot_cpuid = 0;
76int boot_cpuid_phys = 0;
77dev_t boot_dev; 76dev_t boot_dev;
78u64 ppc64_pft_size; 77u64 ppc64_pft_size;
79 78
@@ -96,11 +95,6 @@ int dcache_bsize;
96int icache_bsize; 95int icache_bsize;
97int ucache_bsize; 96int ucache_bsize;
98 97
99/* The main machine-dep calls structure
100 */
101struct machdep_calls ppc_md;
102EXPORT_SYMBOL(ppc_md);
103
104#ifdef CONFIG_MAGIC_SYSRQ 98#ifdef CONFIG_MAGIC_SYSRQ
105unsigned long SYSRQ_KEY; 99unsigned long SYSRQ_KEY;
106#endif /* CONFIG_MAGIC_SYSRQ */ 100#endif /* CONFIG_MAGIC_SYSRQ */
@@ -161,32 +155,6 @@ early_param("smt-enabled", early_smt_enabled);
161#define check_smt_enabled() 155#define check_smt_enabled()
162#endif /* CONFIG_SMP */ 156#endif /* CONFIG_SMP */
163 157
164extern struct machdep_calls pSeries_md;
165extern struct machdep_calls pmac_md;
166extern struct machdep_calls maple_md;
167extern struct machdep_calls cell_md;
168extern struct machdep_calls iseries_md;
169
170/* Ultimately, stuff them in an elf section like initcalls... */
171static struct machdep_calls __initdata *machines[] = {
172#ifdef CONFIG_PPC_PSERIES
173 &pSeries_md,
174#endif /* CONFIG_PPC_PSERIES */
175#ifdef CONFIG_PPC_PMAC
176 &pmac_md,
177#endif /* CONFIG_PPC_PMAC */
178#ifdef CONFIG_PPC_MAPLE
179 &maple_md,
180#endif /* CONFIG_PPC_MAPLE */
181#ifdef CONFIG_PPC_CELL
182 &cell_md,
183#endif
184#ifdef CONFIG_PPC_ISERIES
185 &iseries_md,
186#endif
187 NULL
188};
189
190/* 158/*
191 * Early initialization entry point. This is called by head.S 159 * Early initialization entry point. This is called by head.S
192 * with MMU translation disabled. We rely on the "feature" of 160 * with MMU translation disabled. We rely on the "feature" of
@@ -208,13 +176,10 @@ static struct machdep_calls __initdata *machines[] = {
208 176
209void __init early_setup(unsigned long dt_ptr) 177void __init early_setup(unsigned long dt_ptr)
210{ 178{
211 struct paca_struct *lpaca = get_paca();
212 static struct machdep_calls **mach;
213
214 /* Enable early debugging if any specified (see udbg.h) */ 179 /* Enable early debugging if any specified (see udbg.h) */
215 udbg_early_init(); 180 udbg_early_init();
216 181
217 DBG(" -> early_setup()\n"); 182 DBG(" -> early_setup(), dt_ptr: 0x%lx\n", dt_ptr);
218 183
219 /* 184 /*
220 * Do early initializations using the flattened device 185 * Do early initializations using the flattened device
@@ -223,22 +188,16 @@ void __init early_setup(unsigned long dt_ptr)
223 */ 188 */
224 early_init_devtree(__va(dt_ptr)); 189 early_init_devtree(__va(dt_ptr));
225 190
226 /* 191 /* Now we know the logical id of our boot cpu, setup the paca. */
227 * Iterate all ppc_md structures until we find the proper 192 setup_boot_paca();
228 * one for the current machine type
229 */
230 DBG("Probing machine type for platform %x...\n", _machine);
231 193
232 for (mach = machines; *mach; mach++) { 194 /* Fix up paca fields required for the boot cpu */
233 if ((*mach)->probe(_machine)) 195 get_paca()->cpu_start = 1;
234 break; 196 get_paca()->stab_real = __pa((u64)&initial_stab);
235 } 197 get_paca()->stab_addr = (u64)&initial_stab;
236 /* What can we do if we didn't find ? */ 198
237 if (*mach == NULL) { 199 /* Probe the machine type */
238 DBG("No suitable machine found !\n"); 200 probe_machine();
239 for (;;);
240 }
241 ppc_md = **mach;
242 201
243#ifdef CONFIG_CRASH_DUMP 202#ifdef CONFIG_CRASH_DUMP
244 kdump_setup(); 203 kdump_setup();
@@ -260,7 +219,7 @@ void __init early_setup(unsigned long dt_ptr)
260 if (cpu_has_feature(CPU_FTR_SLB)) 219 if (cpu_has_feature(CPU_FTR_SLB))
261 slb_initialize(); 220 slb_initialize();
262 else 221 else
263 stab_initialize(lpaca->stab_real); 222 stab_initialize(get_paca()->stab_real);
264 } 223 }
265 224
266 DBG(" <- early_setup()\n"); 225 DBG(" <- early_setup()\n");
@@ -340,7 +299,7 @@ static void __init initialize_cache_info(void)
340 const char *dc, *ic; 299 const char *dc, *ic;
341 300
342 /* Then read cache informations */ 301 /* Then read cache informations */
343 if (_machine == PLATFORM_POWERMAC) { 302 if (machine_is(powermac)) {
344 dc = "d-cache-block-size"; 303 dc = "d-cache-block-size";
345 ic = "i-cache-block-size"; 304 ic = "i-cache-block-size";
346 } else { 305 } else {
@@ -484,7 +443,6 @@ void __init setup_system(void)
484 printk("ppc64_pft_size = 0x%lx\n", ppc64_pft_size); 443 printk("ppc64_pft_size = 0x%lx\n", ppc64_pft_size);
485 printk("ppc64_interrupt_controller = 0x%ld\n", 444 printk("ppc64_interrupt_controller = 0x%ld\n",
486 ppc64_interrupt_controller); 445 ppc64_interrupt_controller);
487 printk("platform = 0x%x\n", _machine);
488 printk("physicalMemorySize = 0x%lx\n", lmb_phys_mem_size()); 446 printk("physicalMemorySize = 0x%lx\n", lmb_phys_mem_size());
489 printk("ppc64_caches.dcache_line_size = 0x%x\n", 447 printk("ppc64_caches.dcache_line_size = 0x%x\n",
490 ppc64_caches.dline_size); 448 ppc64_caches.dline_size);
@@ -516,7 +474,7 @@ static void __init irqstack_early_init(void)
516 * interrupt stacks must be under 256MB, we cannot afford to take 474 * interrupt stacks must be under 256MB, we cannot afford to take
517 * SLB misses on them. 475 * SLB misses on them.
518 */ 476 */
519 for_each_cpu(i) { 477 for_each_possible_cpu(i) {
520 softirq_ctx[i] = (struct thread_info *) 478 softirq_ctx[i] = (struct thread_info *)
521 __va(lmb_alloc_base(THREAD_SIZE, 479 __va(lmb_alloc_base(THREAD_SIZE,
522 THREAD_SIZE, 0x10000000)); 480 THREAD_SIZE, 0x10000000));
@@ -549,7 +507,7 @@ static void __init emergency_stack_init(void)
549 */ 507 */
550 limit = min(0x10000000UL, lmb.rmo_size); 508 limit = min(0x10000000UL, lmb.rmo_size);
551 509
552 for_each_cpu(i) 510 for_each_possible_cpu(i)
553 paca[i].emergency_sp = 511 paca[i].emergency_sp =
554 __va(lmb_alloc_base(HW_PAGE_SIZE, 128, limit)) + HW_PAGE_SIZE; 512 __va(lmb_alloc_base(HW_PAGE_SIZE, 128, limit)) + HW_PAGE_SIZE;
555} 513}
@@ -602,12 +560,6 @@ void __init setup_arch(char **cmdline_p)
602 560
603 ppc_md.setup_arch(); 561 ppc_md.setup_arch();
604 562
605 /* Use the default idle loop if the platform hasn't provided one. */
606 if (NULL == ppc_md.idle_loop) {
607 ppc_md.idle_loop = default_idle;
608 printk(KERN_INFO "Using default idle loop\n");
609 }
610
611 paging_init(); 563 paging_init();
612 ppc64_boot_msg(0x15, "Setup Done"); 564 ppc64_boot_msg(0x15, "Setup Done");
613} 565}
@@ -672,7 +624,7 @@ void __init setup_per_cpu_areas(void)
672 size = PERCPU_ENOUGH_ROOM; 624 size = PERCPU_ENOUGH_ROOM;
673#endif 625#endif
674 626
675 for_each_cpu(i) { 627 for_each_possible_cpu(i) {
676 ptr = alloc_bootmem_node(NODE_DATA(cpu_to_node(i)), size); 628 ptr = alloc_bootmem_node(NODE_DATA(cpu_to_node(i)), size);
677 if (!ptr) 629 if (!ptr)
678 panic("Cannot allocate cpu data for CPU %d\n", i); 630 panic("Cannot allocate cpu data for CPU %d\n", i);
diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c
index d7a4e814974d..01e3c08cb550 100644
--- a/arch/powerpc/kernel/signal_32.c
+++ b/arch/powerpc/kernel/signal_32.c
@@ -42,6 +42,7 @@
42 42
43#include <asm/uaccess.h> 43#include <asm/uaccess.h>
44#include <asm/cacheflush.h> 44#include <asm/cacheflush.h>
45#include <asm/syscalls.h>
45#include <asm/sigcontext.h> 46#include <asm/sigcontext.h>
46#include <asm/vdso.h> 47#include <asm/vdso.h>
47#ifdef CONFIG_PPC64 48#ifdef CONFIG_PPC64
diff --git a/arch/powerpc/kernel/signal_64.c b/arch/powerpc/kernel/signal_64.c
index 47f910380a6a..27f65b95184d 100644
--- a/arch/powerpc/kernel/signal_64.c
+++ b/arch/powerpc/kernel/signal_64.c
@@ -33,6 +33,7 @@
33#include <asm/pgtable.h> 33#include <asm/pgtable.h>
34#include <asm/unistd.h> 34#include <asm/unistd.h>
35#include <asm/cacheflush.h> 35#include <asm/cacheflush.h>
36#include <asm/syscalls.h>
36#include <asm/vdso.h> 37#include <asm/vdso.h>
37 38
38#define DEBUG_SIG 0 39#define DEBUG_SIG 0
@@ -211,7 +212,7 @@ static inline void __user * get_sigframe(struct k_sigaction *ka, struct pt_regs
211 /* Default to using normal stack */ 212 /* Default to using normal stack */
212 newsp = regs->gpr[1]; 213 newsp = regs->gpr[1];
213 214
214 if (ka->sa.sa_flags & SA_ONSTACK) { 215 if ((ka->sa.sa_flags & SA_ONSTACK) && current->sas_ss_size) {
215 if (! on_sig_stack(regs->gpr[1])) 216 if (! on_sig_stack(regs->gpr[1]))
216 newsp = (current->sas_ss_sp + current->sas_ss_size); 217 newsp = (current->sas_ss_sp + current->sas_ss_size);
217 } 218 }
diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c
index 805eaedbc308..530f7dba0bd2 100644
--- a/arch/powerpc/kernel/smp.c
+++ b/arch/powerpc/kernel/smp.c
@@ -362,7 +362,7 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
362 362
363 smp_space_timers(max_cpus); 363 smp_space_timers(max_cpus);
364 364
365 for_each_cpu(cpu) 365 for_each_possible_cpu(cpu)
366 if (cpu != boot_cpuid) 366 if (cpu != boot_cpuid)
367 smp_create_idle(cpu); 367 smp_create_idle(cpu);
368} 368}
diff --git a/arch/ppc/kernel/swsusp.S b/arch/powerpc/kernel/swsusp_32.S
index 69773cc1a85f..69773cc1a85f 100644
--- a/arch/ppc/kernel/swsusp.S
+++ b/arch/powerpc/kernel/swsusp_32.S
diff --git a/arch/powerpc/kernel/syscalls.c b/arch/powerpc/kernel/syscalls.c
index ad895c99813b..9b69d99a9103 100644
--- a/arch/powerpc/kernel/syscalls.c
+++ b/arch/powerpc/kernel/syscalls.c
@@ -40,6 +40,7 @@
40#include <asm/uaccess.h> 40#include <asm/uaccess.h>
41#include <asm/ipc.h> 41#include <asm/ipc.h>
42#include <asm/semaphore.h> 42#include <asm/semaphore.h>
43#include <asm/syscalls.h>
43#include <asm/time.h> 44#include <asm/time.h>
44#include <asm/unistd.h> 45#include <asm/unistd.h>
45 46
diff --git a/arch/powerpc/kernel/sysfs.c b/arch/powerpc/kernel/sysfs.c
index 0f0c3a9ae2e5..73560ef6f802 100644
--- a/arch/powerpc/kernel/sysfs.c
+++ b/arch/powerpc/kernel/sysfs.c
@@ -65,20 +65,20 @@ static int __init smt_setup(void)
65 unsigned int cpu; 65 unsigned int cpu;
66 66
67 if (!cpu_has_feature(CPU_FTR_SMT)) 67 if (!cpu_has_feature(CPU_FTR_SMT))
68 return 1; 68 return -ENODEV;
69 69
70 options = find_path_device("/options"); 70 options = find_path_device("/options");
71 if (!options) 71 if (!options)
72 return 1; 72 return -ENODEV;
73 73
74 val = (unsigned int *)get_property(options, "ibm,smt-snooze-delay", 74 val = (unsigned int *)get_property(options, "ibm,smt-snooze-delay",
75 NULL); 75 NULL);
76 if (!smt_snooze_cmdline && val) { 76 if (!smt_snooze_cmdline && val) {
77 for_each_cpu(cpu) 77 for_each_possible_cpu(cpu)
78 per_cpu(smt_snooze_delay, cpu) = *val; 78 per_cpu(smt_snooze_delay, cpu) = *val;
79 } 79 }
80 80
81 return 1; 81 return 0;
82} 82}
83__initcall(smt_setup); 83__initcall(smt_setup);
84 84
@@ -93,7 +93,7 @@ static int __init setup_smt_snooze_delay(char *str)
93 smt_snooze_cmdline = 1; 93 smt_snooze_cmdline = 1;
94 94
95 if (get_option(&str, &snooze)) { 95 if (get_option(&str, &snooze)) {
96 for_each_cpu(cpu) 96 for_each_possible_cpu(cpu)
97 per_cpu(smt_snooze_delay, cpu) = snooze; 97 per_cpu(smt_snooze_delay, cpu) = snooze;
98 } 98 }
99 99
@@ -347,7 +347,7 @@ static int __init topology_init(void)
347 347
348 register_cpu_notifier(&sysfs_cpu_nb); 348 register_cpu_notifier(&sysfs_cpu_nb);
349 349
350 for_each_cpu(cpu) { 350 for_each_possible_cpu(cpu) {
351 struct cpu *c = &per_cpu(cpu_devices, cpu); 351 struct cpu *c = &per_cpu(cpu_devices, cpu);
352 352
353#ifdef CONFIG_NUMA 353#ifdef CONFIG_NUMA
diff --git a/arch/ppc/kernel/temp.c b/arch/powerpc/kernel/tau_6xx.c
index 26bd8ea35a4e..26bd8ea35a4e 100644
--- a/arch/ppc/kernel/temp.c
+++ b/arch/powerpc/kernel/tau_6xx.c
diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c
index 4a27218a086c..24e3ad756de0 100644
--- a/arch/powerpc/kernel/time.c
+++ b/arch/powerpc/kernel/time.c
@@ -261,7 +261,7 @@ void snapshot_timebases(void)
261 261
262 if (!cpu_has_feature(CPU_FTR_PURR)) 262 if (!cpu_has_feature(CPU_FTR_PURR))
263 return; 263 return;
264 for_each_cpu(cpu) 264 for_each_possible_cpu(cpu)
265 spin_lock_init(&per_cpu(cpu_purr_data, cpu).lock); 265 spin_lock_init(&per_cpu(cpu_purr_data, cpu).lock);
266 on_each_cpu(snapshot_tb_and_purr, NULL, 0, 1); 266 on_each_cpu(snapshot_tb_and_purr, NULL, 0, 1);
267} 267}
@@ -751,7 +751,7 @@ void __init smp_space_timers(unsigned int max_cpus)
751 * systems works better if the two threads' timebase interrupts 751 * systems works better if the two threads' timebase interrupts
752 * are staggered by half a jiffy with respect to each other. 752 * are staggered by half a jiffy with respect to each other.
753 */ 753 */
754 for_each_cpu(i) { 754 for_each_possible_cpu(i) {
755 if (i == boot_cpuid) 755 if (i == boot_cpuid)
756 continue; 756 continue;
757 if (i == (boot_cpuid ^ 1)) 757 if (i == (boot_cpuid ^ 1))
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c
index 9763faab6739..4cbde211eb69 100644
--- a/arch/powerpc/kernel/traps.c
+++ b/arch/powerpc/kernel/traps.c
@@ -97,7 +97,6 @@ static DEFINE_SPINLOCK(die_lock);
97int die(const char *str, struct pt_regs *regs, long err) 97int die(const char *str, struct pt_regs *regs, long err)
98{ 98{
99 static int die_counter, crash_dump_start = 0; 99 static int die_counter, crash_dump_start = 0;
100 int nl = 0;
101 100
102 if (debugger(regs)) 101 if (debugger(regs))
103 return 1; 102 return 1;
@@ -106,7 +105,7 @@ int die(const char *str, struct pt_regs *regs, long err)
106 spin_lock_irq(&die_lock); 105 spin_lock_irq(&die_lock);
107 bust_spinlocks(1); 106 bust_spinlocks(1);
108#ifdef CONFIG_PMAC_BACKLIGHT 107#ifdef CONFIG_PMAC_BACKLIGHT
109 if (_machine == _MACH_Pmac) { 108 if (machine_is(powermac)) {
110 set_backlight_enable(1); 109 set_backlight_enable(1);
111 set_backlight_level(BACKLIGHT_MAX); 110 set_backlight_level(BACKLIGHT_MAX);
112 } 111 }
@@ -114,46 +113,18 @@ int die(const char *str, struct pt_regs *regs, long err)
114 printk("Oops: %s, sig: %ld [#%d]\n", str, err, ++die_counter); 113 printk("Oops: %s, sig: %ld [#%d]\n", str, err, ++die_counter);
115#ifdef CONFIG_PREEMPT 114#ifdef CONFIG_PREEMPT
116 printk("PREEMPT "); 115 printk("PREEMPT ");
117 nl = 1;
118#endif 116#endif
119#ifdef CONFIG_SMP 117#ifdef CONFIG_SMP
120 printk("SMP NR_CPUS=%d ", NR_CPUS); 118 printk("SMP NR_CPUS=%d ", NR_CPUS);
121 nl = 1;
122#endif 119#endif
123#ifdef CONFIG_DEBUG_PAGEALLOC 120#ifdef CONFIG_DEBUG_PAGEALLOC
124 printk("DEBUG_PAGEALLOC "); 121 printk("DEBUG_PAGEALLOC ");
125 nl = 1;
126#endif 122#endif
127#ifdef CONFIG_NUMA 123#ifdef CONFIG_NUMA
128 printk("NUMA "); 124 printk("NUMA ");
129 nl = 1;
130#endif 125#endif
131#ifdef CONFIG_PPC64 126 printk("%s\n", ppc_md.name ? "" : ppc_md.name);
132 switch (_machine) { 127
133 case PLATFORM_PSERIES:
134 printk("PSERIES ");
135 nl = 1;
136 break;
137 case PLATFORM_PSERIES_LPAR:
138 printk("PSERIES LPAR ");
139 nl = 1;
140 break;
141 case PLATFORM_ISERIES_LPAR:
142 printk("ISERIES LPAR ");
143 nl = 1;
144 break;
145 case PLATFORM_POWERMAC:
146 printk("POWERMAC ");
147 nl = 1;
148 break;
149 case PLATFORM_CELL:
150 printk("CELL ");
151 nl = 1;
152 break;
153 }
154#endif
155 if (nl)
156 printk("\n");
157 print_modules(); 128 print_modules();
158 show_regs(regs); 129 show_regs(regs);
159 bust_spinlocks(0); 130 bust_spinlocks(0);
diff --git a/arch/powerpc/kernel/vdso.c b/arch/powerpc/kernel/vdso.c
index ec8370368423..573afb68d69e 100644
--- a/arch/powerpc/kernel/vdso.c
+++ b/arch/powerpc/kernel/vdso.c
@@ -33,6 +33,7 @@
33#include <asm/machdep.h> 33#include <asm/machdep.h>
34#include <asm/cputable.h> 34#include <asm/cputable.h>
35#include <asm/sections.h> 35#include <asm/sections.h>
36#include <asm/firmware.h>
36#include <asm/vdso.h> 37#include <asm/vdso.h>
37#include <asm/vdso_datapage.h> 38#include <asm/vdso_datapage.h>
38 39
@@ -667,7 +668,13 @@ void __init vdso_init(void)
667 vdso_data->version.major = SYSTEMCFG_MAJOR; 668 vdso_data->version.major = SYSTEMCFG_MAJOR;
668 vdso_data->version.minor = SYSTEMCFG_MINOR; 669 vdso_data->version.minor = SYSTEMCFG_MINOR;
669 vdso_data->processor = mfspr(SPRN_PVR); 670 vdso_data->processor = mfspr(SPRN_PVR);
670 vdso_data->platform = _machine; 671 /*
672 * Fake the old platform number for pSeries and iSeries and add
673 * in LPAR bit if necessary
674 */
675 vdso_data->platform = machine_is(iseries) ? 0x200 : 0x100;
676 if (firmware_has_feature(FW_FEATURE_LPAR))
677 vdso_data->platform |= 1;
671 vdso_data->physicalMemorySize = lmb_phys_mem_size(); 678 vdso_data->physicalMemorySize = lmb_phys_mem_size();
672 vdso_data->dcache_size = ppc64_caches.dsize; 679 vdso_data->dcache_size = ppc64_caches.dsize;
673 vdso_data->dcache_line_size = ppc64_caches.dline_size; 680 vdso_data->dcache_line_size = ppc64_caches.dline_size;
diff --git a/arch/powerpc/kernel/vdso32/sigtramp.S b/arch/powerpc/kernel/vdso32/sigtramp.S
index e04642781917..0c6a37b29dde 100644
--- a/arch/powerpc/kernel/vdso32/sigtramp.S
+++ b/arch/powerpc/kernel/vdso32/sigtramp.S
@@ -261,7 +261,7 @@ V_FUNCTION_END(__kernel_sigtramp_rt32)
261.Lcie_start: 261.Lcie_start:
262 .long 0 /* CIE ID */ 262 .long 0 /* CIE ID */
263 .byte 1 /* Version number */ 263 .byte 1 /* Version number */
264 .string "zR" /* NUL-terminated augmentation string */ 264 .string "zRS" /* NUL-terminated augmentation string */
265 .uleb128 4 /* Code alignment factor */ 265 .uleb128 4 /* Code alignment factor */
266 .sleb128 -4 /* Data alignment factor */ 266 .sleb128 -4 /* Data alignment factor */
267 .byte 67 /* Return address register column, ap */ 267 .byte 67 /* Return address register column, ap */
diff --git a/arch/powerpc/kernel/vdso64/sigtramp.S b/arch/powerpc/kernel/vdso64/sigtramp.S
index 31b604ab56de..7479edb101b8 100644
--- a/arch/powerpc/kernel/vdso64/sigtramp.S
+++ b/arch/powerpc/kernel/vdso64/sigtramp.S
@@ -263,7 +263,7 @@ V_FUNCTION_END(__kernel_sigtramp_rt64)
263.Lcie_start: 263.Lcie_start:
264 .long 0 /* CIE ID */ 264 .long 0 /* CIE ID */
265 .byte 1 /* Version number */ 265 .byte 1 /* Version number */
266 .string "zR" /* NUL-terminated augmentation string */ 266 .string "zRS" /* NUL-terminated augmentation string */
267 .uleb128 4 /* Code alignment factor */ 267 .uleb128 4 /* Code alignment factor */
268 .sleb128 -8 /* Data alignment factor */ 268 .sleb128 -8 /* Data alignment factor */
269 .byte 67 /* Return address register column, ap */ 269 .byte 67 /* Return address register column, ap */
diff --git a/arch/powerpc/kernel/vmlinux.lds.S b/arch/powerpc/kernel/vmlinux.lds.S
index 7fa7b15fd8e6..fe79c2584cb0 100644
--- a/arch/powerpc/kernel/vmlinux.lds.S
+++ b/arch/powerpc/kernel/vmlinux.lds.S
@@ -1,9 +1,11 @@
1#include <linux/config.h> 1#include <linux/config.h>
2#ifdef CONFIG_PPC64 2#ifdef CONFIG_PPC64
3#include <asm/page.h> 3#include <asm/page.h>
4#define PROVIDE32(x) PROVIDE(__unused__##x)
4#else 5#else
5#define PAGE_SIZE 4096 6#define PAGE_SIZE 4096
6#define KERNELBASE CONFIG_KERNEL_START 7#define KERNELBASE CONFIG_KERNEL_START
8#define PROVIDE32(x) PROVIDE(x)
7#endif 9#endif
8#include <asm-generic/vmlinux.lds.h> 10#include <asm-generic/vmlinux.lds.h>
9 11
@@ -18,43 +20,42 @@ jiffies = jiffies_64 + 4;
18#endif 20#endif
19SECTIONS 21SECTIONS
20{ 22{
21 /* Sections to be discarded. */ 23 /* Sections to be discarded. */
22 /DISCARD/ : { 24 /DISCARD/ : {
23 *(.exitcall.exit) 25 *(.exitcall.exit)
24 *(.exit.data) 26 *(.exit.data)
25 } 27 }
26
27 . = KERNELBASE;
28
29 /* Read-only sections, merged into text segment: */
30 .text : {
31 *(.text .text.*)
32 SCHED_TEXT
33 LOCK_TEXT
34 KPROBES_TEXT
35 *(.fixup)
36#ifdef CONFIG_PPC32
37 *(.got1)
38 __got2_start = .;
39 *(.got2)
40 __got2_end = .;
41#else
42 . = ALIGN(PAGE_SIZE);
43 _etext = .;
44#endif
45 }
46#ifdef CONFIG_PPC32
47 _etext = .;
48 PROVIDE (etext = .);
49 28
50 RODATA 29 . = KERNELBASE;
51 .fini : { *(.fini) } =0
52 .ctors : { *(.ctors) }
53 .dtors : { *(.dtors) }
54 30
55 .fixup : { *(.fixup) } 31/*
56#endif 32 * Text, read only data and other permanent read-only sections
33 */
34
35 /* Text and gots */
36 .text : {
37 *(.text .text.*)
38 SCHED_TEXT
39 LOCK_TEXT
40 KPROBES_TEXT
41 *(.fixup)
57 42
43#ifdef CONFIG_PPC32
44 *(.got1)
45 __got2_start = .;
46 *(.got2)
47 __got2_end = .;
48#endif /* CONFIG_PPC32 */
49
50 . = ALIGN(PAGE_SIZE);
51 _etext = .;
52 PROVIDE32 (etext = .);
53 }
54
55 /* Read-only data */
56 RODATA
57
58 /* Exception & bug tables */
58 __ex_table : { 59 __ex_table : {
59 __start___ex_table = .; 60 __start___ex_table = .;
60 *(__ex_table) 61 *(__ex_table)
@@ -67,192 +68,172 @@ SECTIONS
67 __stop___bug_table = .; 68 __stop___bug_table = .;
68 } 69 }
69 70
70#ifdef CONFIG_PPC64 71/*
72 * Init sections discarded at runtime
73 */
74 . = ALIGN(PAGE_SIZE);
75 __init_begin = .;
76
77 .init.text : {
78 _sinittext = .;
79 *(.init.text)
80 _einittext = .;
81 }
82
83 /* .exit.text is discarded at runtime, not link time,
84 * to deal with references from __bug_table
85 */
86 .exit.text : { *(.exit.text) }
87
88 .init.data : {
89 *(.init.data);
90 __vtop_table_begin = .;
91 *(.vtop_fixup);
92 __vtop_table_end = .;
93 __ptov_table_begin = .;
94 *(.ptov_fixup);
95 __ptov_table_end = .;
96 }
97
98 . = ALIGN(16);
99 .init.setup : {
100 __setup_start = .;
101 *(.init.setup)
102 __setup_end = .;
103 }
104
105 .initcall.init : {
106 __initcall_start = .;
107 *(.initcall1.init)
108 *(.initcall2.init)
109 *(.initcall3.init)
110 *(.initcall4.init)
111 *(.initcall5.init)
112 *(.initcall6.init)
113 *(.initcall7.init)
114 __initcall_end = .;
115 }
116
117 .con_initcall.init : {
118 __con_initcall_start = .;
119 *(.con_initcall.init)
120 __con_initcall_end = .;
121 }
122
123 SECURITY_INIT
124
125 . = ALIGN(8);
71 __ftr_fixup : { 126 __ftr_fixup : {
72 __start___ftr_fixup = .; 127 __start___ftr_fixup = .;
73 *(__ftr_fixup) 128 *(__ftr_fixup)
74 __stop___ftr_fixup = .; 129 __stop___ftr_fixup = .;
75 } 130 }
76 131
77 RODATA 132 . = ALIGN(PAGE_SIZE);
78#endif 133 .init.ramfs : {
134 __initramfs_start = .;
135 *(.init.ramfs)
136 __initramfs_end = .;
137 }
79 138
80#ifdef CONFIG_PPC32 139#ifdef CONFIG_PPC32
81 /* Read-write section, merged into data segment: */ 140 . = ALIGN(32);
82 . = ALIGN(PAGE_SIZE); 141#else
83 _sdata = .; 142 . = ALIGN(128);
84 .data :
85 {
86 *(.data)
87 *(.data1)
88 *(.sdata)
89 *(.sdata2)
90 *(.got.plt) *(.got)
91 *(.dynamic)
92 CONSTRUCTORS
93 }
94
95 . = ALIGN(PAGE_SIZE);
96 __nosave_begin = .;
97 .data_nosave : { *(.data.nosave) }
98 . = ALIGN(PAGE_SIZE);
99 __nosave_end = .;
100
101 . = ALIGN(32);
102 .data.cacheline_aligned : { *(.data.cacheline_aligned) }
103
104 _edata = .;
105 PROVIDE (edata = .);
106
107 . = ALIGN(8192);
108 .data.init_task : { *(.data.init_task) }
109#endif 143#endif
144 .data.percpu : {
145 __per_cpu_start = .;
146 *(.data.percpu)
147 __per_cpu_end = .;
148 }
110 149
111 /* will be freed after init */ 150 . = ALIGN(8);
112 . = ALIGN(PAGE_SIZE); 151 .machine.desc : {
113 __init_begin = .; 152 __machine_desc_start = . ;
114 .init.text : { 153 *(.machine.desc)
115 _sinittext = .; 154 __machine_desc_end = . ;
116 *(.init.text) 155 }
117 _einittext = .; 156
118 } 157 /* freed after init ends here */
119#ifdef CONFIG_PPC32 158 . = ALIGN(PAGE_SIZE);
120 /* .exit.text is discarded at runtime, not link time, 159 __init_end = .;
121 to deal with references from __bug_table */ 160
122 .exit.text : { *(.exit.text) } 161/*
123#endif 162 * And now the various read/write data
124 .init.data : { 163 */
125 *(.init.data); 164
126 __vtop_table_begin = .; 165 . = ALIGN(PAGE_SIZE);
127 *(.vtop_fixup); 166 _sdata = .;
128 __vtop_table_end = .;
129 __ptov_table_begin = .;
130 *(.ptov_fixup);
131 __ptov_table_end = .;
132 }
133
134 . = ALIGN(16);
135 .init.setup : {
136 __setup_start = .;
137 *(.init.setup)
138 __setup_end = .;
139 }
140
141 .initcall.init : {
142 __initcall_start = .;
143 *(.initcall1.init)
144 *(.initcall2.init)
145 *(.initcall3.init)
146 *(.initcall4.init)
147 *(.initcall5.init)
148 *(.initcall6.init)
149 *(.initcall7.init)
150 __initcall_end = .;
151 }
152
153 .con_initcall.init : {
154 __con_initcall_start = .;
155 *(.con_initcall.init)
156 __con_initcall_end = .;
157 }
158
159 SECURITY_INIT
160 167
161#ifdef CONFIG_PPC32 168#ifdef CONFIG_PPC32
162 __start___ftr_fixup = .; 169 .data :
163 __ftr_fixup : { *(__ftr_fixup) } 170 {
164 __stop___ftr_fixup = .; 171 *(.data)
172 *(.sdata)
173 *(.got.plt) *(.got)
174 }
165#else 175#else
166 . = ALIGN(PAGE_SIZE); 176 .data : {
167 .init.ramfs : { 177 *(.data .data.rel* .toc1)
168 __initramfs_start = .; 178 *(.branch_lt)
169 *(.init.ramfs) 179 }
170 __initramfs_end = .;
171 }
172#endif
173 180
174#ifdef CONFIG_PPC32 181 .opd : {
175 . = ALIGN(32); 182 *(.opd)
183 }
184
185 .got : {
186 __toc_start = .;
187 *(.got)
188 *(.toc)
189 }
176#endif 190#endif
177 .data.percpu : {
178 __per_cpu_start = .;
179 *(.data.percpu)
180 __per_cpu_end = .;
181 }
182 191
183 . = ALIGN(PAGE_SIZE); 192 . = ALIGN(PAGE_SIZE);
184#ifdef CONFIG_PPC64 193 _edata = .;
185 . = ALIGN(16384); 194 PROVIDE32 (edata = .);
186 __init_end = .; 195
187 /* freed after init ends here */ 196 /* The initial task and kernel stack */
188 197#ifdef CONFIG_PPC32
189 /* Read/write sections */ 198 . = ALIGN(8192);
190 . = ALIGN(PAGE_SIZE);
191 . = ALIGN(16384);
192 _sdata = .;
193 /* The initial task and kernel stack */
194 .data.init_task : {
195 *(.data.init_task)
196 }
197
198 . = ALIGN(PAGE_SIZE);
199 .data.page_aligned : {
200 *(.data.page_aligned)
201 }
202
203 .data.cacheline_aligned : {
204 *(.data.cacheline_aligned)
205 }
206
207 .data : {
208 *(.data .data.rel* .toc1)
209 *(.branch_lt)
210 }
211
212 .opd : {
213 *(.opd)
214 }
215
216 .got : {
217 __toc_start = .;
218 *(.got)
219 *(.toc)
220 . = ALIGN(PAGE_SIZE);
221 _edata = .;
222 }
223
224 . = ALIGN(PAGE_SIZE);
225#else 199#else
226 __initramfs_start = .; 200 . = ALIGN(16384);
227 .init.ramfs : { 201#endif
228 *(.init.ramfs) 202 .data.init_task : {
229 } 203 *(.data.init_task)
230 __initramfs_end = .; 204 }
231 205
232 . = ALIGN(4096); 206 . = ALIGN(PAGE_SIZE);
233 __init_end = .; 207 .data.page_aligned : {
208 *(.data.page_aligned)
209 }
234 210
235 . = ALIGN(4096); 211 .data.cacheline_aligned : {
236 _sextratext = .; 212 *(.data.cacheline_aligned)
237 _eextratext = .; 213 }
238 214
239 __bss_start = .; 215 . = ALIGN(PAGE_SIZE);
240#endif 216 __data_nosave : {
217 __nosave_begin = .;
218 *(.data.nosave)
219 . = ALIGN(PAGE_SIZE);
220 __nosave_end = .;
221 }
241 222
242 .bss : { 223/*
243 __bss_start = .; 224 * And finally the bss
244 *(.sbss) *(.scommon) 225 */
245 *(.dynbss) 226
246 *(.bss) 227 .bss : {
247 *(COMMON) 228 __bss_start = .;
248 __bss_stop = .; 229 *(.sbss) *(.scommon)
249 } 230 *(.dynbss)
231 *(.bss)
232 *(COMMON)
233 __bss_stop = .;
234 }
250 235
251#ifdef CONFIG_PPC64 236 . = ALIGN(PAGE_SIZE);
252 . = ALIGN(PAGE_SIZE); 237 _end = . ;
253#endif 238 PROVIDE32 (end = .);
254 _end = . ;
255#ifdef CONFIG_PPC32
256 PROVIDE (end = .);
257#endif
258} 239}
diff --git a/arch/powerpc/lib/sstep.c b/arch/powerpc/lib/sstep.c
index 666c2aa55016..c251d9936612 100644
--- a/arch/powerpc/lib/sstep.c
+++ b/arch/powerpc/lib/sstep.c
@@ -18,7 +18,7 @@ extern char system_call_common[];
18 18
19#ifdef CONFIG_PPC64 19#ifdef CONFIG_PPC64
20/* Bits in SRR1 that are copied from MSR */ 20/* Bits in SRR1 that are copied from MSR */
21#define MSR_MASK 0xffffffff87c0ffff 21#define MSR_MASK 0xffffffff87c0ffffUL
22#else 22#else
23#define MSR_MASK 0x87c0ffff 23#define MSR_MASK 0x87c0ffff
24#endif 24#endif
diff --git a/arch/ppc/math-emu/Makefile b/arch/powerpc/math-emu/Makefile
index 754143e8936b..754143e8936b 100644
--- a/arch/ppc/math-emu/Makefile
+++ b/arch/powerpc/math-emu/Makefile
diff --git a/arch/ppc/math-emu/double.h b/arch/powerpc/math-emu/double.h
index ffba8b67f059..ffba8b67f059 100644
--- a/arch/ppc/math-emu/double.h
+++ b/arch/powerpc/math-emu/double.h
diff --git a/arch/ppc/math-emu/fabs.c b/arch/powerpc/math-emu/fabs.c
index 41f0617f3d3a..41f0617f3d3a 100644
--- a/arch/ppc/math-emu/fabs.c
+++ b/arch/powerpc/math-emu/fabs.c
diff --git a/arch/ppc/math-emu/fadd.c b/arch/powerpc/math-emu/fadd.c
index fc8836488b64..fc8836488b64 100644
--- a/arch/ppc/math-emu/fadd.c
+++ b/arch/powerpc/math-emu/fadd.c
diff --git a/arch/ppc/math-emu/fadds.c b/arch/powerpc/math-emu/fadds.c
index 93025b6c8f3c..93025b6c8f3c 100644
--- a/arch/ppc/math-emu/fadds.c
+++ b/arch/powerpc/math-emu/fadds.c
diff --git a/arch/ppc/math-emu/fcmpo.c b/arch/powerpc/math-emu/fcmpo.c
index 4efac394b4cb..4efac394b4cb 100644
--- a/arch/ppc/math-emu/fcmpo.c
+++ b/arch/powerpc/math-emu/fcmpo.c
diff --git a/arch/ppc/math-emu/fcmpu.c b/arch/powerpc/math-emu/fcmpu.c
index b7e33176e618..b7e33176e618 100644
--- a/arch/ppc/math-emu/fcmpu.c
+++ b/arch/powerpc/math-emu/fcmpu.c
diff --git a/arch/ppc/math-emu/fctiw.c b/arch/powerpc/math-emu/fctiw.c
index 3b3c98b840cf..3b3c98b840cf 100644
--- a/arch/ppc/math-emu/fctiw.c
+++ b/arch/powerpc/math-emu/fctiw.c
diff --git a/arch/ppc/math-emu/fctiwz.c b/arch/powerpc/math-emu/fctiwz.c
index 7717eb6fcfb6..7717eb6fcfb6 100644
--- a/arch/ppc/math-emu/fctiwz.c
+++ b/arch/powerpc/math-emu/fctiwz.c
diff --git a/arch/ppc/math-emu/fdiv.c b/arch/powerpc/math-emu/fdiv.c
index f2fba825b2d0..f2fba825b2d0 100644
--- a/arch/ppc/math-emu/fdiv.c
+++ b/arch/powerpc/math-emu/fdiv.c
diff --git a/arch/ppc/math-emu/fdivs.c b/arch/powerpc/math-emu/fdivs.c
index b971196e3175..b971196e3175 100644
--- a/arch/ppc/math-emu/fdivs.c
+++ b/arch/powerpc/math-emu/fdivs.c
diff --git a/arch/ppc/math-emu/fmadd.c b/arch/powerpc/math-emu/fmadd.c
index 0a1dbce793e9..0a1dbce793e9 100644
--- a/arch/ppc/math-emu/fmadd.c
+++ b/arch/powerpc/math-emu/fmadd.c
diff --git a/arch/ppc/math-emu/fmadds.c b/arch/powerpc/math-emu/fmadds.c
index 0f70bba9445e..0f70bba9445e 100644
--- a/arch/ppc/math-emu/fmadds.c
+++ b/arch/powerpc/math-emu/fmadds.c
diff --git a/arch/ppc/math-emu/fmr.c b/arch/powerpc/math-emu/fmr.c
index 28df700c0c7e..28df700c0c7e 100644
--- a/arch/ppc/math-emu/fmr.c
+++ b/arch/powerpc/math-emu/fmr.c
diff --git a/arch/ppc/math-emu/fmsub.c b/arch/powerpc/math-emu/fmsub.c
index 203fd48a6fec..203fd48a6fec 100644
--- a/arch/ppc/math-emu/fmsub.c
+++ b/arch/powerpc/math-emu/fmsub.c
diff --git a/arch/ppc/math-emu/fmsubs.c b/arch/powerpc/math-emu/fmsubs.c
index 8ce68624c189..8ce68624c189 100644
--- a/arch/ppc/math-emu/fmsubs.c
+++ b/arch/powerpc/math-emu/fmsubs.c
diff --git a/arch/ppc/math-emu/fmul.c b/arch/powerpc/math-emu/fmul.c
index 66c7e79aae2e..66c7e79aae2e 100644
--- a/arch/ppc/math-emu/fmul.c
+++ b/arch/powerpc/math-emu/fmul.c
diff --git a/arch/ppc/math-emu/fmuls.c b/arch/powerpc/math-emu/fmuls.c
index 26bc4278271c..26bc4278271c 100644
--- a/arch/ppc/math-emu/fmuls.c
+++ b/arch/powerpc/math-emu/fmuls.c
diff --git a/arch/ppc/math-emu/fnabs.c b/arch/powerpc/math-emu/fnabs.c
index c6b913d179e0..c6b913d179e0 100644
--- a/arch/ppc/math-emu/fnabs.c
+++ b/arch/powerpc/math-emu/fnabs.c
diff --git a/arch/ppc/math-emu/fneg.c b/arch/powerpc/math-emu/fneg.c
index fe9a98deff69..fe9a98deff69 100644
--- a/arch/ppc/math-emu/fneg.c
+++ b/arch/powerpc/math-emu/fneg.c
diff --git a/arch/ppc/math-emu/fnmadd.c b/arch/powerpc/math-emu/fnmadd.c
index 7f312276d920..7f312276d920 100644
--- a/arch/ppc/math-emu/fnmadd.c
+++ b/arch/powerpc/math-emu/fnmadd.c
diff --git a/arch/ppc/math-emu/fnmadds.c b/arch/powerpc/math-emu/fnmadds.c
index 65454c9c70bc..65454c9c70bc 100644
--- a/arch/ppc/math-emu/fnmadds.c
+++ b/arch/powerpc/math-emu/fnmadds.c
diff --git a/arch/ppc/math-emu/fnmsub.c b/arch/powerpc/math-emu/fnmsub.c
index f1ca7482b5f0..f1ca7482b5f0 100644
--- a/arch/ppc/math-emu/fnmsub.c
+++ b/arch/powerpc/math-emu/fnmsub.c
diff --git a/arch/ppc/math-emu/fnmsubs.c b/arch/powerpc/math-emu/fnmsubs.c
index 5c9a09a87dc7..5c9a09a87dc7 100644
--- a/arch/ppc/math-emu/fnmsubs.c
+++ b/arch/powerpc/math-emu/fnmsubs.c
diff --git a/arch/ppc/math-emu/fres.c b/arch/powerpc/math-emu/fres.c
index ec11e46d20af..ec11e46d20af 100644
--- a/arch/ppc/math-emu/fres.c
+++ b/arch/powerpc/math-emu/fres.c
diff --git a/arch/ppc/math-emu/frsp.c b/arch/powerpc/math-emu/frsp.c
index d879b2a3d0c9..d879b2a3d0c9 100644
--- a/arch/ppc/math-emu/frsp.c
+++ b/arch/powerpc/math-emu/frsp.c
diff --git a/arch/ppc/math-emu/frsqrte.c b/arch/powerpc/math-emu/frsqrte.c
index a11ae1829850..a11ae1829850 100644
--- a/arch/ppc/math-emu/frsqrte.c
+++ b/arch/powerpc/math-emu/frsqrte.c
diff --git a/arch/ppc/math-emu/fsel.c b/arch/powerpc/math-emu/fsel.c
index e36e6e72819a..e36e6e72819a 100644
--- a/arch/ppc/math-emu/fsel.c
+++ b/arch/powerpc/math-emu/fsel.c
diff --git a/arch/ppc/math-emu/fsqrt.c b/arch/powerpc/math-emu/fsqrt.c
index 6f8319f64a8a..6f8319f64a8a 100644
--- a/arch/ppc/math-emu/fsqrt.c
+++ b/arch/powerpc/math-emu/fsqrt.c
diff --git a/arch/ppc/math-emu/fsqrts.c b/arch/powerpc/math-emu/fsqrts.c
index 3b2b1cf55c12..3b2b1cf55c12 100644
--- a/arch/ppc/math-emu/fsqrts.c
+++ b/arch/powerpc/math-emu/fsqrts.c
diff --git a/arch/ppc/math-emu/fsub.c b/arch/powerpc/math-emu/fsub.c
index 956679042bb2..956679042bb2 100644
--- a/arch/ppc/math-emu/fsub.c
+++ b/arch/powerpc/math-emu/fsub.c
diff --git a/arch/ppc/math-emu/fsubs.c b/arch/powerpc/math-emu/fsubs.c
index 3428117dfe8c..3428117dfe8c 100644
--- a/arch/ppc/math-emu/fsubs.c
+++ b/arch/powerpc/math-emu/fsubs.c
diff --git a/arch/ppc/math-emu/lfd.c b/arch/powerpc/math-emu/lfd.c
index 7d38101c329b..7d38101c329b 100644
--- a/arch/ppc/math-emu/lfd.c
+++ b/arch/powerpc/math-emu/lfd.c
diff --git a/arch/ppc/math-emu/lfs.c b/arch/powerpc/math-emu/lfs.c
index c86dee3d7655..c86dee3d7655 100644
--- a/arch/ppc/math-emu/lfs.c
+++ b/arch/powerpc/math-emu/lfs.c
diff --git a/arch/ppc/math-emu/math.c b/arch/powerpc/math-emu/math.c
index 589153472761..589153472761 100644
--- a/arch/ppc/math-emu/math.c
+++ b/arch/powerpc/math-emu/math.c
diff --git a/arch/ppc/math-emu/mcrfs.c b/arch/powerpc/math-emu/mcrfs.c
index 106dd912914b..106dd912914b 100644
--- a/arch/ppc/math-emu/mcrfs.c
+++ b/arch/powerpc/math-emu/mcrfs.c
diff --git a/arch/ppc/math-emu/mffs.c b/arch/powerpc/math-emu/mffs.c
index f477c9170e75..f477c9170e75 100644
--- a/arch/ppc/math-emu/mffs.c
+++ b/arch/powerpc/math-emu/mffs.c
diff --git a/arch/ppc/math-emu/mtfsb0.c b/arch/powerpc/math-emu/mtfsb0.c
index 99bfd80f4af3..99bfd80f4af3 100644
--- a/arch/ppc/math-emu/mtfsb0.c
+++ b/arch/powerpc/math-emu/mtfsb0.c
diff --git a/arch/ppc/math-emu/mtfsb1.c b/arch/powerpc/math-emu/mtfsb1.c
index 3d9e7ed92d2b..3d9e7ed92d2b 100644
--- a/arch/ppc/math-emu/mtfsb1.c
+++ b/arch/powerpc/math-emu/mtfsb1.c
diff --git a/arch/ppc/math-emu/mtfsf.c b/arch/powerpc/math-emu/mtfsf.c
index d70cf714994c..d70cf714994c 100644
--- a/arch/ppc/math-emu/mtfsf.c
+++ b/arch/powerpc/math-emu/mtfsf.c
diff --git a/arch/ppc/math-emu/mtfsfi.c b/arch/powerpc/math-emu/mtfsfi.c
index 71df854baa7e..71df854baa7e 100644
--- a/arch/ppc/math-emu/mtfsfi.c
+++ b/arch/powerpc/math-emu/mtfsfi.c
diff --git a/arch/ppc/math-emu/op-1.h b/arch/powerpc/math-emu/op-1.h
index c92fa95f562e..c92fa95f562e 100644
--- a/arch/ppc/math-emu/op-1.h
+++ b/arch/powerpc/math-emu/op-1.h
diff --git a/arch/ppc/math-emu/op-2.h b/arch/powerpc/math-emu/op-2.h
index b9b06b4c6ea1..b9b06b4c6ea1 100644
--- a/arch/ppc/math-emu/op-2.h
+++ b/arch/powerpc/math-emu/op-2.h
diff --git a/arch/ppc/math-emu/op-4.h b/arch/powerpc/math-emu/op-4.h
index fcdd6d064c54..fcdd6d064c54 100644
--- a/arch/ppc/math-emu/op-4.h
+++ b/arch/powerpc/math-emu/op-4.h
diff --git a/arch/ppc/math-emu/op-common.h b/arch/powerpc/math-emu/op-common.h
index afb82b6498ce..afb82b6498ce 100644
--- a/arch/ppc/math-emu/op-common.h
+++ b/arch/powerpc/math-emu/op-common.h
diff --git a/arch/ppc/math-emu/sfp-machine.h b/arch/powerpc/math-emu/sfp-machine.h
index 4b17d83cfcdd..4b17d83cfcdd 100644
--- a/arch/ppc/math-emu/sfp-machine.h
+++ b/arch/powerpc/math-emu/sfp-machine.h
diff --git a/arch/ppc/math-emu/single.h b/arch/powerpc/math-emu/single.h
index f19d99451815..f19d99451815 100644
--- a/arch/ppc/math-emu/single.h
+++ b/arch/powerpc/math-emu/single.h
diff --git a/arch/ppc/math-emu/soft-fp.h b/arch/powerpc/math-emu/soft-fp.h
index cca39598f873..cca39598f873 100644
--- a/arch/ppc/math-emu/soft-fp.h
+++ b/arch/powerpc/math-emu/soft-fp.h
diff --git a/arch/ppc/math-emu/stfd.c b/arch/powerpc/math-emu/stfd.c
index 3f8c2558a9e8..3f8c2558a9e8 100644
--- a/arch/ppc/math-emu/stfd.c
+++ b/arch/powerpc/math-emu/stfd.c
diff --git a/arch/ppc/math-emu/stfiwx.c b/arch/powerpc/math-emu/stfiwx.c
index 95caaeec6a08..95caaeec6a08 100644
--- a/arch/ppc/math-emu/stfiwx.c
+++ b/arch/powerpc/math-emu/stfiwx.c
diff --git a/arch/ppc/math-emu/stfs.c b/arch/powerpc/math-emu/stfs.c
index e87ca23c6dc3..e87ca23c6dc3 100644
--- a/arch/ppc/math-emu/stfs.c
+++ b/arch/powerpc/math-emu/stfs.c
diff --git a/arch/ppc/math-emu/types.c b/arch/powerpc/math-emu/types.c
index e1ed15d829db..e1ed15d829db 100644
--- a/arch/ppc/math-emu/types.c
+++ b/arch/powerpc/math-emu/types.c
diff --git a/arch/ppc/math-emu/udivmodti4.c b/arch/powerpc/math-emu/udivmodti4.c
index 7e112dc1e2f2..7e112dc1e2f2 100644
--- a/arch/ppc/math-emu/udivmodti4.c
+++ b/arch/powerpc/math-emu/udivmodti4.c
diff --git a/arch/powerpc/mm/fault.c b/arch/powerpc/mm/fault.c
index ec4adcb4bc28..5aea0909a5ec 100644
--- a/arch/powerpc/mm/fault.c
+++ b/arch/powerpc/mm/fault.c
@@ -267,25 +267,29 @@ good_area:
267#endif 267#endif
268#if defined(CONFIG_4xx) || defined(CONFIG_BOOKE) 268#if defined(CONFIG_4xx) || defined(CONFIG_BOOKE)
269 pte_t *ptep; 269 pte_t *ptep;
270 pmd_t *pmdp;
270 271
271 /* Since 4xx/Book-E supports per-page execute permission, 272 /* Since 4xx/Book-E supports per-page execute permission,
272 * we lazily flush dcache to icache. */ 273 * we lazily flush dcache to icache. */
273 ptep = NULL; 274 ptep = NULL;
274 if (get_pteptr(mm, address, &ptep) && pte_present(*ptep)) { 275 if (get_pteptr(mm, address, &ptep, &pmdp)) {
275 struct page *page = pte_page(*ptep); 276 spinlock_t *ptl = pte_lockptr(mm, pmdp);
276 277 spin_lock(ptl);
277 if (! test_bit(PG_arch_1, &page->flags)) { 278 if (pte_present(*ptep)) {
278 flush_dcache_icache_page(page); 279 struct page *page = pte_page(*ptep);
279 set_bit(PG_arch_1, &page->flags); 280
281 if (!test_bit(PG_arch_1, &page->flags)) {
282 flush_dcache_icache_page(page);
283 set_bit(PG_arch_1, &page->flags);
284 }
285 pte_update(ptep, 0, _PAGE_HWEXEC);
286 _tlbie(address);
287 pte_unmap_unlock(ptep, ptl);
288 up_read(&mm->mmap_sem);
289 return 0;
280 } 290 }
281 pte_update(ptep, 0, _PAGE_HWEXEC); 291 pte_unmap_unlock(ptep, ptl);
282 _tlbie(address);
283 pte_unmap(ptep);
284 up_read(&mm->mmap_sem);
285 return 0;
286 } 292 }
287 if (ptep != NULL)
288 pte_unmap(ptep);
289#endif 293#endif
290 /* a write */ 294 /* a write */
291 } else if (is_write) { 295 } else if (is_write) {
diff --git a/arch/powerpc/mm/hash_utils_64.c b/arch/powerpc/mm/hash_utils_64.c
index 89b35c181314..c006d9039633 100644
--- a/arch/powerpc/mm/hash_utils_64.c
+++ b/arch/powerpc/mm/hash_utils_64.c
@@ -167,7 +167,7 @@ int htab_bolt_mapping(unsigned long vstart, unsigned long vend,
167 * normal insert callback here. 167 * normal insert callback here.
168 */ 168 */
169#ifdef CONFIG_PPC_ISERIES 169#ifdef CONFIG_PPC_ISERIES
170 if (_machine == PLATFORM_ISERIES_LPAR) 170 if (machine_is(iseries))
171 ret = iSeries_hpte_insert(hpteg, va, 171 ret = iSeries_hpte_insert(hpteg, va,
172 paddr, 172 paddr,
173 tmp_mode, 173 tmp_mode,
@@ -176,7 +176,7 @@ int htab_bolt_mapping(unsigned long vstart, unsigned long vend,
176 else 176 else
177#endif 177#endif
178#ifdef CONFIG_PPC_PSERIES 178#ifdef CONFIG_PPC_PSERIES
179 if (_machine & PLATFORM_LPAR) 179 if (machine_is(pseries) && firmware_has_feature(FW_FEATURE_LPAR))
180 ret = pSeries_lpar_hpte_insert(hpteg, va, 180 ret = pSeries_lpar_hpte_insert(hpteg, va,
181 paddr, 181 paddr,
182 tmp_mode, 182 tmp_mode,
@@ -295,8 +295,7 @@ static void __init htab_init_page_sizes(void)
295 * Not in the device-tree, let's fallback on known size 295 * Not in the device-tree, let's fallback on known size
296 * list for 16M capable GP & GR 296 * list for 16M capable GP & GR
297 */ 297 */
298 if ((_machine != PLATFORM_ISERIES_LPAR) && 298 if (cpu_has_feature(CPU_FTR_16M_PAGE) && !machine_is(iseries))
299 cpu_has_feature(CPU_FTR_16M_PAGE))
300 memcpy(mmu_psize_defs, mmu_psize_defaults_gp, 299 memcpy(mmu_psize_defs, mmu_psize_defaults_gp,
301 sizeof(mmu_psize_defaults_gp)); 300 sizeof(mmu_psize_defaults_gp));
302 found: 301 found:
diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c
index 5e435a9c3431..741dd8802d49 100644
--- a/arch/powerpc/mm/mem.c
+++ b/arch/powerpc/mm/mem.c
@@ -342,7 +342,7 @@ void __init mem_init(void)
342#ifdef CONFIG_NEED_MULTIPLE_NODES 342#ifdef CONFIG_NEED_MULTIPLE_NODES
343 for_each_online_node(nid) { 343 for_each_online_node(nid) {
344 if (NODE_DATA(nid)->node_spanned_pages != 0) { 344 if (NODE_DATA(nid)->node_spanned_pages != 0) {
345 printk("freeing bootmem node %x\n", nid); 345 printk("freeing bootmem node %d\n", nid);
346 totalram_pages += 346 totalram_pages +=
347 free_all_bootmem_node(NODE_DATA(nid)); 347 free_all_bootmem_node(NODE_DATA(nid));
348 } 348 }
diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c
index e89b22aa539e..0a335f34974c 100644
--- a/arch/powerpc/mm/numa.c
+++ b/arch/powerpc/mm/numa.c
@@ -756,6 +756,7 @@ int hot_add_scn_to_nid(unsigned long scn_addr)
756 struct device_node *memory = NULL; 756 struct device_node *memory = NULL;
757 nodemask_t nodes; 757 nodemask_t nodes;
758 int default_nid = any_online_node(NODE_MASK_ALL); 758 int default_nid = any_online_node(NODE_MASK_ALL);
759 int nid;
759 760
760 if (!numa_enabled || (min_common_depth < 0)) 761 if (!numa_enabled || (min_common_depth < 0))
761 return default_nid; 762 return default_nid;
@@ -790,6 +791,7 @@ ha_new_range:
790 goto ha_new_range; 791 goto ha_new_range;
791 } 792 }
792 BUG(); /* section address should be found above */ 793 BUG(); /* section address should be found above */
794 return 0;
793 795
794 /* Temporary code to ensure that returned node is not empty */ 796 /* Temporary code to ensure that returned node is not empty */
795got_nid: 797got_nid:
diff --git a/arch/powerpc/mm/pgtable_32.c b/arch/powerpc/mm/pgtable_32.c
index d296eb6b4545..90628601fac7 100644
--- a/arch/powerpc/mm/pgtable_32.c
+++ b/arch/powerpc/mm/pgtable_32.c
@@ -372,7 +372,7 @@ void __init io_block_mapping(unsigned long virt, phys_addr_t phys,
372 * the PTE pointer is unmodified if PTE is not found. 372 * the PTE pointer is unmodified if PTE is not found.
373 */ 373 */
374int 374int
375get_pteptr(struct mm_struct *mm, unsigned long addr, pte_t **ptep) 375get_pteptr(struct mm_struct *mm, unsigned long addr, pte_t **ptep, pmd_t **pmdp)
376{ 376{
377 pgd_t *pgd; 377 pgd_t *pgd;
378 pmd_t *pmd; 378 pmd_t *pmd;
@@ -387,6 +387,8 @@ get_pteptr(struct mm_struct *mm, unsigned long addr, pte_t **ptep)
387 if (pte) { 387 if (pte) {
388 retval = 1; 388 retval = 1;
389 *ptep = pte; 389 *ptep = pte;
390 if (pmdp)
391 *pmdp = pmd;
390 /* XXX caller needs to do pte_unmap, yuck */ 392 /* XXX caller needs to do pte_unmap, yuck */
391 } 393 }
392 } 394 }
@@ -424,7 +426,7 @@ unsigned long iopa(unsigned long addr)
424 mm = &init_mm; 426 mm = &init_mm;
425 427
426 pa = 0; 428 pa = 0;
427 if (get_pteptr(mm, addr, &pte)) { 429 if (get_pteptr(mm, addr, &pte, NULL)) {
428 pa = (pte_val(*pte) & PAGE_MASK) | (addr & ~PAGE_MASK); 430 pa = (pte_val(*pte) & PAGE_MASK) | (addr & ~PAGE_MASK);
429 pte_unmap(pte); 431 pte_unmap(pte);
430 } 432 }
diff --git a/arch/powerpc/mm/stab.c b/arch/powerpc/mm/stab.c
index 91d25fb27f89..4a9291d9fef8 100644
--- a/arch/powerpc/mm/stab.c
+++ b/arch/powerpc/mm/stab.c
@@ -239,7 +239,7 @@ void stabs_alloc(void)
239 if (cpu_has_feature(CPU_FTR_SLB)) 239 if (cpu_has_feature(CPU_FTR_SLB))
240 return; 240 return;
241 241
242 for_each_cpu(cpu) { 242 for_each_possible_cpu(cpu) {
243 unsigned long newstab; 243 unsigned long newstab;
244 244
245 if (cpu == 0) 245 if (cpu == 0)
diff --git a/arch/powerpc/oprofile/Makefile b/arch/powerpc/oprofile/Makefile
index 554cd7c75321..f5f9859a8338 100644
--- a/arch/powerpc/oprofile/Makefile
+++ b/arch/powerpc/oprofile/Makefile
@@ -6,7 +6,7 @@ DRIVER_OBJS := $(addprefix ../../../drivers/oprofile/, \
6 oprofilefs.o oprofile_stats.o \ 6 oprofilefs.o oprofile_stats.o \
7 timer_int.o ) 7 timer_int.o )
8 8
9oprofile-y := $(DRIVER_OBJS) common.o 9oprofile-y := $(DRIVER_OBJS) common.o backtrace.o
10oprofile-$(CONFIG_PPC64) += op_model_rs64.o op_model_power4.o 10oprofile-$(CONFIG_PPC64) += op_model_rs64.o op_model_power4.o
11oprofile-$(CONFIG_FSL_BOOKE) += op_model_fsl_booke.o 11oprofile-$(CONFIG_FSL_BOOKE) += op_model_fsl_booke.o
12oprofile-$(CONFIG_PPC32) += op_model_7450.o 12oprofile-$(CONFIG_PPC32) += op_model_7450.o
diff --git a/arch/powerpc/oprofile/backtrace.c b/arch/powerpc/oprofile/backtrace.c
new file mode 100644
index 000000000000..75f57bc96b40
--- /dev/null
+++ b/arch/powerpc/oprofile/backtrace.c
@@ -0,0 +1,126 @@
1/**
2 * Copyright (C) 2005 Brian Rogan <bcr6@cornell.edu>, IBM
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version
7 * 2 of the License, or (at your option) any later version.
8**/
9
10#include <linux/oprofile.h>
11#include <linux/sched.h>
12#include <asm/processor.h>
13#include <asm/uaccess.h>
14
15#define STACK_SP(STACK) *(STACK)
16
17#define STACK_LR64(STACK) *((unsigned long *)(STACK) + 2)
18#define STACK_LR32(STACK) *((unsigned int *)(STACK) + 1)
19
20#ifdef CONFIG_PPC64
21#define STACK_LR(STACK) STACK_LR64(STACK)
22#else
23#define STACK_LR(STACK) STACK_LR32(STACK)
24#endif
25
26static unsigned int user_getsp32(unsigned int sp, int is_first)
27{
28 unsigned int stack_frame[2];
29
30 if (!access_ok(VERIFY_READ, sp, sizeof(stack_frame)))
31 return 0;
32
33 /*
34 * The most likely reason for this is that we returned -EFAULT,
35 * which means that we've done all that we can do from
36 * interrupt context.
37 */
38 if (__copy_from_user_inatomic(stack_frame, (void *)(long)sp,
39 sizeof(stack_frame)))
40 return 0;
41
42 if (!is_first)
43 oprofile_add_trace(STACK_LR32(stack_frame));
44
45 /*
46 * We do not enforce increasing stack addresses here because
47 * we may transition to a different stack, eg a signal handler.
48 */
49 return STACK_SP(stack_frame);
50}
51
52#ifdef CONFIG_PPC64
53static unsigned long user_getsp64(unsigned long sp, int is_first)
54{
55 unsigned long stack_frame[3];
56
57 if (!access_ok(VERIFY_READ, sp, sizeof(stack_frame)))
58 return 0;
59
60 if (__copy_from_user_inatomic(stack_frame, (void *)sp,
61 sizeof(stack_frame)))
62 return 0;
63
64 if (!is_first)
65 oprofile_add_trace(STACK_LR64(stack_frame));
66
67 return STACK_SP(stack_frame);
68}
69#endif
70
71static unsigned long kernel_getsp(unsigned long sp, int is_first)
72{
73 unsigned long *stack_frame = (unsigned long *)sp;
74
75 if (!validate_sp(sp, current, STACK_FRAME_OVERHEAD))
76 return 0;
77
78 if (!is_first)
79 oprofile_add_trace(STACK_LR(stack_frame));
80
81 /*
82 * We do not enforce increasing stack addresses here because
83 * we might be transitioning from an interrupt stack to a kernel
84 * stack. validate_sp() is designed to understand this, so just
85 * use it.
86 */
87 return STACK_SP(stack_frame);
88}
89
90void op_powerpc_backtrace(struct pt_regs * const regs, unsigned int depth)
91{
92 unsigned long sp = regs->gpr[1];
93 int first_frame = 1;
94
95 /* We ditch the top stackframe so need to loop through an extra time */
96 depth += 1;
97
98 if (!user_mode(regs)) {
99 while (depth--) {
100 sp = kernel_getsp(sp, first_frame);
101 if (!sp)
102 break;
103 first_frame = 0;
104 }
105 } else {
106#ifdef CONFIG_PPC64
107 if (!test_thread_flag(TIF_32BIT)) {
108 while (depth--) {
109 sp = user_getsp64(sp, first_frame);
110 if (!sp)
111 break;
112 first_frame = 0;
113 }
114
115 return;
116 }
117#endif
118
119 while (depth--) {
120 sp = user_getsp32(sp, first_frame);
121 if (!sp)
122 break;
123 first_frame = 0;
124 }
125 }
126}
diff --git a/arch/powerpc/oprofile/common.c b/arch/powerpc/oprofile/common.c
index cc2535be3a73..5b1de7e8041e 100644
--- a/arch/powerpc/oprofile/common.c
+++ b/arch/powerpc/oprofile/common.c
@@ -117,18 +117,10 @@ static int op_powerpc_create_files(struct super_block *sb, struct dentry *root)
117 117
118 oprofilefs_create_ulong(sb, root, "enable_kernel", &sys.enable_kernel); 118 oprofilefs_create_ulong(sb, root, "enable_kernel", &sys.enable_kernel);
119 oprofilefs_create_ulong(sb, root, "enable_user", &sys.enable_user); 119 oprofilefs_create_ulong(sb, root, "enable_user", &sys.enable_user);
120#ifdef CONFIG_PPC64
121 oprofilefs_create_ulong(sb, root, "backtrace_spinlocks",
122 &sys.backtrace_spinlocks);
123#endif
124 120
125 /* Default to tracing both kernel and user */ 121 /* Default to tracing both kernel and user */
126 sys.enable_kernel = 1; 122 sys.enable_kernel = 1;
127 sys.enable_user = 1; 123 sys.enable_user = 1;
128#ifdef CONFIG_PPC64
129 /* Turn on backtracing through spinlocks by default */
130 sys.backtrace_spinlocks = 1;
131#endif
132 124
133 return 0; 125 return 0;
134} 126}
@@ -168,6 +160,7 @@ int __init oprofile_arch_init(struct oprofile_operations *ops)
168 ops->shutdown = op_powerpc_shutdown; 160 ops->shutdown = op_powerpc_shutdown;
169 ops->start = op_powerpc_start; 161 ops->start = op_powerpc_start;
170 ops->stop = op_powerpc_stop; 162 ops->stop = op_powerpc_stop;
163 ops->backtrace = op_powerpc_backtrace;
171 164
172 printk(KERN_INFO "oprofile: using %s performance monitoring.\n", 165 printk(KERN_INFO "oprofile: using %s performance monitoring.\n",
173 ops->cpu_type); 166 ops->cpu_type);
diff --git a/arch/powerpc/oprofile/op_model_7450.c b/arch/powerpc/oprofile/op_model_7450.c
index 32abfdbb0eb1..e0491c3c71f1 100644
--- a/arch/powerpc/oprofile/op_model_7450.c
+++ b/arch/powerpc/oprofile/op_model_7450.c
@@ -176,13 +176,13 @@ static void fsl7450_handle_interrupt(struct pt_regs *regs,
176 mtmsr(mfmsr() | MSR_PMM); 176 mtmsr(mfmsr() | MSR_PMM);
177 177
178 pc = mfspr(SPRN_SIAR); 178 pc = mfspr(SPRN_SIAR);
179 is_kernel = (pc >= KERNELBASE); 179 is_kernel = is_kernel_addr(pc);
180 180
181 for (i = 0; i < NUM_CTRS; ++i) { 181 for (i = 0; i < NUM_CTRS; ++i) {
182 val = ctr_read(i); 182 val = ctr_read(i);
183 if (val < 0) { 183 if (val < 0) {
184 if (oprofile_running && ctr[i].enabled) { 184 if (oprofile_running && ctr[i].enabled) {
185 oprofile_add_pc(pc, is_kernel, i); 185 oprofile_add_ext_sample(pc, regs, i, is_kernel);
186 ctr_write(i, reset_value[i]); 186 ctr_write(i, reset_value[i]);
187 } else { 187 } else {
188 ctr_write(i, 0); 188 ctr_write(i, 0);
diff --git a/arch/powerpc/oprofile/op_model_fsl_booke.c b/arch/powerpc/oprofile/op_model_fsl_booke.c
index 26539cda6023..93d63e62662f 100644
--- a/arch/powerpc/oprofile/op_model_fsl_booke.c
+++ b/arch/powerpc/oprofile/op_model_fsl_booke.c
@@ -154,13 +154,13 @@ static void fsl_booke_handle_interrupt(struct pt_regs *regs,
154 mtmsr(mfmsr() | MSR_PMM); 154 mtmsr(mfmsr() | MSR_PMM);
155 155
156 pc = regs->nip; 156 pc = regs->nip;
157 is_kernel = (pc >= KERNELBASE); 157 is_kernel = is_kernel_addr(pc);
158 158
159 for (i = 0; i < num_counters; ++i) { 159 for (i = 0; i < num_counters; ++i) {
160 val = ctr_read(i); 160 val = ctr_read(i);
161 if (val < 0) { 161 if (val < 0) {
162 if (oprofile_running && ctr[i].enabled) { 162 if (oprofile_running && ctr[i].enabled) {
163 oprofile_add_pc(pc, is_kernel, i); 163 oprofile_add_ext_sample(pc, regs, i, is_kernel);
164 ctr_write(i, reset_value[i]); 164 ctr_write(i, reset_value[i]);
165 } else { 165 } else {
166 ctr_write(i, 0); 166 ctr_write(i, 0);
diff --git a/arch/powerpc/oprofile/op_model_power4.c b/arch/powerpc/oprofile/op_model_power4.c
index 4b06e53eb9b4..4c2beab1fdc1 100644
--- a/arch/powerpc/oprofile/op_model_power4.c
+++ b/arch/powerpc/oprofile/op_model_power4.c
@@ -25,18 +25,14 @@ static unsigned long reset_value[OP_MAX_COUNTER];
25 25
26static int oprofile_running; 26static int oprofile_running;
27static int mmcra_has_sihv; 27static int mmcra_has_sihv;
28/* Unfortunately these bits vary between CPUs */
29static unsigned long mmcra_sihv = MMCRA_SIHV;
30static unsigned long mmcra_sipr = MMCRA_SIPR;
28 31
29/* mmcr values are set in power4_reg_setup, used in power4_cpu_setup */ 32/* mmcr values are set in power4_reg_setup, used in power4_cpu_setup */
30static u32 mmcr0_val; 33static u32 mmcr0_val;
31static u64 mmcr1_val; 34static u64 mmcr1_val;
32static u32 mmcra_val; 35static u64 mmcra_val;
33
34/*
35 * Since we do not have an NMI, backtracing through spinlocks is
36 * only a best guess. In light of this, allow it to be disabled at
37 * runtime.
38 */
39static int backtrace_spinlocks;
40 36
41static void power4_reg_setup(struct op_counter_config *ctr, 37static void power4_reg_setup(struct op_counter_config *ctr,
42 struct op_system_config *sys, 38 struct op_system_config *sys,
@@ -63,8 +59,6 @@ static void power4_reg_setup(struct op_counter_config *ctr,
63 mmcr1_val = sys->mmcr1; 59 mmcr1_val = sys->mmcr1;
64 mmcra_val = sys->mmcra; 60 mmcra_val = sys->mmcra;
65 61
66 backtrace_spinlocks = sys->backtrace_spinlocks;
67
68 for (i = 0; i < cur_cpu_spec->num_pmcs; ++i) 62 for (i = 0; i < cur_cpu_spec->num_pmcs; ++i)
69 reset_value[i] = 0x80000000UL - ctr[i].count; 63 reset_value[i] = 0x80000000UL - ctr[i].count;
70 64
@@ -197,25 +191,6 @@ static void __attribute_used__ kernel_unknown_bucket(void)
197{ 191{
198} 192}
199 193
200static unsigned long check_spinlock_pc(struct pt_regs *regs,
201 unsigned long profile_pc)
202{
203 unsigned long pc = instruction_pointer(regs);
204
205 /*
206 * If both the SIAR (sampled instruction) and the perfmon exception
207 * occurred in a spinlock region then we account the sample to the
208 * calling function. This isnt 100% correct, we really need soft
209 * IRQ disable so we always get the perfmon exception at the
210 * point at which the SIAR is set.
211 */
212 if (backtrace_spinlocks && in_lock_functions(pc) &&
213 in_lock_functions(profile_pc))
214 return regs->link;
215 else
216 return profile_pc;
217}
218
219/* 194/*
220 * On GQ and newer the MMCRA stores the HV and PR bits at the time 195 * On GQ and newer the MMCRA stores the HV and PR bits at the time
221 * the SIAR was sampled. We use that to work out if the SIAR was sampled in 196 * the SIAR was sampled. We use that to work out if the SIAR was sampled in
@@ -228,17 +203,17 @@ static unsigned long get_pc(struct pt_regs *regs)
228 203
229 /* Cant do much about it */ 204 /* Cant do much about it */
230 if (!mmcra_has_sihv) 205 if (!mmcra_has_sihv)
231 return check_spinlock_pc(regs, pc); 206 return pc;
232 207
233 mmcra = mfspr(SPRN_MMCRA); 208 mmcra = mfspr(SPRN_MMCRA);
234 209
235 /* Were we in the hypervisor? */ 210 /* Were we in the hypervisor? */
236 if (firmware_has_feature(FW_FEATURE_LPAR) && (mmcra & MMCRA_SIHV)) 211 if (firmware_has_feature(FW_FEATURE_LPAR) && (mmcra & mmcra_sihv))
237 /* function descriptor madness */ 212 /* function descriptor madness */
238 return *((unsigned long *)hypervisor_bucket); 213 return *((unsigned long *)hypervisor_bucket);
239 214
240 /* We were in userspace, nothing to do */ 215 /* We were in userspace, nothing to do */
241 if (mmcra & MMCRA_SIPR) 216 if (mmcra & mmcra_sipr)
242 return pc; 217 return pc;
243 218
244#ifdef CONFIG_PPC_RTAS 219#ifdef CONFIG_PPC_RTAS
@@ -257,7 +232,7 @@ static unsigned long get_pc(struct pt_regs *regs)
257 /* function descriptor madness */ 232 /* function descriptor madness */
258 return *((unsigned long *)kernel_unknown_bucket); 233 return *((unsigned long *)kernel_unknown_bucket);
259 234
260 return check_spinlock_pc(regs, pc); 235 return pc;
261} 236}
262 237
263static int get_kernel(unsigned long pc) 238static int get_kernel(unsigned long pc)
@@ -268,7 +243,7 @@ static int get_kernel(unsigned long pc)
268 is_kernel = is_kernel_addr(pc); 243 is_kernel = is_kernel_addr(pc);
269 } else { 244 } else {
270 unsigned long mmcra = mfspr(SPRN_MMCRA); 245 unsigned long mmcra = mfspr(SPRN_MMCRA);
271 is_kernel = ((mmcra & MMCRA_SIPR) == 0); 246 is_kernel = ((mmcra & mmcra_sipr) == 0);
272 } 247 }
273 248
274 return is_kernel; 249 return is_kernel;
@@ -293,7 +268,7 @@ static void power4_handle_interrupt(struct pt_regs *regs,
293 val = ctr_read(i); 268 val = ctr_read(i);
294 if (val < 0) { 269 if (val < 0) {
295 if (oprofile_running && ctr[i].enabled) { 270 if (oprofile_running && ctr[i].enabled) {
296 oprofile_add_pc(pc, is_kernel, i); 271 oprofile_add_ext_sample(pc, regs, i, is_kernel);
297 ctr_write(i, reset_value[i]); 272 ctr_write(i, reset_value[i]);
298 } else { 273 } else {
299 ctr_write(i, 0); 274 ctr_write(i, 0);
diff --git a/arch/powerpc/oprofile/op_model_rs64.c b/arch/powerpc/oprofile/op_model_rs64.c
index 5c909ee609fe..042f8f4867ad 100644
--- a/arch/powerpc/oprofile/op_model_rs64.c
+++ b/arch/powerpc/oprofile/op_model_rs64.c
@@ -175,10 +175,13 @@ static void rs64_handle_interrupt(struct pt_regs *regs,
175 struct op_counter_config *ctr) 175 struct op_counter_config *ctr)
176{ 176{
177 unsigned int mmcr0; 177 unsigned int mmcr0;
178 int is_kernel;
178 int val; 179 int val;
179 int i; 180 int i;
180 unsigned long pc = mfspr(SPRN_SIAR); 181 unsigned long pc = mfspr(SPRN_SIAR);
181 182
183 is_kernel = is_kernel_addr(pc);
184
182 /* set the PMM bit (see comment below) */ 185 /* set the PMM bit (see comment below) */
183 mtmsrd(mfmsr() | MSR_PMM); 186 mtmsrd(mfmsr() | MSR_PMM);
184 187
@@ -186,7 +189,7 @@ static void rs64_handle_interrupt(struct pt_regs *regs,
186 val = ctr_read(i); 189 val = ctr_read(i);
187 if (val < 0) { 190 if (val < 0) {
188 if (ctr[i].enabled) { 191 if (ctr[i].enabled) {
189 oprofile_add_pc(pc, is_kernel_addr(pc), i); 192 oprofile_add_ext_sample(pc, regs, i, is_kernel);
190 ctr_write(i, reset_value[i]); 193 ctr_write(i, reset_value[i]);
191 } else { 194 } else {
192 ctr_write(i, 0); 195 ctr_write(i, 0);
diff --git a/arch/powerpc/platforms/85xx/Kconfig b/arch/powerpc/platforms/85xx/Kconfig
index d3d0ff745e84..06e371282f57 100644
--- a/arch/powerpc/platforms/85xx/Kconfig
+++ b/arch/powerpc/platforms/85xx/Kconfig
@@ -7,6 +7,7 @@ choice
7 7
8config MPC8540_ADS 8config MPC8540_ADS
9 bool "Freescale MPC8540 ADS" 9 bool "Freescale MPC8540 ADS"
10 select DEFAULT_UIMAGE
10 help 11 help
11 This option enables support for the MPC 8540 ADS board 12 This option enables support for the MPC 8540 ADS board
12 13
diff --git a/arch/powerpc/platforms/cell/Kconfig b/arch/powerpc/platforms/cell/Kconfig
index 3157071e241c..c2a3db8edb0c 100644
--- a/arch/powerpc/platforms/cell/Kconfig
+++ b/arch/powerpc/platforms/cell/Kconfig
@@ -10,4 +10,9 @@ config SPU_FS
10 Units on machines implementing the Broadband Processor 10 Units on machines implementing the Broadband Processor
11 Architecture. 11 Architecture.
12 12
13config SPUFS_MMAP
14 bool
15 depends on SPU_FS && SPARSEMEM && !PPC_64K_PAGES
16 default y
17
13endmenu 18endmenu
diff --git a/arch/powerpc/platforms/cell/Makefile b/arch/powerpc/platforms/cell/Makefile
index 3b998a393e3f..e570bad06394 100644
--- a/arch/powerpc/platforms/cell/Makefile
+++ b/arch/powerpc/platforms/cell/Makefile
@@ -6,5 +6,11 @@ obj-$(CONFIG_SPU_FS) += spu-base.o spufs/
6 6
7spu-base-y += spu_base.o spu_priv1.o 7spu-base-y += spu_base.o spu_priv1.o
8 8
9builtin-spufs-$(CONFIG_SPU_FS) += spu_syscalls.o 9# needed only when building loadable spufs.ko
10obj-y += $(builtin-spufs-m) 10spufs-modular-$(CONFIG_SPU_FS) += spu_syscalls.o
11obj-y += $(spufs-modular-m)
12
13# always needed in kernel
14spufs-builtin-$(CONFIG_SPU_FS) += spu_callbacks.o
15obj-y += $(spufs-builtin-y) $(spufs-builtin-m)
16
diff --git a/arch/powerpc/platforms/cell/interrupt.c b/arch/powerpc/platforms/cell/interrupt.c
index 63aa52acf441..978be1c30c1b 100644
--- a/arch/powerpc/platforms/cell/interrupt.c
+++ b/arch/powerpc/platforms/cell/interrupt.c
@@ -63,7 +63,24 @@ static DEFINE_PER_CPU(struct iic, iic);
63 63
64void iic_local_enable(void) 64void iic_local_enable(void)
65{ 65{
66 out_be64(&__get_cpu_var(iic).regs->prio, 0xff); 66 struct iic *iic = &__get_cpu_var(iic);
67 u64 tmp;
68
69 /*
70 * There seems to be a bug that is present in DD2.x CPUs
71 * and still only partially fixed in DD3.1.
72 * This bug causes a value written to the priority register
73 * not to make it there, resulting in a system hang unless we
74 * write it again.
75 * Masking with 0xf0 is done because the Cell BE does not
76 * implement the lower four bits of the interrupt priority,
77 * they always read back as zeroes, although future CPUs
78 * might implement different bits.
79 */
80 do {
81 out_be64(&iic->regs->prio, 0xff);
82 tmp = in_be64(&iic->regs->prio);
83 } while ((tmp & 0xf0) != 0xf0);
67} 84}
68 85
69void iic_local_disable(void) 86void iic_local_disable(void)
@@ -123,7 +140,7 @@ static int iic_external_get_irq(struct iic_pending_bits pending)
123 pending.class != 2) 140 pending.class != 2)
124 break; 141 break;
125 irq = IIC_EXT_OFFSET 142 irq = IIC_EXT_OFFSET
126 + spider_get_irq(pending.prio + node * IIC_NODE_STRIDE) 143 + spider_get_irq(node)
127 + node * IIC_NODE_STRIDE; 144 + node * IIC_NODE_STRIDE;
128 break; 145 break;
129 case 0x01 ... 0x04: 146 case 0x01 ... 0x04:
@@ -174,38 +191,98 @@ int iic_get_irq(struct pt_regs *regs)
174 return irq; 191 return irq;
175} 192}
176 193
177static int setup_iic(int cpu, struct iic *iic) 194/* hardcoded part to be compatible with older firmware */
195
196static int setup_iic_hardcoded(void)
178{ 197{
179 struct device_node *np; 198 struct device_node *np;
180 int nodeid = cpu / 2; 199 int nodeid, cpu;
181 unsigned long regs; 200 unsigned long regs;
201 struct iic *iic;
182 202
183 for (np = of_find_node_by_type(NULL, "cpu"); 203 for_each_cpu(cpu) {
184 np; 204 iic = &per_cpu(iic, cpu);
185 np = of_find_node_by_type(np, "cpu")) { 205 nodeid = cpu/2;
186 if (nodeid == *(int *)get_property(np, "node-id", NULL)) 206
187 break; 207 for (np = of_find_node_by_type(NULL, "cpu");
208 np;
209 np = of_find_node_by_type(np, "cpu")) {
210 if (nodeid == *(int *)get_property(np, "node-id", NULL))
211 break;
212 }
213
214 if (!np) {
215 printk(KERN_WARNING "IIC: CPU %d not found\n", cpu);
216 iic->regs = NULL;
217 iic->target_id = 0xff;
218 return -ENODEV;
219 }
220
221 regs = *(long *)get_property(np, "iic", NULL);
222
223 /* hack until we have decided on the devtree info */
224 regs += 0x400;
225 if (cpu & 1)
226 regs += 0x20;
227
228 printk(KERN_INFO "IIC for CPU %d at %lx\n", cpu, regs);
229 iic->regs = ioremap(regs, sizeof(struct iic_regs));
230 iic->target_id = (nodeid << 4) + ((cpu & 1) ? 0xf : 0xe);
188 } 231 }
189 232
190 if (!np) { 233 return 0;
191 printk(KERN_WARNING "IIC: CPU %d not found\n", cpu); 234}
192 iic->regs = NULL;
193 iic->target_id = 0xff;
194 return -ENODEV;
195 }
196 235
197 regs = *(long *)get_property(np, "iic", NULL); 236static int setup_iic(void)
237{
238 struct device_node *dn;
239 unsigned long *regs;
240 char *compatible;
241 unsigned *np, found = 0;
242 struct iic *iic = NULL;
243
244 for (dn = NULL; (dn = of_find_node_by_name(dn, "interrupt-controller"));) {
245 compatible = (char *)get_property(dn, "compatible", NULL);
246
247 if (!compatible) {
248 printk(KERN_WARNING "no compatible property found !\n");
249 continue;
250 }
198 251
199 /* hack until we have decided on the devtree info */ 252 if (strstr(compatible, "IBM,CBEA-Internal-Interrupt-Controller"))
200 regs += 0x400; 253 regs = (unsigned long *)get_property(dn,"reg", NULL);
201 if (cpu & 1) 254 else
202 regs += 0x20; 255 continue;
203 256
204 printk(KERN_DEBUG "IIC for CPU %d at %lx\n", cpu, regs); 257 if (!regs)
205 iic->regs = __ioremap(regs, sizeof(struct iic_regs), 258 printk(KERN_WARNING "IIC: no reg property\n");
206 _PAGE_NO_CACHE); 259
207 iic->target_id = (nodeid << 4) + ((cpu & 1) ? 0xf : 0xe); 260 np = (unsigned int *)get_property(dn, "ibm,interrupt-server-ranges", NULL);
208 return 0; 261
262 if (!np) {
263 printk(KERN_WARNING "IIC: CPU association not found\n");
264 iic->regs = NULL;
265 iic->target_id = 0xff;
266 return -ENODEV;
267 }
268
269 iic = &per_cpu(iic, np[0]);
270 iic->regs = ioremap(regs[0], sizeof(struct iic_regs));
271 iic->target_id = ((np[0] & 2) << 3) + ((np[0] & 1) ? 0xf : 0xe);
272 printk("IIC for CPU %d at %lx mapped to %p\n", np[0], regs[0], iic->regs);
273
274 iic = &per_cpu(iic, np[1]);
275 iic->regs = ioremap(regs[2], sizeof(struct iic_regs));
276 iic->target_id = ((np[1] & 2) << 3) + ((np[1] & 1) ? 0xf : 0xe);
277 printk("IIC for CPU %d at %lx mapped to %p\n", np[1], regs[2], iic->regs);
278
279 found++;
280 }
281
282 if (found)
283 return 0;
284 else
285 return -ENODEV;
209} 286}
210 287
211#ifdef CONFIG_SMP 288#ifdef CONFIG_SMP
@@ -283,10 +360,12 @@ void iic_init_IRQ(void)
283 int cpu, irq_offset; 360 int cpu, irq_offset;
284 struct iic *iic; 361 struct iic *iic;
285 362
363 if (setup_iic() < 0)
364 setup_iic_hardcoded();
365
286 irq_offset = 0; 366 irq_offset = 0;
287 for_each_cpu(cpu) { 367 for_each_possible_cpu(cpu) {
288 iic = &per_cpu(iic, cpu); 368 iic = &per_cpu(iic, cpu);
289 setup_iic(cpu, iic);
290 if (iic->regs) 369 if (iic->regs)
291 out_be64(&iic->regs->prio, 0xff); 370 out_be64(&iic->regs->prio, 0xff);
292 } 371 }
diff --git a/arch/powerpc/platforms/cell/interrupt.h b/arch/powerpc/platforms/cell/interrupt.h
index a14bd38791c0..799f77d98f96 100644
--- a/arch/powerpc/platforms/cell/interrupt.h
+++ b/arch/powerpc/platforms/cell/interrupt.h
@@ -57,7 +57,7 @@ extern void iic_local_disable(void);
57extern u8 iic_get_target_id(int cpu); 57extern u8 iic_get_target_id(int cpu);
58 58
59extern void spider_init_IRQ(void); 59extern void spider_init_IRQ(void);
60extern int spider_get_irq(unsigned long int_pending); 60extern int spider_get_irq(int node);
61 61
62#endif 62#endif
63#endif /* ASM_CELL_PIC_H */ 63#endif /* ASM_CELL_PIC_H */
diff --git a/arch/powerpc/platforms/cell/iommu.c b/arch/powerpc/platforms/cell/iommu.c
index 46e7cb9c3e64..a49ceb799a8e 100644
--- a/arch/powerpc/platforms/cell/iommu.c
+++ b/arch/powerpc/platforms/cell/iommu.c
@@ -289,7 +289,7 @@ static void cell_do_map_iommu(struct cell_iommu *iommu,
289 ioc_base = iommu->mapped_base; 289 ioc_base = iommu->mapped_base;
290 ioc_mmio_base = iommu->mapped_mmio_base; 290 ioc_mmio_base = iommu->mapped_mmio_base;
291 291
292 for (real_address = 0, io_address = 0; 292 for (real_address = 0, io_address = map_start;
293 io_address <= map_start + map_size; 293 io_address <= map_start + map_size;
294 real_address += io_page_size, io_address += io_page_size) { 294 real_address += io_page_size, io_address += io_page_size) {
295 ioste = get_iost_entry(fake_iopt, io_address, io_page_size); 295 ioste = get_iost_entry(fake_iopt, io_address, io_page_size);
@@ -302,7 +302,7 @@ static void cell_do_map_iommu(struct cell_iommu *iommu,
302 set_iopt_cache(ioc_mmio_base, 302 set_iopt_cache(ioc_mmio_base,
303 get_ioc_hash_1way(ioste, io_address), 303 get_ioc_hash_1way(ioste, io_address),
304 get_ioc_tag(ioste, io_address), 304 get_ioc_tag(ioste, io_address),
305 get_iopt_entry(real_address-map_start, ioid, IOPT_PROT_RW)); 305 get_iopt_entry(real_address, ioid, IOPT_PROT_RW));
306 } 306 }
307} 307}
308 308
@@ -344,8 +344,8 @@ static int cell_map_iommu_hardcoded(int num_nodes)
344 344
345 /* node 0 */ 345 /* node 0 */
346 iommu = &cell_iommus[0]; 346 iommu = &cell_iommus[0];
347 iommu->mapped_base = __ioremap(0x20000511000, 0x1000, _PAGE_NO_CACHE); 347 iommu->mapped_base = ioremap(0x20000511000, 0x1000);
348 iommu->mapped_mmio_base = __ioremap(0x20000510000, 0x1000, _PAGE_NO_CACHE); 348 iommu->mapped_mmio_base = ioremap(0x20000510000, 0x1000);
349 349
350 enable_mapping(iommu->mapped_base, iommu->mapped_mmio_base); 350 enable_mapping(iommu->mapped_base, iommu->mapped_mmio_base);
351 351
@@ -357,8 +357,8 @@ static int cell_map_iommu_hardcoded(int num_nodes)
357 357
358 /* node 1 */ 358 /* node 1 */
359 iommu = &cell_iommus[1]; 359 iommu = &cell_iommus[1];
360 iommu->mapped_base = __ioremap(0x30000511000, 0x1000, _PAGE_NO_CACHE); 360 iommu->mapped_base = ioremap(0x30000511000, 0x1000);
361 iommu->mapped_mmio_base = __ioremap(0x30000510000, 0x1000, _PAGE_NO_CACHE); 361 iommu->mapped_mmio_base = ioremap(0x30000510000, 0x1000);
362 362
363 enable_mapping(iommu->mapped_base, iommu->mapped_mmio_base); 363 enable_mapping(iommu->mapped_base, iommu->mapped_mmio_base);
364 364
@@ -407,8 +407,8 @@ static int cell_map_iommu(void)
407 iommu->base = *base; 407 iommu->base = *base;
408 iommu->mmio_base = *mmio_base; 408 iommu->mmio_base = *mmio_base;
409 409
410 iommu->mapped_base = __ioremap(*base, 0x1000, _PAGE_NO_CACHE); 410 iommu->mapped_base = ioremap(*base, 0x1000);
411 iommu->mapped_mmio_base = __ioremap(*mmio_base, 0x1000, _PAGE_NO_CACHE); 411 iommu->mapped_mmio_base = ioremap(*mmio_base, 0x1000);
412 412
413 enable_mapping(iommu->mapped_base, 413 enable_mapping(iommu->mapped_base,
414 iommu->mapped_mmio_base); 414 iommu->mapped_mmio_base);
diff --git a/arch/powerpc/platforms/cell/pervasive.c b/arch/powerpc/platforms/cell/pervasive.c
index e0e051c675dd..7eed8c624517 100644
--- a/arch/powerpc/platforms/cell/pervasive.c
+++ b/arch/powerpc/platforms/cell/pervasive.c
@@ -203,7 +203,7 @@ found:
203 203
204 pr_debug("pervasive area for CPU %d at %lx, size %x\n", 204 pr_debug("pervasive area for CPU %d at %lx, size %x\n",
205 cpu, real_address, size); 205 cpu, real_address, size);
206 p->regs = __ioremap(real_address, size, _PAGE_NO_CACHE); 206 p->regs = ioremap(real_address, size);
207 p->thread = thread; 207 p->thread = thread;
208 return 0; 208 return 0;
209} 209}
@@ -217,7 +217,7 @@ void __init cell_pervasive_init(void)
217 if (!cpu_has_feature(CPU_FTR_PAUSE_ZERO)) 217 if (!cpu_has_feature(CPU_FTR_PAUSE_ZERO))
218 return; 218 return;
219 219
220 for_each_cpu(cpu) { 220 for_each_possible_cpu(cpu) {
221 p = &cbe_pervasive[cpu]; 221 p = &cbe_pervasive[cpu];
222 ret = cbe_find_pmd_mmio(cpu, p); 222 ret = cbe_find_pmd_mmio(cpu, p);
223 if (ret) 223 if (ret)
diff --git a/arch/powerpc/platforms/cell/setup.c b/arch/powerpc/platforms/cell/setup.c
index fec8e65b36ea..dac5d0365fde 100644
--- a/arch/powerpc/platforms/cell/setup.c
+++ b/arch/powerpc/platforms/cell/setup.c
@@ -195,9 +195,13 @@ static void __init cell_init_early(void)
195} 195}
196 196
197 197
198static int __init cell_probe(int platform) 198static int __init cell_probe(void)
199{ 199{
200 if (platform != PLATFORM_CELL) 200 /* XXX This is temporary, the Cell maintainer will come up with
201 * more appropriate detection logic
202 */
203 unsigned long root = of_get_flat_dt_root();
204 if (!of_flat_dt_is_compatible(root, "IBM,CPBW-1.0"))
201 return 0; 205 return 0;
202 206
203 return 1; 207 return 1;
@@ -212,7 +216,8 @@ static int cell_check_legacy_ioport(unsigned int baseport)
212 return -ENODEV; 216 return -ENODEV;
213} 217}
214 218
215struct machdep_calls __initdata cell_md = { 219define_machine(cell) {
220 .name = "Cell",
216 .probe = cell_probe, 221 .probe = cell_probe,
217 .setup_arch = cell_setup_arch, 222 .setup_arch = cell_setup_arch,
218 .init_early = cell_init_early, 223 .init_early = cell_init_early,
diff --git a/arch/powerpc/platforms/cell/spider-pic.c b/arch/powerpc/platforms/cell/spider-pic.c
index e74132188bdf..55cbdd77a62d 100644
--- a/arch/powerpc/platforms/cell/spider-pic.c
+++ b/arch/powerpc/platforms/cell/spider-pic.c
@@ -84,10 +84,11 @@ static void __iomem *spider_get_irq_config(int irq)
84 84
85static void spider_enable_irq(unsigned int irq) 85static void spider_enable_irq(unsigned int irq)
86{ 86{
87 int nodeid = (irq / IIC_NODE_STRIDE) * 0x10;
87 void __iomem *cfg = spider_get_irq_config(irq); 88 void __iomem *cfg = spider_get_irq_config(irq);
88 irq = spider_get_nr(irq); 89 irq = spider_get_nr(irq);
89 90
90 out_be32(cfg, in_be32(cfg) | 0x3107000eu); 91 out_be32(cfg, (in_be32(cfg) & ~0xf0)| 0x3107000eu | nodeid);
91 out_be32(cfg + 4, in_be32(cfg + 4) | 0x00020000u | irq); 92 out_be32(cfg + 4, in_be32(cfg + 4) | 0x00020000u | irq);
92} 93}
93 94
@@ -131,61 +132,108 @@ static struct hw_interrupt_type spider_pic = {
131 .end = spider_end_irq, 132 .end = spider_end_irq,
132}; 133};
133 134
134 135int spider_get_irq(int node)
135int spider_get_irq(unsigned long int_pending)
136{ 136{
137 void __iomem *regs = spider_get_pic(int_pending);
138 unsigned long cs; 137 unsigned long cs;
139 int irq; 138 void __iomem *regs = spider_pics[node];
140
141 cs = in_be32(regs + TIR_CS);
142 139
143 irq = cs >> 24; 140 cs = in_be32(regs + TIR_CS) >> 24;
144 if (irq != 63)
145 return irq;
146 141
147 return -1; 142 if (cs == 63)
143 return -1;
144 else
145 return cs;
148} 146}
149 147
150void spider_init_IRQ(void) 148/* hardcoded part to be compatible with older firmware */
149
150void spider_init_IRQ_hardcoded(void)
151{ 151{
152 int node; 152 int node;
153 struct device_node *dn;
154 unsigned int *property;
155 long spiderpic; 153 long spiderpic;
154 long pics[] = { 0x24000008000, 0x34000008000 };
156 int n; 155 int n;
157 156
158/* FIXME: detect multiple PICs as soon as the device tree has them */ 157 pr_debug("%s(%d): Using hardcoded defaults\n", __FUNCTION__, __LINE__);
159 for (node = 0; node < 1; node++) {
160 dn = of_find_node_by_path("/");
161 n = prom_n_addr_cells(dn);
162 property = (unsigned int *) get_property(dn,
163 "platform-spider-pic", NULL);
164 158
165 if (!property) 159 for (node = 0; node < num_present_cpus()/2; node++) {
166 continue; 160 spiderpic = pics[node];
167 for (spiderpic = 0; n > 0; --n)
168 spiderpic = (spiderpic << 32) + *property++;
169 printk(KERN_DEBUG "SPIDER addr: %lx\n", spiderpic); 161 printk(KERN_DEBUG "SPIDER addr: %lx\n", spiderpic);
170 spider_pics[node] = __ioremap(spiderpic, 0x800, _PAGE_NO_CACHE); 162 spider_pics[node] = ioremap(spiderpic, 0x800);
171 for (n = 0; n < IIC_NUM_EXT; n++) { 163 for (n = 0; n < IIC_NUM_EXT; n++) {
172 int irq = n + IIC_EXT_OFFSET + node * IIC_NODE_STRIDE; 164 int irq = n + IIC_EXT_OFFSET + node * IIC_NODE_STRIDE;
173 get_irq_desc(irq)->handler = &spider_pic; 165 get_irq_desc(irq)->handler = &spider_pic;
166 }
174 167
175 /* do not mask any interrupts because of level */ 168 /* do not mask any interrupts because of level */
176 out_be32(spider_pics[node] + TIR_MSK, 0x0); 169 out_be32(spider_pics[node] + TIR_MSK, 0x0);
177 170
178 /* disable edge detection clear */ 171 /* disable edge detection clear */
179 /* out_be32(spider_pics[node] + TIR_EDC, 0x0); */ 172 /* out_be32(spider_pics[node] + TIR_EDC, 0x0); */
180 173
181 /* enable interrupt packets to be output */ 174 /* enable interrupt packets to be output */
182 out_be32(spider_pics[node] + TIR_PIEN, 175 out_be32(spider_pics[node] + TIR_PIEN,
183 in_be32(spider_pics[node] + TIR_PIEN) | 0x1); 176 in_be32(spider_pics[node] + TIR_PIEN) | 0x1);
184 177
185 /* Enable the interrupt detection enable bit. Do this last! */ 178 /* Enable the interrupt detection enable bit. Do this last! */
186 out_be32(spider_pics[node] + TIR_DEN, 179 out_be32(spider_pics[node] + TIR_DEN,
187 in_be32(spider_pics[node] +TIR_DEN) | 0x1); 180 in_be32(spider_pics[node] + TIR_DEN) | 0x1);
181 }
182}
183
184void spider_init_IRQ(void)
185{
186 long spider_reg;
187 struct device_node *dn;
188 char *compatible;
189 int n, node = 0;
190
191 for (dn = NULL; (dn = of_find_node_by_name(dn, "interrupt-controller"));) {
192 compatible = (char *)get_property(dn, "compatible", NULL);
188 193
194 if (!compatible)
195 continue;
196
197 if (strstr(compatible, "CBEA,platform-spider-pic"))
198 spider_reg = *(long *)get_property(dn,"reg", NULL);
199 else if (strstr(compatible, "sti,platform-spider-pic")) {
200 spider_init_IRQ_hardcoded();
201 return;
202 } else
203 continue;
204
205 if (!spider_reg)
206 printk("interrupt controller does not have reg property !\n");
207
208 n = prom_n_addr_cells(dn);
209
210 if ( n != 2)
211 printk("reg property with invalid number of elements \n");
212
213 spider_pics[node] = ioremap(spider_reg, 0x800);
214
215 printk("SPIDER addr: %lx with %i addr_cells mapped to %p\n",
216 spider_reg, n, spider_pics[node]);
217
218 for (n = 0; n < IIC_NUM_EXT; n++) {
219 int irq = n + IIC_EXT_OFFSET + node * IIC_NODE_STRIDE;
220 get_irq_desc(irq)->handler = &spider_pic;
189 } 221 }
222
223 /* do not mask any interrupts because of level */
224 out_be32(spider_pics[node] + TIR_MSK, 0x0);
225
226 /* disable edge detection clear */
227 /* out_be32(spider_pics[node] + TIR_EDC, 0x0); */
228
229 /* enable interrupt packets to be output */
230 out_be32(spider_pics[node] + TIR_PIEN,
231 in_be32(spider_pics[node] + TIR_PIEN) | 0x1);
232
233 /* Enable the interrupt detection enable bit. Do this last! */
234 out_be32(spider_pics[node] + TIR_DEN,
235 in_be32(spider_pics[node] + TIR_DEN) | 0x1);
236
237 node++;
190 } 238 }
191} 239}
diff --git a/arch/powerpc/platforms/cell/spu_base.c b/arch/powerpc/platforms/cell/spu_base.c
index a8fa1eeeb174..269dda4fd0b4 100644
--- a/arch/powerpc/platforms/cell/spu_base.c
+++ b/arch/powerpc/platforms/cell/spu_base.c
@@ -111,7 +111,7 @@ static int __spu_trap_data_seg(struct spu *spu, unsigned long ea)
111extern int hash_page(unsigned long ea, unsigned long access, unsigned long trap); //XXX 111extern int hash_page(unsigned long ea, unsigned long access, unsigned long trap); //XXX
112static int __spu_trap_data_map(struct spu *spu, unsigned long ea, u64 dsisr) 112static int __spu_trap_data_map(struct spu *spu, unsigned long ea, u64 dsisr)
113{ 113{
114 pr_debug("%s\n", __FUNCTION__); 114 pr_debug("%s, %lx, %lx\n", __FUNCTION__, dsisr, ea);
115 115
116 /* Handle kernel space hash faults immediately. 116 /* Handle kernel space hash faults immediately.
117 User hash faults need to be deferred to process context. */ 117 User hash faults need to be deferred to process context. */
@@ -168,7 +168,7 @@ static int __spu_trap_halt(struct spu *spu)
168static int __spu_trap_tag_group(struct spu *spu) 168static int __spu_trap_tag_group(struct spu *spu)
169{ 169{
170 pr_debug("%s\n", __FUNCTION__); 170 pr_debug("%s\n", __FUNCTION__);
171 /* wake_up(&spu->dma_wq); */ 171 spu->mfc_callback(spu);
172 return 0; 172 return 0;
173} 173}
174 174
@@ -242,6 +242,8 @@ spu_irq_class_1(int irq, void *data, struct pt_regs *regs)
242 spu_mfc_dsisr_set(spu, 0ul); 242 spu_mfc_dsisr_set(spu, 0ul);
243 spu_int_stat_clear(spu, 1, stat); 243 spu_int_stat_clear(spu, 1, stat);
244 spin_unlock(&spu->register_lock); 244 spin_unlock(&spu->register_lock);
245 pr_debug("%s: %lx %lx %lx %lx\n", __FUNCTION__, mask, stat,
246 dar, dsisr);
245 247
246 if (stat & 1) /* segment fault */ 248 if (stat & 1) /* segment fault */
247 __spu_trap_data_seg(spu, dar); 249 __spu_trap_data_seg(spu, dar);
@@ -484,14 +486,13 @@ int spu_irq_class_1_bottom(struct spu *spu)
484 486
485 ea = spu->dar; 487 ea = spu->dar;
486 dsisr = spu->dsisr; 488 dsisr = spu->dsisr;
487 if (dsisr & MFC_DSISR_PTE_NOT_FOUND) { 489 if (dsisr & (MFC_DSISR_PTE_NOT_FOUND | MFC_DSISR_ACCESS_DENIED)) {
488 access = (_PAGE_PRESENT | _PAGE_USER); 490 access = (_PAGE_PRESENT | _PAGE_USER);
489 access |= (dsisr & MFC_DSISR_ACCESS_PUT) ? _PAGE_RW : 0UL; 491 access |= (dsisr & MFC_DSISR_ACCESS_PUT) ? _PAGE_RW : 0UL;
490 if (hash_page(ea, access, 0x300) != 0) 492 if (hash_page(ea, access, 0x300) != 0)
491 error |= CLASS1_ENABLE_STORAGE_FAULT_INTR; 493 error |= CLASS1_ENABLE_STORAGE_FAULT_INTR;
492 } 494 }
493 if ((error & CLASS1_ENABLE_STORAGE_FAULT_INTR) || 495 if (error & CLASS1_ENABLE_STORAGE_FAULT_INTR) {
494 (dsisr & MFC_DSISR_ACCESS_DENIED)) {
495 if ((ret = spu_handle_mm_fault(spu)) != 0) 496 if ((ret = spu_handle_mm_fault(spu)) != 0)
496 error |= CLASS1_ENABLE_STORAGE_FAULT_INTR; 497 error |= CLASS1_ENABLE_STORAGE_FAULT_INTR;
497 else 498 else
@@ -568,6 +569,11 @@ static int __init spu_map_device(struct spu *spu, struct device_node *spe)
568 if (!spu->local_store) 569 if (!spu->local_store)
569 goto out; 570 goto out;
570 571
572 prop = get_property(spe, "problem", NULL);
573 if (!prop)
574 goto out_unmap;
575 spu->problem_phys = *(unsigned long *)prop;
576
571 spu->problem= map_spe_prop(spe, "problem"); 577 spu->problem= map_spe_prop(spe, "problem");
572 if (!spu->problem) 578 if (!spu->problem)
573 goto out_unmap; 579 goto out_unmap;
@@ -632,6 +638,7 @@ static int __init create_spu(struct device_node *spe)
632 spu->ibox_callback = NULL; 638 spu->ibox_callback = NULL;
633 spu->wbox_callback = NULL; 639 spu->wbox_callback = NULL;
634 spu->stop_callback = NULL; 640 spu->stop_callback = NULL;
641 spu->mfc_callback = NULL;
635 642
636 mutex_lock(&spu_mutex); 643 mutex_lock(&spu_mutex);
637 spu->number = number++; 644 spu->number = number++;
diff --git a/arch/powerpc/platforms/cell/spu_callbacks.c b/arch/powerpc/platforms/cell/spu_callbacks.c
new file mode 100644
index 000000000000..3a4245c926ad
--- /dev/null
+++ b/arch/powerpc/platforms/cell/spu_callbacks.c
@@ -0,0 +1,345 @@
1/*
2 * System call callback functions for SPUs
3 */
4
5#define DEBUG
6
7#include <linux/kallsyms.h>
8#include <linux/module.h>
9#include <linux/syscalls.h>
10
11#include <asm/spu.h>
12#include <asm/syscalls.h>
13#include <asm/unistd.h>
14
15/*
16 * This table defines the system calls that an SPU can call.
17 * It is currently a subset of the 64 bit powerpc system calls,
18 * with the exact semantics.
19 *
20 * The reasons for disabling some of the system calls are:
21 * 1. They interact with the way SPU syscalls are handled
22 * and we can't let them execute ever:
23 * restart_syscall, exit, for, execve, ptrace, ...
24 * 2. They are deprecated and replaced by other means:
25 * uselib, pciconfig_*, sysfs, ...
26 * 3. They are somewhat interacting with the system in a way
27 * we don't want an SPU to:
28 * reboot, init_module, mount, kexec_load
29 * 4. They are optional and we can't rely on them being
30 * linked into the kernel. Unfortunately, the cond_syscall
31 * helper does not work here as it does not add the necessary
32 * opd symbols:
33 * mbind, mq_open, ipc, ...
34 */
35
36void *spu_syscall_table[] = {
37 [__NR_restart_syscall] sys_ni_syscall, /* sys_restart_syscall */
38 [__NR_exit] sys_ni_syscall, /* sys_exit */
39 [__NR_fork] sys_ni_syscall, /* ppc_fork */
40 [__NR_read] sys_read,
41 [__NR_write] sys_write,
42 [__NR_open] sys_open,
43 [__NR_close] sys_close,
44 [__NR_waitpid] sys_waitpid,
45 [__NR_creat] sys_creat,
46 [__NR_link] sys_link,
47 [__NR_unlink] sys_unlink,
48 [__NR_execve] sys_ni_syscall, /* sys_execve */
49 [__NR_chdir] sys_chdir,
50 [__NR_time] sys_time,
51 [__NR_mknod] sys_mknod,
52 [__NR_chmod] sys_chmod,
53 [__NR_lchown] sys_lchown,
54 [__NR_break] sys_ni_syscall,
55 [__NR_oldstat] sys_ni_syscall,
56 [__NR_lseek] sys_lseek,
57 [__NR_getpid] sys_getpid,
58 [__NR_mount] sys_ni_syscall, /* sys_mount */
59 [__NR_umount] sys_ni_syscall,
60 [__NR_setuid] sys_setuid,
61 [__NR_getuid] sys_getuid,
62 [__NR_stime] sys_stime,
63 [__NR_ptrace] sys_ni_syscall, /* sys_ptrace */
64 [__NR_alarm] sys_alarm,
65 [__NR_oldfstat] sys_ni_syscall,
66 [__NR_pause] sys_ni_syscall, /* sys_pause */
67 [__NR_utime] sys_ni_syscall, /* sys_utime */
68 [__NR_stty] sys_ni_syscall,
69 [__NR_gtty] sys_ni_syscall,
70 [__NR_access] sys_access,
71 [__NR_nice] sys_nice,
72 [__NR_ftime] sys_ni_syscall,
73 [__NR_sync] sys_sync,
74 [__NR_kill] sys_kill,
75 [__NR_rename] sys_rename,
76 [__NR_mkdir] sys_mkdir,
77 [__NR_rmdir] sys_rmdir,
78 [__NR_dup] sys_dup,
79 [__NR_pipe] sys_pipe,
80 [__NR_times] sys_times,
81 [__NR_prof] sys_ni_syscall,
82 [__NR_brk] sys_brk,
83 [__NR_setgid] sys_setgid,
84 [__NR_getgid] sys_getgid,
85 [__NR_signal] sys_ni_syscall, /* sys_signal */
86 [__NR_geteuid] sys_geteuid,
87 [__NR_getegid] sys_getegid,
88 [__NR_acct] sys_ni_syscall, /* sys_acct */
89 [__NR_umount2] sys_ni_syscall, /* sys_umount */
90 [__NR_lock] sys_ni_syscall,
91 [__NR_ioctl] sys_ioctl,
92 [__NR_fcntl] sys_fcntl,
93 [__NR_mpx] sys_ni_syscall,
94 [__NR_setpgid] sys_setpgid,
95 [__NR_ulimit] sys_ni_syscall,
96 [__NR_oldolduname] sys_ni_syscall,
97 [__NR_umask] sys_umask,
98 [__NR_chroot] sys_chroot,
99 [__NR_ustat] sys_ni_syscall, /* sys_ustat */
100 [__NR_dup2] sys_dup2,
101 [__NR_getppid] sys_getppid,
102 [__NR_getpgrp] sys_getpgrp,
103 [__NR_setsid] sys_setsid,
104 [__NR_sigaction] sys_ni_syscall,
105 [__NR_sgetmask] sys_sgetmask,
106 [__NR_ssetmask] sys_ssetmask,
107 [__NR_setreuid] sys_setreuid,
108 [__NR_setregid] sys_setregid,
109 [__NR_sigsuspend] sys_ni_syscall,
110 [__NR_sigpending] sys_ni_syscall,
111 [__NR_sethostname] sys_sethostname,
112 [__NR_setrlimit] sys_setrlimit,
113 [__NR_getrlimit] sys_ni_syscall,
114 [__NR_getrusage] sys_getrusage,
115 [__NR_gettimeofday] sys_gettimeofday,
116 [__NR_settimeofday] sys_settimeofday,
117 [__NR_getgroups] sys_getgroups,
118 [__NR_setgroups] sys_setgroups,
119 [__NR_select] sys_ni_syscall,
120 [__NR_symlink] sys_symlink,
121 [__NR_oldlstat] sys_ni_syscall,
122 [__NR_readlink] sys_readlink,
123 [__NR_uselib] sys_ni_syscall, /* sys_uselib */
124 [__NR_swapon] sys_ni_syscall, /* sys_swapon */
125 [__NR_reboot] sys_ni_syscall, /* sys_reboot */
126 [__NR_readdir] sys_ni_syscall,
127 [__NR_mmap] sys_mmap,
128 [__NR_munmap] sys_munmap,
129 [__NR_truncate] sys_truncate,
130 [__NR_ftruncate] sys_ftruncate,
131 [__NR_fchmod] sys_fchmod,
132 [__NR_fchown] sys_fchown,
133 [__NR_getpriority] sys_getpriority,
134 [__NR_setpriority] sys_setpriority,
135 [__NR_profil] sys_ni_syscall,
136 [__NR_statfs] sys_ni_syscall, /* sys_statfs */
137 [__NR_fstatfs] sys_ni_syscall, /* sys_fstatfs */
138 [__NR_ioperm] sys_ni_syscall,
139 [__NR_socketcall] sys_socketcall,
140 [__NR_syslog] sys_syslog,
141 [__NR_setitimer] sys_setitimer,
142 [__NR_getitimer] sys_getitimer,
143 [__NR_stat] sys_newstat,
144 [__NR_lstat] sys_newlstat,
145 [__NR_fstat] sys_newfstat,
146 [__NR_olduname] sys_ni_syscall,
147 [__NR_iopl] sys_ni_syscall,
148 [__NR_vhangup] sys_vhangup,
149 [__NR_idle] sys_ni_syscall,
150 [__NR_vm86] sys_ni_syscall,
151 [__NR_wait4] sys_wait4,
152 [__NR_swapoff] sys_ni_syscall, /* sys_swapoff */
153 [__NR_sysinfo] sys_sysinfo,
154 [__NR_ipc] sys_ni_syscall, /* sys_ipc */
155 [__NR_fsync] sys_fsync,
156 [__NR_sigreturn] sys_ni_syscall,
157 [__NR_clone] sys_ni_syscall, /* ppc_clone */
158 [__NR_setdomainname] sys_setdomainname,
159 [__NR_uname] ppc_newuname,
160 [__NR_modify_ldt] sys_ni_syscall,
161 [__NR_adjtimex] sys_adjtimex,
162 [__NR_mprotect] sys_mprotect,
163 [__NR_sigprocmask] sys_ni_syscall,
164 [__NR_create_module] sys_ni_syscall,
165 [__NR_init_module] sys_ni_syscall, /* sys_init_module */
166 [__NR_delete_module] sys_ni_syscall, /* sys_delete_module */
167 [__NR_get_kernel_syms] sys_ni_syscall,
168 [__NR_quotactl] sys_ni_syscall, /* sys_quotactl */
169 [__NR_getpgid] sys_getpgid,
170 [__NR_fchdir] sys_fchdir,
171 [__NR_bdflush] sys_bdflush,
172 [__NR_sysfs] sys_ni_syscall, /* sys_sysfs */
173 [__NR_personality] ppc64_personality,
174 [__NR_afs_syscall] sys_ni_syscall,
175 [__NR_setfsuid] sys_setfsuid,
176 [__NR_setfsgid] sys_setfsgid,
177 [__NR__llseek] sys_llseek,
178 [__NR_getdents] sys_getdents,
179 [__NR__newselect] sys_select,
180 [__NR_flock] sys_flock,
181 [__NR_msync] sys_msync,
182 [__NR_readv] sys_readv,
183 [__NR_writev] sys_writev,
184 [__NR_getsid] sys_getsid,
185 [__NR_fdatasync] sys_fdatasync,
186 [__NR__sysctl] sys_ni_syscall, /* sys_sysctl */
187 [__NR_mlock] sys_mlock,
188 [__NR_munlock] sys_munlock,
189 [__NR_mlockall] sys_mlockall,
190 [__NR_munlockall] sys_munlockall,
191 [__NR_sched_setparam] sys_sched_setparam,
192 [__NR_sched_getparam] sys_sched_getparam,
193 [__NR_sched_setscheduler] sys_sched_setscheduler,
194 [__NR_sched_getscheduler] sys_sched_getscheduler,
195 [__NR_sched_yield] sys_sched_yield,
196 [__NR_sched_get_priority_max] sys_sched_get_priority_max,
197 [__NR_sched_get_priority_min] sys_sched_get_priority_min,
198 [__NR_sched_rr_get_interval] sys_sched_rr_get_interval,
199 [__NR_nanosleep] sys_nanosleep,
200 [__NR_mremap] sys_mremap,
201 [__NR_setresuid] sys_setresuid,
202 [__NR_getresuid] sys_getresuid,
203 [__NR_query_module] sys_ni_syscall,
204 [__NR_poll] sys_poll,
205 [__NR_nfsservctl] sys_ni_syscall, /* sys_nfsservctl */
206 [__NR_setresgid] sys_setresgid,
207 [__NR_getresgid] sys_getresgid,
208 [__NR_prctl] sys_prctl,
209 [__NR_rt_sigreturn] sys_ni_syscall, /* ppc64_rt_sigreturn */
210 [__NR_rt_sigaction] sys_ni_syscall, /* sys_rt_sigaction */
211 [__NR_rt_sigprocmask] sys_ni_syscall, /* sys_rt_sigprocmask */
212 [__NR_rt_sigpending] sys_ni_syscall, /* sys_rt_sigpending */
213 [__NR_rt_sigtimedwait] sys_ni_syscall, /* sys_rt_sigtimedwait */
214 [__NR_rt_sigqueueinfo] sys_ni_syscall, /* sys_rt_sigqueueinfo */
215 [__NR_rt_sigsuspend] sys_ni_syscall, /* sys_rt_sigsuspend */
216 [__NR_pread64] sys_pread64,
217 [__NR_pwrite64] sys_pwrite64,
218 [__NR_chown] sys_chown,
219 [__NR_getcwd] sys_getcwd,
220 [__NR_capget] sys_capget,
221 [__NR_capset] sys_capset,
222 [__NR_sigaltstack] sys_ni_syscall, /* sys_sigaltstack */
223 [__NR_sendfile] sys_sendfile64,
224 [__NR_getpmsg] sys_ni_syscall,
225 [__NR_putpmsg] sys_ni_syscall,
226 [__NR_vfork] sys_ni_syscall, /* ppc_vfork */
227 [__NR_ugetrlimit] sys_getrlimit,
228 [__NR_readahead] sys_readahead,
229 [192] sys_ni_syscall,
230 [193] sys_ni_syscall,
231 [194] sys_ni_syscall,
232 [195] sys_ni_syscall,
233 [196] sys_ni_syscall,
234 [197] sys_ni_syscall,
235 [__NR_pciconfig_read] sys_ni_syscall, /* sys_pciconfig_read */
236 [__NR_pciconfig_write] sys_ni_syscall, /* sys_pciconfig_write */
237 [__NR_pciconfig_iobase] sys_ni_syscall, /* sys_pciconfig_iobase */
238 [__NR_multiplexer] sys_ni_syscall,
239 [__NR_getdents64] sys_getdents64,
240 [__NR_pivot_root] sys_pivot_root,
241 [204] sys_ni_syscall,
242 [__NR_madvise] sys_madvise,
243 [__NR_mincore] sys_mincore,
244 [__NR_gettid] sys_gettid,
245 [__NR_tkill] sys_tkill,
246 [__NR_setxattr] sys_setxattr,
247 [__NR_lsetxattr] sys_lsetxattr,
248 [__NR_fsetxattr] sys_fsetxattr,
249 [__NR_getxattr] sys_getxattr,
250 [__NR_lgetxattr] sys_lgetxattr,
251 [__NR_fgetxattr] sys_fgetxattr,
252 [__NR_listxattr] sys_listxattr,
253 [__NR_llistxattr] sys_llistxattr,
254 [__NR_flistxattr] sys_flistxattr,
255 [__NR_removexattr] sys_removexattr,
256 [__NR_lremovexattr] sys_lremovexattr,
257 [__NR_fremovexattr] sys_fremovexattr,
258 [__NR_futex] sys_futex,
259 [__NR_sched_setaffinity] sys_sched_setaffinity,
260 [__NR_sched_getaffinity] sys_sched_getaffinity,
261 [__NR_tuxcall] sys_ni_syscall,
262 [226] sys_ni_syscall,
263 [__NR_io_setup] sys_io_setup,
264 [__NR_io_destroy] sys_io_destroy,
265 [__NR_io_getevents] sys_io_getevents,
266 [__NR_io_submit] sys_io_submit,
267 [__NR_io_cancel] sys_io_cancel,
268 [__NR_set_tid_address] sys_ni_syscall, /* sys_set_tid_address */
269 [__NR_fadvise64] sys_fadvise64,
270 [__NR_exit_group] sys_ni_syscall, /* sys_exit_group */
271 [__NR_lookup_dcookie] sys_ni_syscall, /* sys_lookup_dcookie */
272 [__NR_epoll_create] sys_epoll_create,
273 [__NR_epoll_ctl] sys_epoll_ctl,
274 [__NR_epoll_wait] sys_epoll_wait,
275 [__NR_remap_file_pages] sys_remap_file_pages,
276 [__NR_timer_create] sys_timer_create,
277 [__NR_timer_settime] sys_timer_settime,
278 [__NR_timer_gettime] sys_timer_gettime,
279 [__NR_timer_getoverrun] sys_timer_getoverrun,
280 [__NR_timer_delete] sys_timer_delete,
281 [__NR_clock_settime] sys_clock_settime,
282 [__NR_clock_gettime] sys_clock_gettime,
283 [__NR_clock_getres] sys_clock_getres,
284 [__NR_clock_nanosleep] sys_clock_nanosleep,
285 [__NR_swapcontext] sys_ni_syscall, /* ppc64_swapcontext */
286 [__NR_tgkill] sys_tgkill,
287 [__NR_utimes] sys_utimes,
288 [__NR_statfs64] sys_statfs64,
289 [__NR_fstatfs64] sys_fstatfs64,
290 [254] sys_ni_syscall,
291 [__NR_rtas] ppc_rtas,
292 [256] sys_ni_syscall,
293 [257] sys_ni_syscall,
294 [258] sys_ni_syscall,
295 [__NR_mbind] sys_ni_syscall, /* sys_mbind */
296 [__NR_get_mempolicy] sys_ni_syscall, /* sys_get_mempolicy */
297 [__NR_set_mempolicy] sys_ni_syscall, /* sys_set_mempolicy */
298 [__NR_mq_open] sys_ni_syscall, /* sys_mq_open */
299 [__NR_mq_unlink] sys_ni_syscall, /* sys_mq_unlink */
300 [__NR_mq_timedsend] sys_ni_syscall, /* sys_mq_timedsend */
301 [__NR_mq_timedreceive] sys_ni_syscall, /* sys_mq_timedreceive */
302 [__NR_mq_notify] sys_ni_syscall, /* sys_mq_notify */
303 [__NR_mq_getsetattr] sys_ni_syscall, /* sys_mq_getsetattr */
304 [__NR_kexec_load] sys_ni_syscall, /* sys_kexec_load */
305 [__NR_add_key] sys_ni_syscall, /* sys_add_key */
306 [__NR_request_key] sys_ni_syscall, /* sys_request_key */
307 [__NR_keyctl] sys_ni_syscall, /* sys_keyctl */
308 [__NR_waitid] sys_ni_syscall, /* sys_waitid */
309 [__NR_ioprio_set] sys_ni_syscall, /* sys_ioprio_set */
310 [__NR_ioprio_get] sys_ni_syscall, /* sys_ioprio_get */
311 [__NR_inotify_init] sys_ni_syscall, /* sys_inotify_init */
312 [__NR_inotify_add_watch] sys_ni_syscall, /* sys_inotify_add_watch */
313 [__NR_inotify_rm_watch] sys_ni_syscall, /* sys_inotify_rm_watch */
314 [__NR_spu_run] sys_ni_syscall, /* sys_spu_run */
315 [__NR_spu_create] sys_ni_syscall, /* sys_spu_create */
316 [__NR_pselect6] sys_ni_syscall, /* sys_pselect */
317 [__NR_ppoll] sys_ni_syscall, /* sys_ppoll */
318 [__NR_unshare] sys_unshare,
319};
320
321long spu_sys_callback(struct spu_syscall_block *s)
322{
323 long (*syscall)(u64 a1, u64 a2, u64 a3, u64 a4, u64 a5, u64 a6);
324
325 BUILD_BUG_ON(ARRAY_SIZE(spu_syscall_table) != __NR_syscalls);
326
327 syscall = spu_syscall_table[s->nr_ret];
328
329 if (s->nr_ret >= __NR_syscalls) {
330 pr_debug("%s: invalid syscall #%ld", __FUNCTION__, s->nr_ret);
331 return -ENOSYS;
332 }
333
334#ifdef DEBUG
335 print_symbol(KERN_DEBUG "SPU-syscall %s:", (unsigned long)syscall);
336 printk("syscall%ld(%lx, %lx, %lx, %lx, %lx, %lx)\n",
337 s->nr_ret,
338 s->parm[0], s->parm[1], s->parm[2],
339 s->parm[3], s->parm[4], s->parm[5]);
340#endif
341
342 return syscall(s->parm[0], s->parm[1], s->parm[2],
343 s->parm[3], s->parm[4], s->parm[5]);
344}
345EXPORT_SYMBOL_GPL(spu_sys_callback);
diff --git a/arch/powerpc/platforms/cell/spufs/backing_ops.c b/arch/powerpc/platforms/cell/spufs/backing_ops.c
index a5c489a53c61..f1d35ddc9df3 100644
--- a/arch/powerpc/platforms/cell/spufs/backing_ops.c
+++ b/arch/powerpc/platforms/cell/spufs/backing_ops.c
@@ -285,6 +285,49 @@ static void spu_backing_runcntl_stop(struct spu_context *ctx)
285 spu_backing_runcntl_write(ctx, SPU_RUNCNTL_STOP); 285 spu_backing_runcntl_write(ctx, SPU_RUNCNTL_STOP);
286} 286}
287 287
288static int spu_backing_set_mfc_query(struct spu_context * ctx, u32 mask,
289 u32 mode)
290{
291 struct spu_problem_collapsed *prob = &ctx->csa.prob;
292 int ret;
293
294 spin_lock(&ctx->csa.register_lock);
295 ret = -EAGAIN;
296 if (prob->dma_querytype_RW)
297 goto out;
298 ret = 0;
299 /* FIXME: what are the side-effects of this? */
300 prob->dma_querymask_RW = mask;
301 prob->dma_querytype_RW = mode;
302out:
303 spin_unlock(&ctx->csa.register_lock);
304
305 return ret;
306}
307
308static u32 spu_backing_read_mfc_tagstatus(struct spu_context * ctx)
309{
310 return ctx->csa.prob.dma_tagstatus_R;
311}
312
313static u32 spu_backing_get_mfc_free_elements(struct spu_context *ctx)
314{
315 return ctx->csa.prob.dma_qstatus_R;
316}
317
318static int spu_backing_send_mfc_command(struct spu_context *ctx,
319 struct mfc_dma_command *cmd)
320{
321 int ret;
322
323 spin_lock(&ctx->csa.register_lock);
324 ret = -EAGAIN;
325 /* FIXME: set up priv2->puq */
326 spin_unlock(&ctx->csa.register_lock);
327
328 return ret;
329}
330
288struct spu_context_ops spu_backing_ops = { 331struct spu_context_ops spu_backing_ops = {
289 .mbox_read = spu_backing_mbox_read, 332 .mbox_read = spu_backing_mbox_read,
290 .mbox_stat_read = spu_backing_mbox_stat_read, 333 .mbox_stat_read = spu_backing_mbox_stat_read,
@@ -305,4 +348,8 @@ struct spu_context_ops spu_backing_ops = {
305 .get_ls = spu_backing_get_ls, 348 .get_ls = spu_backing_get_ls,
306 .runcntl_write = spu_backing_runcntl_write, 349 .runcntl_write = spu_backing_runcntl_write,
307 .runcntl_stop = spu_backing_runcntl_stop, 350 .runcntl_stop = spu_backing_runcntl_stop,
351 .set_mfc_query = spu_backing_set_mfc_query,
352 .read_mfc_tagstatus = spu_backing_read_mfc_tagstatus,
353 .get_mfc_free_elements = spu_backing_get_mfc_free_elements,
354 .send_mfc_command = spu_backing_send_mfc_command,
308}; 355};
diff --git a/arch/powerpc/platforms/cell/spufs/context.c b/arch/powerpc/platforms/cell/spufs/context.c
index 336f238102fd..8bb33abfad17 100644
--- a/arch/powerpc/platforms/cell/spufs/context.c
+++ b/arch/powerpc/platforms/cell/spufs/context.c
@@ -27,7 +27,7 @@
27#include <asm/spu_csa.h> 27#include <asm/spu_csa.h>
28#include "spufs.h" 28#include "spufs.h"
29 29
30struct spu_context *alloc_spu_context(struct address_space *local_store) 30struct spu_context *alloc_spu_context(void)
31{ 31{
32 struct spu_context *ctx; 32 struct spu_context *ctx;
33 ctx = kmalloc(sizeof *ctx, GFP_KERNEL); 33 ctx = kmalloc(sizeof *ctx, GFP_KERNEL);
@@ -47,10 +47,17 @@ struct spu_context *alloc_spu_context(struct address_space *local_store)
47 init_waitqueue_head(&ctx->ibox_wq); 47 init_waitqueue_head(&ctx->ibox_wq);
48 init_waitqueue_head(&ctx->wbox_wq); 48 init_waitqueue_head(&ctx->wbox_wq);
49 init_waitqueue_head(&ctx->stop_wq); 49 init_waitqueue_head(&ctx->stop_wq);
50 init_waitqueue_head(&ctx->mfc_wq);
50 ctx->ibox_fasync = NULL; 51 ctx->ibox_fasync = NULL;
51 ctx->wbox_fasync = NULL; 52 ctx->wbox_fasync = NULL;
53 ctx->mfc_fasync = NULL;
54 ctx->mfc = NULL;
55 ctx->tagwait = 0;
52 ctx->state = SPU_STATE_SAVED; 56 ctx->state = SPU_STATE_SAVED;
53 ctx->local_store = local_store; 57 ctx->local_store = NULL;
58 ctx->cntl = NULL;
59 ctx->signal1 = NULL;
60 ctx->signal2 = NULL;
54 ctx->spu = NULL; 61 ctx->spu = NULL;
55 ctx->ops = &spu_backing_ops; 62 ctx->ops = &spu_backing_ops;
56 ctx->owner = get_task_mm(current); 63 ctx->owner = get_task_mm(current);
@@ -68,8 +75,6 @@ void destroy_spu_context(struct kref *kref)
68 ctx = container_of(kref, struct spu_context, kref); 75 ctx = container_of(kref, struct spu_context, kref);
69 down_write(&ctx->state_sema); 76 down_write(&ctx->state_sema);
70 spu_deactivate(ctx); 77 spu_deactivate(ctx);
71 ctx->ibox_fasync = NULL;
72 ctx->wbox_fasync = NULL;
73 up_write(&ctx->state_sema); 78 up_write(&ctx->state_sema);
74 spu_fini_csa(&ctx->csa); 79 spu_fini_csa(&ctx->csa);
75 kfree(ctx); 80 kfree(ctx);
@@ -109,7 +114,16 @@ void spu_release(struct spu_context *ctx)
109 114
110void spu_unmap_mappings(struct spu_context *ctx) 115void spu_unmap_mappings(struct spu_context *ctx)
111{ 116{
112 unmap_mapping_range(ctx->local_store, 0, LS_SIZE, 1); 117 if (ctx->local_store)
118 unmap_mapping_range(ctx->local_store, 0, LS_SIZE, 1);
119 if (ctx->mfc)
120 unmap_mapping_range(ctx->mfc, 0, 0x4000, 1);
121 if (ctx->cntl)
122 unmap_mapping_range(ctx->cntl, 0, 0x4000, 1);
123 if (ctx->signal1)
124 unmap_mapping_range(ctx->signal1, 0, 0x4000, 1);
125 if (ctx->signal2)
126 unmap_mapping_range(ctx->signal2, 0, 0x4000, 1);
113} 127}
114 128
115int spu_acquire_runnable(struct spu_context *ctx) 129int spu_acquire_runnable(struct spu_context *ctx)
diff --git a/arch/powerpc/platforms/cell/spufs/file.c b/arch/powerpc/platforms/cell/spufs/file.c
index dfa649c9b956..366185e92667 100644
--- a/arch/powerpc/platforms/cell/spufs/file.c
+++ b/arch/powerpc/platforms/cell/spufs/file.c
@@ -20,6 +20,8 @@
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */ 21 */
22 22
23#undef DEBUG
24
23#include <linux/fs.h> 25#include <linux/fs.h>
24#include <linux/ioctl.h> 26#include <linux/ioctl.h>
25#include <linux/module.h> 27#include <linux/module.h>
@@ -39,8 +41,10 @@ static int
39spufs_mem_open(struct inode *inode, struct file *file) 41spufs_mem_open(struct inode *inode, struct file *file)
40{ 42{
41 struct spufs_inode_info *i = SPUFS_I(inode); 43 struct spufs_inode_info *i = SPUFS_I(inode);
42 file->private_data = i->i_ctx; 44 struct spu_context *ctx = i->i_ctx;
43 file->f_mapping = i->i_ctx->local_store; 45 file->private_data = ctx;
46 file->f_mapping = inode->i_mapping;
47 ctx->local_store = inode->i_mapping;
44 return 0; 48 return 0;
45} 49}
46 50
@@ -84,7 +88,7 @@ spufs_mem_write(struct file *file, const char __user *buffer,
84 return ret; 88 return ret;
85} 89}
86 90
87#ifdef CONFIG_SPARSEMEM 91#ifdef CONFIG_SPUFS_MMAP
88static struct page * 92static struct page *
89spufs_mem_mmap_nopage(struct vm_area_struct *vma, 93spufs_mem_mmap_nopage(struct vm_area_struct *vma,
90 unsigned long address, int *type) 94 unsigned long address, int *type)
@@ -136,11 +140,113 @@ static struct file_operations spufs_mem_fops = {
136 .read = spufs_mem_read, 140 .read = spufs_mem_read,
137 .write = spufs_mem_write, 141 .write = spufs_mem_write,
138 .llseek = generic_file_llseek, 142 .llseek = generic_file_llseek,
139#ifdef CONFIG_SPARSEMEM 143#ifdef CONFIG_SPUFS_MMAP
140 .mmap = spufs_mem_mmap, 144 .mmap = spufs_mem_mmap,
141#endif 145#endif
142}; 146};
143 147
148#ifdef CONFIG_SPUFS_MMAP
149static struct page *spufs_ps_nopage(struct vm_area_struct *vma,
150 unsigned long address,
151 int *type, unsigned long ps_offs)
152{
153 struct page *page = NOPAGE_SIGBUS;
154 int fault_type = VM_FAULT_SIGBUS;
155 struct spu_context *ctx = vma->vm_file->private_data;
156 unsigned long offset = address - vma->vm_start;
157 unsigned long area;
158 int ret;
159
160 offset += vma->vm_pgoff << PAGE_SHIFT;
161 if (offset >= 0x4000)
162 goto out;
163
164 ret = spu_acquire_runnable(ctx);
165 if (ret)
166 goto out;
167
168 area = ctx->spu->problem_phys + ps_offs;
169 page = pfn_to_page((area + offset) >> PAGE_SHIFT);
170 fault_type = VM_FAULT_MINOR;
171 page_cache_get(page);
172
173 spu_release(ctx);
174
175 out:
176 if (type)
177 *type = fault_type;
178
179 return page;
180}
181
182static struct page *spufs_cntl_mmap_nopage(struct vm_area_struct *vma,
183 unsigned long address, int *type)
184{
185 return spufs_ps_nopage(vma, address, type, 0x4000);
186}
187
188static struct vm_operations_struct spufs_cntl_mmap_vmops = {
189 .nopage = spufs_cntl_mmap_nopage,
190};
191
192/*
193 * mmap support for problem state control area [0x4000 - 0x4fff].
194 * Mapping this area requires that the application have CAP_SYS_RAWIO,
195 * as these registers require special care when read/writing.
196 */
197static int spufs_cntl_mmap(struct file *file, struct vm_area_struct *vma)
198{
199 if (!(vma->vm_flags & VM_SHARED))
200 return -EINVAL;
201
202 if (!capable(CAP_SYS_RAWIO))
203 return -EPERM;
204
205 vma->vm_flags |= VM_RESERVED;
206 vma->vm_page_prot = __pgprot(pgprot_val(vma->vm_page_prot)
207 | _PAGE_NO_CACHE);
208
209 vma->vm_ops = &spufs_cntl_mmap_vmops;
210 return 0;
211}
212#endif
213
214static int spufs_cntl_open(struct inode *inode, struct file *file)
215{
216 struct spufs_inode_info *i = SPUFS_I(inode);
217 struct spu_context *ctx = i->i_ctx;
218
219 file->private_data = ctx;
220 file->f_mapping = inode->i_mapping;
221 ctx->cntl = inode->i_mapping;
222 return 0;
223}
224
225static ssize_t
226spufs_cntl_read(struct file *file, char __user *buffer,
227 size_t size, loff_t *pos)
228{
229 /* FIXME: read from spu status */
230 return -EINVAL;
231}
232
233static ssize_t
234spufs_cntl_write(struct file *file, const char __user *buffer,
235 size_t size, loff_t *pos)
236{
237 /* FIXME: write to runctl bit */
238 return -EINVAL;
239}
240
241static struct file_operations spufs_cntl_fops = {
242 .open = spufs_cntl_open,
243 .read = spufs_cntl_read,
244 .write = spufs_cntl_write,
245#ifdef CONFIG_SPUFS_MMAP
246 .mmap = spufs_cntl_mmap,
247#endif
248};
249
144static int 250static int
145spufs_regs_open(struct inode *inode, struct file *file) 251spufs_regs_open(struct inode *inode, struct file *file)
146{ 252{
@@ -501,6 +607,16 @@ static struct file_operations spufs_wbox_stat_fops = {
501 .read = spufs_wbox_stat_read, 607 .read = spufs_wbox_stat_read,
502}; 608};
503 609
610static int spufs_signal1_open(struct inode *inode, struct file *file)
611{
612 struct spufs_inode_info *i = SPUFS_I(inode);
613 struct spu_context *ctx = i->i_ctx;
614 file->private_data = ctx;
615 file->f_mapping = inode->i_mapping;
616 ctx->signal1 = inode->i_mapping;
617 return nonseekable_open(inode, file);
618}
619
504static ssize_t spufs_signal1_read(struct file *file, char __user *buf, 620static ssize_t spufs_signal1_read(struct file *file, char __user *buf,
505 size_t len, loff_t *pos) 621 size_t len, loff_t *pos)
506{ 622{
@@ -541,12 +657,50 @@ static ssize_t spufs_signal1_write(struct file *file, const char __user *buf,
541 return 4; 657 return 4;
542} 658}
543 659
660#ifdef CONFIG_SPUFS_MMAP
661static struct page *spufs_signal1_mmap_nopage(struct vm_area_struct *vma,
662 unsigned long address, int *type)
663{
664 return spufs_ps_nopage(vma, address, type, 0x14000);
665}
666
667static struct vm_operations_struct spufs_signal1_mmap_vmops = {
668 .nopage = spufs_signal1_mmap_nopage,
669};
670
671static int spufs_signal1_mmap(struct file *file, struct vm_area_struct *vma)
672{
673 if (!(vma->vm_flags & VM_SHARED))
674 return -EINVAL;
675
676 vma->vm_flags |= VM_RESERVED;
677 vma->vm_page_prot = __pgprot(pgprot_val(vma->vm_page_prot)
678 | _PAGE_NO_CACHE);
679
680 vma->vm_ops = &spufs_signal1_mmap_vmops;
681 return 0;
682}
683#endif
684
544static struct file_operations spufs_signal1_fops = { 685static struct file_operations spufs_signal1_fops = {
545 .open = spufs_pipe_open, 686 .open = spufs_signal1_open,
546 .read = spufs_signal1_read, 687 .read = spufs_signal1_read,
547 .write = spufs_signal1_write, 688 .write = spufs_signal1_write,
689#ifdef CONFIG_SPUFS_MMAP
690 .mmap = spufs_signal1_mmap,
691#endif
548}; 692};
549 693
694static int spufs_signal2_open(struct inode *inode, struct file *file)
695{
696 struct spufs_inode_info *i = SPUFS_I(inode);
697 struct spu_context *ctx = i->i_ctx;
698 file->private_data = ctx;
699 file->f_mapping = inode->i_mapping;
700 ctx->signal2 = inode->i_mapping;
701 return nonseekable_open(inode, file);
702}
703
550static ssize_t spufs_signal2_read(struct file *file, char __user *buf, 704static ssize_t spufs_signal2_read(struct file *file, char __user *buf,
551 size_t len, loff_t *pos) 705 size_t len, loff_t *pos)
552{ 706{
@@ -589,10 +743,39 @@ static ssize_t spufs_signal2_write(struct file *file, const char __user *buf,
589 return 4; 743 return 4;
590} 744}
591 745
746#ifdef CONFIG_SPUFS_MMAP
747static struct page *spufs_signal2_mmap_nopage(struct vm_area_struct *vma,
748 unsigned long address, int *type)
749{
750 return spufs_ps_nopage(vma, address, type, 0x1c000);
751}
752
753static struct vm_operations_struct spufs_signal2_mmap_vmops = {
754 .nopage = spufs_signal2_mmap_nopage,
755};
756
757static int spufs_signal2_mmap(struct file *file, struct vm_area_struct *vma)
758{
759 if (!(vma->vm_flags & VM_SHARED))
760 return -EINVAL;
761
762 /* FIXME: */
763 vma->vm_flags |= VM_RESERVED;
764 vma->vm_page_prot = __pgprot(pgprot_val(vma->vm_page_prot)
765 | _PAGE_NO_CACHE);
766
767 vma->vm_ops = &spufs_signal2_mmap_vmops;
768 return 0;
769}
770#endif
771
592static struct file_operations spufs_signal2_fops = { 772static struct file_operations spufs_signal2_fops = {
593 .open = spufs_pipe_open, 773 .open = spufs_signal2_open,
594 .read = spufs_signal2_read, 774 .read = spufs_signal2_read,
595 .write = spufs_signal2_write, 775 .write = spufs_signal2_write,
776#ifdef CONFIG_SPUFS_MMAP
777 .mmap = spufs_signal2_mmap,
778#endif
596}; 779};
597 780
598static void spufs_signal1_type_set(void *data, u64 val) 781static void spufs_signal1_type_set(void *data, u64 val)
@@ -641,6 +824,332 @@ static u64 spufs_signal2_type_get(void *data)
641DEFINE_SIMPLE_ATTRIBUTE(spufs_signal2_type, spufs_signal2_type_get, 824DEFINE_SIMPLE_ATTRIBUTE(spufs_signal2_type, spufs_signal2_type_get,
642 spufs_signal2_type_set, "%llu"); 825 spufs_signal2_type_set, "%llu");
643 826
827#ifdef CONFIG_SPUFS_MMAP
828static struct page *spufs_mfc_mmap_nopage(struct vm_area_struct *vma,
829 unsigned long address, int *type)
830{
831 return spufs_ps_nopage(vma, address, type, 0x3000);
832}
833
834static struct vm_operations_struct spufs_mfc_mmap_vmops = {
835 .nopage = spufs_mfc_mmap_nopage,
836};
837
838/*
839 * mmap support for problem state MFC DMA area [0x0000 - 0x0fff].
840 * Mapping this area requires that the application have CAP_SYS_RAWIO,
841 * as these registers require special care when read/writing.
842 */
843static int spufs_mfc_mmap(struct file *file, struct vm_area_struct *vma)
844{
845 if (!(vma->vm_flags & VM_SHARED))
846 return -EINVAL;
847
848 if (!capable(CAP_SYS_RAWIO))
849 return -EPERM;
850
851 vma->vm_flags |= VM_RESERVED;
852 vma->vm_page_prot = __pgprot(pgprot_val(vma->vm_page_prot)
853 | _PAGE_NO_CACHE);
854
855 vma->vm_ops = &spufs_mfc_mmap_vmops;
856 return 0;
857}
858#endif
859
860static int spufs_mfc_open(struct inode *inode, struct file *file)
861{
862 struct spufs_inode_info *i = SPUFS_I(inode);
863 struct spu_context *ctx = i->i_ctx;
864
865 /* we don't want to deal with DMA into other processes */
866 if (ctx->owner != current->mm)
867 return -EINVAL;
868
869 if (atomic_read(&inode->i_count) != 1)
870 return -EBUSY;
871
872 file->private_data = ctx;
873 return nonseekable_open(inode, file);
874}
875
876/* interrupt-level mfc callback function. */
877void spufs_mfc_callback(struct spu *spu)
878{
879 struct spu_context *ctx = spu->ctx;
880
881 wake_up_all(&ctx->mfc_wq);
882
883 pr_debug("%s %s\n", __FUNCTION__, spu->name);
884 if (ctx->mfc_fasync) {
885 u32 free_elements, tagstatus;
886 unsigned int mask;
887
888 /* no need for spu_acquire in interrupt context */
889 free_elements = ctx->ops->get_mfc_free_elements(ctx);
890 tagstatus = ctx->ops->read_mfc_tagstatus(ctx);
891
892 mask = 0;
893 if (free_elements & 0xffff)
894 mask |= POLLOUT;
895 if (tagstatus & ctx->tagwait)
896 mask |= POLLIN;
897
898 kill_fasync(&ctx->mfc_fasync, SIGIO, mask);
899 }
900}
901
902static int spufs_read_mfc_tagstatus(struct spu_context *ctx, u32 *status)
903{
904 /* See if there is one tag group is complete */
905 /* FIXME we need locking around tagwait */
906 *status = ctx->ops->read_mfc_tagstatus(ctx) & ctx->tagwait;
907 ctx->tagwait &= ~*status;
908 if (*status)
909 return 1;
910
911 /* enable interrupt waiting for any tag group,
912 may silently fail if interrupts are already enabled */
913 ctx->ops->set_mfc_query(ctx, ctx->tagwait, 1);
914 return 0;
915}
916
917static ssize_t spufs_mfc_read(struct file *file, char __user *buffer,
918 size_t size, loff_t *pos)
919{
920 struct spu_context *ctx = file->private_data;
921 int ret = -EINVAL;
922 u32 status;
923
924 if (size != 4)
925 goto out;
926
927 spu_acquire(ctx);
928 if (file->f_flags & O_NONBLOCK) {
929 status = ctx->ops->read_mfc_tagstatus(ctx);
930 if (!(status & ctx->tagwait))
931 ret = -EAGAIN;
932 else
933 ctx->tagwait &= ~status;
934 } else {
935 ret = spufs_wait(ctx->mfc_wq,
936 spufs_read_mfc_tagstatus(ctx, &status));
937 }
938 spu_release(ctx);
939
940 if (ret)
941 goto out;
942
943 ret = 4;
944 if (copy_to_user(buffer, &status, 4))
945 ret = -EFAULT;
946
947out:
948 return ret;
949}
950
951static int spufs_check_valid_dma(struct mfc_dma_command *cmd)
952{
953 pr_debug("queueing DMA %x %lx %x %x %x\n", cmd->lsa,
954 cmd->ea, cmd->size, cmd->tag, cmd->cmd);
955
956 switch (cmd->cmd) {
957 case MFC_PUT_CMD:
958 case MFC_PUTF_CMD:
959 case MFC_PUTB_CMD:
960 case MFC_GET_CMD:
961 case MFC_GETF_CMD:
962 case MFC_GETB_CMD:
963 break;
964 default:
965 pr_debug("invalid DMA opcode %x\n", cmd->cmd);
966 return -EIO;
967 }
968
969 if ((cmd->lsa & 0xf) != (cmd->ea &0xf)) {
970 pr_debug("invalid DMA alignment, ea %lx lsa %x\n",
971 cmd->ea, cmd->lsa);
972 return -EIO;
973 }
974
975 switch (cmd->size & 0xf) {
976 case 1:
977 break;
978 case 2:
979 if (cmd->lsa & 1)
980 goto error;
981 break;
982 case 4:
983 if (cmd->lsa & 3)
984 goto error;
985 break;
986 case 8:
987 if (cmd->lsa & 7)
988 goto error;
989 break;
990 case 0:
991 if (cmd->lsa & 15)
992 goto error;
993 break;
994 error:
995 default:
996 pr_debug("invalid DMA alignment %x for size %x\n",
997 cmd->lsa & 0xf, cmd->size);
998 return -EIO;
999 }
1000
1001 if (cmd->size > 16 * 1024) {
1002 pr_debug("invalid DMA size %x\n", cmd->size);
1003 return -EIO;
1004 }
1005
1006 if (cmd->tag & 0xfff0) {
1007 /* we reserve the higher tag numbers for kernel use */
1008 pr_debug("invalid DMA tag\n");
1009 return -EIO;
1010 }
1011
1012 if (cmd->class) {
1013 /* not supported in this version */
1014 pr_debug("invalid DMA class\n");
1015 return -EIO;
1016 }
1017
1018 return 0;
1019}
1020
1021static int spu_send_mfc_command(struct spu_context *ctx,
1022 struct mfc_dma_command cmd,
1023 int *error)
1024{
1025 *error = ctx->ops->send_mfc_command(ctx, &cmd);
1026 if (*error == -EAGAIN) {
1027 /* wait for any tag group to complete
1028 so we have space for the new command */
1029 ctx->ops->set_mfc_query(ctx, ctx->tagwait, 1);
1030 /* try again, because the queue might be
1031 empty again */
1032 *error = ctx->ops->send_mfc_command(ctx, &cmd);
1033 if (*error == -EAGAIN)
1034 return 0;
1035 }
1036 return 1;
1037}
1038
1039static ssize_t spufs_mfc_write(struct file *file, const char __user *buffer,
1040 size_t size, loff_t *pos)
1041{
1042 struct spu_context *ctx = file->private_data;
1043 struct mfc_dma_command cmd;
1044 int ret = -EINVAL;
1045
1046 if (size != sizeof cmd)
1047 goto out;
1048
1049 ret = -EFAULT;
1050 if (copy_from_user(&cmd, buffer, sizeof cmd))
1051 goto out;
1052
1053 ret = spufs_check_valid_dma(&cmd);
1054 if (ret)
1055 goto out;
1056
1057 spu_acquire_runnable(ctx);
1058 if (file->f_flags & O_NONBLOCK) {
1059 ret = ctx->ops->send_mfc_command(ctx, &cmd);
1060 } else {
1061 int status;
1062 ret = spufs_wait(ctx->mfc_wq,
1063 spu_send_mfc_command(ctx, cmd, &status));
1064 if (status)
1065 ret = status;
1066 }
1067 spu_release(ctx);
1068
1069 if (ret)
1070 goto out;
1071
1072 ctx->tagwait |= 1 << cmd.tag;
1073
1074out:
1075 return ret;
1076}
1077
1078static unsigned int spufs_mfc_poll(struct file *file,poll_table *wait)
1079{
1080 struct spu_context *ctx = file->private_data;
1081 u32 free_elements, tagstatus;
1082 unsigned int mask;
1083
1084 spu_acquire(ctx);
1085 ctx->ops->set_mfc_query(ctx, ctx->tagwait, 2);
1086 free_elements = ctx->ops->get_mfc_free_elements(ctx);
1087 tagstatus = ctx->ops->read_mfc_tagstatus(ctx);
1088 spu_release(ctx);
1089
1090 poll_wait(file, &ctx->mfc_wq, wait);
1091
1092 mask = 0;
1093 if (free_elements & 0xffff)
1094 mask |= POLLOUT | POLLWRNORM;
1095 if (tagstatus & ctx->tagwait)
1096 mask |= POLLIN | POLLRDNORM;
1097
1098 pr_debug("%s: free %d tagstatus %d tagwait %d\n", __FUNCTION__,
1099 free_elements, tagstatus, ctx->tagwait);
1100
1101 return mask;
1102}
1103
1104static int spufs_mfc_flush(struct file *file)
1105{
1106 struct spu_context *ctx = file->private_data;
1107 int ret;
1108
1109 spu_acquire(ctx);
1110#if 0
1111/* this currently hangs */
1112 ret = spufs_wait(ctx->mfc_wq,
1113 ctx->ops->set_mfc_query(ctx, ctx->tagwait, 2));
1114 if (ret)
1115 goto out;
1116 ret = spufs_wait(ctx->mfc_wq,
1117 ctx->ops->read_mfc_tagstatus(ctx) == ctx->tagwait);
1118out:
1119#else
1120 ret = 0;
1121#endif
1122 spu_release(ctx);
1123
1124 return ret;
1125}
1126
1127static int spufs_mfc_fsync(struct file *file, struct dentry *dentry,
1128 int datasync)
1129{
1130 return spufs_mfc_flush(file);
1131}
1132
1133static int spufs_mfc_fasync(int fd, struct file *file, int on)
1134{
1135 struct spu_context *ctx = file->private_data;
1136
1137 return fasync_helper(fd, file, on, &ctx->mfc_fasync);
1138}
1139
1140static struct file_operations spufs_mfc_fops = {
1141 .open = spufs_mfc_open,
1142 .read = spufs_mfc_read,
1143 .write = spufs_mfc_write,
1144 .poll = spufs_mfc_poll,
1145 .flush = spufs_mfc_flush,
1146 .fsync = spufs_mfc_fsync,
1147 .fasync = spufs_mfc_fasync,
1148#ifdef CONFIG_SPUFS_MMAP
1149 .mmap = spufs_mfc_mmap,
1150#endif
1151};
1152
644static void spufs_npc_set(void *data, u64 val) 1153static void spufs_npc_set(void *data, u64 val)
645{ 1154{
646 struct spu_context *ctx = data; 1155 struct spu_context *ctx = data;
@@ -783,6 +1292,8 @@ struct tree_descr spufs_dir_contents[] = {
783 { "signal2", &spufs_signal2_fops, 0666, }, 1292 { "signal2", &spufs_signal2_fops, 0666, },
784 { "signal1_type", &spufs_signal1_type, 0666, }, 1293 { "signal1_type", &spufs_signal1_type, 0666, },
785 { "signal2_type", &spufs_signal2_type, 0666, }, 1294 { "signal2_type", &spufs_signal2_type, 0666, },
1295 { "mfc", &spufs_mfc_fops, 0666, },
1296 { "cntl", &spufs_cntl_fops, 0666, },
786 { "npc", &spufs_npc_ops, 0666, }, 1297 { "npc", &spufs_npc_ops, 0666, },
787 { "fpcr", &spufs_fpcr_fops, 0666, }, 1298 { "fpcr", &spufs_fpcr_fops, 0666, },
788 { "decr", &spufs_decr_ops, 0666, }, 1299 { "decr", &spufs_decr_ops, 0666, },
diff --git a/arch/powerpc/platforms/cell/spufs/hw_ops.c b/arch/powerpc/platforms/cell/spufs/hw_ops.c
index 5445719bff79..a13a8b5a014d 100644
--- a/arch/powerpc/platforms/cell/spufs/hw_ops.c
+++ b/arch/powerpc/platforms/cell/spufs/hw_ops.c
@@ -232,6 +232,59 @@ static void spu_hw_runcntl_stop(struct spu_context *ctx)
232 spin_unlock_irq(&ctx->spu->register_lock); 232 spin_unlock_irq(&ctx->spu->register_lock);
233} 233}
234 234
235static int spu_hw_set_mfc_query(struct spu_context * ctx, u32 mask, u32 mode)
236{
237 struct spu_problem *prob = ctx->spu->problem;
238 int ret;
239
240 spin_lock_irq(&ctx->spu->register_lock);
241 ret = -EAGAIN;
242 if (in_be32(&prob->dma_querytype_RW))
243 goto out;
244 ret = 0;
245 out_be32(&prob->dma_querymask_RW, mask);
246 out_be32(&prob->dma_querytype_RW, mode);
247out:
248 spin_unlock_irq(&ctx->spu->register_lock);
249 return ret;
250}
251
252static u32 spu_hw_read_mfc_tagstatus(struct spu_context * ctx)
253{
254 return in_be32(&ctx->spu->problem->dma_tagstatus_R);
255}
256
257static u32 spu_hw_get_mfc_free_elements(struct spu_context *ctx)
258{
259 return in_be32(&ctx->spu->problem->dma_qstatus_R);
260}
261
262static int spu_hw_send_mfc_command(struct spu_context *ctx,
263 struct mfc_dma_command *cmd)
264{
265 u32 status;
266 struct spu_problem *prob = ctx->spu->problem;
267
268 spin_lock_irq(&ctx->spu->register_lock);
269 out_be32(&prob->mfc_lsa_W, cmd->lsa);
270 out_be64(&prob->mfc_ea_W, cmd->ea);
271 out_be32(&prob->mfc_union_W.by32.mfc_size_tag32,
272 cmd->size << 16 | cmd->tag);
273 out_be32(&prob->mfc_union_W.by32.mfc_class_cmd32,
274 cmd->class << 16 | cmd->cmd);
275 status = in_be32(&prob->mfc_union_W.by32.mfc_class_cmd32);
276 spin_unlock_irq(&ctx->spu->register_lock);
277
278 switch (status & 0xffff) {
279 case 0:
280 return 0;
281 case 2:
282 return -EAGAIN;
283 default:
284 return -EINVAL;
285 }
286}
287
235struct spu_context_ops spu_hw_ops = { 288struct spu_context_ops spu_hw_ops = {
236 .mbox_read = spu_hw_mbox_read, 289 .mbox_read = spu_hw_mbox_read,
237 .mbox_stat_read = spu_hw_mbox_stat_read, 290 .mbox_stat_read = spu_hw_mbox_stat_read,
@@ -252,4 +305,8 @@ struct spu_context_ops spu_hw_ops = {
252 .get_ls = spu_hw_get_ls, 305 .get_ls = spu_hw_get_ls,
253 .runcntl_write = spu_hw_runcntl_write, 306 .runcntl_write = spu_hw_runcntl_write,
254 .runcntl_stop = spu_hw_runcntl_stop, 307 .runcntl_stop = spu_hw_runcntl_stop,
308 .set_mfc_query = spu_hw_set_mfc_query,
309 .read_mfc_tagstatus = spu_hw_read_mfc_tagstatus,
310 .get_mfc_free_elements = spu_hw_get_mfc_free_elements,
311 .send_mfc_command = spu_hw_send_mfc_command,
255}; 312};
diff --git a/arch/powerpc/platforms/cell/spufs/inode.c b/arch/powerpc/platforms/cell/spufs/inode.c
index 5be40aa483fd..d9554199afa7 100644
--- a/arch/powerpc/platforms/cell/spufs/inode.c
+++ b/arch/powerpc/platforms/cell/spufs/inode.c
@@ -241,7 +241,7 @@ spufs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
241 inode->i_gid = dir->i_gid; 241 inode->i_gid = dir->i_gid;
242 inode->i_mode &= S_ISGID; 242 inode->i_mode &= S_ISGID;
243 } 243 }
244 ctx = alloc_spu_context(inode->i_mapping); 244 ctx = alloc_spu_context();
245 SPUFS_I(inode)->i_ctx = ctx; 245 SPUFS_I(inode)->i_ctx = ctx;
246 if (!ctx) 246 if (!ctx)
247 goto out_iput; 247 goto out_iput;
@@ -442,7 +442,7 @@ static struct file_system_type spufs_type = {
442 .kill_sb = kill_litter_super, 442 .kill_sb = kill_litter_super,
443}; 443};
444 444
445static int spufs_init(void) 445static int __init spufs_init(void)
446{ 446{
447 int ret; 447 int ret;
448 ret = -ENOMEM; 448 ret = -ENOMEM;
@@ -472,7 +472,7 @@ out:
472} 472}
473module_init(spufs_init); 473module_init(spufs_init);
474 474
475static void spufs_exit(void) 475static void __exit spufs_exit(void)
476{ 476{
477 spu_sched_exit(); 477 spu_sched_exit();
478 unregister_spu_syscalls(&spufs_calls); 478 unregister_spu_syscalls(&spufs_calls);
diff --git a/arch/powerpc/platforms/cell/spufs/run.c b/arch/powerpc/platforms/cell/spufs/run.c
index 18ea8866c61a..c04e078c0fe5 100644
--- a/arch/powerpc/platforms/cell/spufs/run.c
+++ b/arch/powerpc/platforms/cell/spufs/run.c
@@ -76,6 +76,90 @@ static inline int spu_reacquire_runnable(struct spu_context *ctx, u32 *npc,
76 return 0; 76 return 0;
77} 77}
78 78
79/*
80 * SPU syscall restarting is tricky because we violate the basic
81 * assumption that the signal handler is running on the interrupted
82 * thread. Here instead, the handler runs on PowerPC user space code,
83 * while the syscall was called from the SPU.
84 * This means we can only do a very rough approximation of POSIX
85 * signal semantics.
86 */
87int spu_handle_restartsys(struct spu_context *ctx, long *spu_ret,
88 unsigned int *npc)
89{
90 int ret;
91
92 switch (*spu_ret) {
93 case -ERESTARTSYS:
94 case -ERESTARTNOINTR:
95 /*
96 * Enter the regular syscall restarting for
97 * sys_spu_run, then restart the SPU syscall
98 * callback.
99 */
100 *npc -= 8;
101 ret = -ERESTARTSYS;
102 break;
103 case -ERESTARTNOHAND:
104 case -ERESTART_RESTARTBLOCK:
105 /*
106 * Restart block is too hard for now, just return -EINTR
107 * to the SPU.
108 * ERESTARTNOHAND comes from sys_pause, we also return
109 * -EINTR from there.
110 * Assume that we need to be restarted ourselves though.
111 */
112 *spu_ret = -EINTR;
113 ret = -ERESTARTSYS;
114 break;
115 default:
116 printk(KERN_WARNING "%s: unexpected return code %ld\n",
117 __FUNCTION__, *spu_ret);
118 ret = 0;
119 }
120 return ret;
121}
122
123int spu_process_callback(struct spu_context *ctx)
124{
125 struct spu_syscall_block s;
126 u32 ls_pointer, npc;
127 char *ls;
128 long spu_ret;
129 int ret;
130
131 /* get syscall block from local store */
132 npc = ctx->ops->npc_read(ctx);
133 ls = ctx->ops->get_ls(ctx);
134 ls_pointer = *(u32*)(ls + npc);
135 if (ls_pointer > (LS_SIZE - sizeof(s)))
136 return -EFAULT;
137 memcpy(&s, ls + ls_pointer, sizeof (s));
138
139 /* do actual syscall without pinning the spu */
140 ret = 0;
141 spu_ret = -ENOSYS;
142 npc += 4;
143
144 if (s.nr_ret < __NR_syscalls) {
145 spu_release(ctx);
146 /* do actual system call from here */
147 spu_ret = spu_sys_callback(&s);
148 if (spu_ret <= -ERESTARTSYS) {
149 ret = spu_handle_restartsys(ctx, &spu_ret, &npc);
150 }
151 spu_acquire(ctx);
152 if (ret == -ERESTARTSYS)
153 return ret;
154 }
155
156 /* write result, jump over indirect pointer */
157 memcpy(ls + ls_pointer, &spu_ret, sizeof (spu_ret));
158 ctx->ops->npc_write(ctx, npc);
159 ctx->ops->runcntl_write(ctx, SPU_RUNCNTL_RUNNABLE);
160 return ret;
161}
162
79static inline int spu_process_events(struct spu_context *ctx) 163static inline int spu_process_events(struct spu_context *ctx)
80{ 164{
81 struct spu *spu = ctx->spu; 165 struct spu *spu = ctx->spu;
@@ -107,6 +191,13 @@ long spufs_run_spu(struct file *file, struct spu_context *ctx,
107 ret = spufs_wait(ctx->stop_wq, spu_stopped(ctx, status)); 191 ret = spufs_wait(ctx->stop_wq, spu_stopped(ctx, status));
108 if (unlikely(ret)) 192 if (unlikely(ret))
109 break; 193 break;
194 if ((*status & SPU_STATUS_STOPPED_BY_STOP) &&
195 (*status >> SPU_STOP_STATUS_SHIFT == 0x2104)) {
196 ret = spu_process_callback(ctx);
197 if (ret)
198 break;
199 *status &= ~SPU_STATUS_STOPPED_BY_STOP;
200 }
110 if (unlikely(ctx->state != SPU_STATE_RUNNABLE)) { 201 if (unlikely(ctx->state != SPU_STATE_RUNNABLE)) {
111 ret = spu_reacquire_runnable(ctx, npc, status); 202 ret = spu_reacquire_runnable(ctx, npc, status);
112 if (ret) 203 if (ret)
diff --git a/arch/powerpc/platforms/cell/spufs/sched.c b/arch/powerpc/platforms/cell/spufs/sched.c
index 963182fbd1aa..bf652cd77000 100644
--- a/arch/powerpc/platforms/cell/spufs/sched.c
+++ b/arch/powerpc/platforms/cell/spufs/sched.c
@@ -180,6 +180,7 @@ static inline void bind_context(struct spu *spu, struct spu_context *ctx)
180 spu->ibox_callback = spufs_ibox_callback; 180 spu->ibox_callback = spufs_ibox_callback;
181 spu->wbox_callback = spufs_wbox_callback; 181 spu->wbox_callback = spufs_wbox_callback;
182 spu->stop_callback = spufs_stop_callback; 182 spu->stop_callback = spufs_stop_callback;
183 spu->mfc_callback = spufs_mfc_callback;
183 mb(); 184 mb();
184 spu_unmap_mappings(ctx); 185 spu_unmap_mappings(ctx);
185 spu_restore(&ctx->csa, spu); 186 spu_restore(&ctx->csa, spu);
@@ -197,6 +198,7 @@ static inline void unbind_context(struct spu *spu, struct spu_context *ctx)
197 spu->ibox_callback = NULL; 198 spu->ibox_callback = NULL;
198 spu->wbox_callback = NULL; 199 spu->wbox_callback = NULL;
199 spu->stop_callback = NULL; 200 spu->stop_callback = NULL;
201 spu->mfc_callback = NULL;
200 spu->mm = NULL; 202 spu->mm = NULL;
201 spu->pid = 0; 203 spu->pid = 0;
202 spu->prio = MAX_PRIO; 204 spu->prio = MAX_PRIO;
diff --git a/arch/powerpc/platforms/cell/spufs/spufs.h b/arch/powerpc/platforms/cell/spufs/spufs.h
index db2601f0abd5..4485738e2102 100644
--- a/arch/powerpc/platforms/cell/spufs/spufs.h
+++ b/arch/powerpc/platforms/cell/spufs/spufs.h
@@ -43,7 +43,11 @@ struct spu_context {
43 struct spu *spu; /* pointer to a physical SPU */ 43 struct spu *spu; /* pointer to a physical SPU */
44 struct spu_state csa; /* SPU context save area. */ 44 struct spu_state csa; /* SPU context save area. */
45 spinlock_t mmio_lock; /* protects mmio access */ 45 spinlock_t mmio_lock; /* protects mmio access */
46 struct address_space *local_store;/* local store backing store */ 46 struct address_space *local_store; /* local store mapping. */
47 struct address_space *mfc; /* 'mfc' area mappings. */
48 struct address_space *cntl; /* 'control' area mappings. */
49 struct address_space *signal1; /* 'signal1' area mappings. */
50 struct address_space *signal2; /* 'signal2' area mappings. */
47 51
48 enum { SPU_STATE_RUNNABLE, SPU_STATE_SAVED } state; 52 enum { SPU_STATE_RUNNABLE, SPU_STATE_SAVED } state;
49 struct rw_semaphore state_sema; 53 struct rw_semaphore state_sema;
@@ -55,13 +59,27 @@ struct spu_context {
55 wait_queue_head_t ibox_wq; 59 wait_queue_head_t ibox_wq;
56 wait_queue_head_t wbox_wq; 60 wait_queue_head_t wbox_wq;
57 wait_queue_head_t stop_wq; 61 wait_queue_head_t stop_wq;
62 wait_queue_head_t mfc_wq;
58 struct fasync_struct *ibox_fasync; 63 struct fasync_struct *ibox_fasync;
59 struct fasync_struct *wbox_fasync; 64 struct fasync_struct *wbox_fasync;
65 struct fasync_struct *mfc_fasync;
66 u32 tagwait;
60 struct spu_context_ops *ops; 67 struct spu_context_ops *ops;
61 struct work_struct reap_work; 68 struct work_struct reap_work;
62 u64 flags; 69 u64 flags;
63}; 70};
64 71
72struct mfc_dma_command {
73 int32_t pad; /* reserved */
74 uint32_t lsa; /* local storage address */
75 uint64_t ea; /* effective address */
76 uint16_t size; /* transfer size */
77 uint16_t tag; /* command tag */
78 uint16_t class; /* class ID */
79 uint16_t cmd; /* command opcode */
80};
81
82
65/* SPU context query/set operations. */ 83/* SPU context query/set operations. */
66struct spu_context_ops { 84struct spu_context_ops {
67 int (*mbox_read) (struct spu_context * ctx, u32 * data); 85 int (*mbox_read) (struct spu_context * ctx, u32 * data);
@@ -84,6 +102,11 @@ struct spu_context_ops {
84 char*(*get_ls) (struct spu_context * ctx); 102 char*(*get_ls) (struct spu_context * ctx);
85 void (*runcntl_write) (struct spu_context * ctx, u32 data); 103 void (*runcntl_write) (struct spu_context * ctx, u32 data);
86 void (*runcntl_stop) (struct spu_context * ctx); 104 void (*runcntl_stop) (struct spu_context * ctx);
105 int (*set_mfc_query)(struct spu_context * ctx, u32 mask, u32 mode);
106 u32 (*read_mfc_tagstatus)(struct spu_context * ctx);
107 u32 (*get_mfc_free_elements)(struct spu_context *ctx);
108 int (*send_mfc_command)(struct spu_context *ctx,
109 struct mfc_dma_command *cmd);
87}; 110};
88 111
89extern struct spu_context_ops spu_hw_ops; 112extern struct spu_context_ops spu_hw_ops;
@@ -106,7 +129,7 @@ long spufs_create_thread(struct nameidata *nd,
106extern struct file_operations spufs_context_fops; 129extern struct file_operations spufs_context_fops;
107 130
108/* context management */ 131/* context management */
109struct spu_context * alloc_spu_context(struct address_space *local_store); 132struct spu_context * alloc_spu_context(void);
110void destroy_spu_context(struct kref *kref); 133void destroy_spu_context(struct kref *kref);
111struct spu_context * get_spu_context(struct spu_context *ctx); 134struct spu_context * get_spu_context(struct spu_context *ctx);
112int put_spu_context(struct spu_context *ctx); 135int put_spu_context(struct spu_context *ctx);
@@ -159,5 +182,6 @@ size_t spu_ibox_read(struct spu_context *ctx, u32 *data);
159void spufs_ibox_callback(struct spu *spu); 182void spufs_ibox_callback(struct spu *spu);
160void spufs_wbox_callback(struct spu *spu); 183void spufs_wbox_callback(struct spu *spu);
161void spufs_stop_callback(struct spu *spu); 184void spufs_stop_callback(struct spu *spu);
185void spufs_mfc_callback(struct spu *spu);
162 186
163#endif 187#endif
diff --git a/arch/powerpc/platforms/cell/spufs/switch.c b/arch/powerpc/platforms/cell/spufs/switch.c
index 212db28531fa..97898d5d34e5 100644
--- a/arch/powerpc/platforms/cell/spufs/switch.c
+++ b/arch/powerpc/platforms/cell/spufs/switch.c
@@ -2145,7 +2145,8 @@ static void init_priv1(struct spu_state *csa)
2145 csa->priv1.int_mask_class1_RW = CLASS1_ENABLE_SEGMENT_FAULT_INTR | 2145 csa->priv1.int_mask_class1_RW = CLASS1_ENABLE_SEGMENT_FAULT_INTR |
2146 CLASS1_ENABLE_STORAGE_FAULT_INTR; 2146 CLASS1_ENABLE_STORAGE_FAULT_INTR;
2147 csa->priv1.int_mask_class2_RW = CLASS2_ENABLE_SPU_STOP_INTR | 2147 csa->priv1.int_mask_class2_RW = CLASS2_ENABLE_SPU_STOP_INTR |
2148 CLASS2_ENABLE_SPU_HALT_INTR; 2148 CLASS2_ENABLE_SPU_HALT_INTR |
2149 CLASS2_ENABLE_SPU_DMA_TAG_GROUP_COMPLETE_INTR;
2149} 2150}
2150 2151
2151static void init_priv2(struct spu_state *csa) 2152static void init_priv2(struct spu_state *csa)
diff --git a/arch/powerpc/platforms/chrp/chrp.h b/arch/powerpc/platforms/chrp/chrp.h
index 814f54742e0f..63f0aee4c158 100644
--- a/arch/powerpc/platforms/chrp/chrp.h
+++ b/arch/powerpc/platforms/chrp/chrp.h
@@ -8,4 +8,4 @@ extern int chrp_set_rtc_time(struct rtc_time *);
8extern long chrp_time_init(void); 8extern long chrp_time_init(void);
9 9
10extern void chrp_find_bridges(void); 10extern void chrp_find_bridges(void);
11extern void chrp_event_scan(void); 11extern void chrp_event_scan(unsigned long);
diff --git a/arch/powerpc/platforms/chrp/setup.c b/arch/powerpc/platforms/chrp/setup.c
index 8bf4307e323d..23a201718704 100644
--- a/arch/powerpc/platforms/chrp/setup.c
+++ b/arch/powerpc/platforms/chrp/setup.c
@@ -35,6 +35,7 @@
35#include <linux/root_dev.h> 35#include <linux/root_dev.h>
36#include <linux/initrd.h> 36#include <linux/initrd.h>
37#include <linux/module.h> 37#include <linux/module.h>
38#include <linux/timer.h>
38 39
39#include <asm/io.h> 40#include <asm/io.h>
40#include <asm/pgtable.h> 41#include <asm/pgtable.h>
@@ -61,6 +62,10 @@ EXPORT_SYMBOL(_chrp_type);
61 62
62struct mpic *chrp_mpic; 63struct mpic *chrp_mpic;
63 64
65/* Used for doing CHRP event-scans */
66DEFINE_PER_CPU(struct timer_list, heartbeat_timer);
67unsigned long event_scan_interval;
68
64/* 69/*
65 * XXX this should be in xmon.h, but putting it there means xmon.h 70 * XXX this should be in xmon.h, but putting it there means xmon.h
66 * has to include <linux/interrupt.h> (to get irqreturn_t), which 71 * has to include <linux/interrupt.h> (to get irqreturn_t), which
@@ -229,8 +234,6 @@ void __init chrp_setup_arch(void)
229{ 234{
230 struct device_node *root = find_path_device ("/"); 235 struct device_node *root = find_path_device ("/");
231 char *machine = NULL; 236 char *machine = NULL;
232 struct device_node *device;
233 unsigned int *p = NULL;
234 237
235 /* init to some ~sane value until calibrate_delay() runs */ 238 /* init to some ~sane value until calibrate_delay() runs */
236 loops_per_jiffy = 50000000/HZ; 239 loops_per_jiffy = 50000000/HZ;
@@ -287,23 +290,12 @@ void __init chrp_setup_arch(void)
287 */ 290 */
288 sio_init(); 291 sio_init();
289 292
290 /* Get the event scan rate for the rtas so we know how
291 * often it expects a heartbeat. -- Cort
292 */
293 device = find_devices("rtas");
294 if (device)
295 p = (unsigned int *) get_property
296 (device, "rtas-event-scan-rate", NULL);
297 if (p && *p) {
298 ppc_md.heartbeat = chrp_event_scan;
299 ppc_md.heartbeat_reset = HZ / (*p * 30) - 1;
300 ppc_md.heartbeat_count = 1;
301 printk("RTAS Event Scan Rate: %u (%lu jiffies)\n",
302 *p, ppc_md.heartbeat_reset);
303 }
304
305 pci_create_OF_bus_map(); 293 pci_create_OF_bus_map();
306 294
295#ifdef CONFIG_SMP
296 smp_ops = &chrp_smp_ops;
297#endif /* CONFIG_SMP */
298
307 /* 299 /*
308 * Print the banner, then scroll down so boot progress 300 * Print the banner, then scroll down so boot progress
309 * can be printed. -- Cort 301 * can be printed. -- Cort
@@ -312,7 +304,7 @@ void __init chrp_setup_arch(void)
312} 304}
313 305
314void 306void
315chrp_event_scan(void) 307chrp_event_scan(unsigned long unused)
316{ 308{
317 unsigned char log[1024]; 309 unsigned char log[1024];
318 int ret = 0; 310 int ret = 0;
@@ -320,7 +312,8 @@ chrp_event_scan(void)
320 /* XXX: we should loop until the hardware says no more error logs -- Cort */ 312 /* XXX: we should loop until the hardware says no more error logs -- Cort */
321 rtas_call(rtas_token("event-scan"), 4, 1, &ret, 0xffffffff, 0, 313 rtas_call(rtas_token("event-scan"), 4, 1, &ret, 0xffffffff, 0,
322 __pa(log), 1024); 314 __pa(log), 1024);
323 ppc_md.heartbeat_count = ppc_md.heartbeat_reset; 315 mod_timer(&__get_cpu_var(heartbeat_timer),
316 jiffies + event_scan_interval);
324} 317}
325 318
326/* 319/*
@@ -465,6 +458,9 @@ void __init chrp_init_IRQ(void)
465void __init 458void __init
466chrp_init2(void) 459chrp_init2(void)
467{ 460{
461 struct device_node *device;
462 unsigned int *p = NULL;
463
468#ifdef CONFIG_NVRAM 464#ifdef CONFIG_NVRAM
469 chrp_nvram_init(); 465 chrp_nvram_init();
470#endif 466#endif
@@ -476,12 +472,53 @@ chrp_init2(void)
476 request_region(0x80,0x10,"dma page reg"); 472 request_region(0x80,0x10,"dma page reg");
477 request_region(0xc0,0x20,"dma2"); 473 request_region(0xc0,0x20,"dma2");
478 474
475 /* Get the event scan rate for the rtas so we know how
476 * often it expects a heartbeat. -- Cort
477 */
478 device = find_devices("rtas");
479 if (device)
480 p = (unsigned int *) get_property
481 (device, "rtas-event-scan-rate", NULL);
482 if (p && *p) {
483 /*
484 * Arrange to call chrp_event_scan at least *p times
485 * per minute. We use 59 rather than 60 here so that
486 * the rate will be slightly higher than the minimum.
487 * This all assumes we don't do hotplug CPU on any
488 * machine that needs the event scans done.
489 */
490 unsigned long interval, offset;
491 int cpu, ncpus;
492 struct timer_list *timer;
493
494 interval = HZ * 59 / *p;
495 offset = HZ;
496 ncpus = num_online_cpus();
497 event_scan_interval = ncpus * interval;
498 for (cpu = 0; cpu < ncpus; ++cpu) {
499 timer = &per_cpu(heartbeat_timer, cpu);
500 setup_timer(timer, chrp_event_scan, 0);
501 timer->expires = jiffies + offset;
502 add_timer_on(timer, cpu);
503 offset += interval;
504 }
505 printk("RTAS Event Scan Rate: %u (%lu jiffies)\n",
506 *p, interval);
507 }
508
479 if (ppc_md.progress) 509 if (ppc_md.progress)
480 ppc_md.progress(" Have fun! ", 0x7777); 510 ppc_md.progress(" Have fun! ", 0x7777);
481} 511}
482 512
483void __init chrp_init(void) 513static int __init chrp_probe(void)
484{ 514{
515 char *dtype = of_get_flat_dt_prop(of_get_flat_dt_root(),
516 "device_type", NULL);
517 if (dtype == NULL)
518 return 0;
519 if (strcmp(dtype, "chrp"))
520 return 0;
521
485 ISA_DMA_THRESHOLD = ~0L; 522 ISA_DMA_THRESHOLD = ~0L;
486 DMA_MODE_READ = 0x44; 523 DMA_MODE_READ = 0x44;
487 DMA_MODE_WRITE = 0x48; 524 DMA_MODE_WRITE = 0x48;
diff --git a/arch/powerpc/platforms/iseries/setup.c b/arch/powerpc/platforms/iseries/setup.c
index fa4550611c11..6ce8a404ba6b 100644
--- a/arch/powerpc/platforms/iseries/setup.c
+++ b/arch/powerpc/platforms/iseries/setup.c
@@ -675,18 +675,20 @@ static void iseries_dedicated_idle(void)
675void __init iSeries_init_IRQ(void) { } 675void __init iSeries_init_IRQ(void) { }
676#endif 676#endif
677 677
678static int __init iseries_probe(int platform) 678static int __init iseries_probe(void)
679{ 679{
680 if (PLATFORM_ISERIES_LPAR != platform) 680 unsigned long root = of_get_flat_dt_root();
681 if (!of_flat_dt_is_compatible(root, "IBM,iSeries"))
681 return 0; 682 return 0;
682 683
683 ppc64_firmware_features |= FW_FEATURE_ISERIES; 684 powerpc_firmware_features |= FW_FEATURE_ISERIES;
684 ppc64_firmware_features |= FW_FEATURE_LPAR; 685 powerpc_firmware_features |= FW_FEATURE_LPAR;
685 686
686 return 1; 687 return 1;
687} 688}
688 689
689struct machdep_calls __initdata iseries_md = { 690define_machine(iseries) {
691 .name = "iSeries",
690 .setup_arch = iSeries_setup_arch, 692 .setup_arch = iSeries_setup_arch,
691 .show_cpuinfo = iSeries_show_cpuinfo, 693 .show_cpuinfo = iSeries_show_cpuinfo,
692 .init_IRQ = iSeries_init_IRQ, 694 .init_IRQ = iSeries_init_IRQ,
@@ -930,7 +932,6 @@ void build_flat_dt(struct iseries_flat_dt *dt, unsigned long phys_mem_size)
930 932
931 /* /chosen */ 933 /* /chosen */
932 dt_start_node(dt, "chosen"); 934 dt_start_node(dt, "chosen");
933 dt_prop_u32(dt, "linux,platform", PLATFORM_ISERIES_LPAR);
934 dt_prop_str(dt, "bootargs", cmd_line); 935 dt_prop_str(dt, "bootargs", cmd_line);
935 if (cmd_mem_limit) 936 if (cmd_mem_limit)
936 dt_prop_u64(dt, "linux,memory-limit", cmd_mem_limit); 937 dt_prop_u64(dt, "linux,memory-limit", cmd_mem_limit);
diff --git a/arch/powerpc/platforms/maple/setup.c b/arch/powerpc/platforms/maple/setup.c
index ec5c1e10c407..24c0aef4ea39 100644
--- a/arch/powerpc/platforms/maple/setup.c
+++ b/arch/powerpc/platforms/maple/setup.c
@@ -259,9 +259,10 @@ static void __init maple_progress(char *s, unsigned short hex)
259/* 259/*
260 * Called very early, MMU is off, device-tree isn't unflattened 260 * Called very early, MMU is off, device-tree isn't unflattened
261 */ 261 */
262static int __init maple_probe(int platform) 262static int __init maple_probe(void)
263{ 263{
264 if (platform != PLATFORM_MAPLE) 264 unsigned long root = of_get_flat_dt_root();
265 if (!of_flat_dt_is_compatible(root, "Momentum,Maple"))
265 return 0; 266 return 0;
266 /* 267 /*
267 * On U3, the DART (iommu) must be allocated now since it 268 * On U3, the DART (iommu) must be allocated now since it
@@ -274,7 +275,8 @@ static int __init maple_probe(int platform)
274 return 1; 275 return 1;
275} 276}
276 277
277struct machdep_calls __initdata maple_md = { 278define_machine(maple_md) {
279 .name = "Maple",
278 .probe = maple_probe, 280 .probe = maple_probe,
279 .setup_arch = maple_setup_arch, 281 .setup_arch = maple_setup_arch,
280 .init_early = maple_init_early, 282 .init_early = maple_init_early,
@@ -290,7 +292,7 @@ struct machdep_calls __initdata maple_md = {
290 .get_rtc_time = maple_get_rtc_time, 292 .get_rtc_time = maple_get_rtc_time,
291 .calibrate_decr = generic_calibrate_decr, 293 .calibrate_decr = generic_calibrate_decr,
292 .progress = maple_progress, 294 .progress = maple_progress,
293 .idle_loop = native_idle, 295 .power_save = power4_idle,
294#ifdef CONFIG_KEXEC 296#ifdef CONFIG_KEXEC
295 .machine_kexec = default_machine_kexec, 297 .machine_kexec = default_machine_kexec,
296 .machine_kexec_prepare = default_machine_kexec_prepare, 298 .machine_kexec_prepare = default_machine_kexec_prepare,
diff --git a/arch/powerpc/platforms/powermac/bootx_init.c b/arch/powerpc/platforms/powermac/bootx_init.c
index fa8b4d7b5ded..eacbfd9beabc 100644
--- a/arch/powerpc/platforms/powermac/bootx_init.c
+++ b/arch/powerpc/platforms/powermac/bootx_init.c
@@ -161,9 +161,7 @@ static void __init bootx_dt_add_prop(char *name, void *data, int size,
161static void __init bootx_add_chosen_props(unsigned long base, 161static void __init bootx_add_chosen_props(unsigned long base,
162 unsigned long *mem_end) 162 unsigned long *mem_end)
163{ 163{
164 u32 val = _MACH_Pmac; 164 u32 val;
165
166 bootx_dt_add_prop("linux,platform", &val, 4, mem_end);
167 165
168 if (bootx_info->kernelParamsOffset) { 166 if (bootx_info->kernelParamsOffset) {
169 char *args = (char *)((unsigned long)bootx_info) + 167 char *args = (char *)((unsigned long)bootx_info) +
@@ -493,7 +491,7 @@ void __init bootx_init(unsigned long r3, unsigned long r4)
493 && (strcmp(model, "iMac,1") == 0 491 && (strcmp(model, "iMac,1") == 0
494 || strcmp(model, "PowerMac1,1") == 0)) { 492 || strcmp(model, "PowerMac1,1") == 0)) {
495 bootx_printf("iMac,1 detected, shutting down USB \n"); 493 bootx_printf("iMac,1 detected, shutting down USB \n");
496 out_le32((unsigned *)0x80880008, 1); /* XXX */ 494 out_le32((unsigned __iomem *)0x80880008, 1); /* XXX */
497 } 495 }
498 } 496 }
499 497
diff --git a/arch/powerpc/platforms/powermac/feature.c b/arch/powerpc/platforms/powermac/feature.c
index e49eddd5042d..a5063cd675c5 100644
--- a/arch/powerpc/platforms/powermac/feature.c
+++ b/arch/powerpc/platforms/powermac/feature.c
@@ -2951,7 +2951,7 @@ static void *pmac_early_vresume_data;
2951 2951
2952void pmac_set_early_video_resume(void (*proc)(void *data), void *data) 2952void pmac_set_early_video_resume(void (*proc)(void *data), void *data)
2953{ 2953{
2954 if (_machine != _MACH_Pmac) 2954 if (!machine_is(powermac))
2955 return; 2955 return;
2956 preempt_disable(); 2956 preempt_disable();
2957 pmac_early_vresume_proc = proc; 2957 pmac_early_vresume_proc = proc;
diff --git a/arch/powerpc/platforms/powermac/low_i2c.c b/arch/powerpc/platforms/powermac/low_i2c.c
index 87eb6bb7f0e7..e14f9ac55cf4 100644
--- a/arch/powerpc/platforms/powermac/low_i2c.c
+++ b/arch/powerpc/platforms/powermac/low_i2c.c
@@ -1457,6 +1457,9 @@ int __init pmac_i2c_init(void)
1457 return 0; 1457 return 0;
1458 i2c_inited = 1; 1458 i2c_inited = 1;
1459 1459
1460 if (!machine_is(powermac))
1461 return 0;
1462
1460 /* Probe keywest-i2c busses */ 1463 /* Probe keywest-i2c busses */
1461 kw_i2c_probe(); 1464 kw_i2c_probe();
1462 1465
diff --git a/arch/powerpc/platforms/powermac/nvram.c b/arch/powerpc/platforms/powermac/nvram.c
index 5fd28995c74c..262f967b880a 100644
--- a/arch/powerpc/platforms/powermac/nvram.c
+++ b/arch/powerpc/platforms/powermac/nvram.c
@@ -74,7 +74,7 @@ struct core99_header {
74 * Read and write the non-volatile RAM on PowerMacs and CHRP machines. 74 * Read and write the non-volatile RAM on PowerMacs and CHRP machines.
75 */ 75 */
76static int nvram_naddrs; 76static int nvram_naddrs;
77static volatile unsigned char *nvram_data; 77static volatile unsigned char __iomem *nvram_data;
78static int is_core_99; 78static int is_core_99;
79static int core99_bank = 0; 79static int core99_bank = 0;
80static int nvram_partitions[3]; 80static int nvram_partitions[3];
@@ -148,7 +148,7 @@ static ssize_t core99_nvram_size(void)
148} 148}
149 149
150#ifdef CONFIG_PPC32 150#ifdef CONFIG_PPC32
151static volatile unsigned char *nvram_addr; 151static volatile unsigned char __iomem *nvram_addr;
152static int nvram_mult; 152static int nvram_mult;
153 153
154static unsigned char direct_nvram_read_byte(int addr) 154static unsigned char direct_nvram_read_byte(int addr)
@@ -285,7 +285,7 @@ static int sm_erase_bank(int bank)
285 int stat, i; 285 int stat, i;
286 unsigned long timeout; 286 unsigned long timeout;
287 287
288 u8* base = (u8 *)nvram_data + core99_bank*NVRAM_SIZE; 288 u8 __iomem *base = (u8 __iomem *)nvram_data + core99_bank*NVRAM_SIZE;
289 289
290 DBG("nvram: Sharp/Micron Erasing bank %d...\n", bank); 290 DBG("nvram: Sharp/Micron Erasing bank %d...\n", bank);
291 291
@@ -317,7 +317,7 @@ static int sm_write_bank(int bank, u8* datas)
317 int i, stat = 0; 317 int i, stat = 0;
318 unsigned long timeout; 318 unsigned long timeout;
319 319
320 u8* base = (u8 *)nvram_data + core99_bank*NVRAM_SIZE; 320 u8 __iomem *base = (u8 __iomem *)nvram_data + core99_bank*NVRAM_SIZE;
321 321
322 DBG("nvram: Sharp/Micron Writing bank %d...\n", bank); 322 DBG("nvram: Sharp/Micron Writing bank %d...\n", bank);
323 323
@@ -352,7 +352,7 @@ static int amd_erase_bank(int bank)
352 int i, stat = 0; 352 int i, stat = 0;
353 unsigned long timeout; 353 unsigned long timeout;
354 354
355 u8* base = (u8 *)nvram_data + core99_bank*NVRAM_SIZE; 355 u8 __iomem *base = (u8 __iomem *)nvram_data + core99_bank*NVRAM_SIZE;
356 356
357 DBG("nvram: AMD Erasing bank %d...\n", bank); 357 DBG("nvram: AMD Erasing bank %d...\n", bank);
358 358
@@ -399,7 +399,7 @@ static int amd_write_bank(int bank, u8* datas)
399 int i, stat = 0; 399 int i, stat = 0;
400 unsigned long timeout; 400 unsigned long timeout;
401 401
402 u8* base = (u8 *)nvram_data + core99_bank*NVRAM_SIZE; 402 u8 __iomem *base = (u8 __iomem *)nvram_data + core99_bank*NVRAM_SIZE;
403 403
404 DBG("nvram: AMD Writing bank %d...\n", bank); 404 DBG("nvram: AMD Writing bank %d...\n", bank);
405 405
@@ -597,7 +597,7 @@ int __init pmac_nvram_init(void)
597 } 597 }
598 598
599#ifdef CONFIG_PPC32 599#ifdef CONFIG_PPC32
600 if (_machine == _MACH_chrp && nvram_naddrs == 1) { 600 if (machine_is(chrp) && nvram_naddrs == 1) {
601 nvram_data = ioremap(r1.start, s1); 601 nvram_data = ioremap(r1.start, s1);
602 nvram_mult = 1; 602 nvram_mult = 1;
603 ppc_md.nvram_read_val = direct_nvram_read_byte; 603 ppc_md.nvram_read_val = direct_nvram_read_byte;
diff --git a/arch/powerpc/platforms/powermac/pci.c b/arch/powerpc/platforms/powermac/pci.c
index de3f30e6b333..f5d8d15d74fa 100644
--- a/arch/powerpc/platforms/powermac/pci.c
+++ b/arch/powerpc/platforms/powermac/pci.c
@@ -1201,7 +1201,7 @@ void __init pmac_pcibios_after_init(void)
1201#ifdef CONFIG_PPC32 1201#ifdef CONFIG_PPC32
1202void pmac_pci_fixup_cardbus(struct pci_dev* dev) 1202void pmac_pci_fixup_cardbus(struct pci_dev* dev)
1203{ 1203{
1204 if (_machine != _MACH_Pmac) 1204 if (!machine_is(powermac))
1205 return; 1205 return;
1206 /* 1206 /*
1207 * Fix the interrupt routing on the various cardbus bridges 1207 * Fix the interrupt routing on the various cardbus bridges
@@ -1244,8 +1244,9 @@ void pmac_pci_fixup_pciata(struct pci_dev* dev)
1244 * On PowerMacs, we try to switch any PCI ATA controller to 1244 * On PowerMacs, we try to switch any PCI ATA controller to
1245 * fully native mode 1245 * fully native mode
1246 */ 1246 */
1247 if (_machine != _MACH_Pmac) 1247 if (!machine_is(powermac))
1248 return; 1248 return;
1249
1249 /* Some controllers don't have the class IDE */ 1250 /* Some controllers don't have the class IDE */
1250 if (dev->vendor == PCI_VENDOR_ID_PROMISE) 1251 if (dev->vendor == PCI_VENDOR_ID_PROMISE)
1251 switch(dev->device) { 1252 switch(dev->device) {
diff --git a/arch/powerpc/platforms/powermac/pfunc_base.c b/arch/powerpc/platforms/powermac/pfunc_base.c
index 9b7150f10414..a3bd3e728fa3 100644
--- a/arch/powerpc/platforms/powermac/pfunc_base.c
+++ b/arch/powerpc/platforms/powermac/pfunc_base.c
@@ -336,6 +336,8 @@ int __init pmac_pfunc_base_install(void)
336 return 0; 336 return 0;
337 pfbase_inited = 1; 337 pfbase_inited = 1;
338 338
339 if (!machine_is(powermac))
340 return 0;
339 341
340 DBG("Installing base platform functions...\n"); 342 DBG("Installing base platform functions...\n");
341 343
diff --git a/arch/powerpc/platforms/powermac/setup.c b/arch/powerpc/platforms/powermac/setup.c
index 385aab90c4d2..4d15e396655c 100644
--- a/arch/powerpc/platforms/powermac/setup.c
+++ b/arch/powerpc/platforms/powermac/setup.c
@@ -350,6 +350,13 @@ static void __init pmac_setup_arch(void)
350 smp_ops = &psurge_smp_ops; 350 smp_ops = &psurge_smp_ops;
351#endif 351#endif
352#endif /* CONFIG_SMP */ 352#endif /* CONFIG_SMP */
353
354#ifdef CONFIG_ADB
355 if (strstr(cmd_line, "adb_sync")) {
356 extern int __adb_probe_sync;
357 __adb_probe_sync = 1;
358 }
359#endif /* CONFIG_ADB */
353} 360}
354 361
355char *bootpath; 362char *bootpath;
@@ -576,30 +583,6 @@ pmac_halt(void)
576 pmac_power_off(); 583 pmac_power_off();
577} 584}
578 585
579#ifdef CONFIG_PPC32
580void __init pmac_init(void)
581{
582 /* isa_io_base gets set in pmac_pci_init */
583 isa_mem_base = PMAC_ISA_MEM_BASE;
584 pci_dram_offset = PMAC_PCI_DRAM_OFFSET;
585 ISA_DMA_THRESHOLD = ~0L;
586 DMA_MODE_READ = 1;
587 DMA_MODE_WRITE = 2;
588
589 ppc_md = pmac_md;
590
591#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)
592#ifdef CONFIG_BLK_DEV_IDE_PMAC
593 ppc_ide_md.ide_init_hwif = pmac_ide_init_hwif_ports;
594 ppc_ide_md.default_io_base = pmac_ide_get_base;
595#endif /* CONFIG_BLK_DEV_IDE_PMAC */
596#endif /* defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE) */
597
598 if (ppc_md.progress) ppc_md.progress("pmac_init(): exit", 0);
599
600}
601#endif
602
603/* 586/*
604 * Early initialization. 587 * Early initialization.
605 */ 588 */
@@ -646,6 +629,12 @@ static int __init pmac_declare_of_platform_devices(void)
646{ 629{
647 struct device_node *np; 630 struct device_node *np;
648 631
632 if (machine_is(chrp))
633 return -1;
634
635 if (!machine_is(powermac))
636 return 0;
637
649 np = of_find_node_by_name(NULL, "valkyrie"); 638 np = of_find_node_by_name(NULL, "valkyrie");
650 if (np) 639 if (np)
651 of_platform_device_create(np, "valkyrie", NULL); 640 of_platform_device_create(np, "valkyrie", NULL);
@@ -666,12 +655,15 @@ device_initcall(pmac_declare_of_platform_devices);
666/* 655/*
667 * Called very early, MMU is off, device-tree isn't unflattened 656 * Called very early, MMU is off, device-tree isn't unflattened
668 */ 657 */
669static int __init pmac_probe(int platform) 658static int __init pmac_probe(void)
670{ 659{
671#ifdef CONFIG_PPC64 660 unsigned long root = of_get_flat_dt_root();
672 if (platform != PLATFORM_POWERMAC) 661
662 if (!of_flat_dt_is_compatible(root, "Power Macintosh") &&
663 !of_flat_dt_is_compatible(root, "MacRISC"))
673 return 0; 664 return 0;
674 665
666#ifdef CONFIG_PPC64
675 /* 667 /*
676 * On U3, the DART (iommu) must be allocated now since it 668 * On U3, the DART (iommu) must be allocated now since it
677 * has an impact on htab_initialize (due to the large page it 669 * has an impact on htab_initialize (due to the large page it
@@ -681,6 +673,23 @@ static int __init pmac_probe(int platform)
681 alloc_dart_table(); 673 alloc_dart_table();
682#endif 674#endif
683 675
676#ifdef CONFIG_PPC32
677 /* isa_io_base gets set in pmac_pci_init */
678 isa_mem_base = PMAC_ISA_MEM_BASE;
679 pci_dram_offset = PMAC_PCI_DRAM_OFFSET;
680 ISA_DMA_THRESHOLD = ~0L;
681 DMA_MODE_READ = 1;
682 DMA_MODE_WRITE = 2;
683
684#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)
685#ifdef CONFIG_BLK_DEV_IDE_PMAC
686 ppc_ide_md.ide_init_hwif = pmac_ide_init_hwif_ports;
687 ppc_ide_md.default_io_base = pmac_ide_get_base;
688#endif /* CONFIG_BLK_DEV_IDE_PMAC */
689#endif /* defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE) */
690
691#endif /* CONFIG_PPC32 */
692
684#ifdef CONFIG_PMAC_SMU 693#ifdef CONFIG_PMAC_SMU
685 /* 694 /*
686 * SMU based G5s need some memory below 2Gb, at least the current 695 * SMU based G5s need some memory below 2Gb, at least the current
@@ -709,10 +718,8 @@ static int pmac_pci_probe_mode(struct pci_bus *bus)
709} 718}
710#endif 719#endif
711 720
712struct machdep_calls __initdata pmac_md = { 721define_machine(powermac) {
713#if defined(CONFIG_HOTPLUG_CPU) && defined(CONFIG_PPC64) 722 .name = "PowerMac",
714 .cpu_die = generic_mach_cpu_die,
715#endif
716 .probe = pmac_probe, 723 .probe = pmac_probe,
717 .setup_arch = pmac_setup_arch, 724 .setup_arch = pmac_setup_arch,
718 .init_early = pmac_init_early, 725 .init_early = pmac_init_early,
@@ -733,7 +740,7 @@ struct machdep_calls __initdata pmac_md = {
733 .progress = udbg_progress, 740 .progress = udbg_progress,
734#ifdef CONFIG_PPC64 741#ifdef CONFIG_PPC64
735 .pci_probe_mode = pmac_pci_probe_mode, 742 .pci_probe_mode = pmac_pci_probe_mode,
736 .idle_loop = native_idle, 743 .power_save = power4_idle,
737 .enable_pmcs = power4_enable_pmcs, 744 .enable_pmcs = power4_enable_pmcs,
738#ifdef CONFIG_KEXEC 745#ifdef CONFIG_KEXEC
739 .machine_kexec = default_machine_kexec, 746 .machine_kexec = default_machine_kexec,
@@ -746,4 +753,7 @@ struct machdep_calls __initdata pmac_md = {
746 .pcibios_after_init = pmac_pcibios_after_init, 753 .pcibios_after_init = pmac_pcibios_after_init,
747 .phys_mem_access_prot = pci_phys_mem_access_prot, 754 .phys_mem_access_prot = pci_phys_mem_access_prot,
748#endif 755#endif
756#if defined(CONFIG_HOTPLUG_CPU) && defined(CONFIG_PPC64)
757 .cpu_die = generic_mach_cpu_die,
758#endif
749}; 759};
diff --git a/arch/powerpc/platforms/powermac/time.c b/arch/powerpc/platforms/powermac/time.c
index 5d9afa1fa02d..890758aa9667 100644
--- a/arch/powerpc/platforms/powermac/time.c
+++ b/arch/powerpc/platforms/powermac/time.c
@@ -336,10 +336,10 @@ static struct pmu_sleep_notifier time_sleep_notifier = {
336 */ 336 */
337void __init pmac_calibrate_decr(void) 337void __init pmac_calibrate_decr(void)
338{ 338{
339#ifdef CONFIG_PM 339#if defined(CONFIG_PM) && defined(CONFIG_ADB_PMU)
340 /* XXX why here? */ 340 /* XXX why here? */
341 pmu_register_sleep_notifier(&time_sleep_notifier); 341 pmu_register_sleep_notifier(&time_sleep_notifier);
342#endif /* CONFIG_PM */ 342#endif
343 343
344 generic_calibrate_decr(); 344 generic_calibrate_decr();
345 345
diff --git a/arch/powerpc/platforms/powermac/udbg_scc.c b/arch/powerpc/platforms/powermac/udbg_scc.c
index c4352a8db644..b4fa9f03b461 100644
--- a/arch/powerpc/platforms/powermac/udbg_scc.c
+++ b/arch/powerpc/platforms/powermac/udbg_scc.c
@@ -116,7 +116,7 @@ void udbg_scc_init(int force_scc)
116 /* Setup for 57600 8N1 */ 116 /* Setup for 57600 8N1 */
117 if (ch == ch_a) 117 if (ch == ch_a)
118 addr += 0x20; 118 addr += 0x20;
119 sccc = (volatile u8 * __iomem) ioremap(addr & PAGE_MASK, PAGE_SIZE) ; 119 sccc = ioremap(addr & PAGE_MASK, PAGE_SIZE) ;
120 sccc += addr & ~PAGE_MASK; 120 sccc += addr & ~PAGE_MASK;
121 sccd = sccc + 0x10; 121 sccd = sccc + 0x10;
122 122
diff --git a/arch/powerpc/platforms/pseries/eeh.c b/arch/powerpc/platforms/pseries/eeh.c
index 2ab9dcdfb415..9b2b1cb117b3 100644
--- a/arch/powerpc/platforms/pseries/eeh.c
+++ b/arch/powerpc/platforms/pseries/eeh.c
@@ -1018,7 +1018,7 @@ static int __init eeh_init_proc(void)
1018{ 1018{
1019 struct proc_dir_entry *e; 1019 struct proc_dir_entry *e;
1020 1020
1021 if (platform_is_pseries()) { 1021 if (machine_is(pseries)) {
1022 e = create_proc_entry("ppc64/eeh", 0, NULL); 1022 e = create_proc_entry("ppc64/eeh", 0, NULL);
1023 if (e) 1023 if (e)
1024 e->proc_fops = &proc_eeh_operations; 1024 e->proc_fops = &proc_eeh_operations;
diff --git a/arch/powerpc/platforms/pseries/eeh_driver.c b/arch/powerpc/platforms/pseries/eeh_driver.c
index b811d5ff92fe..cc2495a0cdd5 100644
--- a/arch/powerpc/platforms/pseries/eeh_driver.c
+++ b/arch/powerpc/platforms/pseries/eeh_driver.c
@@ -257,6 +257,7 @@ void handle_eeh_events (struct eeh_event *event)
257 struct pci_bus *frozen_bus; 257 struct pci_bus *frozen_bus;
258 int rc = 0; 258 int rc = 0;
259 enum pci_ers_result result = PCI_ERS_RESULT_NONE; 259 enum pci_ers_result result = PCI_ERS_RESULT_NONE;
260 const char *pci_str, *drv_str;
260 261
261 frozen_dn = find_device_pe(event->dn); 262 frozen_dn = find_device_pe(event->dn);
262 frozen_bus = pcibios_find_pci_bus(frozen_dn); 263 frozen_bus = pcibios_find_pci_bus(frozen_dn);
@@ -291,6 +292,13 @@ void handle_eeh_events (struct eeh_event *event)
291 292
292 frozen_pdn = PCI_DN(frozen_dn); 293 frozen_pdn = PCI_DN(frozen_dn);
293 frozen_pdn->eeh_freeze_count++; 294 frozen_pdn->eeh_freeze_count++;
295
296 pci_str = pci_name (frozen_pdn->pcidev);
297 drv_str = pcid_name (frozen_pdn->pcidev);
298 if (!pci_str) {
299 pci_str = pci_name (event->dev);
300 drv_str = pcid_name (event->dev);
301 }
294 302
295 if (frozen_pdn->eeh_freeze_count > EEH_MAX_ALLOWED_FREEZES) 303 if (frozen_pdn->eeh_freeze_count > EEH_MAX_ALLOWED_FREEZES)
296 goto hard_fail; 304 goto hard_fail;
@@ -306,9 +314,7 @@ void handle_eeh_events (struct eeh_event *event)
306 eeh_slot_error_detail(frozen_pdn, 1 /* Temporary Error */); 314 eeh_slot_error_detail(frozen_pdn, 1 /* Temporary Error */);
307 printk(KERN_WARNING 315 printk(KERN_WARNING
308 "EEH: This PCI device has failed %d times since last reboot: %s - %s\n", 316 "EEH: This PCI device has failed %d times since last reboot: %s - %s\n",
309 frozen_pdn->eeh_freeze_count, 317 frozen_pdn->eeh_freeze_count, drv_str, pci_str);
310 pci_name (frozen_pdn->pcidev),
311 pcid_name(frozen_pdn->pcidev));
312 318
313 /* Walk the various device drivers attached to this slot through 319 /* Walk the various device drivers attached to this slot through
314 * a reset sequence, giving each an opportunity to do what it needs 320 * a reset sequence, giving each an opportunity to do what it needs
@@ -360,9 +366,7 @@ hard_fail:
360 "EEH: PCI device %s - %s has failed %d times \n" 366 "EEH: PCI device %s - %s has failed %d times \n"
361 "and has been permanently disabled. Please try reseating\n" 367 "and has been permanently disabled. Please try reseating\n"
362 "this device or replacing it.\n", 368 "this device or replacing it.\n",
363 pci_name (frozen_pdn->pcidev), 369 drv_str, pci_str, frozen_pdn->eeh_freeze_count);
364 pcid_name(frozen_pdn->pcidev),
365 frozen_pdn->eeh_freeze_count);
366 370
367 eeh_slot_error_detail(frozen_pdn, 2 /* Permanent Error */); 371 eeh_slot_error_detail(frozen_pdn, 2 /* Permanent Error */);
368 372
diff --git a/arch/powerpc/platforms/pseries/firmware.c b/arch/powerpc/platforms/pseries/firmware.c
index 989f4bc136cb..c01d8f0cbe6d 100644
--- a/arch/powerpc/platforms/pseries/firmware.c
+++ b/arch/powerpc/platforms/pseries/firmware.c
@@ -91,7 +91,7 @@ void __init fw_feature_init(void)
91 continue; 91 continue;
92 92
93 /* we have a match */ 93 /* we have a match */
94 ppc64_firmware_features |= 94 powerpc_firmware_features |=
95 firmware_features_table[i].val; 95 firmware_features_table[i].val;
96 break; 96 break;
97 } 97 }
diff --git a/arch/powerpc/platforms/pseries/hvconsole.c b/arch/powerpc/platforms/pseries/hvconsole.c
index 138e128a3886..ba6befd96636 100644
--- a/arch/powerpc/platforms/pseries/hvconsole.c
+++ b/arch/powerpc/platforms/pseries/hvconsole.c
@@ -62,6 +62,11 @@ int hvc_put_chars(uint32_t vtermno, const char *buf, int count)
62 unsigned long *lbuf = (unsigned long *) buf; 62 unsigned long *lbuf = (unsigned long *) buf;
63 long ret; 63 long ret;
64 64
65
66 /* hcall will ret H_PARAMETER if 'count' exceeds firmware max.*/
67 if (count > MAX_VIO_PUT_CHARS)
68 count = MAX_VIO_PUT_CHARS;
69
65 ret = plpar_hcall_norets(H_PUT_TERM_CHAR, vtermno, count, lbuf[0], 70 ret = plpar_hcall_norets(H_PUT_TERM_CHAR, vtermno, count, lbuf[0],
66 lbuf[1]); 71 lbuf[1]);
67 if (ret == H_Success) 72 if (ret == H_Success)
diff --git a/arch/powerpc/platforms/pseries/pci.c b/arch/powerpc/platforms/pseries/pci.c
index 946ad59e3352..e97e67f5e079 100644
--- a/arch/powerpc/platforms/pseries/pci.c
+++ b/arch/powerpc/platforms/pseries/pci.c
@@ -120,7 +120,7 @@ static void fixup_winbond_82c105(struct pci_dev* dev)
120 int i; 120 int i;
121 unsigned int reg; 121 unsigned int reg;
122 122
123 if (!platform_is_pseries()) 123 if (!machine_is(pseries))
124 return; 124 return;
125 125
126 printk("Using INTC for W82c105 IDE controller.\n"); 126 printk("Using INTC for W82c105 IDE controller.\n");
diff --git a/arch/powerpc/platforms/pseries/pci_dlpar.c b/arch/powerpc/platforms/pseries/pci_dlpar.c
index 44abdeb9ca03..6bfacc217085 100644
--- a/arch/powerpc/platforms/pseries/pci_dlpar.c
+++ b/arch/powerpc/platforms/pseries/pci_dlpar.c
@@ -28,6 +28,7 @@
28#include <linux/pci.h> 28#include <linux/pci.h>
29#include <asm/pci-bridge.h> 29#include <asm/pci-bridge.h>
30#include <asm/ppc-pci.h> 30#include <asm/ppc-pci.h>
31#include <asm/firmware.h>
31 32
32static struct pci_bus * 33static struct pci_bus *
33find_bus_among_children(struct pci_bus *bus, 34find_bus_among_children(struct pci_bus *bus,
@@ -152,20 +153,24 @@ pcibios_pci_config_bridge(struct pci_dev *dev)
152void 153void
153pcibios_add_pci_devices(struct pci_bus * bus) 154pcibios_add_pci_devices(struct pci_bus * bus)
154{ 155{
155 int slotno, num; 156 int slotno, num, mode;
156 struct pci_dev *dev; 157 struct pci_dev *dev;
157 struct device_node *dn = pci_bus_to_OF_node(bus); 158 struct device_node *dn = pci_bus_to_OF_node(bus);
158 159
159 eeh_add_device_tree_early(dn); 160 eeh_add_device_tree_early(dn);
160 161
161 if (_machine == PLATFORM_PSERIES_LPAR) { 162 mode = PCI_PROBE_NORMAL;
163 if (ppc_md.pci_probe_mode)
164 mode = ppc_md.pci_probe_mode(bus);
165
166 if (mode == PCI_PROBE_DEVTREE) {
162 /* use ofdt-based probe */ 167 /* use ofdt-based probe */
163 of_scan_bus(dn, bus); 168 of_scan_bus(dn, bus);
164 if (!list_empty(&bus->devices)) { 169 if (!list_empty(&bus->devices)) {
165 pcibios_fixup_new_pci_devices(bus, 0); 170 pcibios_fixup_new_pci_devices(bus, 0);
166 pci_bus_add_devices(bus); 171 pci_bus_add_devices(bus);
167 } 172 }
168 } else { 173 } else if (mode == PCI_PROBE_NORMAL) {
169 /* use legacy probe */ 174 /* use legacy probe */
170 slotno = PCI_SLOT(PCI_DN(dn->child)->devfn); 175 slotno = PCI_SLOT(PCI_DN(dn->child)->devfn);
171 num = pci_scan_slot(bus, PCI_DEVFN(slotno, 0)); 176 num = pci_scan_slot(bus, PCI_DEVFN(slotno, 0));
diff --git a/arch/powerpc/platforms/pseries/ras.c b/arch/powerpc/platforms/pseries/ras.c
index b046bcf7443d..9639c66b453d 100644
--- a/arch/powerpc/platforms/pseries/ras.c
+++ b/arch/powerpc/platforms/pseries/ras.c
@@ -132,7 +132,7 @@ static int __init init_ras_IRQ(void)
132 of_node_put(np); 132 of_node_put(np);
133 } 133 }
134 134
135 return 1; 135 return 0;
136} 136}
137__initcall(init_ras_IRQ); 137__initcall(init_ras_IRQ);
138 138
diff --git a/arch/powerpc/platforms/pseries/reconfig.c b/arch/powerpc/platforms/pseries/reconfig.c
index 5ad90676567a..1773103354be 100644
--- a/arch/powerpc/platforms/pseries/reconfig.c
+++ b/arch/powerpc/platforms/pseries/reconfig.c
@@ -17,8 +17,9 @@
17#include <linux/proc_fs.h> 17#include <linux/proc_fs.h>
18 18
19#include <asm/prom.h> 19#include <asm/prom.h>
20#include <asm/pSeries_reconfig.h> 20#include <asm/machdep.h>
21#include <asm/uaccess.h> 21#include <asm/uaccess.h>
22#include <asm/pSeries_reconfig.h>
22 23
23 24
24 25
@@ -508,7 +509,7 @@ static int proc_ppc64_create_ofdt(void)
508{ 509{
509 struct proc_dir_entry *ent; 510 struct proc_dir_entry *ent;
510 511
511 if (!platform_is_pseries()) 512 if (!machine_is(pseries))
512 return 0; 513 return 0;
513 514
514 ent = create_proc_entry("ppc64/ofdt", S_IWUSR, NULL); 515 ent = create_proc_entry("ppc64/ofdt", S_IWUSR, NULL);
diff --git a/arch/powerpc/platforms/pseries/rtasd.c b/arch/powerpc/platforms/pseries/rtasd.c
index a6f628d4c9dc..fcc4d561a236 100644
--- a/arch/powerpc/platforms/pseries/rtasd.c
+++ b/arch/powerpc/platforms/pseries/rtasd.c
@@ -27,6 +27,7 @@
27#include <asm/prom.h> 27#include <asm/prom.h>
28#include <asm/nvram.h> 28#include <asm/nvram.h>
29#include <asm/atomic.h> 29#include <asm/atomic.h>
30#include <asm/machdep.h>
30 31
31#if 0 32#if 0
32#define DEBUG(A...) printk(KERN_ERR A) 33#define DEBUG(A...) printk(KERN_ERR A)
@@ -481,7 +482,7 @@ static int __init rtas_init(void)
481{ 482{
482 struct proc_dir_entry *entry; 483 struct proc_dir_entry *entry;
483 484
484 if (!platform_is_pseries()) 485 if (!machine_is(pseries))
485 return 0; 486 return 0;
486 487
487 /* No RTAS */ 488 /* No RTAS */
diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c
index 44d5c7fdcd97..b2fbf8ba8fbb 100644
--- a/arch/powerpc/platforms/pseries/setup.c
+++ b/arch/powerpc/platforms/pseries/setup.c
@@ -81,8 +81,8 @@ extern void find_udbg_vterm(void);
81 81
82int fwnmi_active; /* TRUE if an FWNMI handler is present */ 82int fwnmi_active; /* TRUE if an FWNMI handler is present */
83 83
84static void pseries_shared_idle(void); 84static void pseries_shared_idle_sleep(void);
85static void pseries_dedicated_idle(void); 85static void pseries_dedicated_idle_sleep(void);
86 86
87struct mpic *pSeries_mpic; 87struct mpic *pSeries_mpic;
88 88
@@ -236,14 +236,13 @@ static void __init pSeries_setup_arch(void)
236 vpa_init(boot_cpuid); 236 vpa_init(boot_cpuid);
237 if (get_lppaca()->shared_proc) { 237 if (get_lppaca()->shared_proc) {
238 printk(KERN_INFO "Using shared processor idle loop\n"); 238 printk(KERN_INFO "Using shared processor idle loop\n");
239 ppc_md.idle_loop = pseries_shared_idle; 239 ppc_md.power_save = pseries_shared_idle_sleep;
240 } else { 240 } else {
241 printk(KERN_INFO "Using dedicated idle loop\n"); 241 printk(KERN_INFO "Using dedicated idle loop\n");
242 ppc_md.idle_loop = pseries_dedicated_idle; 242 ppc_md.power_save = pseries_dedicated_idle_sleep;
243 } 243 }
244 } else { 244 } else {
245 printk(KERN_INFO "Using default idle loop\n"); 245 printk(KERN_INFO "Using default idle loop\n");
246 ppc_md.idle_loop = default_idle;
247 } 246 }
248 247
249 if (firmware_has_feature(FW_FEATURE_LPAR)) 248 if (firmware_has_feature(FW_FEATURE_LPAR))
@@ -373,156 +372,123 @@ static int pSeries_check_legacy_ioport(unsigned int baseport)
373/* 372/*
374 * Called very early, MMU is off, device-tree isn't unflattened 373 * Called very early, MMU is off, device-tree isn't unflattened
375 */ 374 */
376extern struct machdep_calls pSeries_md;
377 375
378static int __init pSeries_probe(int platform) 376static int __init pSeries_probe_hypertas(unsigned long node,
377 const char *uname, int depth,
378 void *data)
379{ 379{
380 if (platform != PLATFORM_PSERIES && 380 if (depth != 1 ||
381 platform != PLATFORM_PSERIES_LPAR) 381 (strcmp(uname, "rtas") != 0 && strcmp(uname, "rtas@0") != 0))
382 return 0; 382 return 0;
383
384 /* if we have some ppc_md fixups for LPAR to do, do
385 * it here ...
386 */
387 383
388 if (platform == PLATFORM_PSERIES_LPAR) 384 if (of_get_flat_dt_prop(node, "ibm,hypertas-functions", NULL) != NULL)
389 ppc64_firmware_features |= FW_FEATURE_LPAR; 385 powerpc_firmware_features |= FW_FEATURE_LPAR;
390 386
391 return 1; 387 return 1;
392} 388}
393 389
394DECLARE_PER_CPU(unsigned long, smt_snooze_delay); 390static int __init pSeries_probe(void)
395
396static inline void dedicated_idle_sleep(unsigned int cpu)
397{ 391{
398 struct lppaca *plppaca = &lppaca[cpu ^ 1]; 392 char *dtype = of_get_flat_dt_prop(of_get_flat_dt_root(),
393 "device_type", NULL);
394 if (dtype == NULL)
395 return 0;
396 if (strcmp(dtype, "chrp"))
397 return 0;
399 398
400 /* Only sleep if the other thread is not idle */ 399 DBG("pSeries detected, looking for LPAR capability...\n");
401 if (!(plppaca->idle)) {
402 local_irq_disable();
403 400
404 /* 401 /* Now try to figure out if we are running on LPAR */
405 * We are about to sleep the thread and so wont be polling any 402 of_scan_flat_dt(pSeries_probe_hypertas, NULL);
406 * more. 403
407 */ 404 DBG("Machine is%s LPAR !\n",
408 clear_thread_flag(TIF_POLLING_NRFLAG); 405 (powerpc_firmware_features & FW_FEATURE_LPAR) ? "" : " not");
409 smp_mb__after_clear_bit(); 406
410 407 return 1;
411 /*
412 * SMT dynamic mode. Cede will result in this thread going
413 * dormant, if the partner thread is still doing work. Thread
414 * wakes up if partner goes idle, an interrupt is presented, or
415 * a prod occurs. Returning from the cede enables external
416 * interrupts.
417 */
418 if (!need_resched())
419 cede_processor();
420 else
421 local_irq_enable();
422 set_thread_flag(TIF_POLLING_NRFLAG);
423 } else {
424 /*
425 * Give the HV an opportunity at the processor, since we are
426 * not doing any work.
427 */
428 poll_pending();
429 }
430} 408}
431 409
432static void pseries_dedicated_idle(void) 410
411DECLARE_PER_CPU(unsigned long, smt_snooze_delay);
412
413static void pseries_dedicated_idle_sleep(void)
433{ 414{
434 unsigned int cpu = smp_processor_id(); 415 unsigned int cpu = smp_processor_id();
435 unsigned long start_snooze; 416 unsigned long start_snooze;
436 unsigned long *smt_snooze_delay = &__get_cpu_var(smt_snooze_delay); 417 unsigned long *smt_snooze_delay = &__get_cpu_var(smt_snooze_delay);
437 set_thread_flag(TIF_POLLING_NRFLAG);
438
439 while (1) {
440 /*
441 * Indicate to the HV that we are idle. Now would be
442 * a good time to find other work to dispatch.
443 */
444 get_lppaca()->idle = 1;
445
446 if (!need_resched()) {
447 start_snooze = get_tb() +
448 *smt_snooze_delay * tb_ticks_per_usec;
449
450 while (!need_resched() && !cpu_is_offline(cpu)) {
451 ppc64_runlatch_off();
452
453 /*
454 * Go into low thread priority and possibly
455 * low power mode.
456 */
457 HMT_low();
458 HMT_very_low();
459
460 if (*smt_snooze_delay != 0 &&
461 get_tb() > start_snooze) {
462 HMT_medium();
463 dedicated_idle_sleep(cpu);
464 }
465
466 }
467
468 HMT_medium();
469 }
470
471 get_lppaca()->idle = 0;
472 ppc64_runlatch_on();
473 418
474 preempt_enable_no_resched(); 419 /*
475 schedule(); 420 * Indicate to the HV that we are idle. Now would be
476 preempt_disable(); 421 * a good time to find other work to dispatch.
422 */
423 get_lppaca()->idle = 1;
477 424
478 if (cpu_is_offline(cpu) && system_state == SYSTEM_RUNNING) 425 /*
479 cpu_die(); 426 * We come in with interrupts disabled, and need_resched()
480 } 427 * has been checked recently. If we should poll for a little
481} 428 * while, do so.
429 */
430 if (*smt_snooze_delay) {
431 start_snooze = get_tb() +
432 *smt_snooze_delay * tb_ticks_per_usec;
433 local_irq_enable();
434 set_thread_flag(TIF_POLLING_NRFLAG);
482 435
483static void pseries_shared_idle(void) 436 while (get_tb() < start_snooze) {
484{ 437 if (need_resched() || cpu_is_offline(cpu))
485 unsigned int cpu = smp_processor_id(); 438 goto out;
439 ppc64_runlatch_off();
440 HMT_low();
441 HMT_very_low();
442 }
486 443
487 while (1) { 444 HMT_medium();
488 /* 445 clear_thread_flag(TIF_POLLING_NRFLAG);
489 * Indicate to the HV that we are idle. Now would be 446 smp_mb();
490 * a good time to find other work to dispatch. 447 local_irq_disable();
491 */ 448 if (need_resched() || cpu_is_offline(cpu))
492 get_lppaca()->idle = 1; 449 goto out;
450 }
493 451
494 while (!need_resched() && !cpu_is_offline(cpu)) { 452 /*
495 local_irq_disable(); 453 * Cede if the other thread is not idle, so that it can
496 ppc64_runlatch_off(); 454 * go single-threaded. If the other thread is idle,
455 * we ask the hypervisor if it has pending work it
456 * wants to do and cede if it does. Otherwise we keep
457 * polling in order to reduce interrupt latency.
458 *
459 * Doing the cede when the other thread is active will
460 * result in this thread going dormant, meaning the other
461 * thread gets to run in single-threaded (ST) mode, which
462 * is slightly faster than SMT mode with this thread at
463 * very low priority. The cede enables interrupts, which
464 * doesn't matter here.
465 */
466 if (!lppaca[cpu ^ 1].idle || poll_pending() == H_Pending)
467 cede_processor();
497 468
498 /* 469out:
499 * Yield the processor to the hypervisor. We return if 470 HMT_medium();
500 * an external interrupt occurs (which are driven prior 471 get_lppaca()->idle = 0;
501 * to returning here) or if a prod occurs from another 472}
502 * processor. When returning here, external interrupts
503 * are enabled.
504 *
505 * Check need_resched() again with interrupts disabled
506 * to avoid a race.
507 */
508 if (!need_resched())
509 cede_processor();
510 else
511 local_irq_enable();
512
513 HMT_medium();
514 }
515 473
516 get_lppaca()->idle = 0; 474static void pseries_shared_idle_sleep(void)
517 ppc64_runlatch_on(); 475{
476 /*
477 * Indicate to the HV that we are idle. Now would be
478 * a good time to find other work to dispatch.
479 */
480 get_lppaca()->idle = 1;
518 481
519 preempt_enable_no_resched(); 482 /*
520 schedule(); 483 * Yield the processor to the hypervisor. We return if
521 preempt_disable(); 484 * an external interrupt occurs (which are driven prior
485 * to returning here) or if a prod occurs from another
486 * processor. When returning here, external interrupts
487 * are enabled.
488 */
489 cede_processor();
522 490
523 if (cpu_is_offline(cpu) && system_state == SYSTEM_RUNNING) 491 get_lppaca()->idle = 0;
524 cpu_die();
525 }
526} 492}
527 493
528static int pSeries_pci_probe_mode(struct pci_bus *bus) 494static int pSeries_pci_probe_mode(struct pci_bus *bus)
@@ -553,7 +519,8 @@ static void pseries_kexec_cpu_down(int crash_shutdown, int secondary)
553} 519}
554#endif 520#endif
555 521
556struct machdep_calls __initdata pSeries_md = { 522define_machine(pseries) {
523 .name = "pSeries",
557 .probe = pSeries_probe, 524 .probe = pSeries_probe,
558 .setup_arch = pSeries_setup_arch, 525 .setup_arch = pSeries_setup_arch,
559 .init_early = pSeries_init_early, 526 .init_early = pSeries_init_early,
diff --git a/arch/powerpc/platforms/pseries/xics.c b/arch/powerpc/platforms/pseries/xics.c
index eb86cdb9b802..4864cb32be25 100644
--- a/arch/powerpc/platforms/pseries/xics.c
+++ b/arch/powerpc/platforms/pseries/xics.c
@@ -500,7 +500,7 @@ nextnode:
500 np; 500 np;
501 np = of_find_node_by_type(np, "cpu")) { 501 np = of_find_node_by_type(np, "cpu")) {
502 ireg = (uint *)get_property(np, "reg", &ilen); 502 ireg = (uint *)get_property(np, "reg", &ilen);
503 if (ireg && ireg[0] == boot_cpuid_phys) { 503 if (ireg && ireg[0] == get_hard_smp_processor_id(boot_cpuid)) {
504 ireg = (uint *)get_property(np, "ibm,ppc-interrupt-gserver#s", 504 ireg = (uint *)get_property(np, "ibm,ppc-interrupt-gserver#s",
505 &ilen); 505 &ilen);
506 i = ilen / sizeof(int); 506 i = ilen / sizeof(int);
@@ -541,7 +541,7 @@ nextnode:
541 ops = &pSeriesLP_ops; 541 ops = &pSeriesLP_ops;
542 else { 542 else {
543#ifdef CONFIG_SMP 543#ifdef CONFIG_SMP
544 for_each_cpu(i) { 544 for_each_possible_cpu(i) {
545 int hard_id; 545 int hard_id;
546 546
547 /* FIXME: Do this dynamically! --RR */ 547 /* FIXME: Do this dynamically! --RR */
diff --git a/arch/ppc/Kconfig b/arch/ppc/Kconfig
index 3a3e302b4ea2..e9a8f5d1dfcd 100644
--- a/arch/ppc/Kconfig
+++ b/arch/ppc/Kconfig
@@ -61,15 +61,15 @@ config 6xx
61 select PPC_FPU 61 select PPC_FPU
62 help 62 help
63 There are four types of PowerPC chips supported. The more common 63 There are four types of PowerPC chips supported. The more common
64 types (601, 603, 604, 740, 750, 7400), the Motorola embedded 64 types (601, 603, 604, 740, 750, 7400), the older Freescale
65 versions (821, 823, 850, 855, 860, 52xx, 82xx, 83xx), the IBM 65 (formerly Motorola) embedded versions (821, 823, 850, 855, 860,
66 embedded versions (403 and 405) and the POWER3 processor. 66 52xx, 82xx, 83xx), the IBM embedded versions (403 and 405) and
67 (For support for more recent 64-bit processors, set ARCH=powerpc.) 67 the Book E embedded processors from IBM (44x) and Freescale (85xx).
68 For support for 64-bit processors, set ARCH=powerpc.
68 Unless you are building a kernel for one of the embedded processor 69 Unless you are building a kernel for one of the embedded processor
69 systems or a POWER3-based IBM RS/6000, choose 6xx. 70 systems, choose 6xx.
70 Note that the kernel runs in 32-bit mode even on 64-bit chips. 71 Also note that because the 52xx, 82xx, & 83xx family have a 603e
71 Also note that because the 52xx, 82xx, & 83xx family has a 603e core, 72 core, specific support for that chipset is asked later on.
72 specific support for that chipset is asked later on.
73 73
74config 40x 74config 40x
75 bool "40x" 75 bool "40x"
@@ -77,10 +77,6 @@ config 40x
77config 44x 77config 44x
78 bool "44x" 78 bool "44x"
79 79
80config POWER3
81 select PPC_FPU
82 bool "POWER3"
83
84config 8xx 80config 8xx
85 bool "8xx" 81 bool "8xx"
86 82
@@ -252,14 +248,9 @@ config PPC601_SYNC_FIX
252source arch/ppc/platforms/4xx/Kconfig 248source arch/ppc/platforms/4xx/Kconfig
253source arch/ppc/platforms/85xx/Kconfig 249source arch/ppc/platforms/85xx/Kconfig
254 250
255config PPC64BRIDGE
256 bool
257 depends on POWER3
258 default y
259
260config PPC_STD_MMU 251config PPC_STD_MMU
261 bool 252 bool
262 depends on 6xx || POWER3 253 depends on 6xx
263 default y 254 default y
264 255
265config NOT_COHERENT_CACHE 256config NOT_COHERENT_CACHE
@@ -534,8 +525,8 @@ endmenu
534 525
535choice 526choice
536 prompt "Machine Type" 527 prompt "Machine Type"
537 depends on 6xx || POWER3 528 depends on 6xx
538 default PPC_MULTIPLATFORM 529 default PPC_PREP
539 ---help--- 530 ---help---
540 Linux currently supports several different kinds of PowerPC-based 531 Linux currently supports several different kinds of PowerPC-based
541 machines: Apple Power Macintoshes and clones (such as the Motorola 532 machines: Apple Power Macintoshes and clones (such as the Motorola
@@ -545,15 +536,14 @@ choice
545 Platform) machines (including all of the recent IBM RS/6000 and 536 Platform) machines (including all of the recent IBM RS/6000 and
546 pSeries machines), and several embedded PowerPC systems containing 537 pSeries machines), and several embedded PowerPC systems containing
547 4xx, 6xx, 7xx, 8xx, 74xx, and 82xx processors. Currently, the 538 4xx, 6xx, 7xx, 8xx, 74xx, and 82xx processors. Currently, the
548 default option is to build a kernel which works on PReP and CHRP. 539 default option is to build a kernel which works on PReP.
549 540
550 Note that support for Apple machines is now only available with 541 Note that support for Apple and CHRP machines is now only available
551 ARCH=powerpc, and has been removed from this menu. If you wish 542 with ARCH=powerpc, and has been removed from this menu. If you
552 to build a kernel for an Apple machine, exit this configuration 543 wish to build a kernel for an Apple or CHRP machine, exit this
553 process and re-run it with ARCH=powerpc. 544 configuration process and re-run it with ARCH=powerpc.
554 545
555 Select CHRP/PReP if configuring for an IBM RS/6000 or 546 Select PReP if configuring for a PReP machine.
556 pSeries machine, or a PReP machine.
557 547
558 Select Gemini if configuring for a Synergy Microsystems' Gemini 548 Select Gemini if configuring for a Synergy Microsystems' Gemini
559 series Single Board Computer. More information is available at: 549 series Single Board Computer. More information is available at:
@@ -562,8 +552,8 @@ choice
562 Select APUS if configuring for a PowerUP Amiga. More information is 552 Select APUS if configuring for a PowerUP Amiga. More information is
563 available at: <http://linux-apus.sourceforge.net/>. 553 available at: <http://linux-apus.sourceforge.net/>.
564 554
565config PPC_MULTIPLATFORM 555config PPC_PREP
566 bool "CHRP/PReP" 556 bool "PReP"
567 557
568config APUS 558config APUS
569 bool "Amiga-APUS" 559 bool "Amiga-APUS"
@@ -715,6 +705,13 @@ config LITE5200
715 much but it's only been tested on this board version. I think this 705 much but it's only been tested on this board version. I think this
716 board is also known as IceCube. 706 board is also known as IceCube.
717 707
708config LITE5200B
709 bool "Freescale LITE5200B"
710 depends LITE5200
711 help
712 Support for the LITE5200B dev board for the MPC5200 from Freescale.
713 This is the new board with 2 PCI slots.
714
718config MPC834x_SYS 715config MPC834x_SYS
719 bool "Freescale MPC834x SYS" 716 bool "Freescale MPC834x SYS"
720 help 717 help
@@ -800,25 +797,6 @@ config CPM2
800 you wish to build a kernel for a machine with a CPM2 coprocessor 797 you wish to build a kernel for a machine with a CPM2 coprocessor
801 on it (826x, 827x, 8560). 798 on it (826x, 827x, 8560).
802 799
803config PPC_CHRP
804 bool "Support for CHRP (Common Hardware Reference Platform) machines"
805 depends on PPC_MULTIPLATFORM
806 select PPC_I8259
807 select PPC_INDIRECT_PCI
808 default y
809
810config PPC_PREP
811 bool "Support for PReP (PowerPC Reference Platform) machines"
812 depends on PPC_MULTIPLATFORM
813 select PPC_I8259
814 select PPC_INDIRECT_PCI
815 default y
816
817config PPC_OF
818 bool
819 depends on PPC_CHRP
820 default y
821
822config PPC_GEN550 800config PPC_GEN550
823 bool 801 bool
824 depends on SANDPOINT || SPRUCE || PPLUS || \ 802 depends on SANDPOINT || SPRUCE || PPLUS || \
@@ -977,14 +955,6 @@ source "mm/Kconfig"
977 955
978source "fs/Kconfig.binfmt" 956source "fs/Kconfig.binfmt"
979 957
980config PROC_DEVICETREE
981 bool "Support for Open Firmware device tree in /proc"
982 depends on PPC_OF && PROC_FS
983 help
984 This option adds a device-tree directory under /proc which contains
985 an image of the device tree that the kernel copies from Open
986 Firmware. If unsure, say Y here.
987
988config PREP_RESIDUAL 958config PREP_RESIDUAL
989 bool "Support for PReP Residual Data" 959 bool "Support for PReP Residual Data"
990 depends on PPC_PREP 960 depends on PPC_PREP
@@ -1177,8 +1147,7 @@ menu "Bus options"
1177 1147
1178config ISA 1148config ISA
1179 bool "Support for ISA-bus hardware" 1149 bool "Support for ISA-bus hardware"
1180 depends on PPC_PREP || PPC_CHRP 1150 depends on PPC_PREP
1181 select PPC_I8259
1182 help 1151 help
1183 Find out whether you have ISA slots on your motherboard. ISA is the 1152 Find out whether you have ISA slots on your motherboard. ISA is the
1184 name of a bus system, i.e. the way the CPU talks to the other stuff 1153 name of a bus system, i.e. the way the CPU talks to the other stuff
@@ -1188,18 +1157,18 @@ config ISA
1188 1157
1189config GENERIC_ISA_DMA 1158config GENERIC_ISA_DMA
1190 bool 1159 bool
1191 depends on POWER3 || 6xx && !CPM2 1160 depends on 6xx && !CPM2
1192 default y 1161 default y
1193 1162
1194config PPC_I8259 1163config PPC_I8259
1195 bool 1164 bool
1196 default y if 85xx 1165 default y if 85xx || PPC_PREP
1197 default n 1166 default n
1198 1167
1199config PPC_INDIRECT_PCI 1168config PPC_INDIRECT_PCI
1200 bool 1169 bool
1201 depends on PCI 1170 depends on PCI
1202 default y if 40x || 44x || 85xx || 83xx 1171 default y if 40x || 44x || 85xx || 83xx || PPC_PREP
1203 default n 1172 default n
1204 1173
1205config EISA 1174config EISA
@@ -1390,7 +1359,7 @@ config CONSISTENT_SIZE
1390 1359
1391config BOOT_LOAD_BOOL 1360config BOOT_LOAD_BOOL
1392 bool "Set the boot link/load address" 1361 bool "Set the boot link/load address"
1393 depends on ADVANCED_OPTIONS && !PPC_MULTIPLATFORM 1362 depends on ADVANCED_OPTIONS && !PPC_PREP
1394 help 1363 help
1395 This option allows you to set the initial load address of the zImage 1364 This option allows you to set the initial load address of the zImage
1396 or zImage.initrd file. This can be useful if you are on a board 1365 or zImage.initrd file. This can be useful if you are on a board
diff --git a/arch/ppc/Kconfig.debug b/arch/ppc/Kconfig.debug
index 8cc75abf3d83..f94b87740973 100644
--- a/arch/ppc/Kconfig.debug
+++ b/arch/ppc/Kconfig.debug
@@ -53,13 +53,6 @@ config BDI_SWITCH
53 Unless you are intending to debug the kernel with one of these 53 Unless you are intending to debug the kernel with one of these
54 machines, say N here. 54 machines, say N here.
55 55
56config BOOTX_TEXT
57 bool "Support for early boot text console (BootX or OpenFirmware only)"
58 depends PPC_OF
59 help
60 Say Y here to see progress messages from the boot firmware in text
61 mode. Requires either BootX or Open Firmware.
62
63config SERIAL_TEXT_DEBUG 56config SERIAL_TEXT_DEBUG
64 bool "Support for early boot texts over serial port" 57 bool "Support for early boot texts over serial port"
65 depends on 4xx || LOPEC || MV64X60 || PPLUS || PRPMC800 || \ 58 depends on 4xx || LOPEC || MV64X60 || PPLUS || PRPMC800 || \
diff --git a/arch/ppc/Makefile b/arch/ppc/Makefile
index 9fbdf54ba2be..0db66dcf0723 100644
--- a/arch/ppc/Makefile
+++ b/arch/ppc/Makefile
@@ -40,10 +40,8 @@ ifndef CONFIG_FSL_BOOKE
40CFLAGS += -mstring 40CFLAGS += -mstring
41endif 41endif
42 42
43cpu-as-$(CONFIG_PPC64BRIDGE) += -Wa,-mppc64bridge
44cpu-as-$(CONFIG_4xx) += -Wa,-m405 43cpu-as-$(CONFIG_4xx) += -Wa,-m405
45cpu-as-$(CONFIG_6xx) += -Wa,-maltivec 44cpu-as-$(CONFIG_6xx) += -Wa,-maltivec
46cpu-as-$(CONFIG_POWER4) += -Wa,-maltivec
47cpu-as-$(CONFIG_E500) += -Wa,-me500 45cpu-as-$(CONFIG_E500) += -Wa,-me500
48cpu-as-$(CONFIG_E200) += -Wa,-me200 46cpu-as-$(CONFIG_E200) += -Wa,-me200
49 47
@@ -59,8 +57,6 @@ head-$(CONFIG_4xx) := arch/ppc/kernel/head_4xx.o
59head-$(CONFIG_44x) := arch/ppc/kernel/head_44x.o 57head-$(CONFIG_44x) := arch/ppc/kernel/head_44x.o
60head-$(CONFIG_FSL_BOOKE) := arch/ppc/kernel/head_fsl_booke.o 58head-$(CONFIG_FSL_BOOKE) := arch/ppc/kernel/head_fsl_booke.o
61 59
62head-$(CONFIG_6xx) += arch/ppc/kernel/idle_6xx.o
63head-$(CONFIG_POWER4) += arch/ppc/kernel/idle_power4.o
64head-$(CONFIG_PPC_FPU) += arch/powerpc/kernel/fpu.o 60head-$(CONFIG_PPC_FPU) += arch/powerpc/kernel/fpu.o
65 61
66core-y += arch/ppc/kernel/ arch/powerpc/kernel/ \ 62core-y += arch/ppc/kernel/ arch/powerpc/kernel/ \
@@ -71,7 +67,7 @@ core-y += arch/ppc/kernel/ arch/powerpc/kernel/ \
71core-$(CONFIG_4xx) += arch/ppc/platforms/4xx/ 67core-$(CONFIG_4xx) += arch/ppc/platforms/4xx/
72core-$(CONFIG_83xx) += arch/ppc/platforms/83xx/ 68core-$(CONFIG_83xx) += arch/ppc/platforms/83xx/
73core-$(CONFIG_85xx) += arch/ppc/platforms/85xx/ 69core-$(CONFIG_85xx) += arch/ppc/platforms/85xx/
74core-$(CONFIG_MATH_EMULATION) += arch/ppc/math-emu/ 70core-$(CONFIG_MATH_EMULATION) += arch/powerpc/math-emu/
75core-$(CONFIG_XMON) += arch/ppc/xmon/ 71core-$(CONFIG_XMON) += arch/ppc/xmon/
76core-$(CONFIG_APUS) += arch/ppc/amiga/ 72core-$(CONFIG_APUS) += arch/ppc/amiga/
77drivers-$(CONFIG_8xx) += arch/ppc/8xx_io/ 73drivers-$(CONFIG_8xx) += arch/ppc/8xx_io/
diff --git a/arch/ppc/boot/Makefile b/arch/ppc/boot/Makefile
index 84eec0bef93c..b739e25d4728 100644
--- a/arch/ppc/boot/Makefile
+++ b/arch/ppc/boot/Makefile
@@ -19,14 +19,13 @@ HOSTCFLAGS += -Iarch/$(ARCH)/boot/include
19BOOT_TARGETS = zImage zImage.initrd znetboot znetboot.initrd 19BOOT_TARGETS = zImage zImage.initrd znetboot znetboot.initrd
20 20
21bootdir-y := simple 21bootdir-y := simple
22bootdir-$(CONFIG_PPC_OF) += openfirmware
23subdir-y := lib common images 22subdir-y := lib common images
24subdir-$(CONFIG_PPC_MULTIPLATFORM) += of1275 23subdir-$(CONFIG_PPC_PREP) += of1275
25 24
26# for cleaning 25# for cleaning
27subdir- += simple openfirmware 26subdir- += simple
28 27
29hostprogs-y := $(addprefix utils/, addnote mknote hack-coff mkprep mkbugboot mktree) 28hostprogs-y := $(addprefix utils/, mkprep mkbugboot mktree)
30 29
31PHONY += $(BOOT_TARGETS) $(bootdir-y) 30PHONY += $(BOOT_TARGETS) $(bootdir-y)
32 31
diff --git a/arch/ppc/boot/openfirmware/Makefile b/arch/ppc/boot/openfirmware/Makefile
deleted file mode 100644
index 66b739743759..000000000000
--- a/arch/ppc/boot/openfirmware/Makefile
+++ /dev/null
@@ -1,109 +0,0 @@
1# Makefile for making bootable images on various OpenFirmware machines.
2#
3# This file is included by the global makefile so that you can add your own
4# architecture-specific flags and dependencies.
5#
6# Paul Mackerras January 1997
7# XCOFF bootable images for PowerMacs
8# Geert Uytterhoeven September 1997
9# ELF bootable iamges for CHRP machines.
10# Tom Rini January 2001
11# Cleaned up, moved into arch/ppc/boot/pmac
12# Tom Rini July/August 2002
13# Merged 'chrp' and 'pmac' into 'openfirmware', and cleaned up the
14# rules.
15
16zImage.initrd znetboot.initrd: del-ramdisk-sec := -R .ramdisk
17zImage.initrd znetboot.initrd: initrd := .initrd
18
19
20boot := arch/ppc/boot
21common := $(boot)/common
22utils := $(boot)/utils
23bootlib := $(boot)/lib
24of1275 := $(boot)/of1275
25images := $(boot)/images
26
27CHRP_LD_ARGS := -T $(srctree)/$(boot)/ld.script -e _start -Ttext 0x00800000
28
29COMMONOBJS := start.o misc.o common.o
30CHRPOBJS := crt0.o $(COMMONOBJS) chrpmain.o
31
32targets := $(CHRPOBJS) dummy.o
33CHRPOBJS := $(addprefix $(obj)/, $(CHRPOBJS))
34
35LIBS := lib/lib.a $(bootlib)/lib.a $(of1275)/lib.a $(common)/lib.a
36
37ifdef CONFIG_SMP
38END := .smp
39endif
40ifdef CONFIG_PPC64BRIDGE
41END += .64
42endif
43
44
45$(images)/ramdisk.image.gz:
46 @echo ' MISSING $@'
47 @echo ' RAM disk image must be provided separately'
48 @/bin/false
49
50quiet_cmd_genimage = GEN $@
51 cmd_genimage = $(OBJCOPY) -R .comment \
52 --add-section=.image=$(images)/vmlinux.gz \
53 --set-section-flags=.image=contents,alloc,load,readonly,data $< $@
54
55targets += image.o
56$(obj)/image.o: $(obj)/dummy.o $(images)/vmlinux.gz FORCE
57 $(call if_changed,genimage)
58
59# Place the ramdisk in the initrd image.
60quiet_cmd_genimage-initrd = GEN $@
61 cmd_genimage-initrd = $(OBJCOPY) $< $@ \
62 --add-section=.ramdisk=$(images)/ramdisk.image.gz \
63 --set-section-flags=.ramdisk=contents,alloc,load,readonly,data
64targets += image.initrd.o
65$(obj)/image.initrd.o: $(obj)/image.o $(images)/ramdisk.image.gz FORCE
66 $(call if_changed,genimage-initrd)
67
68
69targets += crt0.o
70$(obj)/crt0.o: $(common)/crt0.S FORCE
71 $(call if_changed_dep,as_o_S)
72
73quiet_cmd_gen-chrp = CHRP $@
74 cmd_gen-chrp = $(LD) $(CHRP_LD_ARGS) -o $@ $(CHRPOBJS) $< $(LIBS) && \
75 $(OBJCOPY) $@ $@ -R .comment $(del-ramdisk-sec)
76
77$(images)/zImage.chrp: $(obj)/image.o $(CHRPOBJS) $(LIBS) \
78 $(srctree)/$(boot)/ld.script
79 $(call cmd,gen-chrp)
80$(images)/zImage.initrd.chrp: $(obj)/image.initrd.o $(CHRPOBJS) $(LIBS) \
81 $(srctree)/$(boot)/ld.script
82 $(call cmd,gen-chrp)
83
84quiet_cmd_addnote = ADDNOTE $@
85 cmd_addnote = cat $< > $@ && $(utils)/addnote $@
86$(images)/zImage.chrp-rs6k $(images)/zImage.initrd.chrp-rs6k: \
87 %-rs6k: %
88 $(call cmd,addnote)
89
90# The targets used on the make command-line
91
92PHONY += zImage zImage.initrd
93zImage: $(images)/zImage.chrp \
94 $(images)/zImage.chrp-rs6k
95 @echo ' kernel: $@ is ready ($<)'
96zImage.initrd: $(images)/zImage.initrd.chrp \
97 $(images)/zImage.initrd.chrp-rs6k
98 @echo ' kernel: $@ is ready ($<)'
99
100TFTPIMAGE := /tftpboot/zImage
101
102PHONY += znetboot znetboot.initrd
103znetboot: $(images)/zImage.chrp
104 cp $(images)/zImage.chrp $(TFTPIMAGE).chrp$(END)
105 @echo ' kernel: $@ is ready ($<)'
106znetboot.initrd:$(images)/zImage.initrd.chrp
107 cp $(images)/zImage.initrd.chrp $(TFTPIMAGE).chrp$(END)
108 @echo ' kernel: $@ is ready ($<)'
109
diff --git a/arch/ppc/boot/openfirmware/chrpmain.c b/arch/ppc/boot/openfirmware/chrpmain.c
deleted file mode 100644
index 245dbd9fc120..000000000000
--- a/arch/ppc/boot/openfirmware/chrpmain.c
+++ /dev/null
@@ -1,101 +0,0 @@
1/*
2 * Copyright (C) Paul Mackerras 1997.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version
7 * 2 of the License, or (at your option) any later version.
8 */
9#include <linux/string.h>
10#include "nonstdio.h"
11#include "of1275.h"
12#include <asm/processor.h>
13#include <asm/page.h>
14
15/* Passed from the linker */
16extern char __image_begin, __image_end;
17extern char __ramdisk_begin, __ramdisk_end;
18extern char _start, _end;
19
20extern unsigned int heap_max;
21extern void flush_cache(void *, unsigned long);
22extern void gunzip(void *, int, unsigned char *, int *);
23extern void make_bi_recs(unsigned long addr, char *name, unsigned int mach,
24 unsigned int progend);
25
26char *avail_ram;
27char *begin_avail, *end_avail;
28char *avail_high;
29
30#define RAM_START 0x00000000
31#define RAM_END (64<<20)
32
33#define BOOT_START ((unsigned long)_start)
34#define BOOT_END ((unsigned long)(_end + 0xFFF) & ~0xFFF)
35
36#define RAM_FREE ((unsigned long)(_end+0x1000)&~0xFFF)
37#define PROG_START 0x00010000
38#define PROG_SIZE 0x007f0000 /* 8MB */
39
40#define SCRATCH_SIZE (128 << 10)
41
42static char scratch[SCRATCH_SIZE]; /* 128k of scratch space for gunzip */
43
44typedef void (*kernel_start_t)(int, int, void *, unsigned int, unsigned int);
45
46void
47boot(int a1, int a2, void *prom)
48{
49 unsigned sa, len;
50 void *dst;
51 unsigned char *im;
52 unsigned int initrd_size, initrd_start;
53
54 printf("chrpboot starting: loaded at 0x%p\n\r", &_start);
55
56 initrd_size = &__ramdisk_end - &__ramdisk_begin;
57 if (initrd_size) {
58 initrd_start = (RAM_END - initrd_size) & ~0xFFF;
59 a1 = initrd_start;
60 a2 = initrd_size;
61 claim(initrd_start, RAM_END - initrd_start, 0);
62 printf("initial ramdisk moving 0x%x <- 0x%p (%x bytes)\n\r",
63 initrd_start, &__ramdisk_begin, initrd_size);
64 memcpy((char *)initrd_start, &__ramdisk_begin, initrd_size);
65 } else {
66 initrd_start = 0;
67 initrd_size = 0;
68 a2 = 0xdeadbeef;
69 }
70
71 im = &__image_begin;
72 len = &__image_end - &__image_begin;
73 /* claim 4MB starting at PROG_START */
74 claim(PROG_START, PROG_SIZE - PROG_START, 0);
75 dst = (void *) PROG_START;
76 if (im[0] == 0x1f && im[1] == 0x8b) {
77 avail_ram = scratch;
78 begin_avail = avail_high = avail_ram;
79 end_avail = scratch + sizeof(scratch);
80 printf("gunzipping (0x%p <- 0x%p:0x%p)...", dst, im, im+len);
81 gunzip(dst, PROG_SIZE - PROG_START, im, &len);
82 printf("done %u bytes\n\r", len);
83 printf("%u bytes of heap consumed, max in use %u\n\r",
84 avail_high - begin_avail, heap_max);
85 } else {
86 memmove(dst, im, len);
87 }
88
89 flush_cache(dst, len);
90 make_bi_recs(((unsigned long) dst + len), "chrpboot", _MACH_chrp,
91 (PROG_START + PROG_SIZE));
92
93 sa = PROG_START;
94 printf("start address = 0x%x\n\r", sa);
95
96 (*(kernel_start_t)sa)(a1, a2, prom, initrd_start, initrd_size);
97
98 printf("returned?\n\r");
99
100 pause();
101}
diff --git a/arch/ppc/boot/openfirmware/common.c b/arch/ppc/boot/openfirmware/common.c
deleted file mode 100644
index 0f46756a903e..000000000000
--- a/arch/ppc/boot/openfirmware/common.c
+++ /dev/null
@@ -1,146 +0,0 @@
1/*
2 * Copyright (C) Paul Mackerras 1997.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version
7 * 2 of the License, or (at your option) any later version.
8 */
9
10#include "nonstdio.h"
11#include "of1275.h"
12#include <linux/string.h>
13#include <linux/zlib.h>
14#include <asm/bootinfo.h>
15#include <asm/page.h>
16
17/* Information from the linker */
18
19extern int strcmp(const char *s1, const char *s2);
20extern char *avail_ram, *avail_high;
21extern char *end_avail;
22
23unsigned int heap_use, heap_max;
24
25struct memchunk {
26 unsigned int size;
27 struct memchunk *next;
28};
29
30static struct memchunk *freechunks;
31
32static void *zalloc(unsigned size)
33{
34 void *p;
35 struct memchunk **mpp, *mp;
36
37 size = (size + 7) & -8;
38 heap_use += size;
39 if (heap_use > heap_max)
40 heap_max = heap_use;
41 for (mpp = &freechunks; (mp = *mpp) != 0; mpp = &mp->next) {
42 if (mp->size == size) {
43 *mpp = mp->next;
44 return mp;
45 }
46 }
47 p = avail_ram;
48 avail_ram += size;
49 if (avail_ram > avail_high)
50 avail_high = avail_ram;
51 if (avail_ram > end_avail) {
52 printf("oops... out of memory\n\r");
53 pause();
54 }
55 return p;
56}
57
58#define HEAD_CRC 2
59#define EXTRA_FIELD 4
60#define ORIG_NAME 8
61#define COMMENT 0x10
62#define RESERVED 0xe0
63
64void gunzip(void *dst, int dstlen, unsigned char *src, int *lenp)
65{
66 z_stream s;
67 int r, i, flags;
68
69 /* skip header */
70 i = 10;
71 flags = src[3];
72 if (src[2] != Z_DEFLATED || (flags & RESERVED) != 0) {
73 printf("bad gzipped data\n\r");
74 exit();
75 }
76 if ((flags & EXTRA_FIELD) != 0)
77 i = 12 + src[10] + (src[11] << 8);
78 if ((flags & ORIG_NAME) != 0)
79 while (src[i++] != 0)
80 ;
81 if ((flags & COMMENT) != 0)
82 while (src[i++] != 0)
83 ;
84 if ((flags & HEAD_CRC) != 0)
85 i += 2;
86 if (i >= *lenp) {
87 printf("gunzip: ran out of data in header\n\r");
88 exit();
89 }
90
91 /* Initialize ourself. */
92 s.workspace = zalloc(zlib_inflate_workspacesize());
93 r = zlib_inflateInit2(&s, -MAX_WBITS);
94 if (r != Z_OK) {
95 printf("zlib_inflateInit2 returned %d\n\r", r);
96 exit();
97 }
98 s.next_in = src + i;
99 s.avail_in = *lenp - i;
100 s.next_out = dst;
101 s.avail_out = dstlen;
102 r = zlib_inflate(&s, Z_FINISH);
103 if (r != Z_OK && r != Z_STREAM_END) {
104 printf("inflate returned %d msg: %s\n\r", r, s.msg);
105 exit();
106 }
107 *lenp = s.next_out - (unsigned char *) dst;
108 zlib_inflateEnd(&s);
109}
110
111/* Make a bi_rec in OF. We need to be passed a name for BI_BOOTLOADER_ID,
112 * a machine type for BI_MACHTYPE, and the location where the end of the
113 * bootloader is (PROG_START + PROG_SIZE)
114 */
115void make_bi_recs(unsigned long addr, char *name, unsigned int mach,
116 unsigned long progend)
117{
118 struct bi_record *rec;
119
120
121 /* leave a 1MB gap then align to the next 1MB boundary */
122 addr = _ALIGN(addr+ (1<<20) - 1, (1<<20));
123 /* oldworld machine seem very unhappy about this. -- Tom */
124 if (addr >= progend)
125 claim(addr, 0x1000, 0);
126
127 rec = (struct bi_record *)addr;
128 rec->tag = BI_FIRST;
129 rec->size = sizeof(struct bi_record);
130 rec = (struct bi_record *)((unsigned long)rec + rec->size);
131
132 rec->tag = BI_BOOTLOADER_ID;
133 sprintf( (char *)rec->data, name);
134 rec->size = sizeof(struct bi_record) + strlen(name) + 1;
135 rec = (struct bi_record *)((unsigned long)rec + rec->size);
136
137 rec->tag = BI_MACHTYPE;
138 rec->data[0] = mach;
139 rec->data[1] = 1;
140 rec->size = sizeof(struct bi_record) + 2 * sizeof(unsigned long);
141 rec = (struct bi_record *)((unsigned long)rec + rec->size);
142
143 rec->tag = BI_LAST;
144 rec->size = sizeof(struct bi_record);
145 rec = (struct bi_record *)((unsigned long)rec + rec->size);
146}
diff --git a/arch/ppc/boot/openfirmware/dummy.c b/arch/ppc/boot/openfirmware/dummy.c
deleted file mode 100644
index 31dbf45bf99c..000000000000
--- a/arch/ppc/boot/openfirmware/dummy.c
+++ /dev/null
@@ -1,4 +0,0 @@
1int main(void)
2{
3 return 0;
4}
diff --git a/arch/ppc/boot/openfirmware/misc.S b/arch/ppc/boot/openfirmware/misc.S
deleted file mode 100644
index ab9e897cadd0..000000000000
--- a/arch/ppc/boot/openfirmware/misc.S
+++ /dev/null
@@ -1,67 +0,0 @@
1/*
2 * Copyright (C) Paul Mackerras 1997.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version
7 * 2 of the License, or (at your option) any later version.
8 */
9 .text
10
11/*
12 * Use the BAT2 & 3 registers to map the 1st 16MB of RAM to
13 * the address given as the 1st argument.
14 */
15 .globl setup_bats
16setup_bats:
17 mfpvr 5
18 rlwinm 5,5,16,16,31 /* r3 = 1 for 601, 4 for 604 */
19 cmpwi 0,5,1
20 li 0,0
21 bne 4f
22 mtibatl 3,0 /* invalidate BAT first */
23 ori 3,3,4 /* set up BAT registers for 601 */
24 li 4,0x7f
25 mtibatu 2,3
26 mtibatl 2,4
27 oris 3,3,0x80
28 oris 4,4,0x80
29 mtibatu 3,3
30 mtibatl 3,4
31 b 5f
324: mtdbatu 3,0 /* invalidate BATs first */
33 mtibatu 3,0
34 ori 3,3,0xff /* set up BAT registers for 604 */
35 li 4,2
36 mtdbatl 2,4
37 mtdbatu 2,3
38 mtibatl 2,4
39 mtibatu 2,3
40 oris 3,3,0x80
41 oris 4,4,0x80
42 mtdbatl 3,4
43 mtdbatu 3,3
44 mtibatl 3,4
45 mtibatu 3,3
465: sync
47 isync
48 blr
49
50/*
51 * Flush the dcache and invalidate the icache for a range of addresses.
52 *
53 * flush_cache(addr, len)
54 */
55 .global flush_cache
56flush_cache:
57 addi 4,4,0x1f /* len = (len + 0x1f) / 0x20 */
58 rlwinm. 4,4,27,5,31
59 mtctr 4
60 beqlr
611: dcbf 0,3
62 icbi 0,3
63 addi 3,3,0x20
64 bdnz 1b
65 sync
66 isync
67 blr
diff --git a/arch/ppc/boot/openfirmware/start.c b/arch/ppc/boot/openfirmware/start.c
deleted file mode 100644
index 1617a26956bf..000000000000
--- a/arch/ppc/boot/openfirmware/start.c
+++ /dev/null
@@ -1,172 +0,0 @@
1/*
2 * Copyright (C) Paul Mackerras 1997.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version
7 * 2 of the License, or (at your option) any later version.
8 */
9#include <stdarg.h>
10#include "of1275.h"
11
12extern int strlen(const char *s);
13extern void boot(int a1, int a2, void *prom);
14
15phandle stdin;
16phandle stdout;
17phandle stderr;
18
19void printk(char *fmt, ...);
20
21void
22start(int a1, int a2, void *promptr)
23{
24 ofinit(promptr);
25 if (ofstdio(&stdin, &stdout, &stderr))
26 exit();
27
28 boot(a1, a2, promptr);
29 for (;;)
30 exit();
31}
32
33int writestring(void *f, char *ptr, int nb)
34{
35 int w = 0, i;
36 char *ret = "\r";
37
38 for (i = 0; i < nb; ++i) {
39 if (ptr[i] == '\n') {
40 if (i > w) {
41 write(f, ptr + w, i - w);
42 w = i;
43 }
44 write(f, ret, 1);
45 }
46 }
47 if (w < nb)
48 write(f, ptr + w, nb - w);
49 return nb;
50}
51
52int
53putc(int c, void *f)
54{
55 char ch = c;
56
57 return writestring(f, &ch, 1) == 1? c: -1;
58}
59
60int
61putchar(int c)
62{
63 return putc(c, stdout);
64}
65
66int
67fputs(char *str, void *f)
68{
69 int n = strlen(str);
70
71 return writestring(f, str, n) == n? 0: -1;
72}
73
74int
75readchar(void)
76{
77 char ch;
78
79 for (;;) {
80 switch (read(stdin, &ch, 1)) {
81 case 1:
82 return ch;
83 case -1:
84 printk("read(stdin) returned -1\n");
85 return -1;
86 }
87 }
88}
89
90static char line[256];
91static char *lineptr;
92static int lineleft;
93
94int
95getchar(void)
96{
97 int c;
98
99 if (lineleft == 0) {
100 lineptr = line;
101 for (;;) {
102 c = readchar();
103 if (c == -1 || c == 4)
104 break;
105 if (c == '\r' || c == '\n') {
106 *lineptr++ = '\n';
107 putchar('\n');
108 break;
109 }
110 switch (c) {
111 case 0177:
112 case '\b':
113 if (lineptr > line) {
114 putchar('\b');
115 putchar(' ');
116 putchar('\b');
117 --lineptr;
118 }
119 break;
120 case 'U' & 0x1F:
121 while (lineptr > line) {
122 putchar('\b');
123 putchar(' ');
124 putchar('\b');
125 --lineptr;
126 }
127 break;
128 default:
129 if (lineptr >= &line[sizeof(line) - 1])
130 putchar('\a');
131 else {
132 putchar(c);
133 *lineptr++ = c;
134 }
135 }
136 }
137 lineleft = lineptr - line;
138 lineptr = line;
139 }
140 if (lineleft == 0)
141 return -1;
142 --lineleft;
143 return *lineptr++;
144}
145
146extern int vsprintf(char *buf, const char *fmt, va_list args);
147static char sprint_buf[1024];
148
149void
150printk(char *fmt, ...)
151{
152 va_list args;
153 int n;
154
155 va_start(args, fmt);
156 n = vsprintf(sprint_buf, fmt, args);
157 va_end(args);
158 writestring(stdout, sprint_buf, n);
159}
160
161int
162printf(char *fmt, ...)
163{
164 va_list args;
165 int n;
166
167 va_start(args, fmt);
168 n = vsprintf(sprint_buf, fmt, args);
169 va_end(args);
170 writestring(stdout, sprint_buf, n);
171 return n;
172}
diff --git a/arch/ppc/boot/simple/mpc10x_memory.c b/arch/ppc/boot/simple/mpc10x_memory.c
index c24290823f7f..8da8f576031d 100644
--- a/arch/ppc/boot/simple/mpc10x_memory.c
+++ b/arch/ppc/boot/simple/mpc10x_memory.c
@@ -50,10 +50,10 @@ MPC10X_PCI_OP(read, dword, u32 *, in_le32, 0)
50 * the system. This assumes that the firmware has correctly set up the memory 50 * the system. This assumes that the firmware has correctly set up the memory
51 * controller registers. On CONFIG_PPC_PREP, we know we are being called 51 * controller registers. On CONFIG_PPC_PREP, we know we are being called
52 * under a PReP memory map. On all other machines, we assume we are under 52 * under a PReP memory map. On all other machines, we assume we are under
53 * a CHRP memory map. Further, on CONFIG_PPC_MULTIPLATFORM we must rename 53 * a CHRP memory map. Further, on CONFIG_PPC_PREP we must rename
54 * this function. 54 * this function.
55 */ 55 */
56#ifdef CONFIG_PPC_MULTIPLATFORM 56#ifdef CONFIG_PPC_PREP
57#define get_mem_size mpc10x_get_mem_size 57#define get_mem_size mpc10x_get_mem_size
58#endif 58#endif
59unsigned long 59unsigned long
diff --git a/arch/ppc/boot/simple/relocate.S b/arch/ppc/boot/simple/relocate.S
index 7efddc507564..2533113c1cc5 100644
--- a/arch/ppc/boot/simple/relocate.S
+++ b/arch/ppc/boot/simple/relocate.S
@@ -194,7 +194,7 @@ start_ldr:
194 /* 194 /*
195 * Start at the begining. 195 * Start at the begining.
196 */ 196 */
197#ifdef CONFIG_PPC_MULTIPLATFORM 197#ifdef CONFIG_PPC_PREP
198 li r9,0xc 198 li r9,0xc
199 mtlr r9 199 mtlr r9
200 /* tell kernel we're prep, by putting 0xdeadc0de at KERNELLOAD, 200 /* tell kernel we're prep, by putting 0xdeadc0de at KERNELLOAD,
diff --git a/arch/ppc/boot/utils/addnote.c b/arch/ppc/boot/utils/addnote.c
deleted file mode 100644
index 6c52b18f2d04..000000000000
--- a/arch/ppc/boot/utils/addnote.c
+++ /dev/null
@@ -1,175 +0,0 @@
1/*
2 * Program to hack in a PT_NOTE program header entry in an ELF file.
3 * This is needed for OF on RS/6000s to load an image correctly.
4 * Note that OF needs a program header entry for the note, not an
5 * ELF section.
6 *
7 * Copyright 2000 Paul Mackerras.
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * as published by the Free Software Foundation; either version
12 * 2 of the License, or (at your option) any later version.
13 *
14 * Usage: addnote zImage
15 */
16#include <stdio.h>
17#include <stdlib.h>
18#include <fcntl.h>
19#include <unistd.h>
20#include <string.h>
21
22char arch[] = "PowerPC";
23
24#define N_DESCR 6
25unsigned int descr[N_DESCR] = {
26#if 1
27 /* values for IBM RS/6000 machines */
28 0xffffffff, /* real-mode = true */
29 0x00c00000, /* real-base, i.e. where we expect OF to be */
30 0xffffffff, /* real-size */
31 0xffffffff, /* virt-base */
32 0xffffffff, /* virt-size */
33 0x4000, /* load-base */
34#else
35 /* values for longtrail CHRP */
36 0, /* real-mode = false */
37 0xffffffff, /* real-base */
38 0xffffffff, /* real-size */
39 0xffffffff, /* virt-base */
40 0xffffffff, /* virt-size */
41 0x00600000, /* load-base */
42#endif
43};
44
45unsigned char buf[512];
46
47#define GET_16BE(off) ((buf[off] << 8) + (buf[(off)+1]))
48#define GET_32BE(off) ((GET_16BE(off) << 16) + GET_16BE((off)+2))
49
50#define PUT_16BE(off, v) (buf[off] = ((v) >> 8) & 0xff, \
51 buf[(off) + 1] = (v) & 0xff)
52#define PUT_32BE(off, v) (PUT_16BE((off), (v) >> 16), \
53 PUT_16BE((off) + 2, (v)))
54
55/* Structure of an ELF file */
56#define E_IDENT 0 /* ELF header */
57#define E_PHOFF 28
58#define E_PHENTSIZE 42
59#define E_PHNUM 44
60#define E_HSIZE 52 /* size of ELF header */
61
62#define EI_MAGIC 0 /* offsets in E_IDENT area */
63#define EI_CLASS 4
64#define EI_DATA 5
65
66#define PH_TYPE 0 /* ELF program header */
67#define PH_OFFSET 4
68#define PH_FILESZ 16
69#define PH_HSIZE 32 /* size of program header */
70
71#define PT_NOTE 4 /* Program header type = note */
72
73#define ELFCLASS32 1
74#define ELFDATA2MSB 2
75
76unsigned char elf_magic[4] = { 0x7f, 'E', 'L', 'F' };
77
78int main(int ac, char **av)
79{
80 int fd, n, i;
81 int ph, ps, np;
82 int nnote, ns;
83
84 if (ac != 2) {
85 fprintf(stderr, "Usage: %s elf-file\n", av[0]);
86 exit(1);
87 }
88 fd = open(av[1], O_RDWR);
89 if (fd < 0) {
90 perror(av[1]);
91 exit(1);
92 }
93
94 nnote = strlen(arch) + 1 + (N_DESCR + 3) * 4;
95
96 n = read(fd, buf, sizeof(buf));
97 if (n < 0) {
98 perror("read");
99 exit(1);
100 }
101
102 if (n < E_HSIZE || memcmp(&buf[E_IDENT+EI_MAGIC], elf_magic, 4) != 0)
103 goto notelf;
104
105 if (buf[E_IDENT+EI_CLASS] != ELFCLASS32
106 || buf[E_IDENT+EI_DATA] != ELFDATA2MSB) {
107 fprintf(stderr, "%s is not a big-endian 32-bit ELF image\n",
108 av[1]);
109 exit(1);
110 }
111
112 ph = GET_32BE(E_PHOFF);
113 ps = GET_16BE(E_PHENTSIZE);
114 np = GET_16BE(E_PHNUM);
115 if (ph < E_HSIZE || ps < PH_HSIZE || np < 1)
116 goto notelf;
117 if (ph + (np + 1) * ps + nnote > n)
118 goto nospace;
119
120 for (i = 0; i < np; ++i) {
121 if (GET_32BE(ph + PH_TYPE) == PT_NOTE) {
122 fprintf(stderr, "%s already has a note entry\n",
123 av[1]);
124 exit(0);
125 }
126 ph += ps;
127 }
128
129 /* XXX check that the area we want to use is all zeroes */
130 for (i = 0; i < ps + nnote; ++i)
131 if (buf[ph + i] != 0)
132 goto nospace;
133
134 /* fill in the program header entry */
135 ns = ph + ps;
136 PUT_32BE(ph + PH_TYPE, PT_NOTE);
137 PUT_32BE(ph + PH_OFFSET, ns);
138 PUT_32BE(ph + PH_FILESZ, nnote);
139
140 /* fill in the note area we point to */
141 /* XXX we should probably make this a proper section */
142 PUT_32BE(ns, strlen(arch) + 1);
143 PUT_32BE(ns + 4, N_DESCR * 4);
144 PUT_32BE(ns + 8, 0x1275);
145 strcpy(&buf[ns + 12], arch);
146 ns += 12 + strlen(arch) + 1;
147 for (i = 0; i < N_DESCR; ++i)
148 PUT_32BE(ns + i * 4, descr[i]);
149
150 /* Update the number of program headers */
151 PUT_16BE(E_PHNUM, np + 1);
152
153 /* write back */
154 lseek(fd, (long) 0, SEEK_SET);
155 i = write(fd, buf, n);
156 if (i < 0) {
157 perror("write");
158 exit(1);
159 }
160 if (i < n) {
161 fprintf(stderr, "%s: write truncated\n", av[1]);
162 exit(1);
163 }
164
165 exit(0);
166
167 notelf:
168 fprintf(stderr, "%s does not appear to be an ELF file\n", av[0]);
169 exit(1);
170
171 nospace:
172 fprintf(stderr, "sorry, I can't find space in %s to put the note\n",
173 av[0]);
174 exit(1);
175}
diff --git a/arch/ppc/boot/utils/hack-coff.c b/arch/ppc/boot/utils/hack-coff.c
deleted file mode 100644
index 5e5a6573a1ef..000000000000
--- a/arch/ppc/boot/utils/hack-coff.c
+++ /dev/null
@@ -1,84 +0,0 @@
1/*
2 * hack-coff.c - hack the header of an xcoff file to fill in
3 * a few fields needed by the Open Firmware xcoff loader on
4 * Power Macs but not initialized by objcopy.
5 *
6 * Copyright (C) Paul Mackerras 1997.
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version
11 * 2 of the License, or (at your option) any later version.
12 */
13#include <stdio.h>
14#include <stdlib.h>
15#include <unistd.h>
16#include <fcntl.h>
17#include <string.h>
18#include "rs6000.h"
19
20#define AOUT_MAGIC 0x010b
21
22#define get_16be(x) ((((unsigned char *)(x))[0] << 8) \
23 + ((unsigned char *)(x))[1])
24#define put_16be(x, v) (((unsigned char *)(x))[0] = (v) >> 8, \
25 ((unsigned char *)(x))[1] = (v) & 0xff)
26#define get_32be(x) ((((unsigned char *)(x))[0] << 24) \
27 + (((unsigned char *)(x))[1] << 16) \
28 + (((unsigned char *)(x))[2] << 8) \
29 + ((unsigned char *)(x))[3])
30
31int
32main(int ac, char **av)
33{
34 int fd;
35 int i, nsect;
36 int aoutsz;
37 struct external_filehdr fhdr;
38 AOUTHDR aout;
39 struct external_scnhdr shdr;
40
41 if (ac != 2) {
42 fprintf(stderr, "Usage: hack-coff coff-file\n");
43 exit(1);
44 }
45 if ((fd = open(av[1], 2)) == -1) {
46 perror(av[2]);
47 exit(1);
48 }
49 if (read(fd, &fhdr, sizeof(fhdr)) != sizeof(fhdr))
50 goto readerr;
51 i = get_16be(fhdr.f_magic);
52 if (i != U802TOCMAGIC && i != U802WRMAGIC && i != U802ROMAGIC) {
53 fprintf(stderr, "%s: not an xcoff file\n", av[1]);
54 exit(1);
55 }
56 aoutsz = get_16be(fhdr.f_opthdr);
57 if (read(fd, &aout, aoutsz) != aoutsz)
58 goto readerr;
59 nsect = get_16be(fhdr.f_nscns);
60 for (i = 0; i < nsect; ++i) {
61 if (read(fd, &shdr, sizeof(shdr)) != sizeof(shdr))
62 goto readerr;
63 if (strcmp(shdr.s_name, ".text") == 0) {
64 put_16be(aout.o_snentry, i+1);
65 put_16be(aout.o_sntext, i+1);
66 } else if (strcmp(shdr.s_name, ".data") == 0) {
67 put_16be(aout.o_sndata, i+1);
68 } else if (strcmp(shdr.s_name, ".bss") == 0) {
69 put_16be(aout.o_snbss, i+1);
70 }
71 }
72 put_16be(aout.magic, AOUT_MAGIC);
73 if (lseek(fd, (long) sizeof(struct external_filehdr), 0) == -1
74 || write(fd, &aout, aoutsz) != aoutsz) {
75 fprintf(stderr, "%s: write error\n", av[1]);
76 exit(1);
77 }
78 close(fd);
79 exit(0);
80
81readerr:
82 fprintf(stderr, "%s: read error or file too short\n", av[1]);
83 exit(1);
84}
diff --git a/arch/ppc/boot/utils/mknote.c b/arch/ppc/boot/utils/mknote.c
deleted file mode 100644
index b9fbb2cbfc8f..000000000000
--- a/arch/ppc/boot/utils/mknote.c
+++ /dev/null
@@ -1,44 +0,0 @@
1/*
2 * Copyright (C) Cort Dougan 1999.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version
7 * 2 of the License, or (at your option) any later version.
8 *
9 * Generate a note section as per the CHRP specification.
10 *
11 */
12
13#include <stdio.h>
14#include <string.h>
15
16#define PL(x) printf("%c%c%c%c", ((x)>>24)&0xff, ((x)>>16)&0xff, ((x)>>8)&0xff, (x)&0xff );
17
18int main(void)
19{
20/* header */
21 /* namesz */
22 PL(strlen("PowerPC")+1);
23 /* descrsz */
24 PL(6*4);
25 /* type */
26 PL(0x1275);
27 /* name */
28 printf("PowerPC"); printf("%c", 0);
29
30/* descriptor */
31 /* real-mode */
32 PL(0xffffffff);
33 /* real-base */
34 PL(0x00c00000);
35 /* real-size */
36 PL(0xffffffff);
37 /* virt-base */
38 PL(0xffffffff);
39 /* virt-size */
40 PL(0xffffffff);
41 /* load-base */
42 PL(0x4000);
43 return 0;
44}
diff --git a/arch/ppc/configs/ibmchrp_defconfig b/arch/ppc/configs/ibmchrp_defconfig
deleted file mode 100644
index 27f3e69c1f96..000000000000
--- a/arch/ppc/configs/ibmchrp_defconfig
+++ /dev/null
@@ -1,875 +0,0 @@
1#
2# Automatically generated make config: don't edit
3#
4CONFIG_MMU=y
5CONFIG_RWSEM_XCHGADD_ALGORITHM=y
6CONFIG_HAVE_DEC_LOCK=y
7CONFIG_PPC=y
8CONFIG_PPC32=y
9CONFIG_GENERIC_NVRAM=y
10
11#
12# Code maturity level options
13#
14CONFIG_EXPERIMENTAL=y
15CONFIG_CLEAN_COMPILE=y
16# CONFIG_STANDALONE is not set
17CONFIG_BROKEN_ON_SMP=y
18
19#
20# General setup
21#
22CONFIG_SWAP=y
23CONFIG_SYSVIPC=y
24CONFIG_POSIX_MQUEUE=y
25# CONFIG_BSD_PROCESS_ACCT is not set
26CONFIG_SYSCTL=y
27# CONFIG_AUDIT is not set
28CONFIG_LOG_BUF_SHIFT=14
29# CONFIG_HOTPLUG is not set
30CONFIG_IKCONFIG=y
31CONFIG_IKCONFIG_PROC=y
32# CONFIG_EMBEDDED is not set
33CONFIG_KALLSYMS=y
34CONFIG_FUTEX=y
35CONFIG_EPOLL=y
36CONFIG_IOSCHED_NOOP=y
37CONFIG_IOSCHED_AS=y
38CONFIG_IOSCHED_DEADLINE=y
39CONFIG_IOSCHED_CFQ=y
40# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
41
42#
43# Loadable module support
44#
45CONFIG_MODULES=y
46CONFIG_MODULE_UNLOAD=y
47CONFIG_MODULE_FORCE_UNLOAD=y
48CONFIG_OBSOLETE_MODPARM=y
49# CONFIG_MODVERSIONS is not set
50CONFIG_KMOD=y
51
52#
53# Processor
54#
55CONFIG_6xx=y
56# CONFIG_40x is not set
57# CONFIG_44x is not set
58# CONFIG_POWER3 is not set
59# CONFIG_POWER4 is not set
60# CONFIG_8xx is not set
61# CONFIG_ALTIVEC is not set
62# CONFIG_TAU is not set
63# CONFIG_CPU_FREQ is not set
64# CONFIG_PPC601_SYNC_FIX is not set
65CONFIG_PPC_STD_MMU=y
66
67#
68# Platform options
69#
70CONFIG_PPC_MULTIPLATFORM=y
71# CONFIG_APUS is not set
72# CONFIG_WILLOW is not set
73# CONFIG_PCORE is not set
74# CONFIG_POWERPMC250 is not set
75# CONFIG_EV64260 is not set
76# CONFIG_SPRUCE is not set
77# CONFIG_LOPEC is not set
78# CONFIG_MCPN765 is not set
79# CONFIG_MVME5100 is not set
80# CONFIG_PPLUS is not set
81# CONFIG_PRPMC750 is not set
82# CONFIG_PRPMC800 is not set
83# CONFIG_SANDPOINT is not set
84# CONFIG_ADIR is not set
85# CONFIG_K2 is not set
86# CONFIG_PAL4 is not set
87# CONFIG_GEMINI is not set
88# CONFIG_EST8260 is not set
89# CONFIG_SBS8260 is not set
90# CONFIG_RPX6 is not set
91# CONFIG_TQM8260 is not set
92CONFIG_PPC_CHRP=y
93CONFIG_PPC_PMAC=y
94CONFIG_PPC_PREP=y
95CONFIG_PPC_OF=y
96CONFIG_PPCBUG_NVRAM=y
97# CONFIG_SMP is not set
98# CONFIG_PREEMPT is not set
99CONFIG_HIGHMEM=y
100CONFIG_KERNEL_ELF=y
101CONFIG_BINFMT_ELF=y
102CONFIG_BINFMT_MISC=y
103CONFIG_PROC_DEVICETREE=y
104CONFIG_PPC_RTAS=y
105# CONFIG_PREP_RESIDUAL is not set
106# CONFIG_CMDLINE_BOOL is not set
107
108#
109# Bus options
110#
111CONFIG_ISA=y
112CONFIG_GENERIC_ISA_DMA=y
113CONFIG_PCI=y
114CONFIG_PCI_DOMAINS=y
115CONFIG_PCI_LEGACY_PROC=y
116CONFIG_PCI_NAMES=y
117
118#
119# Advanced setup
120#
121# CONFIG_ADVANCED_OPTIONS is not set
122
123#
124# Default settings for advanced configuration options are used
125#
126CONFIG_HIGHMEM_START=0xfe000000
127CONFIG_LOWMEM_SIZE=0x30000000
128CONFIG_KERNEL_START=0xc0000000
129CONFIG_TASK_SIZE=0x80000000
130CONFIG_BOOT_LOAD=0x00800000
131
132#
133# Device Drivers
134#
135
136#
137# Generic Driver Options
138#
139
140#
141# Memory Technology Devices (MTD)
142#
143# CONFIG_MTD is not set
144
145#
146# Parallel port support
147#
148# CONFIG_PARPORT is not set
149
150#
151# Plug and Play support
152#
153# CONFIG_PNP is not set
154
155#
156# Block devices
157#
158CONFIG_BLK_DEV_FD=y
159# CONFIG_BLK_DEV_XD is not set
160# CONFIG_BLK_CPQ_DA is not set
161# CONFIG_BLK_CPQ_CISS_DA is not set
162# CONFIG_BLK_DEV_DAC960 is not set
163# CONFIG_BLK_DEV_UMEM is not set
164CONFIG_BLK_DEV_LOOP=y
165# CONFIG_BLK_DEV_CRYPTOLOOP is not set
166# CONFIG_BLK_DEV_NBD is not set
167# CONFIG_BLK_DEV_CARMEL is not set
168CONFIG_BLK_DEV_RAM=y
169CONFIG_BLK_DEV_RAM_SIZE=4096
170CONFIG_BLK_DEV_INITRD=y
171CONFIG_LBD=y
172
173#
174# ATA/ATAPI/MFM/RLL support
175#
176# CONFIG_IDE is not set
177
178#
179# SCSI device support
180#
181CONFIG_SCSI=y
182CONFIG_SCSI_PROC_FS=y
183
184#
185# SCSI support type (disk, tape, CD-ROM)
186#
187CONFIG_BLK_DEV_SD=y
188CONFIG_CHR_DEV_ST=y
189# CONFIG_CHR_DEV_OSST is not set
190CONFIG_BLK_DEV_SR=y
191CONFIG_BLK_DEV_SR_VENDOR=y
192CONFIG_CHR_DEV_SG=y
193
194#
195# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
196#
197# CONFIG_SCSI_MULTI_LUN is not set
198# CONFIG_SCSI_REPORT_LUNS is not set
199CONFIG_SCSI_CONSTANTS=y
200# CONFIG_SCSI_LOGGING is not set
201
202#
203# SCSI Transport Attributes
204#
205CONFIG_SCSI_SPI_ATTRS=y
206# CONFIG_SCSI_FC_ATTRS is not set
207
208#
209# SCSI low-level drivers
210#
211# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
212# CONFIG_SCSI_7000FASST is not set
213# CONFIG_SCSI_ACARD is not set
214# CONFIG_SCSI_AHA152X is not set
215# CONFIG_SCSI_AHA1542 is not set
216# CONFIG_SCSI_AACRAID is not set
217# CONFIG_SCSI_AIC7XXX is not set
218# CONFIG_SCSI_AIC7XXX_OLD is not set
219# CONFIG_SCSI_AIC79XX is not set
220# CONFIG_SCSI_ADVANSYS is not set
221# CONFIG_SCSI_IN2000 is not set
222# CONFIG_SCSI_MEGARAID is not set
223# CONFIG_SCSI_SATA is not set
224# CONFIG_SCSI_BUSLOGIC is not set
225# CONFIG_SCSI_CPQFCTS is not set
226# CONFIG_SCSI_DMX3191D is not set
227# CONFIG_SCSI_DTC3280 is not set
228# CONFIG_SCSI_EATA is not set
229# CONFIG_SCSI_EATA_PIO is not set
230# CONFIG_SCSI_FUTURE_DOMAIN is not set
231# CONFIG_SCSI_GDTH is not set
232# CONFIG_SCSI_GENERIC_NCR5380 is not set
233# CONFIG_SCSI_GENERIC_NCR5380_MMIO is not set
234# CONFIG_SCSI_IPS is not set
235# CONFIG_SCSI_INIA100 is not set
236# CONFIG_SCSI_NCR53C406A is not set
237CONFIG_SCSI_SYM53C8XX_2=y
238CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=0
239CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16
240CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64
241# CONFIG_SCSI_SYM53C8XX_IOMAPPED is not set
242# CONFIG_SCSI_IPR is not set
243# CONFIG_SCSI_PAS16 is not set
244# CONFIG_SCSI_PSI240I is not set
245# CONFIG_SCSI_QLOGIC_FAS is not set
246# CONFIG_SCSI_QLOGIC_ISP is not set
247# CONFIG_SCSI_QLOGIC_FC is not set
248# CONFIG_SCSI_QLOGIC_1280 is not set
249CONFIG_SCSI_QLA2XXX=y
250# CONFIG_SCSI_QLA21XX is not set
251# CONFIG_SCSI_QLA22XX is not set
252# CONFIG_SCSI_QLA2300 is not set
253# CONFIG_SCSI_QLA2322 is not set
254# CONFIG_SCSI_QLA6312 is not set
255# CONFIG_SCSI_QLA6322 is not set
256# CONFIG_SCSI_SYM53C416 is not set
257# CONFIG_SCSI_DC395x is not set
258# CONFIG_SCSI_DC390T is not set
259# CONFIG_SCSI_T128 is not set
260# CONFIG_SCSI_U14_34F is not set
261# CONFIG_SCSI_NSP32 is not set
262# CONFIG_SCSI_DEBUG is not set
263# CONFIG_SCSI_MESH is not set
264# CONFIG_SCSI_MAC53C94 is not set
265
266#
267# Old CD-ROM drivers (not SCSI, not IDE)
268#
269# CONFIG_CD_NO_IDESCSI is not set
270
271#
272# Multi-device support (RAID and LVM)
273#
274# CONFIG_MD is not set
275
276#
277# Fusion MPT device support
278#
279# CONFIG_FUSION is not set
280
281#
282# IEEE 1394 (FireWire) support
283#
284# CONFIG_IEEE1394 is not set
285
286#
287# I2O device support
288#
289# CONFIG_I2O is not set
290
291#
292# Macintosh device drivers
293#
294# CONFIG_ADB is not set
295# CONFIG_ADB_CUDA is not set
296# CONFIG_ADB_PMU is not set
297# CONFIG_MAC_FLOPPY is not set
298# CONFIG_MAC_SERIAL is not set
299
300#
301# Networking support
302#
303CONFIG_NET=y
304
305#
306# Networking options
307#
308CONFIG_PACKET=y
309# CONFIG_PACKET_MMAP is not set
310# CONFIG_NETLINK_DEV is not set
311CONFIG_UNIX=y
312# CONFIG_NET_KEY is not set
313CONFIG_INET=y
314CONFIG_IP_MULTICAST=y
315# CONFIG_IP_ADVANCED_ROUTER is not set
316# CONFIG_IP_PNP is not set
317# CONFIG_NET_IPIP is not set
318# CONFIG_NET_IPGRE is not set
319# CONFIG_IP_MROUTE is not set
320# CONFIG_ARPD is not set
321CONFIG_SYN_COOKIES=y
322# CONFIG_INET_AH is not set
323# CONFIG_INET_ESP is not set
324# CONFIG_INET_IPCOMP is not set
325
326#
327# IP: Virtual Server Configuration
328#
329# CONFIG_IP_VS is not set
330# CONFIG_IPV6 is not set
331CONFIG_NETFILTER=y
332# CONFIG_NETFILTER_DEBUG is not set
333
334#
335# IP: Netfilter Configuration
336#
337CONFIG_IP_NF_CONNTRACK=m
338CONFIG_IP_NF_FTP=m
339CONFIG_IP_NF_IRC=m
340CONFIG_IP_NF_TFTP=m
341CONFIG_IP_NF_AMANDA=m
342# CONFIG_IP_NF_QUEUE is not set
343CONFIG_IP_NF_IPTABLES=m
344CONFIG_IP_NF_MATCH_LIMIT=m
345CONFIG_IP_NF_MATCH_IPRANGE=m
346CONFIG_IP_NF_MATCH_MAC=m
347# CONFIG_IP_NF_MATCH_PKTTYPE is not set
348CONFIG_IP_NF_MATCH_MARK=m
349CONFIG_IP_NF_MATCH_MULTIPORT=m
350CONFIG_IP_NF_MATCH_TOS=m
351CONFIG_IP_NF_MATCH_RECENT=m
352CONFIG_IP_NF_MATCH_ECN=m
353CONFIG_IP_NF_MATCH_DSCP=m
354CONFIG_IP_NF_MATCH_AH_ESP=m
355CONFIG_IP_NF_MATCH_LENGTH=m
356CONFIG_IP_NF_MATCH_TTL=m
357CONFIG_IP_NF_MATCH_TCPMSS=m
358CONFIG_IP_NF_MATCH_HELPER=m
359CONFIG_IP_NF_MATCH_STATE=m
360CONFIG_IP_NF_MATCH_CONNTRACK=m
361CONFIG_IP_NF_MATCH_OWNER=m
362CONFIG_IP_NF_FILTER=m
363CONFIG_IP_NF_TARGET_REJECT=m
364CONFIG_IP_NF_NAT=m
365CONFIG_IP_NF_NAT_NEEDED=y
366CONFIG_IP_NF_TARGET_MASQUERADE=m
367CONFIG_IP_NF_TARGET_REDIRECT=m
368CONFIG_IP_NF_TARGET_NETMAP=m
369CONFIG_IP_NF_TARGET_SAME=m
370CONFIG_IP_NF_NAT_SNMP_BASIC=m
371CONFIG_IP_NF_NAT_IRC=m
372CONFIG_IP_NF_NAT_FTP=m
373CONFIG_IP_NF_NAT_TFTP=m
374CONFIG_IP_NF_NAT_AMANDA=m
375# CONFIG_IP_NF_MANGLE is not set
376# CONFIG_IP_NF_TARGET_LOG is not set
377CONFIG_IP_NF_TARGET_ULOG=m
378CONFIG_IP_NF_TARGET_TCPMSS=m
379CONFIG_IP_NF_ARPTABLES=m
380CONFIG_IP_NF_ARPFILTER=m
381CONFIG_IP_NF_ARP_MANGLE=m
382CONFIG_IP_NF_COMPAT_IPCHAINS=m
383# CONFIG_IP_NF_COMPAT_IPFWADM is not set
384CONFIG_IP_NF_TARGET_NOTRACK=m
385CONFIG_IP_NF_RAW=m
386
387#
388# SCTP Configuration (EXPERIMENTAL)
389#
390# CONFIG_IP_SCTP is not set
391# CONFIG_ATM is not set
392# CONFIG_BRIDGE is not set
393# CONFIG_VLAN_8021Q is not set
394# CONFIG_DECNET is not set
395# CONFIG_LLC2 is not set
396# CONFIG_IPX is not set
397# CONFIG_ATALK is not set
398# CONFIG_X25 is not set
399# CONFIG_LAPB is not set
400# CONFIG_NET_DIVERT is not set
401# CONFIG_ECONET is not set
402# CONFIG_WAN_ROUTER is not set
403# CONFIG_NET_HW_FLOWCONTROL is not set
404
405#
406# QoS and/or fair queueing
407#
408# CONFIG_NET_SCHED is not set
409
410#
411# Network testing
412#
413# CONFIG_NET_PKTGEN is not set
414# CONFIG_NETPOLL is not set
415# CONFIG_NET_POLL_CONTROLLER is not set
416# CONFIG_HAMRADIO is not set
417# CONFIG_IRDA is not set
418# CONFIG_BT is not set
419CONFIG_NETDEVICES=y
420# CONFIG_DUMMY is not set
421# CONFIG_BONDING is not set
422# CONFIG_EQUALIZER is not set
423# CONFIG_TUN is not set
424
425#
426# ARCnet devices
427#
428# CONFIG_ARCNET is not set
429
430#
431# Ethernet (10 or 100Mbit)
432#
433CONFIG_NET_ETHERNET=y
434CONFIG_MII=y
435# CONFIG_MACE is not set
436# CONFIG_BMAC is not set
437# CONFIG_OAKNET is not set
438# CONFIG_HAPPYMEAL is not set
439# CONFIG_SUNGEM is not set
440# CONFIG_NET_VENDOR_3COM is not set
441# CONFIG_LANCE is not set
442# CONFIG_NET_VENDOR_SMC is not set
443# CONFIG_NET_VENDOR_RACAL is not set
444
445#
446# Tulip family network device support
447#
448# CONFIG_NET_TULIP is not set
449# CONFIG_AT1700 is not set
450# CONFIG_DEPCA is not set
451# CONFIG_HP100 is not set
452# CONFIG_NET_ISA is not set
453CONFIG_NET_PCI=y
454CONFIG_PCNET32=y
455# CONFIG_AMD8111_ETH is not set
456# CONFIG_ADAPTEC_STARFIRE is not set
457# CONFIG_AC3200 is not set
458# CONFIG_APRICOT is not set
459# CONFIG_B44 is not set
460# CONFIG_FORCEDETH is not set
461# CONFIG_CS89x0 is not set
462# CONFIG_DGRS is not set
463# CONFIG_EEPRO100 is not set
464# CONFIG_E100 is not set
465# CONFIG_FEALNX is not set
466# CONFIG_NATSEMI is not set
467# CONFIG_NE2K_PCI is not set
468# CONFIG_8139CP is not set
469# CONFIG_8139TOO is not set
470# CONFIG_SIS900 is not set
471# CONFIG_EPIC100 is not set
472# CONFIG_SUNDANCE is not set
473# CONFIG_TLAN is not set
474# CONFIG_VIA_RHINE is not set
475# CONFIG_NET_POCKET is not set
476
477#
478# Ethernet (1000 Mbit)
479#
480# CONFIG_ACENIC is not set
481# CONFIG_DL2K is not set
482# CONFIG_E1000 is not set
483# CONFIG_NS83820 is not set
484# CONFIG_HAMACHI is not set
485# CONFIG_YELLOWFIN is not set
486# CONFIG_R8169 is not set
487# CONFIG_SK98LIN is not set
488# CONFIG_TIGON3 is not set
489
490#
491# Ethernet (10000 Mbit)
492#
493# CONFIG_IXGB is not set
494# CONFIG_S2IO is not set
495
496#
497# Token Ring devices
498#
499# CONFIG_TR is not set
500
501#
502# Wireless LAN (non-hamradio)
503#
504# CONFIG_NET_RADIO is not set
505
506#
507# Wan interfaces
508#
509# CONFIG_WAN is not set
510# CONFIG_FDDI is not set
511# CONFIG_HIPPI is not set
512# CONFIG_PPP is not set
513# CONFIG_SLIP is not set
514# CONFIG_NET_FC is not set
515# CONFIG_RCPCI is not set
516# CONFIG_SHAPER is not set
517# CONFIG_NETCONSOLE is not set
518
519#
520# ISDN subsystem
521#
522# CONFIG_ISDN is not set
523
524#
525# Telephony Support
526#
527# CONFIG_PHONE is not set
528
529#
530# Input device support
531#
532CONFIG_INPUT=y
533
534#
535# Userland interfaces
536#
537CONFIG_INPUT_MOUSEDEV=y
538CONFIG_INPUT_MOUSEDEV_PSAUX=y
539CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
540CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
541# CONFIG_INPUT_JOYDEV is not set
542# CONFIG_INPUT_TSDEV is not set
543CONFIG_INPUT_EVDEV=y
544# CONFIG_INPUT_EVBUG is not set
545
546#
547# Input I/O drivers
548#
549# CONFIG_GAMEPORT is not set
550CONFIG_SOUND_GAMEPORT=y
551CONFIG_SERIO=y
552CONFIG_SERIO_I8042=y
553CONFIG_SERIO_SERPORT=y
554# CONFIG_SERIO_CT82C710 is not set
555# CONFIG_SERIO_PCIPS2 is not set
556
557#
558# Input Device Drivers
559#
560CONFIG_INPUT_KEYBOARD=y
561CONFIG_KEYBOARD_ATKBD=y
562# CONFIG_KEYBOARD_SUNKBD is not set
563# CONFIG_KEYBOARD_LKKBD is not set
564# CONFIG_KEYBOARD_XTKBD is not set
565# CONFIG_KEYBOARD_NEWTON is not set
566CONFIG_INPUT_MOUSE=y
567CONFIG_MOUSE_PS2=y
568# CONFIG_MOUSE_SERIAL is not set
569# CONFIG_MOUSE_INPORT is not set
570# CONFIG_MOUSE_LOGIBM is not set
571# CONFIG_MOUSE_PC110PAD is not set
572# CONFIG_MOUSE_VSXXXAA is not set
573# CONFIG_INPUT_JOYSTICK is not set
574# CONFIG_INPUT_TOUCHSCREEN is not set
575CONFIG_INPUT_MISC=y
576CONFIG_INPUT_UINPUT=y
577
578#
579# Character devices
580#
581CONFIG_VT=y
582CONFIG_VT_CONSOLE=y
583CONFIG_HW_CONSOLE=y
584# CONFIG_SERIAL_NONSTANDARD is not set
585
586#
587# Serial drivers
588#
589CONFIG_SERIAL_8250=y
590# CONFIG_SERIAL_8250_CONSOLE is not set
591CONFIG_SERIAL_8250_NR_UARTS=4
592# CONFIG_SERIAL_8250_EXTENDED is not set
593
594#
595# Non-8250 serial port support
596#
597CONFIG_SERIAL_CORE=y
598# CONFIG_SERIAL_PMACZILOG is not set
599CONFIG_UNIX98_PTYS=y
600CONFIG_LEGACY_PTYS=y
601CONFIG_LEGACY_PTY_COUNT=256
602# CONFIG_QIC02_TAPE is not set
603
604#
605# IPMI
606#
607# CONFIG_IPMI_HANDLER is not set
608
609#
610# Watchdog Cards
611#
612# CONFIG_WATCHDOG is not set
613CONFIG_NVRAM=y
614CONFIG_GEN_RTC=y
615# CONFIG_GEN_RTC_X is not set
616# CONFIG_DTLK is not set
617# CONFIG_R3964 is not set
618# CONFIG_APPLICOM is not set
619
620#
621# Ftape, the floppy tape device driver
622#
623# CONFIG_FTAPE is not set
624# CONFIG_AGP is not set
625# CONFIG_DRM is not set
626# CONFIG_RAW_DRIVER is not set
627
628#
629# I2C support
630#
631# CONFIG_I2C is not set
632
633#
634# Misc devices
635#
636
637#
638# Multimedia devices
639#
640# CONFIG_VIDEO_DEV is not set
641
642#
643# Digital Video Broadcasting Devices
644#
645# CONFIG_DVB is not set
646
647#
648# Graphics support
649#
650CONFIG_FB=y
651# CONFIG_FB_PM2 is not set
652# CONFIG_FB_CYBER2000 is not set
653CONFIG_FB_OF=y
654# CONFIG_FB_CONTROL is not set
655# CONFIG_FB_PLATINUM is not set
656# CONFIG_FB_VALKYRIE is not set
657# CONFIG_FB_CT65550 is not set
658# CONFIG_FB_IMSTT is not set
659# CONFIG_FB_S3TRIO is not set
660# CONFIG_FB_VGA16 is not set
661# CONFIG_FB_RIVA is not set
662CONFIG_FB_MATROX=y
663CONFIG_FB_MATROX_MILLENIUM=y
664CONFIG_FB_MATROX_MYSTIQUE=y
665# CONFIG_FB_MATROX_G450 is not set
666CONFIG_FB_MATROX_G100A=y
667CONFIG_FB_MATROX_G100=y
668# CONFIG_FB_MATROX_MULTIHEAD is not set
669# CONFIG_FB_RADEON_OLD is not set
670# CONFIG_FB_RADEON is not set
671# CONFIG_FB_ATY128 is not set
672# CONFIG_FB_ATY is not set
673# CONFIG_FB_SIS is not set
674# CONFIG_FB_NEOMAGIC is not set
675# CONFIG_FB_KYRO is not set
676CONFIG_FB_3DFX=y
677# CONFIG_FB_VOODOO1 is not set
678# CONFIG_FB_TRIDENT is not set
679# CONFIG_FB_VIRTUAL is not set
680
681#
682# Console display driver support
683#
684CONFIG_VGA_CONSOLE=y
685# CONFIG_MDA_CONSOLE is not set
686CONFIG_DUMMY_CONSOLE=y
687CONFIG_FRAMEBUFFER_CONSOLE=y
688CONFIG_PCI_CONSOLE=y
689# CONFIG_FONTS is not set
690CONFIG_FONT_8x8=y
691CONFIG_FONT_8x16=y
692
693#
694# Logo configuration
695#
696CONFIG_LOGO=y
697CONFIG_LOGO_LINUX_MONO=y
698CONFIG_LOGO_LINUX_VGA16=y
699CONFIG_LOGO_LINUX_CLUT224=y
700
701#
702# Sound
703#
704# CONFIG_SOUND is not set
705
706#
707# USB support
708#
709# CONFIG_USB is not set
710
711#
712# USB Gadget Support
713#
714# CONFIG_USB_GADGET is not set
715
716#
717# File systems
718#
719CONFIG_EXT2_FS=y
720# CONFIG_EXT2_FS_XATTR is not set
721# CONFIG_EXT3_FS is not set
722# CONFIG_JBD is not set
723# CONFIG_REISERFS_FS is not set
724# CONFIG_JFS_FS is not set
725# CONFIG_XFS_FS is not set
726# CONFIG_MINIX_FS is not set
727# CONFIG_ROMFS_FS is not set
728# CONFIG_QUOTA is not set
729# CONFIG_AUTOFS_FS is not set
730# CONFIG_AUTOFS4_FS is not set
731
732#
733# CD-ROM/DVD Filesystems
734#
735CONFIG_ISO9660_FS=y
736# CONFIG_JOLIET is not set
737# CONFIG_ZISOFS is not set
738# CONFIG_UDF_FS is not set
739
740#
741# DOS/FAT/NT Filesystems
742#
743CONFIG_FAT_FS=m
744CONFIG_MSDOS_FS=m
745CONFIG_VFAT_FS=m
746# CONFIG_NTFS_FS is not set
747
748#
749# Pseudo filesystems
750#
751CONFIG_PROC_FS=y
752CONFIG_PROC_KCORE=y
753CONFIG_SYSFS=y
754CONFIG_DEVFS_FS=y
755# CONFIG_DEVFS_MOUNT is not set
756# CONFIG_DEVFS_DEBUG is not set
757# CONFIG_DEVPTS_FS_XATTR is not set
758CONFIG_TMPFS=y
759# CONFIG_HUGETLB_PAGE is not set
760CONFIG_RAMFS=y
761
762#
763# Miscellaneous filesystems
764#
765# CONFIG_ADFS_FS is not set
766# CONFIG_AFFS_FS is not set
767# CONFIG_HFS_FS is not set
768# CONFIG_HFSPLUS_FS is not set
769# CONFIG_BEFS_FS is not set
770# CONFIG_BFS_FS is not set
771# CONFIG_EFS_FS is not set
772# CONFIG_CRAMFS is not set
773# CONFIG_VXFS_FS is not set
774# CONFIG_HPFS_FS is not set
775# CONFIG_QNX4FS_FS is not set
776# CONFIG_SYSV_FS is not set
777# CONFIG_UFS_FS is not set
778
779#
780# Network File Systems
781#
782# CONFIG_NFS_FS is not set
783# CONFIG_NFSD is not set
784# CONFIG_EXPORTFS is not set
785# CONFIG_SMB_FS is not set
786# CONFIG_CIFS is not set
787# CONFIG_NCP_FS is not set
788# CONFIG_CODA_FS is not set
789# CONFIG_AFS_FS is not set
790
791#
792# Partition Types
793#
794CONFIG_PARTITION_ADVANCED=y
795# CONFIG_ACORN_PARTITION is not set
796# CONFIG_OSF_PARTITION is not set
797# CONFIG_AMIGA_PARTITION is not set
798# CONFIG_ATARI_PARTITION is not set
799CONFIG_MAC_PARTITION=y
800CONFIG_MSDOS_PARTITION=y
801# CONFIG_BSD_DISKLABEL is not set
802# CONFIG_MINIX_SUBPARTITION is not set
803# CONFIG_SOLARIS_X86_PARTITION is not set
804# CONFIG_UNIXWARE_DISKLABEL is not set
805# CONFIG_LDM_PARTITION is not set
806# CONFIG_NEC98_PARTITION is not set
807# CONFIG_SGI_PARTITION is not set
808# CONFIG_ULTRIX_PARTITION is not set
809# CONFIG_SUN_PARTITION is not set
810# CONFIG_EFI_PARTITION is not set
811
812#
813# Native Language Support
814#
815CONFIG_NLS=y
816CONFIG_NLS_DEFAULT="iso8859-1"
817# CONFIG_NLS_CODEPAGE_437 is not set
818# CONFIG_NLS_CODEPAGE_737 is not set
819# CONFIG_NLS_CODEPAGE_775 is not set
820# CONFIG_NLS_CODEPAGE_850 is not set
821# CONFIG_NLS_CODEPAGE_852 is not set
822# CONFIG_NLS_CODEPAGE_855 is not set
823# CONFIG_NLS_CODEPAGE_857 is not set
824# CONFIG_NLS_CODEPAGE_860 is not set
825# CONFIG_NLS_CODEPAGE_861 is not set
826# CONFIG_NLS_CODEPAGE_862 is not set
827# CONFIG_NLS_CODEPAGE_863 is not set
828# CONFIG_NLS_CODEPAGE_864 is not set
829# CONFIG_NLS_CODEPAGE_865 is not set
830# CONFIG_NLS_CODEPAGE_866 is not set
831# CONFIG_NLS_CODEPAGE_869 is not set
832# CONFIG_NLS_CODEPAGE_936 is not set
833# CONFIG_NLS_CODEPAGE_950 is not set
834# CONFIG_NLS_CODEPAGE_932 is not set
835# CONFIG_NLS_CODEPAGE_949 is not set
836# CONFIG_NLS_CODEPAGE_874 is not set
837# CONFIG_NLS_ISO8859_8 is not set
838# CONFIG_NLS_CODEPAGE_1250 is not set
839# CONFIG_NLS_CODEPAGE_1251 is not set
840CONFIG_NLS_ISO8859_1=m
841# CONFIG_NLS_ISO8859_2 is not set
842# CONFIG_NLS_ISO8859_3 is not set
843# CONFIG_NLS_ISO8859_4 is not set
844# CONFIG_NLS_ISO8859_5 is not set
845# CONFIG_NLS_ISO8859_6 is not set
846# CONFIG_NLS_ISO8859_7 is not set
847# CONFIG_NLS_ISO8859_9 is not set
848# CONFIG_NLS_ISO8859_13 is not set
849# CONFIG_NLS_ISO8859_14 is not set
850# CONFIG_NLS_ISO8859_15 is not set
851# CONFIG_NLS_KOI8_R is not set
852# CONFIG_NLS_KOI8_U is not set
853# CONFIG_NLS_UTF8 is not set
854
855#
856# Library routines
857#
858CONFIG_CRC32=y
859# CONFIG_LIBCRC32C is not set
860
861#
862# Kernel hacking
863#
864# CONFIG_DEBUG_KERNEL is not set
865# CONFIG_BOOTX_TEXT is not set
866
867#
868# Security options
869#
870# CONFIG_SECURITY is not set
871
872#
873# Cryptographic options
874#
875# CONFIG_CRYPTO is not set
diff --git a/arch/ppc/configs/pmac_defconfig b/arch/ppc/configs/pmac_defconfig
deleted file mode 100644
index a2db8b541c9b..000000000000
--- a/arch/ppc/configs/pmac_defconfig
+++ /dev/null
@@ -1,1591 +0,0 @@
1#
2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.13-rc3
4# Wed Jul 13 14:13:13 2005
5#
6CONFIG_MMU=y
7CONFIG_GENERIC_HARDIRQS=y
8CONFIG_RWSEM_XCHGADD_ALGORITHM=y
9CONFIG_GENERIC_CALIBRATE_DELAY=y
10CONFIG_HAVE_DEC_LOCK=y
11CONFIG_PPC=y
12CONFIG_PPC32=y
13CONFIG_GENERIC_NVRAM=y
14CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
15
16#
17# Code maturity level options
18#
19CONFIG_EXPERIMENTAL=y
20CONFIG_CLEAN_COMPILE=y
21CONFIG_BROKEN_ON_SMP=y
22CONFIG_INIT_ENV_ARG_LIMIT=32
23
24#
25# General setup
26#
27CONFIG_LOCALVERSION=""
28CONFIG_SWAP=y
29CONFIG_SYSVIPC=y
30CONFIG_POSIX_MQUEUE=y
31# CONFIG_BSD_PROCESS_ACCT is not set
32CONFIG_SYSCTL=y
33# CONFIG_AUDIT is not set
34CONFIG_HOTPLUG=y
35CONFIG_KOBJECT_UEVENT=y
36CONFIG_IKCONFIG=y
37CONFIG_IKCONFIG_PROC=y
38# CONFIG_EMBEDDED is not set
39CONFIG_KALLSYMS=y
40# CONFIG_KALLSYMS_ALL is not set
41# CONFIG_KALLSYMS_EXTRA_PASS is not set
42CONFIG_PRINTK=y
43CONFIG_BUG=y
44CONFIG_BASE_FULL=y
45CONFIG_FUTEX=y
46CONFIG_EPOLL=y
47CONFIG_SHMEM=y
48CONFIG_CC_ALIGN_FUNCTIONS=0
49CONFIG_CC_ALIGN_LABELS=0
50CONFIG_CC_ALIGN_LOOPS=0
51CONFIG_CC_ALIGN_JUMPS=0
52# CONFIG_TINY_SHMEM is not set
53CONFIG_BASE_SMALL=0
54
55#
56# Loadable module support
57#
58CONFIG_MODULES=y
59CONFIG_MODULE_UNLOAD=y
60# CONFIG_MODULE_FORCE_UNLOAD is not set
61CONFIG_OBSOLETE_MODPARM=y
62CONFIG_MODVERSIONS=y
63CONFIG_MODULE_SRCVERSION_ALL=y
64CONFIG_KMOD=y
65
66#
67# Processor
68#
69CONFIG_6xx=y
70# CONFIG_40x is not set
71# CONFIG_44x is not set
72# CONFIG_POWER3 is not set
73# CONFIG_POWER4 is not set
74# CONFIG_8xx is not set
75# CONFIG_E200 is not set
76# CONFIG_E500 is not set
77CONFIG_PPC_FPU=y
78CONFIG_ALTIVEC=y
79CONFIG_TAU=y
80# CONFIG_TAU_INT is not set
81# CONFIG_TAU_AVERAGE is not set
82# CONFIG_KEXEC is not set
83CONFIG_CPU_FREQ=y
84CONFIG_CPU_FREQ_TABLE=y
85# CONFIG_CPU_FREQ_DEBUG is not set
86CONFIG_CPU_FREQ_STAT=m
87CONFIG_CPU_FREQ_STAT_DETAILS=y
88CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y
89# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set
90CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
91CONFIG_CPU_FREQ_GOV_POWERSAVE=m
92CONFIG_CPU_FREQ_GOV_USERSPACE=m
93CONFIG_CPU_FREQ_GOV_ONDEMAND=m
94CONFIG_CPU_FREQ_GOV_CONSERVATIVE=m
95CONFIG_CPU_FREQ_PMAC=y
96CONFIG_PPC601_SYNC_FIX=y
97CONFIG_PM=y
98CONFIG_PPC_STD_MMU=y
99
100#
101# Platform options
102#
103CONFIG_PPC_MULTIPLATFORM=y
104# CONFIG_APUS is not set
105# CONFIG_KATANA is not set
106# CONFIG_WILLOW is not set
107# CONFIG_CPCI690 is not set
108# CONFIG_PCORE is not set
109# CONFIG_POWERPMC250 is not set
110# CONFIG_CHESTNUT is not set
111# CONFIG_SPRUCE is not set
112# CONFIG_HDPU is not set
113# CONFIG_EV64260 is not set
114# CONFIG_LOPEC is not set
115# CONFIG_MCPN765 is not set
116# CONFIG_MVME5100 is not set
117# CONFIG_PPLUS is not set
118# CONFIG_PRPMC750 is not set
119# CONFIG_PRPMC800 is not set
120# CONFIG_SANDPOINT is not set
121# CONFIG_RADSTONE_PPC7D is not set
122# CONFIG_ADIR is not set
123# CONFIG_K2 is not set
124# CONFIG_PAL4 is not set
125# CONFIG_GEMINI is not set
126# CONFIG_EST8260 is not set
127# CONFIG_SBC82xx is not set
128# CONFIG_SBS8260 is not set
129# CONFIG_RPX8260 is not set
130# CONFIG_TQM8260 is not set
131# CONFIG_ADS8272 is not set
132# CONFIG_PQ2FADS is not set
133# CONFIG_LITE5200 is not set
134# CONFIG_MPC834x_SYS is not set
135CONFIG_PPC_CHRP=y
136CONFIG_PPC_PMAC=y
137CONFIG_PPC_PREP=y
138CONFIG_PPC_OF=y
139CONFIG_PPCBUG_NVRAM=y
140# CONFIG_SMP is not set
141# CONFIG_HIGHMEM is not set
142# CONFIG_HZ_100 is not set
143CONFIG_HZ_250=y
144# CONFIG_HZ_1000 is not set
145CONFIG_HZ=250
146CONFIG_PREEMPT_NONE=y
147# CONFIG_PREEMPT_VOLUNTARY is not set
148# CONFIG_PREEMPT is not set
149CONFIG_SELECT_MEMORY_MODEL=y
150CONFIG_FLATMEM_MANUAL=y
151# CONFIG_DISCONTIGMEM_MANUAL is not set
152# CONFIG_SPARSEMEM_MANUAL is not set
153CONFIG_FLATMEM=y
154CONFIG_FLAT_NODE_MEM_MAP=y
155CONFIG_BINFMT_ELF=y
156CONFIG_BINFMT_MISC=m
157CONFIG_PROC_DEVICETREE=y
158# CONFIG_PREP_RESIDUAL is not set
159# CONFIG_CMDLINE_BOOL is not set
160# CONFIG_PM_DEBUG is not set
161CONFIG_SOFTWARE_SUSPEND=y
162CONFIG_PM_STD_PARTITION=""
163# CONFIG_SECCOMP is not set
164CONFIG_ISA_DMA_API=y
165
166#
167# Bus options
168#
169# CONFIG_ISA is not set
170CONFIG_GENERIC_ISA_DMA=y
171CONFIG_PCI=y
172CONFIG_PCI_DOMAINS=y
173CONFIG_PCI_LEGACY_PROC=y
174CONFIG_PCI_NAMES=y
175# CONFIG_PCI_DEBUG is not set
176
177#
178# PCCARD (PCMCIA/CardBus) support
179#
180CONFIG_PCCARD=m
181# CONFIG_PCMCIA_DEBUG is not set
182CONFIG_PCMCIA=m
183# CONFIG_PCMCIA_LOAD_CIS is not set
184# CONFIG_PCMCIA_IOCTL is not set
185CONFIG_CARDBUS=y
186
187#
188# PC-card bridges
189#
190CONFIG_YENTA=m
191# CONFIG_PD6729 is not set
192# CONFIG_I82092 is not set
193# CONFIG_TCIC is not set
194CONFIG_PCCARD_NONSTATIC=m
195
196#
197# Advanced setup
198#
199CONFIG_ADVANCED_OPTIONS=y
200CONFIG_HIGHMEM_START=0xfe000000
201# CONFIG_LOWMEM_SIZE_BOOL is not set
202CONFIG_LOWMEM_SIZE=0x30000000
203# CONFIG_KERNEL_START_BOOL is not set
204CONFIG_KERNEL_START=0xc0000000
205CONFIG_TASK_SIZE_BOOL=y
206CONFIG_TASK_SIZE=0xc0000000
207CONFIG_BOOT_LOAD=0x00800000
208
209#
210# Networking
211#
212CONFIG_NET=y
213
214#
215# Networking options
216#
217CONFIG_PACKET=y
218# CONFIG_PACKET_MMAP is not set
219CONFIG_UNIX=y
220# CONFIG_NET_KEY is not set
221CONFIG_INET=y
222CONFIG_IP_MULTICAST=y
223# CONFIG_IP_ADVANCED_ROUTER is not set
224CONFIG_IP_FIB_HASH=y
225# CONFIG_IP_PNP is not set
226# CONFIG_NET_IPIP is not set
227# CONFIG_NET_IPGRE is not set
228# CONFIG_IP_MROUTE is not set
229# CONFIG_ARPD is not set
230CONFIG_SYN_COOKIES=y
231# CONFIG_INET_AH is not set
232# CONFIG_INET_ESP is not set
233# CONFIG_INET_IPCOMP is not set
234# CONFIG_INET_TUNNEL is not set
235CONFIG_IP_TCPDIAG=y
236# CONFIG_IP_TCPDIAG_IPV6 is not set
237# CONFIG_TCP_CONG_ADVANCED is not set
238CONFIG_TCP_CONG_BIC=y
239
240#
241# IP: Virtual Server Configuration
242#
243# CONFIG_IP_VS is not set
244# CONFIG_IPV6 is not set
245CONFIG_NETFILTER=y
246# CONFIG_NETFILTER_DEBUG is not set
247
248#
249# IP: Netfilter Configuration
250#
251CONFIG_IP_NF_CONNTRACK=m
252CONFIG_IP_NF_CT_ACCT=y
253CONFIG_IP_NF_CONNTRACK_MARK=y
254CONFIG_IP_NF_CT_PROTO_SCTP=m
255CONFIG_IP_NF_FTP=m
256CONFIG_IP_NF_IRC=m
257CONFIG_IP_NF_TFTP=m
258CONFIG_IP_NF_AMANDA=m
259CONFIG_IP_NF_QUEUE=m
260CONFIG_IP_NF_IPTABLES=m
261CONFIG_IP_NF_MATCH_LIMIT=m
262CONFIG_IP_NF_MATCH_IPRANGE=m
263CONFIG_IP_NF_MATCH_MAC=m
264CONFIG_IP_NF_MATCH_PKTTYPE=m
265CONFIG_IP_NF_MATCH_MARK=m
266CONFIG_IP_NF_MATCH_MULTIPORT=m
267CONFIG_IP_NF_MATCH_TOS=m
268CONFIG_IP_NF_MATCH_RECENT=m
269CONFIG_IP_NF_MATCH_ECN=m
270CONFIG_IP_NF_MATCH_DSCP=m
271CONFIG_IP_NF_MATCH_AH_ESP=m
272CONFIG_IP_NF_MATCH_LENGTH=m
273CONFIG_IP_NF_MATCH_TTL=m
274CONFIG_IP_NF_MATCH_TCPMSS=m
275CONFIG_IP_NF_MATCH_HELPER=m
276CONFIG_IP_NF_MATCH_STATE=m
277CONFIG_IP_NF_MATCH_CONNTRACK=m
278CONFIG_IP_NF_MATCH_OWNER=m
279CONFIG_IP_NF_MATCH_ADDRTYPE=m
280CONFIG_IP_NF_MATCH_REALM=m
281CONFIG_IP_NF_MATCH_SCTP=m
282CONFIG_IP_NF_MATCH_COMMENT=m
283CONFIG_IP_NF_MATCH_CONNMARK=m
284CONFIG_IP_NF_MATCH_HASHLIMIT=m
285CONFIG_IP_NF_FILTER=m
286CONFIG_IP_NF_TARGET_REJECT=m
287CONFIG_IP_NF_TARGET_LOG=m
288CONFIG_IP_NF_TARGET_ULOG=m
289CONFIG_IP_NF_TARGET_TCPMSS=m
290CONFIG_IP_NF_NAT=m
291CONFIG_IP_NF_NAT_NEEDED=y
292CONFIG_IP_NF_TARGET_MASQUERADE=m
293CONFIG_IP_NF_TARGET_REDIRECT=m
294CONFIG_IP_NF_TARGET_NETMAP=m
295CONFIG_IP_NF_TARGET_SAME=m
296CONFIG_IP_NF_NAT_SNMP_BASIC=m
297CONFIG_IP_NF_NAT_IRC=m
298CONFIG_IP_NF_NAT_FTP=m
299CONFIG_IP_NF_NAT_TFTP=m
300CONFIG_IP_NF_NAT_AMANDA=m
301CONFIG_IP_NF_MANGLE=m
302CONFIG_IP_NF_TARGET_TOS=m
303CONFIG_IP_NF_TARGET_ECN=m
304CONFIG_IP_NF_TARGET_DSCP=m
305CONFIG_IP_NF_TARGET_MARK=m
306CONFIG_IP_NF_TARGET_CLASSIFY=m
307CONFIG_IP_NF_TARGET_CONNMARK=m
308CONFIG_IP_NF_TARGET_CLUSTERIP=m
309CONFIG_IP_NF_RAW=m
310CONFIG_IP_NF_TARGET_NOTRACK=m
311CONFIG_IP_NF_ARPTABLES=m
312CONFIG_IP_NF_ARPFILTER=m
313CONFIG_IP_NF_ARP_MANGLE=m
314
315#
316# SCTP Configuration (EXPERIMENTAL)
317#
318# CONFIG_IP_SCTP is not set
319# CONFIG_ATM is not set
320# CONFIG_BRIDGE is not set
321# CONFIG_VLAN_8021Q is not set
322# CONFIG_DECNET is not set
323# CONFIG_LLC2 is not set
324# CONFIG_IPX is not set
325# CONFIG_ATALK is not set
326# CONFIG_X25 is not set
327# CONFIG_LAPB is not set
328# CONFIG_NET_DIVERT is not set
329# CONFIG_ECONET is not set
330# CONFIG_WAN_ROUTER is not set
331# CONFIG_NET_SCHED is not set
332CONFIG_NET_CLS_ROUTE=y
333
334#
335# Network testing
336#
337# CONFIG_NET_PKTGEN is not set
338CONFIG_NETPOLL=y
339# CONFIG_NETPOLL_RX is not set
340# CONFIG_NETPOLL_TRAP is not set
341CONFIG_NET_POLL_CONTROLLER=y
342# CONFIG_HAMRADIO is not set
343CONFIG_IRDA=m
344
345#
346# IrDA protocols
347#
348CONFIG_IRLAN=m
349CONFIG_IRNET=m
350CONFIG_IRCOMM=m
351# CONFIG_IRDA_ULTRA is not set
352
353#
354# IrDA options
355#
356CONFIG_IRDA_CACHE_LAST_LSAP=y
357CONFIG_IRDA_FAST_RR=y
358# CONFIG_IRDA_DEBUG is not set
359
360#
361# Infrared-port device drivers
362#
363
364#
365# SIR device drivers
366#
367CONFIG_IRTTY_SIR=m
368
369#
370# Dongle support
371#
372# CONFIG_DONGLE is not set
373
374#
375# Old SIR device drivers
376#
377# CONFIG_IRPORT_SIR is not set
378
379#
380# Old Serial dongle support
381#
382
383#
384# FIR device drivers
385#
386# CONFIG_USB_IRDA is not set
387# CONFIG_SIGMATEL_FIR is not set
388# CONFIG_NSC_FIR is not set
389# CONFIG_WINBOND_FIR is not set
390# CONFIG_TOSHIBA_FIR is not set
391# CONFIG_SMC_IRCC_FIR is not set
392# CONFIG_ALI_FIR is not set
393# CONFIG_VLSI_FIR is not set
394# CONFIG_VIA_FIR is not set
395# CONFIG_BT is not set
396
397#
398# Device Drivers
399#
400
401#
402# Generic Driver Options
403#
404# CONFIG_STANDALONE is not set
405CONFIG_PREVENT_FIRMWARE_BUILD=y
406CONFIG_FW_LOADER=m
407# CONFIG_DEBUG_DRIVER is not set
408
409#
410# Memory Technology Devices (MTD)
411#
412# CONFIG_MTD is not set
413
414#
415# Parallel port support
416#
417# CONFIG_PARPORT is not set
418
419#
420# Plug and Play support
421#
422
423#
424# Block devices
425#
426# CONFIG_BLK_DEV_FD is not set
427CONFIG_MAC_FLOPPY=m
428# CONFIG_BLK_CPQ_DA is not set
429# CONFIG_BLK_CPQ_CISS_DA is not set
430# CONFIG_BLK_DEV_DAC960 is not set
431# CONFIG_BLK_DEV_UMEM is not set
432# CONFIG_BLK_DEV_COW_COMMON is not set
433CONFIG_BLK_DEV_LOOP=y
434# CONFIG_BLK_DEV_CRYPTOLOOP is not set
435# CONFIG_BLK_DEV_NBD is not set
436# CONFIG_BLK_DEV_SX8 is not set
437# CONFIG_BLK_DEV_UB is not set
438CONFIG_BLK_DEV_RAM=y
439CONFIG_BLK_DEV_RAM_COUNT=16
440CONFIG_BLK_DEV_RAM_SIZE=4096
441CONFIG_BLK_DEV_INITRD=y
442CONFIG_INITRAMFS_SOURCE=""
443CONFIG_LBD=y
444CONFIG_CDROM_PKTCDVD=m
445CONFIG_CDROM_PKTCDVD_BUFFERS=8
446# CONFIG_CDROM_PKTCDVD_WCACHE is not set
447
448#
449# IO Schedulers
450#
451CONFIG_IOSCHED_NOOP=y
452CONFIG_IOSCHED_AS=y
453CONFIG_IOSCHED_DEADLINE=y
454CONFIG_IOSCHED_CFQ=y
455# CONFIG_ATA_OVER_ETH is not set
456
457#
458# ATA/ATAPI/MFM/RLL support
459#
460CONFIG_IDE=y
461CONFIG_BLK_DEV_IDE=y
462
463#
464# Please see Documentation/ide.txt for help/info on IDE drives
465#
466# CONFIG_BLK_DEV_IDE_SATA is not set
467CONFIG_BLK_DEV_IDEDISK=y
468# CONFIG_IDEDISK_MULTI_MODE is not set
469# CONFIG_BLK_DEV_IDECS is not set
470CONFIG_BLK_DEV_IDECD=y
471# CONFIG_BLK_DEV_IDETAPE is not set
472CONFIG_BLK_DEV_IDEFLOPPY=y
473CONFIG_BLK_DEV_IDESCSI=y
474# CONFIG_IDE_TASK_IOCTL is not set
475
476#
477# IDE chipset support/bugfixes
478#
479# CONFIG_IDE_GENERIC is not set
480CONFIG_BLK_DEV_IDEPCI=y
481CONFIG_IDEPCI_SHARE_IRQ=y
482# CONFIG_BLK_DEV_OFFBOARD is not set
483CONFIG_BLK_DEV_GENERIC=y
484# CONFIG_BLK_DEV_OPTI621 is not set
485# CONFIG_BLK_DEV_SL82C105 is not set
486CONFIG_BLK_DEV_IDEDMA_PCI=y
487# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
488CONFIG_IDEDMA_PCI_AUTO=y
489# CONFIG_IDEDMA_ONLYDISK is not set
490# CONFIG_BLK_DEV_AEC62XX is not set
491# CONFIG_BLK_DEV_ALI15X3 is not set
492# CONFIG_BLK_DEV_AMD74XX is not set
493CONFIG_BLK_DEV_CMD64X=y
494# CONFIG_BLK_DEV_TRIFLEX is not set
495# CONFIG_BLK_DEV_CY82C693 is not set
496# CONFIG_BLK_DEV_CS5520 is not set
497# CONFIG_BLK_DEV_CS5530 is not set
498# CONFIG_BLK_DEV_HPT34X is not set
499# CONFIG_BLK_DEV_HPT366 is not set
500# CONFIG_BLK_DEV_SC1200 is not set
501# CONFIG_BLK_DEV_PIIX is not set
502# CONFIG_BLK_DEV_IT821X is not set
503# CONFIG_BLK_DEV_NS87415 is not set
504# CONFIG_BLK_DEV_PDC202XX_OLD is not set
505CONFIG_BLK_DEV_PDC202XX_NEW=y
506# CONFIG_PDC202XX_FORCE is not set
507# CONFIG_BLK_DEV_SVWKS is not set
508# CONFIG_BLK_DEV_SIIMAGE is not set
509# CONFIG_BLK_DEV_SLC90E66 is not set
510# CONFIG_BLK_DEV_TRM290 is not set
511# CONFIG_BLK_DEV_VIA82CXXX is not set
512CONFIG_BLK_DEV_IDE_PMAC=y
513CONFIG_BLK_DEV_IDE_PMAC_ATA100FIRST=y
514CONFIG_BLK_DEV_IDEDMA_PMAC=y
515CONFIG_BLK_DEV_IDE_PMAC_BLINK=y
516# CONFIG_IDE_ARM is not set
517CONFIG_BLK_DEV_IDEDMA=y
518# CONFIG_IDEDMA_IVB is not set
519CONFIG_IDEDMA_AUTO=y
520# CONFIG_BLK_DEV_HD is not set
521
522#
523# SCSI device support
524#
525CONFIG_SCSI=y
526CONFIG_SCSI_PROC_FS=y
527
528#
529# SCSI support type (disk, tape, CD-ROM)
530#
531CONFIG_BLK_DEV_SD=y
532CONFIG_CHR_DEV_ST=y
533# CONFIG_CHR_DEV_OSST is not set
534CONFIG_BLK_DEV_SR=y
535CONFIG_BLK_DEV_SR_VENDOR=y
536CONFIG_CHR_DEV_SG=y
537# CONFIG_CHR_DEV_SCH is not set
538
539#
540# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
541#
542# CONFIG_SCSI_MULTI_LUN is not set
543CONFIG_SCSI_CONSTANTS=y
544# CONFIG_SCSI_LOGGING is not set
545
546#
547# SCSI Transport Attributes
548#
549CONFIG_SCSI_SPI_ATTRS=y
550# CONFIG_SCSI_FC_ATTRS is not set
551# CONFIG_SCSI_ISCSI_ATTRS is not set
552
553#
554# SCSI low-level drivers
555#
556# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
557# CONFIG_SCSI_3W_9XXX is not set
558# CONFIG_SCSI_ACARD is not set
559# CONFIG_SCSI_AACRAID is not set
560CONFIG_SCSI_AIC7XXX=m
561CONFIG_AIC7XXX_CMDS_PER_DEVICE=253
562CONFIG_AIC7XXX_RESET_DELAY_MS=15000
563CONFIG_AIC7XXX_DEBUG_ENABLE=y
564CONFIG_AIC7XXX_DEBUG_MASK=0
565CONFIG_AIC7XXX_REG_PRETTY_PRINT=y
566CONFIG_SCSI_AIC7XXX_OLD=m
567# CONFIG_SCSI_AIC79XX is not set
568# CONFIG_SCSI_DPT_I2O is not set
569# CONFIG_MEGARAID_NEWGEN is not set
570# CONFIG_MEGARAID_LEGACY is not set
571# CONFIG_SCSI_SATA is not set
572# CONFIG_SCSI_BUSLOGIC is not set
573# CONFIG_SCSI_DMX3191D is not set
574# CONFIG_SCSI_EATA is not set
575# CONFIG_SCSI_FUTURE_DOMAIN is not set
576# CONFIG_SCSI_GDTH is not set
577# CONFIG_SCSI_IPS is not set
578# CONFIG_SCSI_INITIO is not set
579# CONFIG_SCSI_INIA100 is not set
580CONFIG_SCSI_SYM53C8XX_2=y
581CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=0
582CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16
583CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64
584# CONFIG_SCSI_SYM53C8XX_IOMAPPED is not set
585# CONFIG_SCSI_IPR is not set
586# CONFIG_SCSI_QLOGIC_FC is not set
587# CONFIG_SCSI_QLOGIC_1280 is not set
588CONFIG_SCSI_QLA2XXX=y
589# CONFIG_SCSI_QLA21XX is not set
590# CONFIG_SCSI_QLA22XX is not set
591# CONFIG_SCSI_QLA2300 is not set
592# CONFIG_SCSI_QLA2322 is not set
593# CONFIG_SCSI_QLA6312 is not set
594# CONFIG_SCSI_LPFC is not set
595# CONFIG_SCSI_DC395x is not set
596# CONFIG_SCSI_DC390T is not set
597# CONFIG_SCSI_NSP32 is not set
598# CONFIG_SCSI_DEBUG is not set
599CONFIG_SCSI_MESH=y
600CONFIG_SCSI_MESH_SYNC_RATE=5
601CONFIG_SCSI_MESH_RESET_DELAY_MS=1000
602CONFIG_SCSI_MAC53C94=y
603
604#
605# PCMCIA SCSI adapter support
606#
607# CONFIG_PCMCIA_AHA152X is not set
608# CONFIG_PCMCIA_FDOMAIN is not set
609# CONFIG_PCMCIA_NINJA_SCSI is not set
610# CONFIG_PCMCIA_QLOGIC is not set
611# CONFIG_PCMCIA_SYM53C500 is not set
612
613#
614# Multi-device support (RAID and LVM)
615#
616# CONFIG_MD is not set
617
618#
619# Fusion MPT device support
620#
621# CONFIG_FUSION is not set
622# CONFIG_FUSION_SPI is not set
623# CONFIG_FUSION_FC is not set
624
625#
626# IEEE 1394 (FireWire) support
627#
628CONFIG_IEEE1394=m
629
630#
631# Subsystem Options
632#
633# CONFIG_IEEE1394_VERBOSEDEBUG is not set
634# CONFIG_IEEE1394_OUI_DB is not set
635CONFIG_IEEE1394_EXTRA_CONFIG_ROMS=y
636CONFIG_IEEE1394_CONFIG_ROM_IP1394=y
637# CONFIG_IEEE1394_EXPORT_FULL_API is not set
638
639#
640# Device Drivers
641#
642# CONFIG_IEEE1394_PCILYNX is not set
643CONFIG_IEEE1394_OHCI1394=m
644
645#
646# Protocol Drivers
647#
648CONFIG_IEEE1394_VIDEO1394=m
649CONFIG_IEEE1394_SBP2=m
650# CONFIG_IEEE1394_SBP2_PHYS_DMA is not set
651CONFIG_IEEE1394_ETH1394=m
652CONFIG_IEEE1394_DV1394=m
653CONFIG_IEEE1394_RAWIO=m
654CONFIG_IEEE1394_CMP=m
655CONFIG_IEEE1394_AMDTP=m
656
657#
658# I2O device support
659#
660# CONFIG_I2O is not set
661
662#
663# Macintosh device drivers
664#
665CONFIG_ADB=y
666CONFIG_ADB_CUDA=y
667CONFIG_ADB_PMU=y
668CONFIG_PMAC_APM_EMU=y
669CONFIG_PMAC_MEDIABAY=y
670CONFIG_PMAC_BACKLIGHT=y
671CONFIG_ADB_MACIO=y
672CONFIG_INPUT_ADBHID=y
673CONFIG_MAC_EMUMOUSEBTN=y
674CONFIG_THERM_WINDTUNNEL=m
675CONFIG_THERM_ADT746X=m
676# CONFIG_ANSLCD is not set
677
678#
679# Network device support
680#
681CONFIG_NETDEVICES=y
682# CONFIG_DUMMY is not set
683# CONFIG_BONDING is not set
684# CONFIG_EQUALIZER is not set
685CONFIG_TUN=m
686
687#
688# ARCnet devices
689#
690# CONFIG_ARCNET is not set
691
692#
693# Ethernet (10 or 100Mbit)
694#
695CONFIG_NET_ETHERNET=y
696CONFIG_MII=y
697CONFIG_MACE=y
698# CONFIG_MACE_AAUI_PORT is not set
699CONFIG_BMAC=y
700# CONFIG_HAPPYMEAL is not set
701CONFIG_SUNGEM=y
702# CONFIG_NET_VENDOR_3COM is not set
703
704#
705# Tulip family network device support
706#
707# CONFIG_NET_TULIP is not set
708# CONFIG_HP100 is not set
709CONFIG_NET_PCI=y
710CONFIG_PCNET32=y
711# CONFIG_AMD8111_ETH is not set
712# CONFIG_ADAPTEC_STARFIRE is not set
713# CONFIG_B44 is not set
714# CONFIG_FORCEDETH is not set
715# CONFIG_DGRS is not set
716# CONFIG_EEPRO100 is not set
717# CONFIG_E100 is not set
718# CONFIG_FEALNX is not set
719# CONFIG_NATSEMI is not set
720# CONFIG_NE2K_PCI is not set
721# CONFIG_8139CP is not set
722# CONFIG_8139TOO is not set
723# CONFIG_SIS900 is not set
724# CONFIG_EPIC100 is not set
725# CONFIG_SUNDANCE is not set
726# CONFIG_TLAN is not set
727# CONFIG_VIA_RHINE is not set
728
729#
730# Ethernet (1000 Mbit)
731#
732# CONFIG_ACENIC is not set
733# CONFIG_DL2K is not set
734# CONFIG_E1000 is not set
735# CONFIG_NS83820 is not set
736# CONFIG_HAMACHI is not set
737# CONFIG_YELLOWFIN is not set
738# CONFIG_R8169 is not set
739# CONFIG_SKGE is not set
740# CONFIG_SK98LIN is not set
741# CONFIG_VIA_VELOCITY is not set
742# CONFIG_TIGON3 is not set
743# CONFIG_BNX2 is not set
744# CONFIG_MV643XX_ETH is not set
745
746#
747# Ethernet (10000 Mbit)
748#
749# CONFIG_IXGB is not set
750# CONFIG_S2IO is not set
751
752#
753# Token Ring devices
754#
755# CONFIG_TR is not set
756
757#
758# Wireless LAN (non-hamradio)
759#
760CONFIG_NET_RADIO=y
761
762#
763# Obsolete Wireless cards support (pre-802.11)
764#
765# CONFIG_STRIP is not set
766# CONFIG_PCMCIA_WAVELAN is not set
767# CONFIG_PCMCIA_NETWAVE is not set
768
769#
770# Wireless 802.11 Frequency Hopping cards support
771#
772# CONFIG_PCMCIA_RAYCS is not set
773
774#
775# Wireless 802.11b ISA/PCI cards support
776#
777CONFIG_HERMES=m
778CONFIG_APPLE_AIRPORT=m
779# CONFIG_PLX_HERMES is not set
780# CONFIG_TMD_HERMES is not set
781# CONFIG_PCI_HERMES is not set
782# CONFIG_ATMEL is not set
783
784#
785# Wireless 802.11b Pcmcia/Cardbus cards support
786#
787CONFIG_PCMCIA_HERMES=m
788# CONFIG_AIRO_CS is not set
789# CONFIG_PCMCIA_WL3501 is not set
790
791#
792# Prism GT/Duette 802.11(a/b/g) PCI/Cardbus support
793#
794# CONFIG_PRISM54 is not set
795CONFIG_NET_WIRELESS=y
796
797#
798# PCMCIA network device support
799#
800# CONFIG_NET_PCMCIA is not set
801
802#
803# Wan interfaces
804#
805# CONFIG_WAN is not set
806# CONFIG_FDDI is not set
807# CONFIG_HIPPI is not set
808CONFIG_PPP=y
809CONFIG_PPP_MULTILINK=y
810# CONFIG_PPP_FILTER is not set
811CONFIG_PPP_ASYNC=y
812CONFIG_PPP_SYNC_TTY=m
813CONFIG_PPP_DEFLATE=y
814CONFIG_PPP_BSDCOMP=m
815CONFIG_PPPOE=m
816# CONFIG_SLIP is not set
817# CONFIG_NET_FC is not set
818# CONFIG_SHAPER is not set
819CONFIG_NETCONSOLE=m
820
821#
822# ISDN subsystem
823#
824# CONFIG_ISDN is not set
825
826#
827# Telephony Support
828#
829# CONFIG_PHONE is not set
830
831#
832# Input device support
833#
834CONFIG_INPUT=y
835
836#
837# Userland interfaces
838#
839CONFIG_INPUT_MOUSEDEV=y
840# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
841CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
842CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
843# CONFIG_INPUT_JOYDEV is not set
844# CONFIG_INPUT_TSDEV is not set
845CONFIG_INPUT_EVDEV=y
846# CONFIG_INPUT_EVBUG is not set
847
848#
849# Input Device Drivers
850#
851CONFIG_INPUT_KEYBOARD=y
852# CONFIG_KEYBOARD_ATKBD is not set
853# CONFIG_KEYBOARD_SUNKBD is not set
854# CONFIG_KEYBOARD_LKKBD is not set
855# CONFIG_KEYBOARD_XTKBD is not set
856# CONFIG_KEYBOARD_NEWTON is not set
857CONFIG_INPUT_MOUSE=y
858# CONFIG_MOUSE_PS2 is not set
859# CONFIG_MOUSE_SERIAL is not set
860# CONFIG_MOUSE_VSXXXAA is not set
861# CONFIG_INPUT_JOYSTICK is not set
862# CONFIG_INPUT_TOUCHSCREEN is not set
863# CONFIG_INPUT_MISC is not set
864
865#
866# Hardware I/O ports
867#
868# CONFIG_SERIO is not set
869# CONFIG_GAMEPORT is not set
870
871#
872# Character devices
873#
874CONFIG_VT=y
875CONFIG_VT_CONSOLE=y
876CONFIG_HW_CONSOLE=y
877# CONFIG_SERIAL_NONSTANDARD is not set
878
879#
880# Serial drivers
881#
882CONFIG_SERIAL_8250=m
883CONFIG_SERIAL_8250_CS=m
884CONFIG_SERIAL_8250_NR_UARTS=4
885# CONFIG_SERIAL_8250_EXTENDED is not set
886
887#
888# Non-8250 serial port support
889#
890CONFIG_SERIAL_CORE=y
891CONFIG_SERIAL_CORE_CONSOLE=y
892CONFIG_SERIAL_PMACZILOG=y
893CONFIG_SERIAL_PMACZILOG_CONSOLE=y
894# CONFIG_SERIAL_JSM is not set
895CONFIG_UNIX98_PTYS=y
896CONFIG_LEGACY_PTYS=y
897CONFIG_LEGACY_PTY_COUNT=256
898
899#
900# IPMI
901#
902# CONFIG_IPMI_HANDLER is not set
903
904#
905# Watchdog Cards
906#
907# CONFIG_WATCHDOG is not set
908CONFIG_NVRAM=y
909CONFIG_GEN_RTC=y
910# CONFIG_GEN_RTC_X is not set
911# CONFIG_DTLK is not set
912# CONFIG_R3964 is not set
913# CONFIG_APPLICOM is not set
914
915#
916# Ftape, the floppy tape device driver
917#
918CONFIG_AGP=m
919CONFIG_AGP_UNINORTH=m
920CONFIG_DRM=m
921# CONFIG_DRM_TDFX is not set
922CONFIG_DRM_R128=m
923CONFIG_DRM_RADEON=m
924# CONFIG_DRM_MGA is not set
925# CONFIG_DRM_SIS is not set
926# CONFIG_DRM_VIA is not set
927
928#
929# PCMCIA character devices
930#
931# CONFIG_SYNCLINK_CS is not set
932# CONFIG_RAW_DRIVER is not set
933
934#
935# TPM devices
936#
937# CONFIG_TCG_TPM is not set
938
939#
940# I2C support
941#
942CONFIG_I2C=y
943CONFIG_I2C_CHARDEV=m
944
945#
946# I2C Algorithms
947#
948CONFIG_I2C_ALGOBIT=y
949# CONFIG_I2C_ALGOPCF is not set
950# CONFIG_I2C_ALGOPCA is not set
951
952#
953# I2C Hardware Bus support
954#
955# CONFIG_I2C_ALI1535 is not set
956# CONFIG_I2C_ALI1563 is not set
957# CONFIG_I2C_ALI15X3 is not set
958# CONFIG_I2C_AMD756 is not set
959# CONFIG_I2C_AMD8111 is not set
960# CONFIG_I2C_HYDRA is not set
961# CONFIG_I2C_I801 is not set
962# CONFIG_I2C_I810 is not set
963# CONFIG_I2C_PIIX4 is not set
964# CONFIG_I2C_ISA is not set
965CONFIG_I2C_KEYWEST=m
966# CONFIG_I2C_MPC is not set
967# CONFIG_I2C_NFORCE2 is not set
968# CONFIG_I2C_PARPORT_LIGHT is not set
969# CONFIG_I2C_PROSAVAGE is not set
970# CONFIG_I2C_SAVAGE4 is not set
971# CONFIG_SCx200_ACB is not set
972# CONFIG_I2C_SIS5595 is not set
973# CONFIG_I2C_SIS630 is not set
974# CONFIG_I2C_SIS96X is not set
975# CONFIG_I2C_STUB is not set
976# CONFIG_I2C_VIA is not set
977# CONFIG_I2C_VIAPRO is not set
978# CONFIG_I2C_VOODOO3 is not set
979# CONFIG_I2C_PCA_ISA is not set
980# CONFIG_I2C_SENSOR is not set
981
982#
983# Miscellaneous I2C Chip support
984#
985# CONFIG_SENSORS_DS1337 is not set
986# CONFIG_SENSORS_DS1374 is not set
987# CONFIG_SENSORS_EEPROM is not set
988# CONFIG_SENSORS_PCF8574 is not set
989# CONFIG_SENSORS_PCA9539 is not set
990# CONFIG_SENSORS_PCF8591 is not set
991# CONFIG_SENSORS_RTC8564 is not set
992# CONFIG_SENSORS_M41T00 is not set
993# CONFIG_SENSORS_MAX6875 is not set
994# CONFIG_I2C_DEBUG_CORE is not set
995# CONFIG_I2C_DEBUG_ALGO is not set
996# CONFIG_I2C_DEBUG_BUS is not set
997# CONFIG_I2C_DEBUG_CHIP is not set
998
999#
1000# Dallas's 1-wire bus
1001#
1002# CONFIG_W1 is not set
1003
1004#
1005# Hardware Monitoring support
1006#
1007# CONFIG_HWMON is not set
1008
1009#
1010# Misc devices
1011#
1012
1013#
1014# Multimedia devices
1015#
1016# CONFIG_VIDEO_DEV is not set
1017
1018#
1019# Digital Video Broadcasting Devices
1020#
1021# CONFIG_DVB is not set
1022
1023#
1024# Graphics support
1025#
1026CONFIG_FB=y
1027CONFIG_FB_CFB_FILLRECT=y
1028CONFIG_FB_CFB_COPYAREA=y
1029CONFIG_FB_CFB_IMAGEBLIT=y
1030CONFIG_FB_SOFT_CURSOR=y
1031CONFIG_FB_MACMODES=y
1032CONFIG_FB_MODE_HELPERS=y
1033CONFIG_FB_TILEBLITTING=y
1034# CONFIG_FB_CIRRUS is not set
1035# CONFIG_FB_PM2 is not set
1036# CONFIG_FB_CYBER2000 is not set
1037CONFIG_FB_OF=y
1038CONFIG_FB_CONTROL=y
1039CONFIG_FB_PLATINUM=y
1040CONFIG_FB_VALKYRIE=y
1041CONFIG_FB_CT65550=y
1042# CONFIG_FB_ASILIANT is not set
1043CONFIG_FB_IMSTT=y
1044# CONFIG_FB_VGA16 is not set
1045# CONFIG_FB_NVIDIA is not set
1046# CONFIG_FB_RIVA is not set
1047CONFIG_FB_MATROX=y
1048CONFIG_FB_MATROX_MILLENIUM=y
1049CONFIG_FB_MATROX_MYSTIQUE=y
1050CONFIG_FB_MATROX_G=y
1051# CONFIG_FB_MATROX_I2C is not set
1052# CONFIG_FB_MATROX_MULTIHEAD is not set
1053# CONFIG_FB_RADEON_OLD is not set
1054CONFIG_FB_RADEON=y
1055CONFIG_FB_RADEON_I2C=y
1056# CONFIG_FB_RADEON_DEBUG is not set
1057CONFIG_FB_ATY128=y
1058CONFIG_FB_ATY=y
1059CONFIG_FB_ATY_CT=y
1060CONFIG_FB_ATY_GENERIC_LCD=y
1061# CONFIG_FB_ATY_XL_INIT is not set
1062CONFIG_FB_ATY_GX=y
1063# CONFIG_FB_SAVAGE is not set
1064# CONFIG_FB_SIS is not set
1065# CONFIG_FB_NEOMAGIC is not set
1066# CONFIG_FB_KYRO is not set
1067CONFIG_FB_3DFX=y
1068CONFIG_FB_3DFX_ACCEL=y
1069# CONFIG_FB_VOODOO1 is not set
1070# CONFIG_FB_TRIDENT is not set
1071# CONFIG_FB_S1D13XXX is not set
1072# CONFIG_FB_VIRTUAL is not set
1073
1074#
1075# Console display driver support
1076#
1077# CONFIG_VGA_CONSOLE is not set
1078CONFIG_DUMMY_CONSOLE=y
1079CONFIG_FRAMEBUFFER_CONSOLE=y
1080# CONFIG_FONTS is not set
1081CONFIG_FONT_8x8=y
1082CONFIG_FONT_8x16=y
1083
1084#
1085# Logo configuration
1086#
1087CONFIG_LOGO=y
1088CONFIG_LOGO_LINUX_MONO=y
1089CONFIG_LOGO_LINUX_VGA16=y
1090CONFIG_LOGO_LINUX_CLUT224=y
1091CONFIG_BACKLIGHT_LCD_SUPPORT=y
1092CONFIG_BACKLIGHT_CLASS_DEVICE=y
1093CONFIG_BACKLIGHT_DEVICE=y
1094CONFIG_LCD_CLASS_DEVICE=y
1095CONFIG_LCD_DEVICE=y
1096
1097#
1098# Sound
1099#
1100CONFIG_SOUND=m
1101CONFIG_DMASOUND_PMAC=m
1102CONFIG_DMASOUND=m
1103
1104#
1105# Advanced Linux Sound Architecture
1106#
1107CONFIG_SND=m
1108CONFIG_SND_TIMER=m
1109CONFIG_SND_PCM=m
1110CONFIG_SND_HWDEP=m
1111CONFIG_SND_RAWMIDI=m
1112CONFIG_SND_SEQUENCER=m
1113CONFIG_SND_SEQ_DUMMY=m
1114CONFIG_SND_OSSEMUL=y
1115CONFIG_SND_MIXER_OSS=m
1116CONFIG_SND_PCM_OSS=m
1117CONFIG_SND_SEQUENCER_OSS=y
1118# CONFIG_SND_VERBOSE_PRINTK is not set
1119# CONFIG_SND_DEBUG is not set
1120
1121#
1122# Generic devices
1123#
1124CONFIG_SND_DUMMY=m
1125# CONFIG_SND_VIRMIDI is not set
1126# CONFIG_SND_MTPAV is not set
1127# CONFIG_SND_SERIAL_U16550 is not set
1128# CONFIG_SND_MPU401 is not set
1129
1130#
1131# PCI devices
1132#
1133# CONFIG_SND_ALI5451 is not set
1134# CONFIG_SND_ATIIXP is not set
1135# CONFIG_SND_ATIIXP_MODEM is not set
1136# CONFIG_SND_AU8810 is not set
1137# CONFIG_SND_AU8820 is not set
1138# CONFIG_SND_AU8830 is not set
1139# CONFIG_SND_AZT3328 is not set
1140# CONFIG_SND_BT87X is not set
1141# CONFIG_SND_CS46XX is not set
1142# CONFIG_SND_CS4281 is not set
1143# CONFIG_SND_EMU10K1 is not set
1144# CONFIG_SND_EMU10K1X is not set
1145# CONFIG_SND_CA0106 is not set
1146# CONFIG_SND_KORG1212 is not set
1147# CONFIG_SND_MIXART is not set
1148# CONFIG_SND_NM256 is not set
1149# CONFIG_SND_RME32 is not set
1150# CONFIG_SND_RME96 is not set
1151# CONFIG_SND_RME9652 is not set
1152# CONFIG_SND_HDSP is not set
1153# CONFIG_SND_HDSPM is not set
1154# CONFIG_SND_TRIDENT is not set
1155# CONFIG_SND_YMFPCI is not set
1156# CONFIG_SND_ALS4000 is not set
1157# CONFIG_SND_CMIPCI is not set
1158# CONFIG_SND_ENS1370 is not set
1159# CONFIG_SND_ENS1371 is not set
1160# CONFIG_SND_ES1938 is not set
1161# CONFIG_SND_ES1968 is not set
1162# CONFIG_SND_MAESTRO3 is not set
1163# CONFIG_SND_FM801 is not set
1164# CONFIG_SND_ICE1712 is not set
1165# CONFIG_SND_ICE1724 is not set
1166# CONFIG_SND_INTEL8X0 is not set
1167# CONFIG_SND_INTEL8X0M is not set
1168# CONFIG_SND_SONICVIBES is not set
1169# CONFIG_SND_VIA82XX is not set
1170# CONFIG_SND_VIA82XX_MODEM is not set
1171# CONFIG_SND_VX222 is not set
1172# CONFIG_SND_HDA_INTEL is not set
1173
1174#
1175# ALSA PowerMac devices
1176#
1177CONFIG_SND_POWERMAC=m
1178
1179#
1180# USB devices
1181#
1182CONFIG_SND_USB_AUDIO=m
1183CONFIG_SND_USB_USX2Y=m
1184
1185#
1186# PCMCIA devices
1187#
1188
1189#
1190# Open Sound System
1191#
1192# CONFIG_SOUND_PRIME is not set
1193
1194#
1195# USB support
1196#
1197CONFIG_USB_ARCH_HAS_HCD=y
1198CONFIG_USB_ARCH_HAS_OHCI=y
1199CONFIG_USB=y
1200# CONFIG_USB_DEBUG is not set
1201
1202#
1203# Miscellaneous USB options
1204#
1205CONFIG_USB_DEVICEFS=y
1206# CONFIG_USB_BANDWIDTH is not set
1207CONFIG_USB_DYNAMIC_MINORS=y
1208CONFIG_USB_SUSPEND=y
1209# CONFIG_USB_OTG is not set
1210
1211#
1212# USB Host Controller Drivers
1213#
1214# CONFIG_USB_EHCI_HCD is not set
1215# CONFIG_USB_ISP116X_HCD is not set
1216CONFIG_USB_OHCI_HCD=y
1217# CONFIG_USB_OHCI_BIG_ENDIAN is not set
1218CONFIG_USB_OHCI_LITTLE_ENDIAN=y
1219# CONFIG_USB_UHCI_HCD is not set
1220# CONFIG_USB_SL811_HCD is not set
1221
1222#
1223# USB Device Class drivers
1224#
1225# CONFIG_USB_AUDIO is not set
1226# CONFIG_USB_BLUETOOTH_TTY is not set
1227# CONFIG_USB_MIDI is not set
1228CONFIG_USB_ACM=m
1229CONFIG_USB_PRINTER=m
1230
1231#
1232# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
1233#
1234# CONFIG_USB_STORAGE is not set
1235
1236#
1237# USB Input Devices
1238#
1239CONFIG_USB_HID=y
1240CONFIG_USB_HIDINPUT=y
1241# CONFIG_HID_FF is not set
1242CONFIG_USB_HIDDEV=y
1243# CONFIG_USB_AIPTEK is not set
1244# CONFIG_USB_WACOM is not set
1245# CONFIG_USB_ACECAD is not set
1246# CONFIG_USB_KBTAB is not set
1247# CONFIG_USB_POWERMATE is not set
1248# CONFIG_USB_MTOUCH is not set
1249# CONFIG_USB_ITMTOUCH is not set
1250# CONFIG_USB_EGALAX is not set
1251# CONFIG_USB_XPAD is not set
1252# CONFIG_USB_ATI_REMOTE is not set
1253# CONFIG_USB_KEYSPAN_REMOTE is not set
1254
1255#
1256# USB Imaging devices
1257#
1258# CONFIG_USB_MDC800 is not set
1259# CONFIG_USB_MICROTEK is not set
1260
1261#
1262# USB Multimedia devices
1263#
1264# CONFIG_USB_DABUSB is not set
1265
1266#
1267# Video4Linux support is needed for USB Multimedia device support
1268#
1269
1270#
1271# USB Network Adapters
1272#
1273# CONFIG_USB_CATC is not set
1274# CONFIG_USB_KAWETH is not set
1275CONFIG_USB_PEGASUS=m
1276# CONFIG_USB_RTL8150 is not set
1277# CONFIG_USB_USBNET is not set
1278# CONFIG_USB_ZD1201 is not set
1279# CONFIG_USB_MON is not set
1280
1281#
1282# USB port drivers
1283#
1284
1285#
1286# USB Serial Converter support
1287#
1288CONFIG_USB_SERIAL=m
1289# CONFIG_USB_SERIAL_GENERIC is not set
1290# CONFIG_USB_SERIAL_AIRPRIME is not set
1291# CONFIG_USB_SERIAL_BELKIN is not set
1292# CONFIG_USB_SERIAL_WHITEHEAT is not set
1293# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
1294# CONFIG_USB_SERIAL_CP2101 is not set
1295# CONFIG_USB_SERIAL_CYPRESS_M8 is not set
1296# CONFIG_USB_SERIAL_EMPEG is not set
1297# CONFIG_USB_SERIAL_FTDI_SIO is not set
1298CONFIG_USB_SERIAL_VISOR=m
1299# CONFIG_USB_SERIAL_IPAQ is not set
1300# CONFIG_USB_SERIAL_IR is not set
1301# CONFIG_USB_SERIAL_EDGEPORT is not set
1302# CONFIG_USB_SERIAL_EDGEPORT_TI is not set
1303# CONFIG_USB_SERIAL_GARMIN is not set
1304# CONFIG_USB_SERIAL_IPW is not set
1305# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
1306CONFIG_USB_SERIAL_KEYSPAN=m
1307CONFIG_USB_SERIAL_KEYSPAN_MPR=y
1308CONFIG_USB_SERIAL_KEYSPAN_USA28=y
1309CONFIG_USB_SERIAL_KEYSPAN_USA28X=y
1310CONFIG_USB_SERIAL_KEYSPAN_USA28XA=y
1311CONFIG_USB_SERIAL_KEYSPAN_USA28XB=y
1312CONFIG_USB_SERIAL_KEYSPAN_USA19=y
1313CONFIG_USB_SERIAL_KEYSPAN_USA18X=y
1314CONFIG_USB_SERIAL_KEYSPAN_USA19W=y
1315CONFIG_USB_SERIAL_KEYSPAN_USA19QW=y
1316CONFIG_USB_SERIAL_KEYSPAN_USA19QI=y
1317CONFIG_USB_SERIAL_KEYSPAN_USA49W=y
1318CONFIG_USB_SERIAL_KEYSPAN_USA49WLC=y
1319# CONFIG_USB_SERIAL_KLSI is not set
1320# CONFIG_USB_SERIAL_KOBIL_SCT is not set
1321# CONFIG_USB_SERIAL_MCT_U232 is not set
1322# CONFIG_USB_SERIAL_PL2303 is not set
1323# CONFIG_USB_SERIAL_HP4X is not set
1324# CONFIG_USB_SERIAL_SAFE is not set
1325# CONFIG_USB_SERIAL_TI is not set
1326# CONFIG_USB_SERIAL_CYBERJACK is not set
1327# CONFIG_USB_SERIAL_XIRCOM is not set
1328# CONFIG_USB_SERIAL_OPTION is not set
1329# CONFIG_USB_SERIAL_OMNINET is not set
1330CONFIG_USB_EZUSB=y
1331
1332#
1333# USB Miscellaneous drivers
1334#
1335# CONFIG_USB_EMI62 is not set
1336# CONFIG_USB_EMI26 is not set
1337# CONFIG_USB_AUERSWALD is not set
1338# CONFIG_USB_RIO500 is not set
1339# CONFIG_USB_LEGOTOWER is not set
1340# CONFIG_USB_LCD is not set
1341# CONFIG_USB_LED is not set
1342# CONFIG_USB_CYTHERM is not set
1343# CONFIG_USB_PHIDGETKIT is not set
1344# CONFIG_USB_PHIDGETSERVO is not set
1345# CONFIG_USB_IDMOUSE is not set
1346# CONFIG_USB_LD is not set
1347# CONFIG_USB_TEST is not set
1348
1349#
1350# USB DSL modem support
1351#
1352
1353#
1354# USB Gadget Support
1355#
1356# CONFIG_USB_GADGET is not set
1357
1358#
1359# MMC/SD Card support
1360#
1361# CONFIG_MMC is not set
1362
1363#
1364# InfiniBand support
1365#
1366# CONFIG_INFINIBAND is not set
1367
1368#
1369# SN Devices
1370#
1371
1372#
1373# File systems
1374#
1375CONFIG_EXT2_FS=y
1376CONFIG_EXT2_FS_XATTR=y
1377# CONFIG_EXT2_FS_POSIX_ACL is not set
1378# CONFIG_EXT2_FS_SECURITY is not set
1379# CONFIG_EXT2_FS_XIP is not set
1380CONFIG_EXT3_FS=y
1381CONFIG_EXT3_FS_XATTR=y
1382# CONFIG_EXT3_FS_POSIX_ACL is not set
1383# CONFIG_EXT3_FS_SECURITY is not set
1384CONFIG_JBD=y
1385# CONFIG_JBD_DEBUG is not set
1386CONFIG_FS_MBCACHE=y
1387# CONFIG_REISERFS_FS is not set
1388# CONFIG_JFS_FS is not set
1389CONFIG_FS_POSIX_ACL=y
1390
1391#
1392# XFS support
1393#
1394# CONFIG_XFS_FS is not set
1395# CONFIG_MINIX_FS is not set
1396# CONFIG_ROMFS_FS is not set
1397CONFIG_INOTIFY=y
1398# CONFIG_QUOTA is not set
1399CONFIG_DNOTIFY=y
1400# CONFIG_AUTOFS_FS is not set
1401# CONFIG_AUTOFS4_FS is not set
1402
1403#
1404# CD-ROM/DVD Filesystems
1405#
1406CONFIG_ISO9660_FS=y
1407# CONFIG_JOLIET is not set
1408# CONFIG_ZISOFS is not set
1409CONFIG_UDF_FS=m
1410CONFIG_UDF_NLS=y
1411
1412#
1413# DOS/FAT/NT Filesystems
1414#
1415CONFIG_FAT_FS=m
1416CONFIG_MSDOS_FS=m
1417CONFIG_VFAT_FS=m
1418CONFIG_FAT_DEFAULT_CODEPAGE=437
1419CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
1420# CONFIG_NTFS_FS is not set
1421
1422#
1423# Pseudo filesystems
1424#
1425CONFIG_PROC_FS=y
1426CONFIG_PROC_KCORE=y
1427CONFIG_SYSFS=y
1428CONFIG_DEVPTS_FS_XATTR=y
1429CONFIG_DEVPTS_FS_SECURITY=y
1430CONFIG_TMPFS=y
1431CONFIG_TMPFS_XATTR=y
1432CONFIG_TMPFS_SECURITY=y
1433# CONFIG_HUGETLB_PAGE is not set
1434CONFIG_RAMFS=y
1435
1436#
1437# Miscellaneous filesystems
1438#
1439# CONFIG_ADFS_FS is not set
1440# CONFIG_AFFS_FS is not set
1441CONFIG_HFS_FS=m
1442CONFIG_HFSPLUS_FS=m
1443# CONFIG_BEFS_FS is not set
1444# CONFIG_BFS_FS is not set
1445# CONFIG_EFS_FS is not set
1446CONFIG_CRAMFS=m
1447# CONFIG_VXFS_FS is not set
1448# CONFIG_HPFS_FS is not set
1449# CONFIG_QNX4FS_FS is not set
1450# CONFIG_SYSV_FS is not set
1451# CONFIG_UFS_FS is not set
1452
1453#
1454# Network File Systems
1455#
1456CONFIG_NFS_FS=y
1457CONFIG_NFS_V3=y
1458CONFIG_NFS_V3_ACL=y
1459# CONFIG_NFS_V4 is not set
1460# CONFIG_NFS_DIRECTIO is not set
1461CONFIG_NFSD=y
1462CONFIG_NFSD_V2_ACL=y
1463CONFIG_NFSD_V3=y
1464CONFIG_NFSD_V3_ACL=y
1465# CONFIG_NFSD_V4 is not set
1466CONFIG_NFSD_TCP=y
1467CONFIG_LOCKD=y
1468CONFIG_LOCKD_V4=y
1469CONFIG_EXPORTFS=y
1470CONFIG_NFS_ACL_SUPPORT=y
1471CONFIG_NFS_COMMON=y
1472CONFIG_SUNRPC=y
1473# CONFIG_RPCSEC_GSS_KRB5 is not set
1474# CONFIG_RPCSEC_GSS_SPKM3 is not set
1475CONFIG_SMB_FS=m
1476# CONFIG_SMB_NLS_DEFAULT is not set
1477# CONFIG_CIFS is not set
1478# CONFIG_NCP_FS is not set
1479# CONFIG_CODA_FS is not set
1480# CONFIG_AFS_FS is not set
1481
1482#
1483# Partition Types
1484#
1485CONFIG_PARTITION_ADVANCED=y
1486# CONFIG_ACORN_PARTITION is not set
1487# CONFIG_OSF_PARTITION is not set
1488# CONFIG_AMIGA_PARTITION is not set
1489# CONFIG_ATARI_PARTITION is not set
1490CONFIG_MAC_PARTITION=y
1491CONFIG_MSDOS_PARTITION=y
1492# CONFIG_BSD_DISKLABEL is not set
1493# CONFIG_MINIX_SUBPARTITION is not set
1494# CONFIG_SOLARIS_X86_PARTITION is not set
1495# CONFIG_UNIXWARE_DISKLABEL is not set
1496# CONFIG_LDM_PARTITION is not set
1497# CONFIG_SGI_PARTITION is not set
1498# CONFIG_ULTRIX_PARTITION is not set
1499# CONFIG_SUN_PARTITION is not set
1500# CONFIG_EFI_PARTITION is not set
1501
1502#
1503# Native Language Support
1504#
1505CONFIG_NLS=y
1506CONFIG_NLS_DEFAULT="iso8859-1"
1507# CONFIG_NLS_CODEPAGE_437 is not set
1508# CONFIG_NLS_CODEPAGE_737 is not set
1509# CONFIG_NLS_CODEPAGE_775 is not set
1510# CONFIG_NLS_CODEPAGE_850 is not set
1511# CONFIG_NLS_CODEPAGE_852 is not set
1512# CONFIG_NLS_CODEPAGE_855 is not set
1513# CONFIG_NLS_CODEPAGE_857 is not set
1514# CONFIG_NLS_CODEPAGE_860 is not set
1515# CONFIG_NLS_CODEPAGE_861 is not set
1516# CONFIG_NLS_CODEPAGE_862 is not set
1517# CONFIG_NLS_CODEPAGE_863 is not set
1518# CONFIG_NLS_CODEPAGE_864 is not set
1519# CONFIG_NLS_CODEPAGE_865 is not set
1520# CONFIG_NLS_CODEPAGE_866 is not set
1521# CONFIG_NLS_CODEPAGE_869 is not set
1522# CONFIG_NLS_CODEPAGE_936 is not set
1523# CONFIG_NLS_CODEPAGE_950 is not set
1524# CONFIG_NLS_CODEPAGE_932 is not set
1525# CONFIG_NLS_CODEPAGE_949 is not set
1526# CONFIG_NLS_CODEPAGE_874 is not set
1527# CONFIG_NLS_ISO8859_8 is not set
1528CONFIG_NLS_CODEPAGE_1250=m
1529CONFIG_NLS_CODEPAGE_1251=m
1530CONFIG_NLS_ASCII=m
1531CONFIG_NLS_ISO8859_1=m
1532# CONFIG_NLS_ISO8859_2 is not set
1533# CONFIG_NLS_ISO8859_3 is not set
1534# CONFIG_NLS_ISO8859_4 is not set
1535# CONFIG_NLS_ISO8859_5 is not set
1536# CONFIG_NLS_ISO8859_6 is not set
1537# CONFIG_NLS_ISO8859_7 is not set
1538# CONFIG_NLS_ISO8859_9 is not set
1539# CONFIG_NLS_ISO8859_13 is not set
1540# CONFIG_NLS_ISO8859_14 is not set
1541CONFIG_NLS_ISO8859_15=m
1542# CONFIG_NLS_KOI8_R is not set
1543# CONFIG_NLS_KOI8_U is not set
1544CONFIG_NLS_UTF8=m
1545
1546#
1547# Library routines
1548#
1549CONFIG_CRC_CCITT=y
1550CONFIG_CRC32=y
1551# CONFIG_LIBCRC32C is not set
1552CONFIG_ZLIB_INFLATE=y
1553CONFIG_ZLIB_DEFLATE=y
1554
1555#
1556# Profiling support
1557#
1558# CONFIG_PROFILING is not set
1559
1560#
1561# Kernel hacking
1562#
1563# CONFIG_PRINTK_TIME is not set
1564CONFIG_DEBUG_KERNEL=y
1565CONFIG_MAGIC_SYSRQ=y
1566CONFIG_LOG_BUF_SHIFT=16
1567# CONFIG_SCHEDSTATS is not set
1568# CONFIG_DEBUG_SLAB is not set
1569# CONFIG_DEBUG_SPINLOCK is not set
1570# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
1571# CONFIG_DEBUG_KOBJECT is not set
1572# CONFIG_DEBUG_INFO is not set
1573# CONFIG_DEBUG_FS is not set
1574# CONFIG_XMON is not set
1575# CONFIG_BDI_SWITCH is not set
1576CONFIG_BOOTX_TEXT=y
1577
1578#
1579# Security options
1580#
1581# CONFIG_KEYS is not set
1582# CONFIG_SECURITY is not set
1583
1584#
1585# Cryptographic options
1586#
1587# CONFIG_CRYPTO is not set
1588
1589#
1590# Hardware crypto devices
1591#
diff --git a/arch/ppc/configs/power3_defconfig b/arch/ppc/configs/power3_defconfig
deleted file mode 100644
index a1ef929bca59..000000000000
--- a/arch/ppc/configs/power3_defconfig
+++ /dev/null
@@ -1,1035 +0,0 @@
1#
2# Automatically generated make config: don't edit
3#
4CONFIG_MMU=y
5CONFIG_RWSEM_XCHGADD_ALGORITHM=y
6CONFIG_HAVE_DEC_LOCK=y
7CONFIG_PPC=y
8CONFIG_PPC32=y
9CONFIG_GENERIC_NVRAM=y
10
11#
12# Code maturity level options
13#
14CONFIG_EXPERIMENTAL=y
15CONFIG_CLEAN_COMPILE=y
16# CONFIG_STANDALONE is not set
17
18#
19# General setup
20#
21CONFIG_SWAP=y
22CONFIG_SYSVIPC=y
23CONFIG_POSIX_MQUEUE=y
24# CONFIG_BSD_PROCESS_ACCT is not set
25CONFIG_SYSCTL=y
26# CONFIG_AUDIT is not set
27CONFIG_LOG_BUF_SHIFT=15
28# CONFIG_HOTPLUG is not set
29CONFIG_IKCONFIG=y
30CONFIG_IKCONFIG_PROC=y
31# CONFIG_EMBEDDED is not set
32CONFIG_KALLSYMS=y
33CONFIG_FUTEX=y
34CONFIG_EPOLL=y
35CONFIG_IOSCHED_NOOP=y
36CONFIG_IOSCHED_AS=y
37CONFIG_IOSCHED_DEADLINE=y
38CONFIG_IOSCHED_CFQ=y
39# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
40
41#
42# Loadable module support
43#
44CONFIG_MODULES=y
45CONFIG_MODULE_UNLOAD=y
46CONFIG_MODULE_FORCE_UNLOAD=y
47CONFIG_OBSOLETE_MODPARM=y
48# CONFIG_MODVERSIONS is not set
49CONFIG_KMOD=y
50CONFIG_STOP_MACHINE=y
51
52#
53# Processor
54#
55# CONFIG_6xx is not set
56# CONFIG_40x is not set
57# CONFIG_44x is not set
58CONFIG_POWER3=y
59# CONFIG_POWER4 is not set
60# CONFIG_8xx is not set
61# CONFIG_CPU_FREQ is not set
62CONFIG_PPC64BRIDGE=y
63CONFIG_PPC_STD_MMU=y
64
65#
66# Platform options
67#
68CONFIG_PPC_MULTIPLATFORM=y
69# CONFIG_APUS is not set
70# CONFIG_WILLOW is not set
71# CONFIG_PCORE is not set
72# CONFIG_POWERPMC250 is not set
73# CONFIG_EV64260 is not set
74# CONFIG_SPRUCE is not set
75# CONFIG_LOPEC is not set
76# CONFIG_MCPN765 is not set
77# CONFIG_MVME5100 is not set
78# CONFIG_PPLUS is not set
79# CONFIG_PRPMC750 is not set
80# CONFIG_PRPMC800 is not set
81# CONFIG_SANDPOINT is not set
82# CONFIG_ADIR is not set
83# CONFIG_K2 is not set
84# CONFIG_PAL4 is not set
85# CONFIG_GEMINI is not set
86# CONFIG_EST8260 is not set
87# CONFIG_SBS8260 is not set
88# CONFIG_RPX6 is not set
89# CONFIG_TQM8260 is not set
90CONFIG_PPC_CHRP=y
91CONFIG_PPC_PMAC=y
92CONFIG_PPC_PREP=y
93CONFIG_PPC_OF=y
94CONFIG_PPCBUG_NVRAM=y
95CONFIG_SMP=y
96# CONFIG_IRQ_ALL_CPUS is not set
97CONFIG_NR_CPUS=32
98# CONFIG_PREEMPT is not set
99CONFIG_HIGHMEM=y
100CONFIG_KERNEL_ELF=y
101CONFIG_BINFMT_ELF=y
102CONFIG_BINFMT_MISC=y
103CONFIG_PROC_DEVICETREE=y
104CONFIG_PPC_RTAS=y
105# CONFIG_PREP_RESIDUAL is not set
106# CONFIG_CMDLINE_BOOL is not set
107
108#
109# Bus options
110#
111CONFIG_ISA=y
112CONFIG_GENERIC_ISA_DMA=y
113CONFIG_PCI=y
114CONFIG_PCI_DOMAINS=y
115CONFIG_PCI_LEGACY_PROC=y
116CONFIG_PCI_NAMES=y
117
118#
119# Advanced setup
120#
121CONFIG_ADVANCED_OPTIONS=y
122# CONFIG_HIGHMEM_START_BOOL is not set
123CONFIG_HIGHMEM_START=0xfe000000
124# CONFIG_LOWMEM_SIZE_BOOL is not set
125CONFIG_LOWMEM_SIZE=0x30000000
126# CONFIG_KERNEL_START_BOOL is not set
127CONFIG_KERNEL_START=0xc0000000
128CONFIG_TASK_SIZE_BOOL=y
129CONFIG_TASK_SIZE=0xc0000000
130CONFIG_BOOT_LOAD=0x00800000
131
132#
133# Device Drivers
134#
135
136#
137# Generic Driver Options
138#
139
140#
141# Memory Technology Devices (MTD)
142#
143# CONFIG_MTD is not set
144
145#
146# Parallel port support
147#
148CONFIG_PARPORT=m
149CONFIG_PARPORT_PC=m
150CONFIG_PARPORT_PC_CML1=m
151# CONFIG_PARPORT_SERIAL is not set
152CONFIG_PARPORT_PC_FIFO=y
153# CONFIG_PARPORT_PC_SUPERIO is not set
154# CONFIG_PARPORT_OTHER is not set
155# CONFIG_PARPORT_1284 is not set
156
157#
158# Plug and Play support
159#
160# CONFIG_PNP is not set
161
162#
163# Block devices
164#
165CONFIG_BLK_DEV_FD=y
166# CONFIG_BLK_DEV_XD is not set
167# CONFIG_PARIDE is not set
168# CONFIG_BLK_CPQ_DA is not set
169# CONFIG_BLK_CPQ_CISS_DA is not set
170# CONFIG_BLK_DEV_DAC960 is not set
171# CONFIG_BLK_DEV_UMEM is not set
172CONFIG_BLK_DEV_LOOP=y
173# CONFIG_BLK_DEV_CRYPTOLOOP is not set
174# CONFIG_BLK_DEV_NBD is not set
175# CONFIG_BLK_DEV_CARMEL is not set
176CONFIG_BLK_DEV_RAM=y
177CONFIG_BLK_DEV_RAM_SIZE=4096
178CONFIG_BLK_DEV_INITRD=y
179CONFIG_LBD=y
180
181#
182# ATA/ATAPI/MFM/RLL support
183#
184# CONFIG_IDE is not set
185
186#
187# SCSI device support
188#
189CONFIG_SCSI=y
190CONFIG_SCSI_PROC_FS=y
191
192#
193# SCSI support type (disk, tape, CD-ROM)
194#
195CONFIG_BLK_DEV_SD=y
196CONFIG_CHR_DEV_ST=y
197# CONFIG_CHR_DEV_OSST is not set
198CONFIG_BLK_DEV_SR=y
199CONFIG_BLK_DEV_SR_VENDOR=y
200CONFIG_CHR_DEV_SG=y
201
202#
203# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
204#
205# CONFIG_SCSI_MULTI_LUN is not set
206# CONFIG_SCSI_REPORT_LUNS is not set
207CONFIG_SCSI_CONSTANTS=y
208CONFIG_SCSI_LOGGING=y
209
210#
211# SCSI Transport Attributes
212#
213CONFIG_SCSI_SPI_ATTRS=y
214# CONFIG_SCSI_FC_ATTRS is not set
215
216#
217# SCSI low-level drivers
218#
219# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
220# CONFIG_SCSI_7000FASST is not set
221# CONFIG_SCSI_ACARD is not set
222# CONFIG_SCSI_AHA152X is not set
223# CONFIG_SCSI_AHA1542 is not set
224# CONFIG_SCSI_AACRAID is not set
225# CONFIG_SCSI_AIC7XXX is not set
226# CONFIG_SCSI_AIC7XXX_OLD is not set
227# CONFIG_SCSI_AIC79XX is not set
228# CONFIG_SCSI_ADVANSYS is not set
229# CONFIG_SCSI_IN2000 is not set
230# CONFIG_SCSI_MEGARAID is not set
231# CONFIG_SCSI_SATA is not set
232# CONFIG_SCSI_BUSLOGIC is not set
233# CONFIG_SCSI_CPQFCTS is not set
234# CONFIG_SCSI_DMX3191D is not set
235# CONFIG_SCSI_DTC3280 is not set
236# CONFIG_SCSI_EATA is not set
237# CONFIG_SCSI_EATA_PIO is not set
238# CONFIG_SCSI_FUTURE_DOMAIN is not set
239# CONFIG_SCSI_GDTH is not set
240# CONFIG_SCSI_GENERIC_NCR5380 is not set
241# CONFIG_SCSI_GENERIC_NCR5380_MMIO is not set
242# CONFIG_SCSI_IPS is not set
243# CONFIG_SCSI_INIA100 is not set
244# CONFIG_SCSI_PPA is not set
245# CONFIG_SCSI_IMM is not set
246# CONFIG_SCSI_NCR53C406A is not set
247CONFIG_SCSI_SYM53C8XX_2=y
248CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=1
249CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16
250CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64
251# CONFIG_SCSI_SYM53C8XX_IOMAPPED is not set
252# CONFIG_SCSI_IPR is not set
253# CONFIG_SCSI_PAS16 is not set
254# CONFIG_SCSI_PSI240I is not set
255# CONFIG_SCSI_QLOGIC_FAS is not set
256# CONFIG_SCSI_QLOGIC_ISP is not set
257# CONFIG_SCSI_QLOGIC_FC is not set
258# CONFIG_SCSI_QLOGIC_1280 is not set
259CONFIG_SCSI_QLA2XXX=y
260# CONFIG_SCSI_QLA21XX is not set
261# CONFIG_SCSI_QLA22XX is not set
262# CONFIG_SCSI_QLA2300 is not set
263# CONFIG_SCSI_QLA2322 is not set
264# CONFIG_SCSI_QLA6312 is not set
265# CONFIG_SCSI_QLA6322 is not set
266# CONFIG_SCSI_SYM53C416 is not set
267# CONFIG_SCSI_DC395x is not set
268# CONFIG_SCSI_DC390T is not set
269# CONFIG_SCSI_T128 is not set
270# CONFIG_SCSI_U14_34F is not set
271# CONFIG_SCSI_NSP32 is not set
272# CONFIG_SCSI_DEBUG is not set
273# CONFIG_SCSI_MESH is not set
274# CONFIG_SCSI_MAC53C94 is not set
275
276#
277# Old CD-ROM drivers (not SCSI, not IDE)
278#
279# CONFIG_CD_NO_IDESCSI is not set
280
281#
282# Multi-device support (RAID and LVM)
283#
284CONFIG_MD=y
285CONFIG_BLK_DEV_MD=y
286CONFIG_MD_LINEAR=y
287CONFIG_MD_RAID0=y
288CONFIG_MD_RAID1=y
289CONFIG_MD_RAID5=y
290CONFIG_MD_RAID6=y
291# CONFIG_MD_MULTIPATH is not set
292CONFIG_BLK_DEV_DM=y
293CONFIG_DM_CRYPT=y
294
295#
296# Fusion MPT device support
297#
298# CONFIG_FUSION is not set
299
300#
301# IEEE 1394 (FireWire) support
302#
303# CONFIG_IEEE1394 is not set
304
305#
306# I2O device support
307#
308# CONFIG_I2O is not set
309
310#
311# Macintosh device drivers
312#
313# CONFIG_ADB is not set
314# CONFIG_ADB_CUDA is not set
315# CONFIG_ADB_PMU is not set
316# CONFIG_MAC_FLOPPY is not set
317# CONFIG_MAC_SERIAL is not set
318
319#
320# Networking support
321#
322CONFIG_NET=y
323
324#
325# Networking options
326#
327CONFIG_PACKET=y
328# CONFIG_PACKET_MMAP is not set
329# CONFIG_NETLINK_DEV is not set
330CONFIG_UNIX=y
331# CONFIG_NET_KEY is not set
332CONFIG_INET=y
333CONFIG_IP_MULTICAST=y
334# CONFIG_IP_ADVANCED_ROUTER is not set
335# CONFIG_IP_PNP is not set
336# CONFIG_NET_IPIP is not set
337# CONFIG_NET_IPGRE is not set
338# CONFIG_IP_MROUTE is not set
339# CONFIG_ARPD is not set
340CONFIG_SYN_COOKIES=y
341# CONFIG_INET_AH is not set
342# CONFIG_INET_ESP is not set
343# CONFIG_INET_IPCOMP is not set
344# CONFIG_IPV6 is not set
345# CONFIG_NETFILTER is not set
346
347#
348# SCTP Configuration (EXPERIMENTAL)
349#
350# CONFIG_IP_SCTP is not set
351# CONFIG_ATM is not set
352# CONFIG_BRIDGE is not set
353# CONFIG_VLAN_8021Q is not set
354# CONFIG_DECNET is not set
355# CONFIG_LLC2 is not set
356# CONFIG_IPX is not set
357# CONFIG_ATALK is not set
358# CONFIG_X25 is not set
359# CONFIG_LAPB is not set
360# CONFIG_NET_DIVERT is not set
361# CONFIG_ECONET is not set
362# CONFIG_WAN_ROUTER is not set
363# CONFIG_NET_HW_FLOWCONTROL is not set
364
365#
366# QoS and/or fair queueing
367#
368# CONFIG_NET_SCHED is not set
369
370#
371# Network testing
372#
373# CONFIG_NET_PKTGEN is not set
374# CONFIG_NETPOLL is not set
375# CONFIG_NET_POLL_CONTROLLER is not set
376# CONFIG_HAMRADIO is not set
377# CONFIG_IRDA is not set
378# CONFIG_BT is not set
379CONFIG_NETDEVICES=y
380# CONFIG_DUMMY is not set
381# CONFIG_BONDING is not set
382# CONFIG_EQUALIZER is not set
383# CONFIG_TUN is not set
384
385#
386# ARCnet devices
387#
388# CONFIG_ARCNET is not set
389
390#
391# Ethernet (10 or 100Mbit)
392#
393CONFIG_NET_ETHERNET=y
394CONFIG_MII=y
395# CONFIG_MACE is not set
396# CONFIG_BMAC is not set
397# CONFIG_OAKNET is not set
398# CONFIG_HAPPYMEAL is not set
399# CONFIG_SUNGEM is not set
400# CONFIG_NET_VENDOR_3COM is not set
401# CONFIG_LANCE is not set
402# CONFIG_NET_VENDOR_SMC is not set
403# CONFIG_NET_VENDOR_RACAL is not set
404
405#
406# Tulip family network device support
407#
408# CONFIG_NET_TULIP is not set
409# CONFIG_AT1700 is not set
410# CONFIG_DEPCA is not set
411# CONFIG_HP100 is not set
412# CONFIG_NET_ISA is not set
413CONFIG_NET_PCI=y
414CONFIG_PCNET32=y
415# CONFIG_AMD8111_ETH is not set
416# CONFIG_ADAPTEC_STARFIRE is not set
417# CONFIG_AC3200 is not set
418# CONFIG_APRICOT is not set
419# CONFIG_B44 is not set
420# CONFIG_FORCEDETH is not set
421# CONFIG_CS89x0 is not set
422# CONFIG_DGRS is not set
423# CONFIG_EEPRO100 is not set
424CONFIG_E100=y
425# CONFIG_E100_NAPI is not set
426# CONFIG_FEALNX is not set
427# CONFIG_NATSEMI is not set
428# CONFIG_NE2K_PCI is not set
429# CONFIG_8139CP is not set
430# CONFIG_8139TOO is not set
431# CONFIG_SIS900 is not set
432# CONFIG_EPIC100 is not set
433# CONFIG_SUNDANCE is not set
434# CONFIG_TLAN is not set
435# CONFIG_VIA_RHINE is not set
436# CONFIG_NET_POCKET is not set
437
438#
439# Ethernet (1000 Mbit)
440#
441# CONFIG_ACENIC is not set
442# CONFIG_DL2K is not set
443CONFIG_E1000=y
444# CONFIG_E1000_NAPI is not set
445# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set
446# CONFIG_NS83820 is not set
447# CONFIG_HAMACHI is not set
448# CONFIG_YELLOWFIN is not set
449# CONFIG_R8169 is not set
450# CONFIG_SK98LIN is not set
451# CONFIG_TIGON3 is not set
452
453#
454# Ethernet (10000 Mbit)
455#
456# CONFIG_IXGB is not set
457# CONFIG_S2IO is not set
458
459#
460# Token Ring devices
461#
462# CONFIG_TR is not set
463
464#
465# Wireless LAN (non-hamradio)
466#
467# CONFIG_NET_RADIO is not set
468
469#
470# Wan interfaces
471#
472# CONFIG_WAN is not set
473# CONFIG_FDDI is not set
474# CONFIG_HIPPI is not set
475# CONFIG_PLIP is not set
476# CONFIG_PPP is not set
477# CONFIG_SLIP is not set
478# CONFIG_NET_FC is not set
479# CONFIG_RCPCI is not set
480# CONFIG_SHAPER is not set
481# CONFIG_NETCONSOLE is not set
482
483#
484# ISDN subsystem
485#
486# CONFIG_ISDN is not set
487
488#
489# Telephony Support
490#
491# CONFIG_PHONE is not set
492
493#
494# Input device support
495#
496CONFIG_INPUT=y
497
498#
499# Userland interfaces
500#
501CONFIG_INPUT_MOUSEDEV=y
502CONFIG_INPUT_MOUSEDEV_PSAUX=y
503CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
504CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
505# CONFIG_INPUT_JOYDEV is not set
506# CONFIG_INPUT_TSDEV is not set
507CONFIG_INPUT_EVDEV=y
508# CONFIG_INPUT_EVBUG is not set
509
510#
511# Input I/O drivers
512#
513CONFIG_GAMEPORT=m
514CONFIG_SOUND_GAMEPORT=m
515# CONFIG_GAMEPORT_NS558 is not set
516# CONFIG_GAMEPORT_L4 is not set
517# CONFIG_GAMEPORT_EMU10K1 is not set
518# CONFIG_GAMEPORT_VORTEX is not set
519# CONFIG_GAMEPORT_FM801 is not set
520# CONFIG_GAMEPORT_CS461x is not set
521CONFIG_SERIO=y
522CONFIG_SERIO_I8042=y
523CONFIG_SERIO_SERPORT=y
524# CONFIG_SERIO_CT82C710 is not set
525# CONFIG_SERIO_PARKBD is not set
526# CONFIG_SERIO_PCIPS2 is not set
527
528#
529# Input Device Drivers
530#
531CONFIG_INPUT_KEYBOARD=y
532CONFIG_KEYBOARD_ATKBD=y
533# CONFIG_KEYBOARD_SUNKBD is not set
534# CONFIG_KEYBOARD_LKKBD is not set
535# CONFIG_KEYBOARD_XTKBD is not set
536# CONFIG_KEYBOARD_NEWTON is not set
537CONFIG_INPUT_MOUSE=y
538CONFIG_MOUSE_PS2=y
539# CONFIG_MOUSE_SERIAL is not set
540# CONFIG_MOUSE_INPORT is not set
541# CONFIG_MOUSE_LOGIBM is not set
542# CONFIG_MOUSE_PC110PAD is not set
543# CONFIG_MOUSE_VSXXXAA is not set
544# CONFIG_INPUT_JOYSTICK is not set
545# CONFIG_INPUT_TOUCHSCREEN is not set
546CONFIG_INPUT_MISC=y
547CONFIG_INPUT_UINPUT=y
548
549#
550# Character devices
551#
552CONFIG_VT=y
553CONFIG_VT_CONSOLE=y
554CONFIG_HW_CONSOLE=y
555# CONFIG_SERIAL_NONSTANDARD is not set
556
557#
558# Serial drivers
559#
560CONFIG_SERIAL_8250=y
561CONFIG_SERIAL_8250_CONSOLE=y
562CONFIG_SERIAL_8250_NR_UARTS=4
563# CONFIG_SERIAL_8250_EXTENDED is not set
564
565#
566# Non-8250 serial port support
567#
568CONFIG_SERIAL_CORE=y
569CONFIG_SERIAL_CORE_CONSOLE=y
570# CONFIG_SERIAL_PMACZILOG is not set
571CONFIG_UNIX98_PTYS=y
572CONFIG_LEGACY_PTYS=y
573CONFIG_LEGACY_PTY_COUNT=256
574CONFIG_PRINTER=m
575# CONFIG_LP_CONSOLE is not set
576# CONFIG_PPDEV is not set
577# CONFIG_TIPAR is not set
578# CONFIG_QIC02_TAPE is not set
579
580#
581# IPMI
582#
583# CONFIG_IPMI_HANDLER is not set
584
585#
586# Watchdog Cards
587#
588# CONFIG_WATCHDOG is not set
589CONFIG_NVRAM=y
590CONFIG_GEN_RTC=y
591# CONFIG_GEN_RTC_X is not set
592# CONFIG_DTLK is not set
593# CONFIG_R3964 is not set
594# CONFIG_APPLICOM is not set
595
596#
597# Ftape, the floppy tape device driver
598#
599# CONFIG_AGP is not set
600# CONFIG_DRM is not set
601# CONFIG_RAW_DRIVER is not set
602
603#
604# I2C support
605#
606CONFIG_I2C=y
607CONFIG_I2C_CHARDEV=y
608
609#
610# I2C Algorithms
611#
612CONFIG_I2C_ALGOBIT=y
613CONFIG_I2C_ALGOPCF=y
614
615#
616# I2C Hardware Bus support
617#
618# CONFIG_I2C_ALI1535 is not set
619# CONFIG_I2C_ALI1563 is not set
620# CONFIG_I2C_ALI15X3 is not set
621# CONFIG_I2C_AMD756 is not set
622# CONFIG_I2C_AMD8111 is not set
623# CONFIG_I2C_HYDRA is not set
624# CONFIG_I2C_I801 is not set
625# CONFIG_I2C_I810 is not set
626# CONFIG_I2C_ISA is not set
627# CONFIG_I2C_KEYWEST is not set
628# CONFIG_I2C_NFORCE2 is not set
629# CONFIG_I2C_PARPORT is not set
630# CONFIG_I2C_PARPORT_LIGHT is not set
631# CONFIG_I2C_PIIX4 is not set
632# CONFIG_I2C_PROSAVAGE is not set
633# CONFIG_I2C_SAVAGE4 is not set
634# CONFIG_SCx200_ACB is not set
635# CONFIG_I2C_SIS5595 is not set
636# CONFIG_I2C_SIS630 is not set
637# CONFIG_I2C_SIS96X is not set
638# CONFIG_I2C_VIA is not set
639# CONFIG_I2C_VIAPRO is not set
640# CONFIG_I2C_VOODOO3 is not set
641
642#
643# Hardware Sensors Chip support
644#
645# CONFIG_I2C_SENSOR is not set
646# CONFIG_SENSORS_ADM1021 is not set
647# CONFIG_SENSORS_ASB100 is not set
648# CONFIG_SENSORS_DS1621 is not set
649# CONFIG_SENSORS_FSCHER is not set
650# CONFIG_SENSORS_GL518SM is not set
651# CONFIG_SENSORS_IT87 is not set
652# CONFIG_SENSORS_LM75 is not set
653# CONFIG_SENSORS_LM78 is not set
654# CONFIG_SENSORS_LM80 is not set
655# CONFIG_SENSORS_LM83 is not set
656# CONFIG_SENSORS_LM85 is not set
657# CONFIG_SENSORS_LM90 is not set
658# CONFIG_SENSORS_VIA686A is not set
659# CONFIG_SENSORS_W83781D is not set
660# CONFIG_SENSORS_W83L785TS is not set
661# CONFIG_SENSORS_W83627HF is not set
662
663#
664# Other I2C Chip support
665#
666# CONFIG_SENSORS_EEPROM is not set
667# CONFIG_SENSORS_PCF8574 is not set
668# CONFIG_SENSORS_PCF8591 is not set
669# CONFIG_I2C_DEBUG_CORE is not set
670# CONFIG_I2C_DEBUG_ALGO is not set
671# CONFIG_I2C_DEBUG_BUS is not set
672# CONFIG_I2C_DEBUG_CHIP is not set
673
674#
675# Misc devices
676#
677
678#
679# Multimedia devices
680#
681# CONFIG_VIDEO_DEV is not set
682
683#
684# Digital Video Broadcasting Devices
685#
686# CONFIG_DVB is not set
687
688#
689# Graphics support
690#
691CONFIG_FB=y
692# CONFIG_FB_PM2 is not set
693# CONFIG_FB_CYBER2000 is not set
694CONFIG_FB_OF=y
695# CONFIG_FB_CONTROL is not set
696# CONFIG_FB_PLATINUM is not set
697# CONFIG_FB_VALKYRIE is not set
698# CONFIG_FB_CT65550 is not set
699# CONFIG_FB_IMSTT is not set
700# CONFIG_FB_S3TRIO is not set
701# CONFIG_FB_VGA16 is not set
702# CONFIG_FB_RIVA is not set
703CONFIG_FB_MATROX=y
704CONFIG_FB_MATROX_MILLENIUM=y
705CONFIG_FB_MATROX_MYSTIQUE=y
706# CONFIG_FB_MATROX_G450 is not set
707CONFIG_FB_MATROX_G100A=y
708CONFIG_FB_MATROX_G100=y
709CONFIG_FB_MATROX_I2C=y
710# CONFIG_FB_MATROX_MAVEN is not set
711CONFIG_FB_MATROX_MULTIHEAD=y
712# CONFIG_FB_RADEON_OLD is not set
713# CONFIG_FB_RADEON is not set
714# CONFIG_FB_ATY128 is not set
715# CONFIG_FB_ATY is not set
716# CONFIG_FB_SIS is not set
717# CONFIG_FB_NEOMAGIC is not set
718# CONFIG_FB_KYRO is not set
719# CONFIG_FB_3DFX is not set
720# CONFIG_FB_VOODOO1 is not set
721# CONFIG_FB_TRIDENT is not set
722# CONFIG_FB_VIRTUAL is not set
723
724#
725# Console display driver support
726#
727# CONFIG_VGA_CONSOLE is not set
728# CONFIG_MDA_CONSOLE is not set
729CONFIG_DUMMY_CONSOLE=y
730CONFIG_FRAMEBUFFER_CONSOLE=y
731CONFIG_PCI_CONSOLE=y
732# CONFIG_FONTS is not set
733CONFIG_FONT_8x8=y
734CONFIG_FONT_8x16=y
735
736#
737# Logo configuration
738#
739CONFIG_LOGO=y
740CONFIG_LOGO_LINUX_MONO=y
741CONFIG_LOGO_LINUX_VGA16=y
742CONFIG_LOGO_LINUX_CLUT224=y
743
744#
745# Sound
746#
747CONFIG_SOUND=y
748# CONFIG_DMASOUND_PMAC is not set
749
750#
751# Advanced Linux Sound Architecture
752#
753CONFIG_SND=m
754CONFIG_SND_TIMER=m
755CONFIG_SND_PCM=m
756CONFIG_SND_HWDEP=m
757CONFIG_SND_RAWMIDI=m
758CONFIG_SND_SEQUENCER=m
759CONFIG_SND_SEQ_DUMMY=m
760CONFIG_SND_OSSEMUL=y
761CONFIG_SND_MIXER_OSS=m
762CONFIG_SND_PCM_OSS=m
763CONFIG_SND_SEQUENCER_OSS=y
764# CONFIG_SND_VERBOSE_PRINTK is not set
765# CONFIG_SND_DEBUG is not set
766
767#
768# Generic devices
769#
770CONFIG_SND_MPU401_UART=m
771CONFIG_SND_OPL3_LIB=m
772CONFIG_SND_DUMMY=m
773# CONFIG_SND_VIRMIDI is not set
774# CONFIG_SND_MTPAV is not set
775# CONFIG_SND_SERIAL_U16550 is not set
776# CONFIG_SND_MPU401 is not set
777
778#
779# ISA devices
780#
781# CONFIG_SND_AD1848 is not set
782# CONFIG_SND_CS4231 is not set
783CONFIG_SND_CS4232=m
784# CONFIG_SND_CS4236 is not set
785# CONFIG_SND_ES1688 is not set
786# CONFIG_SND_ES18XX is not set
787# CONFIG_SND_GUSCLASSIC is not set
788# CONFIG_SND_GUSEXTREME is not set
789# CONFIG_SND_GUSMAX is not set
790# CONFIG_SND_INTERWAVE is not set
791# CONFIG_SND_INTERWAVE_STB is not set
792# CONFIG_SND_OPTI92X_AD1848 is not set
793# CONFIG_SND_OPTI92X_CS4231 is not set
794# CONFIG_SND_OPTI93X is not set
795# CONFIG_SND_SB8 is not set
796# CONFIG_SND_SB16 is not set
797# CONFIG_SND_SBAWE is not set
798# CONFIG_SND_WAVEFRONT is not set
799# CONFIG_SND_CMI8330 is not set
800# CONFIG_SND_OPL3SA2 is not set
801# CONFIG_SND_SGALAXY is not set
802# CONFIG_SND_SSCAPE is not set
803
804#
805# PCI devices
806#
807CONFIG_SND_AC97_CODEC=m
808# CONFIG_SND_ALI5451 is not set
809# CONFIG_SND_ATIIXP is not set
810# CONFIG_SND_AU8810 is not set
811# CONFIG_SND_AU8820 is not set
812# CONFIG_SND_AU8830 is not set
813# CONFIG_SND_AZT3328 is not set
814# CONFIG_SND_BT87X is not set
815CONFIG_SND_CS46XX=m
816# CONFIG_SND_CS46XX_NEW_DSP is not set
817CONFIG_SND_CS4281=m
818# CONFIG_SND_EMU10K1 is not set
819# CONFIG_SND_KORG1212 is not set
820# CONFIG_SND_MIXART is not set
821# CONFIG_SND_NM256 is not set
822# CONFIG_SND_RME32 is not set
823# CONFIG_SND_RME96 is not set
824# CONFIG_SND_RME9652 is not set
825# CONFIG_SND_HDSP is not set
826# CONFIG_SND_TRIDENT is not set
827# CONFIG_SND_YMFPCI is not set
828# CONFIG_SND_ALS4000 is not set
829# CONFIG_SND_CMIPCI is not set
830# CONFIG_SND_ENS1370 is not set
831# CONFIG_SND_ENS1371 is not set
832# CONFIG_SND_ES1938 is not set
833# CONFIG_SND_ES1968 is not set
834# CONFIG_SND_MAESTRO3 is not set
835# CONFIG_SND_FM801 is not set
836# CONFIG_SND_ICE1712 is not set
837# CONFIG_SND_ICE1724 is not set
838# CONFIG_SND_INTEL8X0 is not set
839# CONFIG_SND_INTEL8X0M is not set
840# CONFIG_SND_SONICVIBES is not set
841# CONFIG_SND_VIA82XX is not set
842# CONFIG_SND_VX222 is not set
843
844#
845# ALSA PowerMac devices
846#
847# CONFIG_SND_POWERMAC is not set
848
849#
850# Open Sound System
851#
852# CONFIG_SOUND_PRIME is not set
853
854#
855# USB support
856#
857# CONFIG_USB is not set
858
859#
860# USB Gadget Support
861#
862# CONFIG_USB_GADGET is not set
863
864#
865# File systems
866#
867CONFIG_EXT2_FS=y
868# CONFIG_EXT2_FS_XATTR is not set
869# CONFIG_EXT3_FS is not set
870# CONFIG_JBD is not set
871# CONFIG_REISERFS_FS is not set
872# CONFIG_JFS_FS is not set
873# CONFIG_XFS_FS is not set
874# CONFIG_MINIX_FS is not set
875# CONFIG_ROMFS_FS is not set
876# CONFIG_QUOTA is not set
877# CONFIG_AUTOFS_FS is not set
878# CONFIG_AUTOFS4_FS is not set
879
880#
881# CD-ROM/DVD Filesystems
882#
883CONFIG_ISO9660_FS=y
884CONFIG_JOLIET=y
885# CONFIG_ZISOFS is not set
886# CONFIG_UDF_FS is not set
887
888#
889# DOS/FAT/NT Filesystems
890#
891CONFIG_FAT_FS=y
892CONFIG_MSDOS_FS=y
893CONFIG_VFAT_FS=y
894# CONFIG_NTFS_FS is not set
895
896#
897# Pseudo filesystems
898#
899CONFIG_PROC_FS=y
900CONFIG_PROC_KCORE=y
901CONFIG_SYSFS=y
902# CONFIG_DEVFS_FS is not set
903# CONFIG_DEVPTS_FS_XATTR is not set
904CONFIG_TMPFS=y
905# CONFIG_HUGETLB_PAGE is not set
906CONFIG_RAMFS=y
907
908#
909# Miscellaneous filesystems
910#
911# CONFIG_ADFS_FS is not set
912# CONFIG_AFFS_FS is not set
913# CONFIG_HFS_FS is not set
914# CONFIG_HFSPLUS_FS is not set
915# CONFIG_BEFS_FS is not set
916# CONFIG_BFS_FS is not set
917# CONFIG_EFS_FS is not set
918# CONFIG_CRAMFS is not set
919# CONFIG_VXFS_FS is not set
920# CONFIG_HPFS_FS is not set
921# CONFIG_QNX4FS_FS is not set
922# CONFIG_SYSV_FS is not set
923# CONFIG_UFS_FS is not set
924
925#
926# Network File Systems
927#
928CONFIG_NFS_FS=y
929# CONFIG_NFS_V3 is not set
930# CONFIG_NFS_V4 is not set
931# CONFIG_NFS_DIRECTIO is not set
932CONFIG_NFSD=y
933# CONFIG_NFSD_V3 is not set
934# CONFIG_NFSD_TCP is not set
935CONFIG_LOCKD=y
936CONFIG_EXPORTFS=y
937CONFIG_SUNRPC=y
938# CONFIG_RPCSEC_GSS_KRB5 is not set
939# CONFIG_SMB_FS is not set
940# CONFIG_CIFS is not set
941# CONFIG_NCP_FS is not set
942# CONFIG_CODA_FS is not set
943# CONFIG_AFS_FS is not set
944
945#
946# Partition Types
947#
948# CONFIG_PARTITION_ADVANCED is not set
949CONFIG_MSDOS_PARTITION=y
950
951#
952# Native Language Support
953#
954CONFIG_NLS=y
955CONFIG_NLS_DEFAULT="iso8859-1"
956CONFIG_NLS_CODEPAGE_437=y
957# CONFIG_NLS_CODEPAGE_737 is not set
958# CONFIG_NLS_CODEPAGE_775 is not set
959# CONFIG_NLS_CODEPAGE_850 is not set
960# CONFIG_NLS_CODEPAGE_852 is not set
961# CONFIG_NLS_CODEPAGE_855 is not set
962# CONFIG_NLS_CODEPAGE_857 is not set
963# CONFIG_NLS_CODEPAGE_860 is not set
964# CONFIG_NLS_CODEPAGE_861 is not set
965# CONFIG_NLS_CODEPAGE_862 is not set
966# CONFIG_NLS_CODEPAGE_863 is not set
967# CONFIG_NLS_CODEPAGE_864 is not set
968# CONFIG_NLS_CODEPAGE_865 is not set
969# CONFIG_NLS_CODEPAGE_866 is not set
970# CONFIG_NLS_CODEPAGE_869 is not set
971# CONFIG_NLS_CODEPAGE_936 is not set
972# CONFIG_NLS_CODEPAGE_950 is not set
973# CONFIG_NLS_CODEPAGE_932 is not set
974# CONFIG_NLS_CODEPAGE_949 is not set
975# CONFIG_NLS_CODEPAGE_874 is not set
976# CONFIG_NLS_ISO8859_8 is not set
977# CONFIG_NLS_CODEPAGE_1250 is not set
978# CONFIG_NLS_CODEPAGE_1251 is not set
979CONFIG_NLS_ISO8859_1=y
980# CONFIG_NLS_ISO8859_2 is not set
981# CONFIG_NLS_ISO8859_3 is not set
982# CONFIG_NLS_ISO8859_4 is not set
983# CONFIG_NLS_ISO8859_5 is not set
984# CONFIG_NLS_ISO8859_6 is not set
985# CONFIG_NLS_ISO8859_7 is not set
986# CONFIG_NLS_ISO8859_9 is not set
987# CONFIG_NLS_ISO8859_13 is not set
988# CONFIG_NLS_ISO8859_14 is not set
989# CONFIG_NLS_ISO8859_15 is not set
990# CONFIG_NLS_KOI8_R is not set
991# CONFIG_NLS_KOI8_U is not set
992# CONFIG_NLS_UTF8 is not set
993
994#
995# Library routines
996#
997CONFIG_CRC32=y
998# CONFIG_LIBCRC32C is not set
999CONFIG_ZLIB_INFLATE=m
1000CONFIG_ZLIB_DEFLATE=m
1001
1002#
1003# Kernel hacking
1004#
1005# CONFIG_DEBUG_KERNEL is not set
1006CONFIG_BOOTX_TEXT=y
1007
1008#
1009# Security options
1010#
1011# CONFIG_SECURITY is not set
1012
1013#
1014# Cryptographic options
1015#
1016CONFIG_CRYPTO=y
1017CONFIG_CRYPTO_HMAC=y
1018CONFIG_CRYPTO_NULL=y
1019CONFIG_CRYPTO_MD4=m
1020CONFIG_CRYPTO_MD5=m
1021CONFIG_CRYPTO_SHA1=m
1022CONFIG_CRYPTO_SHA256=m
1023CONFIG_CRYPTO_SHA512=m
1024CONFIG_CRYPTO_DES=m
1025CONFIG_CRYPTO_BLOWFISH=m
1026CONFIG_CRYPTO_TWOFISH=m
1027# CONFIG_CRYPTO_SERPENT is not set
1028CONFIG_CRYPTO_AES=m
1029CONFIG_CRYPTO_CAST5=m
1030CONFIG_CRYPTO_CAST6=m
1031CONFIG_CRYPTO_ARC4=m
1032CONFIG_CRYPTO_DEFLATE=m
1033CONFIG_CRYPTO_MICHAEL_MIC=m
1034# CONFIG_CRYPTO_CRC32C is not set
1035# CONFIG_CRYPTO_TEST is not set
diff --git a/arch/ppc/configs/common_defconfig b/arch/ppc/configs/prep_defconfig
index 4d33bee23a89..4d33bee23a89 100644
--- a/arch/ppc/configs/common_defconfig
+++ b/arch/ppc/configs/prep_defconfig
diff --git a/arch/ppc/kernel/Makefile b/arch/ppc/kernel/Makefile
index e399bbb969a4..466437f4bcbb 100644
--- a/arch/ppc/kernel/Makefile
+++ b/arch/ppc/kernel/Makefile
@@ -1,48 +1,24 @@
1# 1#
2# Makefile for the linux kernel. 2# Makefile for the linux kernel.
3# 3#
4ifneq ($(CONFIG_PPC_MERGE),y)
5
6extra-$(CONFIG_PPC_STD_MMU) := head.o 4extra-$(CONFIG_PPC_STD_MMU) := head.o
7extra-$(CONFIG_40x) := head_4xx.o 5extra-$(CONFIG_40x) := head_4xx.o
8extra-$(CONFIG_44x) := head_44x.o 6extra-$(CONFIG_44x) := head_44x.o
9extra-$(CONFIG_FSL_BOOKE) := head_fsl_booke.o 7extra-$(CONFIG_FSL_BOOKE) := head_fsl_booke.o
10extra-$(CONFIG_8xx) := head_8xx.o 8extra-$(CONFIG_8xx) := head_8xx.o
11extra-$(CONFIG_6xx) += idle_6xx.o
12extra-y += vmlinux.lds 9extra-y += vmlinux.lds
13 10
14obj-y := entry.o traps.o idle.o time.o misc.o \ 11obj-y := entry.o traps.o time.o misc.o \
15 setup.o \ 12 setup.o \
16 ppc_htab.o 13 ppc_htab.o
17obj-$(CONFIG_6xx) += l2cr.o cpu_setup_6xx.o 14obj-$(CONFIG_MODULES) += ppc_ksyms.o
18obj-$(CONFIG_SOFTWARE_SUSPEND) += swsusp.o
19obj-$(CONFIG_MODULES) += module.o ppc_ksyms.o
20obj-$(CONFIG_NOT_COHERENT_CACHE) += dma-mapping.o 15obj-$(CONFIG_NOT_COHERENT_CACHE) += dma-mapping.o
21obj-$(CONFIG_PCI) += pci.o 16obj-$(CONFIG_PCI) += pci.o
22obj-$(CONFIG_RAPIDIO) += rio.o 17obj-$(CONFIG_RAPIDIO) += rio.o
23obj-$(CONFIG_KGDB) += ppc-stub.o 18obj-$(CONFIG_KGDB) += ppc-stub.o
24obj-$(CONFIG_SMP) += smp.o smp-tbsync.o 19obj-$(CONFIG_SMP) += smp.o smp-tbsync.o
25obj-$(CONFIG_TAU) += temp.o
26ifndef CONFIG_E200
27obj-$(CONFIG_FSL_BOOKE) += perfmon_fsl_booke.o
28endif
29obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o 20obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o
30 21
31ifndef CONFIG_MATH_EMULATION 22ifndef CONFIG_MATH_EMULATION
32obj-$(CONFIG_8xx) += softemu8xx.o 23obj-$(CONFIG_8xx) += softemu8xx.o
33endif 24endif
34
35# These are here while we do the architecture merge
36
37else
38obj-y := idle.o
39obj-$(CONFIG_6xx) += l2cr.o cpu_setup_6xx.o
40obj-$(CONFIG_SOFTWARE_SUSPEND) += swsusp.o
41obj-$(CONFIG_MODULES) += module.o
42obj-$(CONFIG_NOT_COHERENT_CACHE) += dma-mapping.o
43obj-$(CONFIG_KGDB) += ppc-stub.o
44obj-$(CONFIG_TAU) += temp.o
45ifndef CONFIG_E200
46obj-$(CONFIG_FSL_BOOKE) += perfmon_fsl_booke.o
47endif
48endif
diff --git a/arch/ppc/kernel/entry.S b/arch/ppc/kernel/entry.S
index 3a2815978488..5891ecbdc703 100644
--- a/arch/ppc/kernel/entry.S
+++ b/arch/ppc/kernel/entry.S
@@ -135,10 +135,10 @@ transfer_to_handler:
135 mfspr r11,SPRN_HID0 135 mfspr r11,SPRN_HID0
136 mtcr r11 136 mtcr r11
137BEGIN_FTR_SECTION 137BEGIN_FTR_SECTION
138 bt- 8,power_save_6xx_restore /* Check DOZE */ 138 bt- 8,4f /* Check DOZE */
139END_FTR_SECTION_IFSET(CPU_FTR_CAN_DOZE) 139END_FTR_SECTION_IFSET(CPU_FTR_CAN_DOZE)
140BEGIN_FTR_SECTION 140BEGIN_FTR_SECTION
141 bt- 9,power_save_6xx_restore /* Check NAP */ 141 bt- 9,4f /* Check NAP */
142END_FTR_SECTION_IFSET(CPU_FTR_CAN_NAP) 142END_FTR_SECTION_IFSET(CPU_FTR_CAN_NAP)
143#endif /* CONFIG_6xx */ 143#endif /* CONFIG_6xx */
144 .globl transfer_to_handler_cont 144 .globl transfer_to_handler_cont
@@ -157,6 +157,10 @@ transfer_to_handler_cont:
157 SYNC 157 SYNC
158 RFI /* jump to handler, enable MMU */ 158 RFI /* jump to handler, enable MMU */
159 159
160#ifdef CONFIG_6xx
1614: b power_save_6xx_restore
162#endif
163
160/* 164/*
161 * On kernel stack overflow, load up an initial stack pointer 165 * On kernel stack overflow, load up an initial stack pointer
162 * and call StackOverflow(regs), which should not return. 166 * and call StackOverflow(regs), which should not return.
@@ -926,55 +930,3 @@ END_FTR_SECTION_IFSET(CPU_FTR_601)
926 b 4b 930 b 4b
927 931
928 .comm ee_restarts,4 932 .comm ee_restarts,4
929
930/*
931 * PROM code for specific machines follows. Put it
932 * here so it's easy to add arch-specific sections later.
933 * -- Cort
934 */
935#ifdef CONFIG_PPC_OF
936/*
937 * On CHRP, the Run-Time Abstraction Services (RTAS) have to be
938 * called with the MMU off.
939 */
940_GLOBAL(enter_rtas)
941 stwu r1,-INT_FRAME_SIZE(r1)
942 mflr r0
943 stw r0,INT_FRAME_SIZE+4(r1)
944 lis r4,rtas_data@ha
945 lwz r4,rtas_data@l(r4)
946 lis r6,1f@ha /* physical return address for rtas */
947 addi r6,r6,1f@l
948 tophys(r6,r6)
949 tophys(r7,r1)
950 lis r8,rtas_entry@ha
951 lwz r8,rtas_entry@l(r8)
952 mfmsr r9
953 stw r9,8(r1)
954 LOAD_MSR_KERNEL(r0,MSR_KERNEL)
955 SYNC /* disable interrupts so SRR0/1 */
956 MTMSRD(r0) /* don't get trashed */
957 li r9,MSR_KERNEL & ~(MSR_IR|MSR_DR)
958 mtlr r6
959 CLR_TOP32(r7)
960 mtspr SPRN_SPRG2,r7
961 mtspr SPRN_SRR0,r8
962 mtspr SPRN_SRR1,r9
963 RFI
9641: tophys(r9,r1)
965 lwz r8,INT_FRAME_SIZE+4(r9) /* get return address */
966 lwz r9,8(r9) /* original msr value */
967 FIX_SRR1(r9,r0)
968 addi r1,r1,INT_FRAME_SIZE
969 li r0,0
970 mtspr SPRN_SPRG2,r0
971 mtspr SPRN_SRR0,r8
972 mtspr SPRN_SRR1,r9
973 RFI /* return to caller */
974
975 .globl machine_check_in_rtas
976machine_check_in_rtas:
977 twi 31,0,0
978 /* XXX load up BATs and panic */
979
980#endif /* CONFIG_PPC_OF */
diff --git a/arch/ppc/kernel/head.S b/arch/ppc/kernel/head.S
index 53ea845fb911..01303efeddad 100644
--- a/arch/ppc/kernel/head.S
+++ b/arch/ppc/kernel/head.S
@@ -37,19 +37,6 @@
37#include <asm/amigappc.h> 37#include <asm/amigappc.h>
38#endif 38#endif
39 39
40#ifdef CONFIG_PPC64BRIDGE
41#define LOAD_BAT(n, reg, RA, RB) \
42 ld RA,(n*32)+0(reg); \
43 ld RB,(n*32)+8(reg); \
44 mtspr SPRN_IBAT##n##U,RA; \
45 mtspr SPRN_IBAT##n##L,RB; \
46 ld RA,(n*32)+16(reg); \
47 ld RB,(n*32)+24(reg); \
48 mtspr SPRN_DBAT##n##U,RA; \
49 mtspr SPRN_DBAT##n##L,RB; \
50
51#else /* CONFIG_PPC64BRIDGE */
52
53/* 601 only have IBAT; cr0.eq is set on 601 when using this macro */ 40/* 601 only have IBAT; cr0.eq is set on 601 when using this macro */
54#define LOAD_BAT(n, reg, RA, RB) \ 41#define LOAD_BAT(n, reg, RA, RB) \
55 /* see the comment for clear_bats() -- Cort */ \ 42 /* see the comment for clear_bats() -- Cort */ \
@@ -66,7 +53,6 @@
66 mtspr SPRN_DBAT##n##U,RA; \ 53 mtspr SPRN_DBAT##n##U,RA; \
67 mtspr SPRN_DBAT##n##L,RB; \ 54 mtspr SPRN_DBAT##n##L,RB; \
681: 551:
69#endif /* CONFIG_PPC64BRIDGE */
70 56
71 .text 57 .text
72 .stabs "arch/ppc/kernel/",N_SO,0,0,0f 58 .stabs "arch/ppc/kernel/",N_SO,0,0,0f
@@ -129,11 +115,6 @@ _start:
129 115
130 .globl __start 116 .globl __start
131__start: 117__start:
132/*
133 * We have to do any OF calls before we map ourselves to KERNELBASE,
134 * because OF may have I/O devices mapped into that area
135 * (particularly on CHRP).
136 */
137 mr r31,r3 /* save parameters */ 118 mr r31,r3 /* save parameters */
138 mr r30,r4 119 mr r30,r4
139 mr r29,r5 120 mr r29,r5
@@ -148,14 +129,6 @@ __start:
148 */ 129 */
149 bl early_init 130 bl early_init
150 131
151/*
152 * On POWER4, we first need to tweak some CPU configuration registers
153 * like real mode cache inhibit or exception base
154 */
155#ifdef CONFIG_POWER4
156 bl __970_cpu_preinit
157#endif /* CONFIG_POWER4 */
158
159#ifdef CONFIG_APUS 132#ifdef CONFIG_APUS
160/* On APUS the __va/__pa constants need to be set to the correct 133/* On APUS the __va/__pa constants need to be set to the correct
161 * values before continuing. 134 * values before continuing.
@@ -169,7 +142,6 @@ __start:
169 */ 142 */
170 bl mmu_off 143 bl mmu_off
171__after_mmu_off: 144__after_mmu_off:
172#ifndef CONFIG_POWER4
173 bl clear_bats 145 bl clear_bats
174 bl flush_tlbs 146 bl flush_tlbs
175 147
@@ -177,10 +149,6 @@ __after_mmu_off:
177#if !defined(CONFIG_APUS) && defined(CONFIG_BOOTX_TEXT) 149#if !defined(CONFIG_APUS) && defined(CONFIG_BOOTX_TEXT)
178 bl setup_disp_bat 150 bl setup_disp_bat
179#endif 151#endif
180#else /* CONFIG_POWER4 */
181 bl reloc_offset
182 bl initial_mm_power4
183#endif /* CONFIG_POWER4 */
184 152
185/* 153/*
186 * Call setup_cpu for CPU 0 and initialize 6xx Idle 154 * Call setup_cpu for CPU 0 and initialize 6xx Idle
@@ -192,18 +160,11 @@ __after_mmu_off:
192 bl reloc_offset 160 bl reloc_offset
193 bl init_idle_6xx 161 bl init_idle_6xx
194#endif /* CONFIG_6xx */ 162#endif /* CONFIG_6xx */
195#ifdef CONFIG_POWER4
196 bl reloc_offset
197 bl init_idle_power4
198#endif /* CONFIG_POWER4 */
199 163
200 164
201#ifndef CONFIG_APUS 165#ifndef CONFIG_APUS
202/* 166/*
203 * We need to run with _start at physical address 0. 167 * We need to run with _start at physical address 0.
204 * On CHRP, we are loaded at 0x10000 since OF on CHRP uses
205 * the exception vectors at 0 (and therefore this copy
206 * overwrites OF's exception vectors with our own).
207 * If the MMU is already turned on, we copy stuff to KERNELBASE, 168 * If the MMU is already turned on, we copy stuff to KERNELBASE,
208 * otherwise we copy it to 0. 169 * otherwise we copy it to 0.
209 */ 170 */
@@ -358,51 +319,19 @@ i##n: \
358#endif 319#endif
359 320
360/* Machine check */ 321/* Machine check */
361/*
362 * On CHRP, this is complicated by the fact that we could get a
363 * machine check inside RTAS, and we have no guarantee that certain
364 * critical registers will have the values we expect. The set of
365 * registers that might have bad values includes all the GPRs
366 * and all the BATs. We indicate that we are in RTAS by putting
367 * a non-zero value, the address of the exception frame to use,
368 * in SPRG2. The machine check handler checks SPRG2 and uses its
369 * value if it is non-zero. If we ever needed to free up SPRG2,
370 * we could use a field in the thread_info or thread_struct instead.
371 * (Other exception handlers assume that r1 is a valid kernel stack
372 * pointer when we take an exception from supervisor mode.)
373 * -- paulus.
374 */
375 . = 0x200 322 . = 0x200
376 mtspr SPRN_SPRG0,r10 323 mtspr SPRN_SPRG0,r10
377 mtspr SPRN_SPRG1,r11 324 mtspr SPRN_SPRG1,r11
378 mfcr r10 325 mfcr r10
379#ifdef CONFIG_PPC_CHRP
380 mfspr r11,SPRN_SPRG2
381 cmpwi 0,r11,0
382 bne 7f
383#endif /* CONFIG_PPC_CHRP */
384 EXCEPTION_PROLOG_1 326 EXCEPTION_PROLOG_1
3857: EXCEPTION_PROLOG_2 3277: EXCEPTION_PROLOG_2
386 addi r3,r1,STACK_FRAME_OVERHEAD 328 addi r3,r1,STACK_FRAME_OVERHEAD
387#ifdef CONFIG_PPC_CHRP
388 mfspr r4,SPRN_SPRG2
389 cmpwi cr1,r4,0
390 bne cr1,1f
391#endif
392 EXC_XFER_STD(0x200, machine_check_exception) 329 EXC_XFER_STD(0x200, machine_check_exception)
393#ifdef CONFIG_PPC_CHRP
3941: b machine_check_in_rtas
395#endif
396 330
397/* Data access exception. */ 331/* Data access exception. */
398 . = 0x300 332 . = 0x300
399#ifdef CONFIG_PPC64BRIDGE
400 b DataAccess
401DataAccessCont:
402#else
403DataAccess: 333DataAccess:
404 EXCEPTION_PROLOG 334 EXCEPTION_PROLOG
405#endif /* CONFIG_PPC64BRIDGE */
406 mfspr r10,SPRN_DSISR 335 mfspr r10,SPRN_DSISR
407 andis. r0,r10,0xa470 /* weird error? */ 336 andis. r0,r10,0xa470 /* weird error? */
408 bne 1f /* if not, try to put a PTE */ 337 bne 1f /* if not, try to put a PTE */
@@ -414,21 +343,10 @@ DataAccess:
414 mfspr r4,SPRN_DAR 343 mfspr r4,SPRN_DAR
415 EXC_XFER_EE_LITE(0x300, handle_page_fault) 344 EXC_XFER_EE_LITE(0x300, handle_page_fault)
416 345
417#ifdef CONFIG_PPC64BRIDGE
418/* SLB fault on data access. */
419 . = 0x380
420 b DataSegment
421#endif /* CONFIG_PPC64BRIDGE */
422
423/* Instruction access exception. */ 346/* Instruction access exception. */
424 . = 0x400 347 . = 0x400
425#ifdef CONFIG_PPC64BRIDGE
426 b InstructionAccess
427InstructionAccessCont:
428#else
429InstructionAccess: 348InstructionAccess:
430 EXCEPTION_PROLOG 349 EXCEPTION_PROLOG
431#endif /* CONFIG_PPC64BRIDGE */
432 andis. r0,r9,0x4000 /* no pte found? */ 350 andis. r0,r9,0x4000 /* no pte found? */
433 beq 1f /* if so, try to put a PTE */ 351 beq 1f /* if so, try to put a PTE */
434 li r3,0 /* into the hash table */ 352 li r3,0 /* into the hash table */
@@ -438,12 +356,6 @@ InstructionAccess:
438 mr r5,r9 356 mr r5,r9
439 EXC_XFER_EE_LITE(0x400, handle_page_fault) 357 EXC_XFER_EE_LITE(0x400, handle_page_fault)
440 358
441#ifdef CONFIG_PPC64BRIDGE
442/* SLB fault on instruction access. */
443 . = 0x480
444 b InstructionSegment
445#endif /* CONFIG_PPC64BRIDGE */
446
447/* External interrupt */ 359/* External interrupt */
448 EXCEPTION(0x500, HardwareInterrupt, do_IRQ, EXC_XFER_LITE) 360 EXCEPTION(0x500, HardwareInterrupt, do_IRQ, EXC_XFER_LITE)
449 361
@@ -708,15 +620,9 @@ DataStoreTLBMiss:
708 EXCEPTION(0x1300, Trap_13, instruction_breakpoint_exception, EXC_XFER_EE) 620 EXCEPTION(0x1300, Trap_13, instruction_breakpoint_exception, EXC_XFER_EE)
709 EXCEPTION(0x1400, SMI, SMIException, EXC_XFER_EE) 621 EXCEPTION(0x1400, SMI, SMIException, EXC_XFER_EE)
710 EXCEPTION(0x1500, Trap_15, unknown_exception, EXC_XFER_EE) 622 EXCEPTION(0x1500, Trap_15, unknown_exception, EXC_XFER_EE)
711#ifdef CONFIG_POWER4
712 EXCEPTION(0x1600, Trap_16, unknown_exception, EXC_XFER_EE)
713 EXCEPTION(0x1700, Trap_17, altivec_assist_exception, EXC_XFER_EE)
714 EXCEPTION(0x1800, Trap_18, TAUException, EXC_XFER_STD)
715#else /* !CONFIG_POWER4 */
716 EXCEPTION(0x1600, Trap_16, altivec_assist_exception, EXC_XFER_EE) 623 EXCEPTION(0x1600, Trap_16, altivec_assist_exception, EXC_XFER_EE)
717 EXCEPTION(0x1700, Trap_17, TAUException, EXC_XFER_STD) 624 EXCEPTION(0x1700, Trap_17, TAUException, EXC_XFER_STD)
718 EXCEPTION(0x1800, Trap_18, unknown_exception, EXC_XFER_EE) 625 EXCEPTION(0x1800, Trap_18, unknown_exception, EXC_XFER_EE)
719#endif /* CONFIG_POWER4 */
720 EXCEPTION(0x1900, Trap_19, unknown_exception, EXC_XFER_EE) 626 EXCEPTION(0x1900, Trap_19, unknown_exception, EXC_XFER_EE)
721 EXCEPTION(0x1a00, Trap_1a, unknown_exception, EXC_XFER_EE) 627 EXCEPTION(0x1a00, Trap_1a, unknown_exception, EXC_XFER_EE)
722 EXCEPTION(0x1b00, Trap_1b, unknown_exception, EXC_XFER_EE) 628 EXCEPTION(0x1b00, Trap_1b, unknown_exception, EXC_XFER_EE)
@@ -754,28 +660,6 @@ AltiVecUnavailable:
754 addi r3,r1,STACK_FRAME_OVERHEAD 660 addi r3,r1,STACK_FRAME_OVERHEAD
755 EXC_XFER_EE_LITE(0xf20, altivec_unavailable_exception) 661 EXC_XFER_EE_LITE(0xf20, altivec_unavailable_exception)
756 662
757#ifdef CONFIG_PPC64BRIDGE
758DataAccess:
759 EXCEPTION_PROLOG
760 b DataAccessCont
761
762InstructionAccess:
763 EXCEPTION_PROLOG
764 b InstructionAccessCont
765
766DataSegment:
767 EXCEPTION_PROLOG
768 addi r3,r1,STACK_FRAME_OVERHEAD
769 mfspr r4,SPRN_DAR
770 stw r4,_DAR(r11)
771 EXC_XFER_STD(0x380, unknown_exception)
772
773InstructionSegment:
774 EXCEPTION_PROLOG
775 addi r3,r1,STACK_FRAME_OVERHEAD
776 EXC_XFER_STD(0x480, unknown_exception)
777#endif /* CONFIG_PPC64BRIDGE */
778
779#ifdef CONFIG_ALTIVEC 663#ifdef CONFIG_ALTIVEC
780/* Note that the AltiVec support is closely modeled after the FP 664/* Note that the AltiVec support is closely modeled after the FP
781 * support. Changes to one are likely to be applicable to the 665 * support. Changes to one are likely to be applicable to the
@@ -1048,13 +932,6 @@ __secondary_start_pmac_0:
1048 932
1049 .globl __secondary_start 933 .globl __secondary_start
1050__secondary_start: 934__secondary_start:
1051#ifdef CONFIG_PPC64BRIDGE
1052 mfmsr r0
1053 clrldi r0,r0,1 /* make sure it's in 32-bit mode */
1054 SYNC
1055 MTMSRD(r0)
1056 isync
1057#endif
1058 /* Copy some CPU settings from CPU 0 */ 935 /* Copy some CPU settings from CPU 0 */
1059 bl __restore_cpu_setup 936 bl __restore_cpu_setup
1060 937
@@ -1065,10 +942,6 @@ __secondary_start:
1065 lis r3,-KERNELBASE@h 942 lis r3,-KERNELBASE@h
1066 bl init_idle_6xx 943 bl init_idle_6xx
1067#endif /* CONFIG_6xx */ 944#endif /* CONFIG_6xx */
1068#ifdef CONFIG_POWER4
1069 lis r3,-KERNELBASE@h
1070 bl init_idle_power4
1071#endif /* CONFIG_POWER4 */
1072 945
1073 /* get current_thread_info and current */ 946 /* get current_thread_info and current */
1074 lis r1,secondary_ti@ha 947 lis r1,secondary_ti@ha
@@ -1109,12 +982,12 @@ __secondary_start:
1109 * Those generic dummy functions are kept for CPUs not 982 * Those generic dummy functions are kept for CPUs not
1110 * included in CONFIG_6xx 983 * included in CONFIG_6xx
1111 */ 984 */
1112#if !defined(CONFIG_6xx) && !defined(CONFIG_POWER4) 985#if !defined(CONFIG_6xx)
1113_GLOBAL(__save_cpu_setup) 986_GLOBAL(__save_cpu_setup)
1114 blr 987 blr
1115_GLOBAL(__restore_cpu_setup) 988_GLOBAL(__restore_cpu_setup)
1116 blr 989 blr
1117#endif /* !defined(CONFIG_6xx) && !defined(CONFIG_POWER4) */ 990#endif /* !defined(CONFIG_6xx) */
1118 991
1119 992
1120/* 993/*
@@ -1132,11 +1005,6 @@ load_up_mmu:
1132 tophys(r6,r6) 1005 tophys(r6,r6)
1133 lwz r6,_SDR1@l(r6) 1006 lwz r6,_SDR1@l(r6)
1134 mtspr SPRN_SDR1,r6 1007 mtspr SPRN_SDR1,r6
1135#ifdef CONFIG_PPC64BRIDGE
1136 /* clear the ASR so we only use the pseudo-segment registers. */
1137 li r6,0
1138 mtasr r6
1139#endif /* CONFIG_PPC64BRIDGE */
1140 li r0,16 /* load up segment register values */ 1008 li r0,16 /* load up segment register values */
1141 mtctr r0 /* for context 0 */ 1009 mtctr r0 /* for context 0 */
1142 lis r3,0x2000 /* Ku = 1, VSID = 0 */ 1010 lis r3,0x2000 /* Ku = 1, VSID = 0 */
@@ -1145,7 +1013,7 @@ load_up_mmu:
1145 addi r3,r3,0x111 /* increment VSID */ 1013 addi r3,r3,0x111 /* increment VSID */
1146 addis r4,r4,0x1000 /* address of next segment */ 1014 addis r4,r4,0x1000 /* address of next segment */
1147 bdnz 3b 1015 bdnz 3b
1148#ifndef CONFIG_POWER4 1016
1149/* Load the BAT registers with the values set up by MMU_init. 1017/* Load the BAT registers with the values set up by MMU_init.
1150 MMU_init takes care of whether we're on a 601 or not. */ 1018 MMU_init takes care of whether we're on a 601 or not. */
1151 mfpvr r3 1019 mfpvr r3
@@ -1158,7 +1026,7 @@ load_up_mmu:
1158 LOAD_BAT(1,r3,r4,r5) 1026 LOAD_BAT(1,r3,r4,r5)
1159 LOAD_BAT(2,r3,r4,r5) 1027 LOAD_BAT(2,r3,r4,r5)
1160 LOAD_BAT(3,r3,r4,r5) 1028 LOAD_BAT(3,r3,r4,r5)
1161#endif /* CONFIG_POWER4 */ 1029
1162 blr 1030 blr
1163 1031
1164/* 1032/*
@@ -1269,9 +1137,6 @@ _GLOBAL(set_context)
1269 li r4,0 1137 li r4,0
1270 isync 1138 isync
12713: 11393:
1272#ifdef CONFIG_PPC64BRIDGE
1273 slbie r4
1274#endif /* CONFIG_PPC64BRIDGE */
1275 mtsrin r3,r4 1140 mtsrin r3,r4
1276 addi r3,r3,0x111 /* next VSID */ 1141 addi r3,r3,0x111 /* next VSID */
1277 rlwinm r3,r3,0,8,3 /* clear out any overflow from VSID field */ 1142 rlwinm r3,r3,0,8,3 /* clear out any overflow from VSID field */
@@ -1358,7 +1223,6 @@ mmu_off:
1358 sync 1223 sync
1359 RFI 1224 RFI
1360 1225
1361#ifndef CONFIG_POWER4
1362/* 1226/*
1363 * Use the first pair of BAT registers to map the 1st 16MB 1227 * Use the first pair of BAT registers to map the 1st 16MB
1364 * of RAM to KERNELBASE. From this point on we can't safely 1228 * of RAM to KERNELBASE. From this point on we can't safely
@@ -1366,7 +1230,6 @@ mmu_off:
1366 */ 1230 */
1367initial_bats: 1231initial_bats:
1368 lis r11,KERNELBASE@h 1232 lis r11,KERNELBASE@h
1369#ifndef CONFIG_PPC64BRIDGE
1370 mfspr r9,SPRN_PVR 1233 mfspr r9,SPRN_PVR
1371 rlwinm r9,r9,16,16,31 /* r9 = 1 for 601, 4 for 604 */ 1234 rlwinm r9,r9,16,16,31 /* r9 = 1 for 601, 4 for 604 */
1372 cmpwi 0,r9,1 1235 cmpwi 0,r9,1
@@ -1381,7 +1244,6 @@ initial_bats:
1381 mtspr SPRN_IBAT1L,r10 1244 mtspr SPRN_IBAT1L,r10
1382 isync 1245 isync
1383 blr 1246 blr
1384#endif /* CONFIG_PPC64BRIDGE */
1385 1247
13864: tophys(r8,r11) 12484: tophys(r8,r11)
1387#ifdef CONFIG_SMP 1249#ifdef CONFIG_SMP
@@ -1395,11 +1257,6 @@ initial_bats:
1395 ori r11,r11,BL_256M<<2|0x2 /* set up BAT registers for 604 */ 1257 ori r11,r11,BL_256M<<2|0x2 /* set up BAT registers for 604 */
1396#endif /* CONFIG_APUS */ 1258#endif /* CONFIG_APUS */
1397 1259
1398#ifdef CONFIG_PPC64BRIDGE
1399 /* clear out the high 32 bits in the BAT */
1400 clrldi r11,r11,32
1401 clrldi r8,r8,32
1402#endif /* CONFIG_PPC64BRIDGE */
1403 mtspr SPRN_DBAT0L,r8 /* N.B. 6xx (not 601) have valid */ 1260 mtspr SPRN_DBAT0L,r8 /* N.B. 6xx (not 601) have valid */
1404 mtspr SPRN_DBAT0U,r11 /* bit in upper BAT register */ 1261 mtspr SPRN_DBAT0U,r11 /* bit in upper BAT register */
1405 mtspr SPRN_IBAT0L,r8 1262 mtspr SPRN_IBAT0L,r8
@@ -1432,38 +1289,6 @@ setup_disp_bat:
1432 1289
1433#endif /* !defined(CONFIG_APUS) && defined(CONFIG_BOOTX_TEXT) */ 1290#endif /* !defined(CONFIG_APUS) && defined(CONFIG_BOOTX_TEXT) */
1434 1291
1435#else /* CONFIG_POWER4 */
1436/*
1437 * Load up the SDR1 and segment register values now
1438 * since we don't have the BATs.
1439 * Also make sure we are running in 32-bit mode.
1440 */
1441
1442initial_mm_power4:
1443 addis r14,r3,_SDR1@ha /* get the value from _SDR1 */
1444 lwz r14,_SDR1@l(r14) /* assume hash table below 4GB */
1445 mtspr SPRN_SDR1,r14
1446 slbia
1447 lis r4,0x2000 /* set pseudo-segment reg 12 */
1448 ori r5,r4,0x0ccc
1449 mtsr 12,r5
1450#if 0
1451 ori r5,r4,0x0888 /* set pseudo-segment reg 8 */
1452 mtsr 8,r5 /* (for access to serial port) */
1453#endif
1454#ifdef CONFIG_BOOTX_TEXT
1455 ori r5,r4,0x0999 /* set pseudo-segment reg 9 */
1456 mtsr 9,r5 /* (for access to screen) */
1457#endif
1458 mfmsr r0
1459 clrldi r0,r0,1
1460 sync
1461 mtmsr r0
1462 isync
1463 blr
1464
1465#endif /* CONFIG_POWER4 */
1466
1467#ifdef CONFIG_8260 1292#ifdef CONFIG_8260
1468/* Jump into the system reset for the rom. 1293/* Jump into the system reset for the rom.
1469 * We first disable the MMU, and then jump to the ROM reset address. 1294 * We first disable the MMU, and then jump to the ROM reset address.
diff --git a/arch/ppc/kernel/idle.c b/arch/ppc/kernel/idle.c
deleted file mode 100644
index 1be3ca5bae40..000000000000
--- a/arch/ppc/kernel/idle.c
+++ /dev/null
@@ -1,112 +0,0 @@
1/*
2 * Idle daemon for PowerPC. Idle daemon will handle any action
3 * that needs to be taken when the system becomes idle.
4 *
5 * Written by Cort Dougan (cort@cs.nmt.edu). Subsequently hacked
6 * on by Tom Rini, Armin Kuster, Paul Mackerras and others.
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version
11 * 2 of the License, or (at your option) any later version.
12 */
13#include <linux/config.h>
14#include <linux/errno.h>
15#include <linux/sched.h>
16#include <linux/kernel.h>
17#include <linux/mm.h>
18#include <linux/smp.h>
19#include <linux/smp_lock.h>
20#include <linux/stddef.h>
21#include <linux/unistd.h>
22#include <linux/ptrace.h>
23#include <linux/slab.h>
24#include <linux/sysctl.h>
25#include <linux/cpu.h>
26
27#include <asm/pgtable.h>
28#include <asm/uaccess.h>
29#include <asm/system.h>
30#include <asm/io.h>
31#include <asm/mmu.h>
32#include <asm/cache.h>
33#include <asm/cputable.h>
34#include <asm/machdep.h>
35#include <asm/smp.h>
36
37void default_idle(void)
38{
39 void (*powersave)(void);
40
41 powersave = ppc_md.power_save;
42
43 if (!need_resched()) {
44 if (powersave != NULL)
45 powersave();
46#ifdef CONFIG_SMP
47 else {
48 set_thread_flag(TIF_POLLING_NRFLAG);
49 while (!need_resched() &&
50 !cpu_is_offline(smp_processor_id()))
51 barrier();
52 clear_thread_flag(TIF_POLLING_NRFLAG);
53 }
54#endif
55 }
56}
57
58/*
59 * The body of the idle task.
60 */
61void cpu_idle(void)
62{
63 int cpu = smp_processor_id();
64
65 for (;;) {
66 while (!need_resched()) {
67 if (ppc_md.idle != NULL)
68 ppc_md.idle();
69 else
70 default_idle();
71 }
72
73 if (cpu_is_offline(cpu) && system_state == SYSTEM_RUNNING)
74 cpu_die();
75 preempt_enable_no_resched();
76 schedule();
77 preempt_disable();
78 }
79}
80
81#if defined(CONFIG_SYSCTL) && defined(CONFIG_6xx)
82/*
83 * Register the sysctl to set/clear powersave_nap.
84 */
85extern int powersave_nap;
86
87static ctl_table powersave_nap_ctl_table[]={
88 {
89 .ctl_name = KERN_PPC_POWERSAVE_NAP,
90 .procname = "powersave-nap",
91 .data = &powersave_nap,
92 .maxlen = sizeof(int),
93 .mode = 0644,
94 .proc_handler = &proc_dointvec,
95 },
96 { 0, },
97};
98static ctl_table powersave_nap_sysctl_root[] = {
99 { 1, "kernel", NULL, 0, 0755, powersave_nap_ctl_table, },
100 { 0,},
101};
102
103static int __init
104register_powersave_nap_sysctl(void)
105{
106 register_sysctl_table(powersave_nap_sysctl_root, 0);
107
108 return 0;
109}
110
111__initcall(register_powersave_nap_sysctl);
112#endif
diff --git a/arch/ppc/kernel/idle_6xx.S b/arch/ppc/kernel/idle_6xx.S
deleted file mode 100644
index 1a2194cf6828..000000000000
--- a/arch/ppc/kernel/idle_6xx.S
+++ /dev/null
@@ -1,233 +0,0 @@
1/*
2 * This file contains the power_save function for 6xx & 7xxx CPUs
3 * rewritten in assembler
4 *
5 * Warning ! This code assumes that if your machine has a 750fx
6 * it will have PLL 1 set to low speed mode (used during NAP/DOZE).
7 * if this is not the case some additional changes will have to
8 * be done to check a runtime var (a bit like powersave-nap)
9 *
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version
13 * 2 of the License, or (at your option) any later version.
14 */
15
16#include <linux/config.h>
17#include <linux/threads.h>
18#include <asm/processor.h>
19#include <asm/page.h>
20#include <asm/cputable.h>
21#include <asm/thread_info.h>
22#include <asm/ppc_asm.h>
23#include <asm/asm-offsets.h>
24
25#undef DEBUG
26
27 .text
28
29/*
30 * Init idle, called at early CPU setup time from head.S for each CPU
31 * Make sure no rest of NAP mode remains in HID0, save default
32 * values for some CPU specific registers. Called with r24
33 * containing CPU number and r3 reloc offset
34 */
35_GLOBAL(init_idle_6xx)
36BEGIN_FTR_SECTION
37 mfspr r4,SPRN_HID0
38 rlwinm r4,r4,0,10,8 /* Clear NAP */
39 mtspr SPRN_HID0, r4
40 b 1f
41END_FTR_SECTION_IFSET(CPU_FTR_CAN_NAP)
42 blr
431:
44 slwi r5,r24,2
45 add r5,r5,r3
46BEGIN_FTR_SECTION
47 mfspr r4,SPRN_MSSCR0
48 addis r6,r5, nap_save_msscr0@ha
49 stw r4,nap_save_msscr0@l(r6)
50END_FTR_SECTION_IFSET(CPU_FTR_NAP_DISABLE_L2_PR)
51BEGIN_FTR_SECTION
52 mfspr r4,SPRN_HID1
53 addis r6,r5,nap_save_hid1@ha
54 stw r4,nap_save_hid1@l(r6)
55END_FTR_SECTION_IFSET(CPU_FTR_DUAL_PLL_750FX)
56 blr
57
58/*
59 * Here is the power_save_6xx function. This could eventually be
60 * split into several functions & changing the function pointer
61 * depending on the various features.
62 */
63_GLOBAL(ppc6xx_idle)
64 /* Check if we can nap or doze, put HID0 mask in r3
65 */
66 lis r3, 0
67BEGIN_FTR_SECTION
68 lis r3,HID0_DOZE@h
69END_FTR_SECTION_IFSET(CPU_FTR_CAN_DOZE)
70BEGIN_FTR_SECTION
71 /* We must dynamically check for the NAP feature as it
72 * can be cleared by CPU init after the fixups are done
73 */
74 lis r4,cur_cpu_spec@ha
75 lwz r4,cur_cpu_spec@l(r4)
76 lwz r4,CPU_SPEC_FEATURES(r4)
77 andi. r0,r4,CPU_FTR_CAN_NAP
78 beq 1f
79 /* Now check if user or arch enabled NAP mode */
80 lis r4,powersave_nap@ha
81 lwz r4,powersave_nap@l(r4)
82 cmpwi 0,r4,0
83 beq 1f
84 lis r3,HID0_NAP@h
851:
86END_FTR_SECTION_IFSET(CPU_FTR_CAN_NAP)
87 cmpwi 0,r3,0
88 beqlr
89
90 /* Clear MSR:EE */
91 mfmsr r7
92 rlwinm r0,r7,0,17,15
93 mtmsr r0
94
95 /* Check current_thread_info()->flags */
96 rlwinm r4,r1,0,0,18
97 lwz r4,TI_FLAGS(r4)
98 andi. r0,r4,_TIF_NEED_RESCHED
99 beq 1f
100 mtmsr r7 /* out of line this ? */
101 blr
1021:
103 /* Some pre-nap cleanups needed on some CPUs */
104 andis. r0,r3,HID0_NAP@h
105 beq 2f
106BEGIN_FTR_SECTION
107 /* Disable L2 prefetch on some 745x and try to ensure
108 * L2 prefetch engines are idle. As explained by errata
109 * text, we can't be sure they are, we just hope very hard
110 * that well be enough (sic !). At least I noticed Apple
111 * doesn't even bother doing the dcbf's here...
112 */
113 mfspr r4,SPRN_MSSCR0
114 rlwinm r4,r4,0,0,29
115 sync
116 mtspr SPRN_MSSCR0,r4
117 sync
118 isync
119 lis r4,KERNELBASE@h
120 dcbf 0,r4
121 dcbf 0,r4
122 dcbf 0,r4
123 dcbf 0,r4
124END_FTR_SECTION_IFSET(CPU_FTR_NAP_DISABLE_L2_PR)
125#ifdef DEBUG
126 lis r6,nap_enter_count@ha
127 lwz r4,nap_enter_count@l(r6)
128 addi r4,r4,1
129 stw r4,nap_enter_count@l(r6)
130#endif
1312:
132BEGIN_FTR_SECTION
133 /* Go to low speed mode on some 750FX */
134 lis r4,powersave_lowspeed@ha
135 lwz r4,powersave_lowspeed@l(r4)
136 cmpwi 0,r4,0
137 beq 1f
138 mfspr r4,SPRN_HID1
139 oris r4,r4,0x0001
140 mtspr SPRN_HID1,r4
1411:
142END_FTR_SECTION_IFSET(CPU_FTR_DUAL_PLL_750FX)
143
144 /* Go to NAP or DOZE now */
145 mfspr r4,SPRN_HID0
146 lis r5,(HID0_NAP|HID0_SLEEP)@h
147BEGIN_FTR_SECTION
148 oris r5,r5,HID0_DOZE@h
149END_FTR_SECTION_IFSET(CPU_FTR_CAN_DOZE)
150 andc r4,r4,r5
151 or r4,r4,r3
152BEGIN_FTR_SECTION
153 oris r4,r4,HID0_DPM@h /* that should be done once for all */
154END_FTR_SECTION_IFCLR(CPU_FTR_NO_DPM)
155 mtspr SPRN_HID0,r4
156BEGIN_FTR_SECTION
157 DSSALL
158 sync
159END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
160 ori r7,r7,MSR_EE /* Could be ommited (already set) */
161 oris r7,r7,MSR_POW@h
162 sync
163 isync
164 mtmsr r7
165 isync
166 sync
167 blr
168
169/*
170 * Return from NAP/DOZE mode, restore some CPU specific registers,
171 * we are called with DR/IR still off and r2 containing physical
172 * address of current.
173 */
174_GLOBAL(power_save_6xx_restore)
175 mfspr r11,SPRN_HID0
176 rlwinm. r11,r11,0,10,8 /* Clear NAP & copy NAP bit !state to cr1 EQ */
177 cror 4*cr1+eq,4*cr0+eq,4*cr0+eq
178BEGIN_FTR_SECTION
179 rlwinm r11,r11,0,9,7 /* Clear DOZE */
180END_FTR_SECTION_IFSET(CPU_FTR_CAN_DOZE)
181 mtspr SPRN_HID0, r11
182
183#ifdef DEBUG
184 beq cr1,1f
185 lis r11,(nap_return_count-KERNELBASE)@ha
186 lwz r9,nap_return_count@l(r11)
187 addi r9,r9,1
188 stw r9,nap_return_count@l(r11)
1891:
190#endif
191
192 rlwinm r9,r1,0,0,18
193 tophys(r9,r9)
194 lwz r11,TI_CPU(r9)
195 slwi r11,r11,2
196 /* Todo make sure all these are in the same page
197 * and load r22 (@ha part + CPU offset) only once
198 */
199BEGIN_FTR_SECTION
200 beq cr1,1f
201 addis r9,r11,(nap_save_msscr0-KERNELBASE)@ha
202 lwz r9,nap_save_msscr0@l(r9)
203 mtspr SPRN_MSSCR0, r9
204 sync
205 isync
2061:
207END_FTR_SECTION_IFSET(CPU_FTR_NAP_DISABLE_L2_PR)
208BEGIN_FTR_SECTION
209 addis r9,r11,(nap_save_hid1-KERNELBASE)@ha
210 lwz r9,nap_save_hid1@l(r9)
211 mtspr SPRN_HID1, r9
212END_FTR_SECTION_IFSET(CPU_FTR_DUAL_PLL_750FX)
213 b transfer_to_handler_cont
214
215 .data
216
217_GLOBAL(nap_save_msscr0)
218 .space 4*NR_CPUS
219
220_GLOBAL(nap_save_hid1)
221 .space 4*NR_CPUS
222
223_GLOBAL(powersave_nap)
224 .long 0
225_GLOBAL(powersave_lowspeed)
226 .long 0
227
228#ifdef DEBUG
229_GLOBAL(nap_enter_count)
230 .space 4
231_GLOBAL(nap_return_count)
232 .space 4
233#endif
diff --git a/arch/ppc/kernel/idle_power4.S b/arch/ppc/kernel/idle_power4.S
deleted file mode 100644
index cc0d535365cd..000000000000
--- a/arch/ppc/kernel/idle_power4.S
+++ /dev/null
@@ -1,91 +0,0 @@
1/*
2 * This file contains the power_save function for 6xx & 7xxx CPUs
3 * rewritten in assembler
4 *
5 * Warning ! This code assumes that if your machine has a 750fx
6 * it will have PLL 1 set to low speed mode (used during NAP/DOZE).
7 * if this is not the case some additional changes will have to
8 * be done to check a runtime var (a bit like powersave-nap)
9 *
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version
13 * 2 of the License, or (at your option) any later version.
14 */
15
16#include <linux/config.h>
17#include <linux/threads.h>
18#include <asm/processor.h>
19#include <asm/page.h>
20#include <asm/cputable.h>
21#include <asm/thread_info.h>
22#include <asm/ppc_asm.h>
23#include <asm/asm-offsets.h>
24
25#undef DEBUG
26
27 .text
28
29/*
30 * Init idle, called at early CPU setup time from head.S for each CPU
31 * So nothing for now. Called with r24 containing CPU number and r3
32 * reloc offset
33 */
34 .globl init_idle_power4
35init_idle_power4:
36 blr
37
38/*
39 * Here is the power_save_6xx function. This could eventually be
40 * split into several functions & changing the function pointer
41 * depending on the various features.
42 */
43 .globl power4_idle
44power4_idle:
45BEGIN_FTR_SECTION
46 blr
47END_FTR_SECTION_IFCLR(CPU_FTR_CAN_NAP)
48 /* We must dynamically check for the NAP feature as it
49 * can be cleared by CPU init after the fixups are done
50 */
51 lis r4,cur_cpu_spec@ha
52 lwz r4,cur_cpu_spec@l(r4)
53 lwz r4,CPU_SPEC_FEATURES(r4)
54 andi. r0,r4,CPU_FTR_CAN_NAP
55 beqlr
56 /* Now check if user or arch enabled NAP mode */
57 lis r4,powersave_nap@ha
58 lwz r4,powersave_nap@l(r4)
59 cmpwi 0,r4,0
60 beqlr
61
62 /* Clear MSR:EE */
63 mfmsr r7
64 rlwinm r0,r7,0,17,15
65 mtmsr r0
66
67 /* Check current_thread_info()->flags */
68 rlwinm r4,r1,0,0,18
69 lwz r4,TI_FLAGS(r4)
70 andi. r0,r4,_TIF_NEED_RESCHED
71 beq 1f
72 mtmsr r7 /* out of line this ? */
73 blr
741:
75 /* Go to NAP now */
76BEGIN_FTR_SECTION
77 DSSALL
78 sync
79END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
80 ori r7,r7,MSR_EE /* Could be ommited (already set) */
81 oris r7,r7,MSR_POW@h
82 sync
83 isync
84 mtmsr r7
85 isync
86 sync
87 blr
88
89 .globl powersave_nap
90powersave_nap:
91 .long 0
diff --git a/arch/ppc/kernel/pci.c b/arch/ppc/kernel/pci.c
index 04d04c5bfdd0..809673a36f7a 100644
--- a/arch/ppc/kernel/pci.c
+++ b/arch/ppc/kernel/pci.c
@@ -46,9 +46,6 @@ static void pcibios_fixup_resources(struct pci_dev* dev);
46static void fixup_broken_pcnet32(struct pci_dev* dev); 46static void fixup_broken_pcnet32(struct pci_dev* dev);
47static int reparent_resources(struct resource *parent, struct resource *res); 47static int reparent_resources(struct resource *parent, struct resource *res);
48static void fixup_cpc710_pci64(struct pci_dev* dev); 48static void fixup_cpc710_pci64(struct pci_dev* dev);
49#ifdef CONFIG_PPC_OF
50static u8* pci_to_OF_bus_map;
51#endif
52 49
53/* By default, we don't re-assign bus numbers. 50/* By default, we don't re-assign bus numbers.
54 */ 51 */
@@ -625,406 +622,13 @@ pcibios_alloc_controller(void)
625 return hose; 622 return hose;
626} 623}
627 624
628#ifdef CONFIG_PPC_OF
629/*
630 * Functions below are used on OpenFirmware machines.
631 */
632static void
633make_one_node_map(struct device_node* node, u8 pci_bus)
634{
635 int *bus_range;
636 int len;
637
638 if (pci_bus >= pci_bus_count)
639 return;
640 bus_range = (int *) get_property(node, "bus-range", &len);
641 if (bus_range == NULL || len < 2 * sizeof(int)) {
642 printk(KERN_WARNING "Can't get bus-range for %s, "
643 "assuming it starts at 0\n", node->full_name);
644 pci_to_OF_bus_map[pci_bus] = 0;
645 } else
646 pci_to_OF_bus_map[pci_bus] = bus_range[0];
647
648 for (node=node->child; node != 0;node = node->sibling) {
649 struct pci_dev* dev;
650 unsigned int *class_code, *reg;
651
652 class_code = (unsigned int *) get_property(node, "class-code", NULL);
653 if (!class_code || ((*class_code >> 8) != PCI_CLASS_BRIDGE_PCI &&
654 (*class_code >> 8) != PCI_CLASS_BRIDGE_CARDBUS))
655 continue;
656 reg = (unsigned int *)get_property(node, "reg", NULL);
657 if (!reg)
658 continue;
659 dev = pci_find_slot(pci_bus, ((reg[0] >> 8) & 0xff));
660 if (!dev || !dev->subordinate)
661 continue;
662 make_one_node_map(node, dev->subordinate->number);
663 }
664}
665
666void
667pcibios_make_OF_bus_map(void)
668{
669 int i;
670 struct pci_controller* hose;
671 u8* of_prop_map;
672
673 pci_to_OF_bus_map = (u8*)kmalloc(pci_bus_count, GFP_KERNEL);
674 if (!pci_to_OF_bus_map) {
675 printk(KERN_ERR "Can't allocate OF bus map !\n");
676 return;
677 }
678
679 /* We fill the bus map with invalid values, that helps
680 * debugging.
681 */
682 for (i=0; i<pci_bus_count; i++)
683 pci_to_OF_bus_map[i] = 0xff;
684
685 /* For each hose, we begin searching bridges */
686 for(hose=hose_head; hose; hose=hose->next) {
687 struct device_node* node;
688 node = (struct device_node *)hose->arch_data;
689 if (!node)
690 continue;
691 make_one_node_map(node, hose->first_busno);
692 }
693 of_prop_map = get_property(find_path_device("/"), "pci-OF-bus-map", NULL);
694 if (of_prop_map)
695 memcpy(of_prop_map, pci_to_OF_bus_map, pci_bus_count);
696#ifdef DEBUG
697 printk("PCI->OF bus map:\n");
698 for (i=0; i<pci_bus_count; i++) {
699 if (pci_to_OF_bus_map[i] == 0xff)
700 continue;
701 printk("%d -> %d\n", i, pci_to_OF_bus_map[i]);
702 }
703#endif
704}
705
706typedef int (*pci_OF_scan_iterator)(struct device_node* node, void* data);
707
708static struct device_node*
709scan_OF_pci_childs(struct device_node* node, pci_OF_scan_iterator filter, void* data)
710{
711 struct device_node* sub_node;
712
713 for (; node != 0;node = node->sibling) {
714 unsigned int *class_code;
715
716 if (filter(node, data))
717 return node;
718
719 /* For PCI<->PCI bridges or CardBus bridges, we go down
720 * Note: some OFs create a parent node "multifunc-device" as
721 * a fake root for all functions of a multi-function device,
722 * we go down them as well.
723 */
724 class_code = (unsigned int *) get_property(node, "class-code", NULL);
725 if ((!class_code || ((*class_code >> 8) != PCI_CLASS_BRIDGE_PCI &&
726 (*class_code >> 8) != PCI_CLASS_BRIDGE_CARDBUS)) &&
727 strcmp(node->name, "multifunc-device"))
728 continue;
729 sub_node = scan_OF_pci_childs(node->child, filter, data);
730 if (sub_node)
731 return sub_node;
732 }
733 return NULL;
734}
735
736static int
737scan_OF_pci_childs_iterator(struct device_node* node, void* data)
738{
739 unsigned int *reg;
740 u8* fdata = (u8*)data;
741
742 reg = (unsigned int *) get_property(node, "reg", NULL);
743 if (reg && ((reg[0] >> 8) & 0xff) == fdata[1]
744 && ((reg[0] >> 16) & 0xff) == fdata[0])
745 return 1;
746 return 0;
747}
748
749static struct device_node*
750scan_OF_childs_for_device(struct device_node* node, u8 bus, u8 dev_fn)
751{
752 u8 filter_data[2] = {bus, dev_fn};
753
754 return scan_OF_pci_childs(node, scan_OF_pci_childs_iterator, filter_data);
755}
756
757/*
758 * Scans the OF tree for a device node matching a PCI device
759 */
760struct device_node *
761pci_busdev_to_OF_node(struct pci_bus *bus, int devfn)
762{
763 struct pci_controller *hose;
764 struct device_node *node;
765 int busnr;
766
767 if (!have_of)
768 return NULL;
769
770 /* Lookup the hose */
771 busnr = bus->number;
772 hose = pci_bus_to_hose(busnr);
773 if (!hose)
774 return NULL;
775
776 /* Check it has an OF node associated */
777 node = (struct device_node *) hose->arch_data;
778 if (!node)
779 return NULL;
780
781 /* Fixup bus number according to what OF think it is. */
782 if (pci_to_OF_bus_map)
783 busnr = pci_to_OF_bus_map[busnr];
784 if (busnr == 0xff)
785 return NULL;
786
787 /* Now, lookup childs of the hose */
788 return scan_OF_childs_for_device(node->child, busnr, devfn);
789}
790EXPORT_SYMBOL(pci_busdev_to_OF_node);
791
792struct device_node*
793pci_device_to_OF_node(struct pci_dev *dev)
794{
795 return pci_busdev_to_OF_node(dev->bus, dev->devfn);
796}
797EXPORT_SYMBOL(pci_device_to_OF_node);
798
799/* This routine is meant to be used early during boot, when the
800 * PCI bus numbers have not yet been assigned, and you need to
801 * issue PCI config cycles to an OF device.
802 * It could also be used to "fix" RTAS config cycles if you want
803 * to set pci_assign_all_buses to 1 and still use RTAS for PCI
804 * config cycles.
805 */
806struct pci_controller* pci_find_hose_for_OF_device(struct device_node* node)
807{
808 if (!have_of)
809 return NULL;
810 while(node) {
811 struct pci_controller* hose;
812 for (hose=hose_head;hose;hose=hose->next)
813 if (hose->arch_data == node)
814 return hose;
815 node=node->parent;
816 }
817 return NULL;
818}
819
820static int
821find_OF_pci_device_filter(struct device_node* node, void* data)
822{
823 return ((void *)node == data);
824}
825
826/*
827 * Returns the PCI device matching a given OF node
828 */
829int
830pci_device_from_OF_node(struct device_node* node, u8* bus, u8* devfn)
831{
832 unsigned int *reg;
833 struct pci_controller* hose;
834 struct pci_dev* dev = NULL;
835
836 if (!have_of)
837 return -ENODEV;
838 /* Make sure it's really a PCI device */
839 hose = pci_find_hose_for_OF_device(node);
840 if (!hose || !hose->arch_data)
841 return -ENODEV;
842 if (!scan_OF_pci_childs(((struct device_node*)hose->arch_data)->child,
843 find_OF_pci_device_filter, (void *)node))
844 return -ENODEV;
845 reg = (unsigned int *) get_property(node, "reg", NULL);
846 if (!reg)
847 return -ENODEV;
848 *bus = (reg[0] >> 16) & 0xff;
849 *devfn = ((reg[0] >> 8) & 0xff);
850
851 /* Ok, here we need some tweak. If we have already renumbered
852 * all busses, we can't rely on the OF bus number any more.
853 * the pci_to_OF_bus_map is not enough as several PCI busses
854 * may match the same OF bus number.
855 */
856 if (!pci_to_OF_bus_map)
857 return 0;
858
859 for_each_pci_dev(dev)
860 if (pci_to_OF_bus_map[dev->bus->number] == *bus &&
861 dev->devfn == *devfn) {
862 *bus = dev->bus->number;
863 pci_dev_put(dev);
864 return 0;
865 }
866
867 return -ENODEV;
868}
869EXPORT_SYMBOL(pci_device_from_OF_node);
870
871void __init
872pci_process_bridge_OF_ranges(struct pci_controller *hose,
873 struct device_node *dev, int primary)
874{
875 static unsigned int static_lc_ranges[256] __initdata;
876 unsigned int *dt_ranges, *lc_ranges, *ranges, *prev;
877 unsigned int size;
878 int rlen = 0, orig_rlen;
879 int memno = 0;
880 struct resource *res;
881 int np, na = prom_n_addr_cells(dev);
882 np = na + 5;
883
884 /* First we try to merge ranges to fix a problem with some pmacs
885 * that can have more than 3 ranges, fortunately using contiguous
886 * addresses -- BenH
887 */
888 dt_ranges = (unsigned int *) get_property(dev, "ranges", &rlen);
889 if (!dt_ranges)
890 return;
891 /* Sanity check, though hopefully that never happens */
892 if (rlen > sizeof(static_lc_ranges)) {
893 printk(KERN_WARNING "OF ranges property too large !\n");
894 rlen = sizeof(static_lc_ranges);
895 }
896 lc_ranges = static_lc_ranges;
897 memcpy(lc_ranges, dt_ranges, rlen);
898 orig_rlen = rlen;
899
900 /* Let's work on a copy of the "ranges" property instead of damaging
901 * the device-tree image in memory
902 */
903 ranges = lc_ranges;
904 prev = NULL;
905 while ((rlen -= np * sizeof(unsigned int)) >= 0) {
906 if (prev) {
907 if (prev[0] == ranges[0] && prev[1] == ranges[1] &&
908 (prev[2] + prev[na+4]) == ranges[2] &&
909 (prev[na+2] + prev[na+4]) == ranges[na+2]) {
910 prev[na+4] += ranges[na+4];
911 ranges[0] = 0;
912 ranges += np;
913 continue;
914 }
915 }
916 prev = ranges;
917 ranges += np;
918 }
919
920 /*
921 * The ranges property is laid out as an array of elements,
922 * each of which comprises:
923 * cells 0 - 2: a PCI address
924 * cells 3 or 3+4: a CPU physical address
925 * (size depending on dev->n_addr_cells)
926 * cells 4+5 or 5+6: the size of the range
927 */
928 ranges = lc_ranges;
929 rlen = orig_rlen;
930 while (ranges && (rlen -= np * sizeof(unsigned int)) >= 0) {
931 res = NULL;
932 size = ranges[na+4];
933 switch ((ranges[0] >> 24) & 0x3) {
934 case 1: /* I/O space */
935 if (ranges[2] != 0)
936 break;
937 hose->io_base_phys = ranges[na+2];
938 /* limit I/O space to 16MB */
939 if (size > 0x01000000)
940 size = 0x01000000;
941 hose->io_base_virt = ioremap(ranges[na+2], size);
942 if (primary)
943 isa_io_base = (unsigned long) hose->io_base_virt;
944 res = &hose->io_resource;
945 res->flags = IORESOURCE_IO;
946 res->start = ranges[2];
947 DBG("PCI: IO 0x%lx -> 0x%lx\n",
948 res->start, res->start + size - 1);
949 break;
950 case 2: /* memory space */
951 memno = 0;
952 if (ranges[1] == 0 && ranges[2] == 0
953 && ranges[na+4] <= (16 << 20)) {
954 /* 1st 16MB, i.e. ISA memory area */
955 if (primary)
956 isa_mem_base = ranges[na+2];
957 memno = 1;
958 }
959 while (memno < 3 && hose->mem_resources[memno].flags)
960 ++memno;
961 if (memno == 0)
962 hose->pci_mem_offset = ranges[na+2] - ranges[2];
963 if (memno < 3) {
964 res = &hose->mem_resources[memno];
965 res->flags = IORESOURCE_MEM;
966 if(ranges[0] & 0x40000000)
967 res->flags |= IORESOURCE_PREFETCH;
968 res->start = ranges[na+2];
969 DBG("PCI: MEM[%d] 0x%lx -> 0x%lx\n", memno,
970 res->start, res->start + size - 1);
971 }
972 break;
973 }
974 if (res != NULL) {
975 res->name = dev->full_name;
976 res->end = res->start + size - 1;
977 res->parent = NULL;
978 res->sibling = NULL;
979 res->child = NULL;
980 }
981 ranges += np;
982 }
983}
984
985/* We create the "pci-OF-bus-map" property now so it appears in the
986 * /proc device tree
987 */
988void __init
989pci_create_OF_bus_map(void)
990{
991 struct property* of_prop;
992
993 of_prop = (struct property*) alloc_bootmem(sizeof(struct property) + 256);
994 if (of_prop && find_path_device("/")) {
995 memset(of_prop, -1, sizeof(struct property) + 256);
996 of_prop->name = "pci-OF-bus-map";
997 of_prop->length = 256;
998 of_prop->value = (unsigned char *)&of_prop[1];
999 prom_add_property(find_path_device("/"), of_prop);
1000 }
1001}
1002
1003static ssize_t pci_show_devspec(struct device *dev, struct device_attribute *attr, char *buf)
1004{
1005 struct pci_dev *pdev;
1006 struct device_node *np;
1007
1008 pdev = to_pci_dev (dev);
1009 np = pci_device_to_OF_node(pdev);
1010 if (np == NULL || np->full_name == NULL)
1011 return 0;
1012 return sprintf(buf, "%s", np->full_name);
1013}
1014static DEVICE_ATTR(devspec, S_IRUGO, pci_show_devspec, NULL);
1015
1016#else /* CONFIG_PPC_OF */
1017void pcibios_make_OF_bus_map(void) 625void pcibios_make_OF_bus_map(void)
1018{ 626{
1019} 627}
1020#endif /* CONFIG_PPC_OF */
1021 628
1022/* Add sysfs properties */ 629/* Add sysfs properties */
1023void pcibios_add_platform_entries(struct pci_dev *pdev) 630void pcibios_add_platform_entries(struct pci_dev *pdev)
1024{ 631{
1025#ifdef CONFIG_PPC_OF
1026 device_create_file(&pdev->dev, &dev_attr_devspec);
1027#endif /* CONFIG_PPC_OF */
1028} 632}
1029 633
1030 634
diff --git a/arch/ppc/kernel/ppc_htab.c b/arch/ppc/kernel/ppc_htab.c
index 9b84bffdefce..75c645043746 100644
--- a/arch/ppc/kernel/ppc_htab.c
+++ b/arch/ppc/kernel/ppc_htab.c
@@ -104,7 +104,7 @@ static char *pmc2_lookup(unsigned long mmcr0)
104static int ppc_htab_show(struct seq_file *m, void *v) 104static int ppc_htab_show(struct seq_file *m, void *v)
105{ 105{
106 unsigned long mmcr0 = 0, pmc1 = 0, pmc2 = 0; 106 unsigned long mmcr0 = 0, pmc1 = 0, pmc2 = 0;
107#if defined(CONFIG_PPC_STD_MMU) && !defined(CONFIG_PPC64BRIDGE) 107#if defined(CONFIG_PPC_STD_MMU)
108 unsigned int kptes = 0, uptes = 0; 108 unsigned int kptes = 0, uptes = 0;
109 PTE *ptr; 109 PTE *ptr;
110#endif /* CONFIG_PPC_STD_MMU */ 110#endif /* CONFIG_PPC_STD_MMU */
@@ -133,7 +133,6 @@ static int ppc_htab_show(struct seq_file *m, void *v)
133 return 0; 133 return 0;
134 } 134 }
135 135
136#ifndef CONFIG_PPC64BRIDGE
137 for (ptr = Hash; ptr < Hash_end; ptr++) { 136 for (ptr = Hash; ptr < Hash_end; ptr++) {
138 unsigned int mctx, vsid; 137 unsigned int mctx, vsid;
139 138
@@ -147,7 +146,6 @@ static int ppc_htab_show(struct seq_file *m, void *v)
147 else 146 else
148 uptes++; 147 uptes++;
149 } 148 }
150#endif
151 149
152 seq_printf(m, 150 seq_printf(m,
153 "PTE Hash Table Information\n" 151 "PTE Hash Table Information\n"
@@ -155,20 +153,16 @@ static int ppc_htab_show(struct seq_file *m, void *v)
155 "Buckets\t\t: %lu\n" 153 "Buckets\t\t: %lu\n"
156 "Address\t\t: %08lx\n" 154 "Address\t\t: %08lx\n"
157 "Entries\t\t: %lu\n" 155 "Entries\t\t: %lu\n"
158#ifndef CONFIG_PPC64BRIDGE
159 "User ptes\t: %u\n" 156 "User ptes\t: %u\n"
160 "Kernel ptes\t: %u\n" 157 "Kernel ptes\t: %u\n"
161 "Percent full\t: %lu%%\n" 158 "Percent full\t: %lu%%\n"
162#endif
163 , (unsigned long)(Hash_size>>10), 159 , (unsigned long)(Hash_size>>10),
164 (Hash_size/(sizeof(PTE)*8)), 160 (Hash_size/(sizeof(PTE)*8)),
165 (unsigned long)Hash, 161 (unsigned long)Hash,
166 Hash_size/sizeof(PTE) 162 Hash_size/sizeof(PTE)
167#ifndef CONFIG_PPC64BRIDGE
168 , uptes, 163 , uptes,
169 kptes, 164 kptes,
170 ((kptes+uptes)*100) / (Hash_size/sizeof(PTE)) 165 ((kptes+uptes)*100) / (Hash_size/sizeof(PTE))
171#endif
172 ); 166 );
173 167
174 seq_printf(m, 168 seq_printf(m,
diff --git a/arch/ppc/kernel/ppc_ksyms.c b/arch/ppc/kernel/ppc_ksyms.c
index 82adb4601348..865ba74991a9 100644
--- a/arch/ppc/kernel/ppc_ksyms.c
+++ b/arch/ppc/kernel/ppc_ksyms.c
@@ -18,7 +18,6 @@
18#include <linux/bitops.h> 18#include <linux/bitops.h>
19 19
20#include <asm/page.h> 20#include <asm/page.h>
21#include <asm/semaphore.h>
22#include <asm/processor.h> 21#include <asm/processor.h>
23#include <asm/uaccess.h> 22#include <asm/uaccess.h>
24#include <asm/io.h> 23#include <asm/io.h>
@@ -30,7 +29,6 @@
30#include <linux/adb.h> 29#include <linux/adb.h>
31#include <linux/cuda.h> 30#include <linux/cuda.h>
32#include <linux/pmu.h> 31#include <linux/pmu.h>
33#include <asm/prom.h>
34#include <asm/system.h> 32#include <asm/system.h>
35#include <asm/pci-bridge.h> 33#include <asm/pci-bridge.h>
36#include <asm/irq.h> 34#include <asm/irq.h>
@@ -208,27 +206,6 @@ EXPORT_SYMBOL(adb_try_handler_change);
208EXPORT_SYMBOL(cuda_request); 206EXPORT_SYMBOL(cuda_request);
209EXPORT_SYMBOL(cuda_poll); 207EXPORT_SYMBOL(cuda_poll);
210#endif /* CONFIG_ADB_CUDA */ 208#endif /* CONFIG_ADB_CUDA */
211#ifdef CONFIG_PPC_OF
212EXPORT_SYMBOL(find_devices);
213EXPORT_SYMBOL(find_type_devices);
214EXPORT_SYMBOL(find_compatible_devices);
215EXPORT_SYMBOL(find_path_device);
216EXPORT_SYMBOL(device_is_compatible);
217EXPORT_SYMBOL(machine_is_compatible);
218EXPORT_SYMBOL(find_all_nodes);
219EXPORT_SYMBOL(get_property);
220EXPORT_SYMBOL(request_OF_resource);
221EXPORT_SYMBOL(release_OF_resource);
222EXPORT_SYMBOL(of_find_node_by_name);
223EXPORT_SYMBOL(of_find_node_by_type);
224EXPORT_SYMBOL(of_find_compatible_node);
225EXPORT_SYMBOL(of_find_node_by_path);
226EXPORT_SYMBOL(of_find_all_nodes);
227EXPORT_SYMBOL(of_get_parent);
228EXPORT_SYMBOL(of_get_next_child);
229EXPORT_SYMBOL(of_node_get);
230EXPORT_SYMBOL(of_node_put);
231#endif /* CONFIG_PPC_OF */
232#if defined(CONFIG_BOOTX_TEXT) 209#if defined(CONFIG_BOOTX_TEXT)
233EXPORT_SYMBOL(btext_update_display); 210EXPORT_SYMBOL(btext_update_display);
234#endif 211#endif
@@ -262,9 +239,6 @@ EXPORT_SYMBOL(console_drivers);
262EXPORT_SYMBOL(xmon); 239EXPORT_SYMBOL(xmon);
263EXPORT_SYMBOL(xmon_printf); 240EXPORT_SYMBOL(xmon_printf);
264#endif 241#endif
265EXPORT_SYMBOL(__up);
266EXPORT_SYMBOL(__down);
267EXPORT_SYMBOL(__down_interruptible);
268 242
269#if defined(CONFIG_KGDB) || defined(CONFIG_XMON) 243#if defined(CONFIG_KGDB) || defined(CONFIG_XMON)
270extern void (*debugger)(struct pt_regs *regs); 244extern void (*debugger)(struct pt_regs *regs);
diff --git a/arch/ppc/kernel/setup.c b/arch/ppc/kernel/setup.c
index 53e9deacee82..1f79e84ab464 100644
--- a/arch/ppc/kernel/setup.c
+++ b/arch/ppc/kernel/setup.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Common prep/chrp boot and setup code. 2 * Common prep boot and setup code.
3 */ 3 */
4 4
5#include <linux/config.h> 5#include <linux/config.h>
@@ -72,17 +72,12 @@ unsigned long ISA_DMA_THRESHOLD;
72unsigned int DMA_MODE_READ; 72unsigned int DMA_MODE_READ;
73unsigned int DMA_MODE_WRITE; 73unsigned int DMA_MODE_WRITE;
74 74
75#ifdef CONFIG_PPC_MULTIPLATFORM 75#ifdef CONFIG_PPC_PREP
76int _machine = 0;
77EXPORT_SYMBOL(_machine);
78
79extern void prep_init(unsigned long r3, unsigned long r4, 76extern void prep_init(unsigned long r3, unsigned long r4,
80 unsigned long r5, unsigned long r6, unsigned long r7); 77 unsigned long r5, unsigned long r6, unsigned long r7);
81extern void chrp_init(unsigned long r3, unsigned long r4,
82 unsigned long r5, unsigned long r6, unsigned long r7);
83 78
84dev_t boot_dev; 79dev_t boot_dev;
85#endif /* CONFIG_PPC_MULTIPLATFORM */ 80#endif /* CONFIG_PPC_PREP */
86 81
87int have_of; 82int have_of;
88EXPORT_SYMBOL(have_of); 83EXPORT_SYMBOL(have_of);
@@ -319,72 +314,12 @@ early_init(int r3, int r4, int r5)
319 identify_cpu(offset, 0); 314 identify_cpu(offset, 0);
320 do_cpu_ftr_fixups(offset); 315 do_cpu_ftr_fixups(offset);
321 316
322#if defined(CONFIG_PPC_OF)
323 reloc_got2(offset);
324
325 /*
326 * don't do anything on prep
327 * for now, don't use bootinfo because it breaks yaboot 0.5
328 * and assume that if we didn't find a magic number, we have OF
329 */
330 if (*(unsigned long *)(0) != 0xdeadc0de)
331 phys = prom_init(r3, r4, (prom_entry)r5);
332
333 reloc_got2(-offset);
334#endif
335
336 return phys; 317 return phys;
337} 318}
338 319
339#ifdef CONFIG_PPC_OF 320#ifdef CONFIG_PPC_PREP
340/*
341 * Assume here that all clock rates are the same in a
342 * smp system. -- Cort
343 */
344int
345of_show_percpuinfo(struct seq_file *m, int i)
346{
347 struct device_node *cpu_node;
348 u32 *fp;
349 int s;
350
351 cpu_node = find_type_devices("cpu");
352 if (!cpu_node)
353 return 0;
354 for (s = 0; s < i && cpu_node->next; s++)
355 cpu_node = cpu_node->next;
356 fp = (u32 *)get_property(cpu_node, "clock-frequency", NULL);
357 if (fp)
358 seq_printf(m, "clock\t\t: %dMHz\n", *fp / 1000000);
359 return 0;
360}
361
362void __init
363intuit_machine_type(void)
364{
365 char *model;
366 struct device_node *root;
367
368 /* ask the OF info if we're a chrp or pmac */
369 root = find_path_device("/");
370 if (root != 0) {
371 /* assume pmac unless proven to be chrp -- Cort */
372 _machine = _MACH_Pmac;
373 model = get_property(root, "device_type", NULL);
374 if (model && !strncmp("chrp", model, 4))
375 _machine = _MACH_chrp;
376 else {
377 model = get_property(root, "model", NULL);
378 if (model && !strncmp(model, "IBM", 3))
379 _machine = _MACH_chrp;
380 }
381 }
382}
383#endif
384
385#ifdef CONFIG_PPC_MULTIPLATFORM
386/* 321/*
387 * The PPC_MULTIPLATFORM version of platform_init... 322 * The PPC_PREP version of platform_init...
388 */ 323 */
389void __init 324void __init
390platform_init(unsigned long r3, unsigned long r4, unsigned long r5, 325platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
@@ -399,161 +334,9 @@ platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
399 334
400 parse_bootinfo(find_bootinfo()); 335 parse_bootinfo(find_bootinfo());
401 336
402 /* if we didn't get any bootinfo telling us what we are... */ 337 prep_init(r3, r4, r5, r6, r7);
403 if (_machine == 0) {
404 /* prep boot loader tells us if we're prep or not */
405 if ( *(unsigned long *)(KERNELBASE) == (0xdeadc0de) )
406 _machine = _MACH_prep;
407 }
408
409#ifdef CONFIG_PPC_PREP
410 /* not much more to do here, if prep */
411 if (_machine == _MACH_prep) {
412 prep_init(r3, r4, r5, r6, r7);
413 return;
414 }
415#endif
416
417#ifdef CONFIG_PPC_OF
418 have_of = 1;
419
420 /* prom_init has already been called from __start */
421 if (boot_infos)
422 relocate_nodes();
423
424 /* If we aren't PReP, we can find out if we're Pmac
425 * or CHRP with this. */
426 if (_machine == 0)
427 intuit_machine_type();
428
429 /* finish_device_tree may need _machine defined. */
430 finish_device_tree();
431
432 /*
433 * If we were booted via quik, r3 points to the physical
434 * address of the command-line parameters.
435 * If we were booted from an xcoff image (i.e. netbooted or
436 * booted from floppy), we get the command line from the
437 * bootargs property of the /chosen node.
438 * If an initial ramdisk is present, r3 and r4
439 * are used for initrd_start and initrd_size,
440 * otherwise they contain 0xdeadbeef.
441 */
442 if (r3 >= 0x4000 && r3 < 0x800000 && r4 == 0) {
443 strlcpy(cmd_line, (char *)r3 + KERNELBASE,
444 sizeof(cmd_line));
445 } else if (boot_infos != 0) {
446 /* booted by BootX - check for ramdisk */
447 if (boot_infos->kernelParamsOffset != 0)
448 strlcpy(cmd_line, (char *) boot_infos
449 + boot_infos->kernelParamsOffset,
450 sizeof(cmd_line));
451#ifdef CONFIG_BLK_DEV_INITRD
452 if (boot_infos->ramDisk) {
453 initrd_start = (unsigned long) boot_infos
454 + boot_infos->ramDisk;
455 initrd_end = initrd_start + boot_infos->ramDiskSize;
456 initrd_below_start_ok = 1;
457 }
458#endif
459 } else {
460 struct device_node *chosen;
461 char *p;
462
463#ifdef CONFIG_BLK_DEV_INITRD
464 if (r3 && r4 && r4 != 0xdeadbeef) {
465 if (r3 < KERNELBASE)
466 r3 += KERNELBASE;
467 initrd_start = r3;
468 initrd_end = r3 + r4;
469 ROOT_DEV = Root_RAM0;
470 initrd_below_start_ok = 1;
471 }
472#endif
473 chosen = find_devices("chosen");
474 if (chosen != NULL) {
475 p = get_property(chosen, "bootargs", NULL);
476 if (p && *p) {
477 strlcpy(cmd_line, p, sizeof(cmd_line));
478 }
479 }
480 }
481#ifdef CONFIG_ADB
482 if (strstr(cmd_line, "adb_sync")) {
483 extern int __adb_probe_sync;
484 __adb_probe_sync = 1;
485 }
486#endif /* CONFIG_ADB */
487
488 switch (_machine) {
489#ifdef CONFIG_PPC_CHRP
490 case _MACH_chrp:
491 chrp_init(r3, r4, r5, r6, r7);
492 break;
493#endif
494 }
495#endif /* CONFIG_PPC_OF */
496} 338}
497#endif /* CONFIG_PPC_MULTIPLATFORM */ 339#endif /* CONFIG_PPC_PREP */
498
499#ifdef CONFIG_PPC_OF
500#ifdef CONFIG_SERIAL_CORE_CONSOLE
501extern char *of_stdout_device;
502
503static int __init set_preferred_console(void)
504{
505 struct device_node *prom_stdout;
506 char *name;
507 int offset = 0;
508
509 if (of_stdout_device == NULL)
510 return -ENODEV;
511
512 /* The user has requested a console so this is already set up. */
513 if (strstr(saved_command_line, "console="))
514 return -EBUSY;
515
516 prom_stdout = find_path_device(of_stdout_device);
517 if (!prom_stdout)
518 return -ENODEV;
519
520 name = (char *)get_property(prom_stdout, "name", NULL);
521 if (!name)
522 return -ENODEV;
523
524 if (strcmp(name, "serial") == 0) {
525 int i;
526 u32 *reg = (u32 *)get_property(prom_stdout, "reg", &i);
527 if (i > 8) {
528 switch (reg[1]) {
529 case 0x3f8:
530 offset = 0;
531 break;
532 case 0x2f8:
533 offset = 1;
534 break;
535 case 0x898:
536 offset = 2;
537 break;
538 case 0x890:
539 offset = 3;
540 break;
541 default:
542 /* We dont recognise the serial port */
543 return -ENODEV;
544 }
545 }
546 } else if (strcmp(name, "ch-a") == 0)
547 offset = 0;
548 else if (strcmp(name, "ch-b") == 0)
549 offset = 1;
550 else
551 return -ENODEV;
552 return add_preferred_console("ttyS", offset, NULL);
553}
554console_initcall(set_preferred_console);
555#endif /* CONFIG_SERIAL_CORE_CONSOLE */
556#endif /* CONFIG_PPC_OF */
557 340
558struct bi_record *find_bootinfo(void) 341struct bi_record *find_bootinfo(void)
559{ 342{
@@ -589,23 +372,6 @@ void parse_bootinfo(struct bi_record *rec)
589 initrd_end = data[0] + data[1] + KERNELBASE; 372 initrd_end = data[0] + data[1] + KERNELBASE;
590 break; 373 break;
591#endif /* CONFIG_BLK_DEV_INITRD */ 374#endif /* CONFIG_BLK_DEV_INITRD */
592#ifdef CONFIG_PPC_MULTIPLATFORM
593 case BI_MACHTYPE:
594 /* Machine types changed with the merge. Since the
595 * bootinfo are now deprecated, we can just hard code
596 * the appropriate conversion here for when we are
597 * called with yaboot which passes us a machine type
598 * this way.
599 */
600 switch(data[0]) {
601 case 1: _machine = _MACH_prep; break;
602 case 2: _machine = _MACH_Pmac; break;
603 case 4: _machine = _MACH_chrp; break;
604 default:
605 _machine = data[0];
606 }
607 break;
608#endif
609 case BI_MEMSIZE: 375 case BI_MEMSIZE:
610 boot_mem_size = data[0]; 376 boot_mem_size = data[0];
611 break; 377 break;
@@ -631,9 +397,6 @@ machine_init(unsigned long r3, unsigned long r4, unsigned long r5,
631#ifdef CONFIG_6xx 397#ifdef CONFIG_6xx
632 ppc_md.power_save = ppc6xx_idle; 398 ppc_md.power_save = ppc6xx_idle;
633#endif 399#endif
634#ifdef CONFIG_POWER4
635 ppc_md.power_save = power4_idle;
636#endif
637 400
638 platform_init(r3, r4, r5, r6, r7); 401 platform_init(r3, r4, r5, r6, r7);
639 402
@@ -711,7 +474,7 @@ int __init ppc_init(void)
711 if ( ppc_md.progress ) ppc_md.progress(" ", 0xffff); 474 if ( ppc_md.progress ) ppc_md.progress(" ", 0xffff);
712 475
713 /* register CPU devices */ 476 /* register CPU devices */
714 for_each_cpu(i) 477 for_each_possible_cpu(i)
715 register_cpu(&cpu_devices[i], i, NULL); 478 register_cpu(&cpu_devices[i], i, NULL);
716 479
717 /* call platform init */ 480 /* call platform init */
@@ -799,7 +562,4 @@ void __init setup_arch(char **cmdline_p)
799 if ( ppc_md.progress ) ppc_md.progress("arch: exit", 0x3eab); 562 if ( ppc_md.progress ) ppc_md.progress("arch: exit", 0x3eab);
800 563
801 paging_init(); 564 paging_init();
802
803 /* this is for modules since _machine can be a define -- Cort */
804 ppc_md.ppc_machine = _machine;
805} 565}
diff --git a/arch/ppc/kernel/smp.c b/arch/ppc/kernel/smp.c
index e55cdda6149a..f77795a64dae 100644
--- a/arch/ppc/kernel/smp.c
+++ b/arch/ppc/kernel/smp.c
@@ -311,7 +311,7 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
311 /* Backup CPU 0 state */ 311 /* Backup CPU 0 state */
312 __save_cpu_setup(); 312 __save_cpu_setup();
313 313
314 for_each_cpu(cpu) { 314 for_each_possible_cpu(cpu) {
315 if (cpu == smp_processor_id()) 315 if (cpu == smp_processor_id())
316 continue; 316 continue;
317 /* create a process for the processor */ 317 /* create a process for the processor */
diff --git a/arch/ppc/lib/strcase.c b/arch/ppc/lib/strcase.c
index 36b521091bbc..3b0094cc2b52 100644
--- a/arch/ppc/lib/strcase.c
+++ b/arch/ppc/lib/strcase.c
@@ -1,4 +1,5 @@
1#include <linux/ctype.h> 1#include <linux/ctype.h>
2#include <linux/types.h>
2 3
3int strcasecmp(const char *s1, const char *s2) 4int strcasecmp(const char *s1, const char *s2)
4{ 5{
@@ -11,7 +12,7 @@ int strcasecmp(const char *s1, const char *s2)
11 return c1 - c2; 12 return c1 - c2;
12} 13}
13 14
14int strncasecmp(const char *s1, const char *s2, int n) 15int strncasecmp(const char *s1, const char *s2, size_t n)
15{ 16{
16 int c1, c2; 17 int c1, c2;
17 18
diff --git a/arch/ppc/mm/fault.c b/arch/ppc/mm/fault.c
index 0217188ef465..8e08ca32531a 100644
--- a/arch/ppc/mm/fault.c
+++ b/arch/ppc/mm/fault.c
@@ -202,6 +202,7 @@ good_area:
202 /* an exec - 4xx/Book-E allows for per-page execute permission */ 202 /* an exec - 4xx/Book-E allows for per-page execute permission */
203 } else if (TRAP(regs) == 0x400) { 203 } else if (TRAP(regs) == 0x400) {
204 pte_t *ptep; 204 pte_t *ptep;
205 pmd_t *pmdp;
205 206
206#if 0 207#if 0
207 /* It would be nice to actually enforce the VM execute 208 /* It would be nice to actually enforce the VM execute
@@ -215,21 +216,24 @@ good_area:
215 /* Since 4xx/Book-E supports per-page execute permission, 216 /* Since 4xx/Book-E supports per-page execute permission,
216 * we lazily flush dcache to icache. */ 217 * we lazily flush dcache to icache. */
217 ptep = NULL; 218 ptep = NULL;
218 if (get_pteptr(mm, address, &ptep) && pte_present(*ptep)) { 219 if (get_pteptr(mm, address, &ptep, &pmdp)) {
219 struct page *page = pte_page(*ptep); 220 spinlock_t *ptl = pte_lockptr(mm, pmdp);
220 221 spin_lock(ptl);
221 if (! test_bit(PG_arch_1, &page->flags)) { 222 if (pte_present(*ptep)) {
222 flush_dcache_icache_page(page); 223 struct page *page = pte_page(*ptep);
223 set_bit(PG_arch_1, &page->flags); 224
225 if (!test_bit(PG_arch_1, &page->flags)) {
226 flush_dcache_icache_page(page);
227 set_bit(PG_arch_1, &page->flags);
228 }
229 pte_update(ptep, 0, _PAGE_HWEXEC);
230 _tlbie(address);
231 pte_unmap_unlock(ptep, ptl);
232 up_read(&mm->mmap_sem);
233 return 0;
224 } 234 }
225 pte_update(ptep, 0, _PAGE_HWEXEC); 235 pte_unmap_unlock(ptep, ptl);
226 _tlbie(address);
227 pte_unmap(ptep);
228 up_read(&mm->mmap_sem);
229 return 0;
230 } 236 }
231 if (ptep != NULL)
232 pte_unmap(ptep);
233#endif 237#endif
234 /* a read */ 238 /* a read */
235 } else { 239 } else {
diff --git a/arch/ppc/mm/hashtable.S b/arch/ppc/mm/hashtable.S
index f09fa88db35a..31d0a924317c 100644
--- a/arch/ppc/mm/hashtable.S
+++ b/arch/ppc/mm/hashtable.S
@@ -74,12 +74,6 @@ _GLOBAL(hash_page_sync)
74 */ 74 */
75 .text 75 .text
76_GLOBAL(hash_page) 76_GLOBAL(hash_page)
77#ifdef CONFIG_PPC64BRIDGE
78 mfmsr r0
79 clrldi r0,r0,1 /* make sure it's in 32-bit mode */
80 MTMSRD(r0)
81 isync
82#endif
83 tophys(r7,0) /* gets -KERNELBASE into r7 */ 77 tophys(r7,0) /* gets -KERNELBASE into r7 */
84#ifdef CONFIG_SMP 78#ifdef CONFIG_SMP
85 addis r8,r7,mmu_hash_lock@h 79 addis r8,r7,mmu_hash_lock@h
@@ -303,7 +297,6 @@ Hash_base = 0xc0180000
303Hash_bits = 12 /* e.g. 256kB hash table */ 297Hash_bits = 12 /* e.g. 256kB hash table */
304Hash_msk = (((1 << Hash_bits) - 1) * 64) 298Hash_msk = (((1 << Hash_bits) - 1) * 64)
305 299
306#ifndef CONFIG_PPC64BRIDGE
307/* defines for the PTE format for 32-bit PPCs */ 300/* defines for the PTE format for 32-bit PPCs */
308#define PTE_SIZE 8 301#define PTE_SIZE 8
309#define PTEG_SIZE 64 302#define PTEG_SIZE 64
@@ -317,21 +310,6 @@ Hash_msk = (((1 << Hash_bits) - 1) * 64)
317#define SET_V(r) oris r,r,PTE_V@h 310#define SET_V(r) oris r,r,PTE_V@h
318#define CLR_V(r,t) rlwinm r,r,0,1,31 311#define CLR_V(r,t) rlwinm r,r,0,1,31
319 312
320#else
321/* defines for the PTE format for 64-bit PPCs */
322#define PTE_SIZE 16
323#define PTEG_SIZE 128
324#define LG_PTEG_SIZE 7
325#define LDPTEu ldu
326#define STPTE std
327#define CMPPTE cmpd
328#define PTE_H 2
329#define PTE_V 1
330#define TST_V(r) andi. r,r,PTE_V
331#define SET_V(r) ori r,r,PTE_V
332#define CLR_V(r,t) li t,PTE_V; andc r,r,t
333#endif /* CONFIG_PPC64BRIDGE */
334
335#define HASH_LEFT 31-(LG_PTEG_SIZE+Hash_bits-1) 313#define HASH_LEFT 31-(LG_PTEG_SIZE+Hash_bits-1)
336#define HASH_RIGHT 31-LG_PTEG_SIZE 314#define HASH_RIGHT 31-LG_PTEG_SIZE
337 315
@@ -349,14 +327,8 @@ BEGIN_FTR_SECTION
349END_FTR_SECTION_IFSET(CPU_FTR_NEED_COHERENT) 327END_FTR_SECTION_IFSET(CPU_FTR_NEED_COHERENT)
350 328
351 /* Construct the high word of the PPC-style PTE (r5) */ 329 /* Construct the high word of the PPC-style PTE (r5) */
352#ifndef CONFIG_PPC64BRIDGE
353 rlwinm r5,r3,7,1,24 /* put VSID in 0x7fffff80 bits */ 330 rlwinm r5,r3,7,1,24 /* put VSID in 0x7fffff80 bits */
354 rlwimi r5,r4,10,26,31 /* put in API (abbrev page index) */ 331 rlwimi r5,r4,10,26,31 /* put in API (abbrev page index) */
355#else /* CONFIG_PPC64BRIDGE */
356 clrlwi r3,r3,8 /* reduce vsid to 24 bits */
357 sldi r5,r3,12 /* shift vsid into position */
358 rlwimi r5,r4,16,20,24 /* put in API (abbrev page index) */
359#endif /* CONFIG_PPC64BRIDGE */
360 SET_V(r5) /* set V (valid) bit */ 332 SET_V(r5) /* set V (valid) bit */
361 333
362 /* Get the address of the primary PTE group in the hash table (r3) */ 334 /* Get the address of the primary PTE group in the hash table (r3) */
@@ -540,14 +512,8 @@ _GLOBAL(flush_hash_pages)
540 add r3,r3,r0 /* note code below trims to 24 bits */ 512 add r3,r3,r0 /* note code below trims to 24 bits */
541 513
542 /* Construct the high word of the PPC-style PTE (r11) */ 514 /* Construct the high word of the PPC-style PTE (r11) */
543#ifndef CONFIG_PPC64BRIDGE
544 rlwinm r11,r3,7,1,24 /* put VSID in 0x7fffff80 bits */ 515 rlwinm r11,r3,7,1,24 /* put VSID in 0x7fffff80 bits */
545 rlwimi r11,r4,10,26,31 /* put in API (abbrev page index) */ 516 rlwimi r11,r4,10,26,31 /* put in API (abbrev page index) */
546#else /* CONFIG_PPC64BRIDGE */
547 clrlwi r3,r3,8 /* reduce vsid to 24 bits */
548 sldi r11,r3,12 /* shift vsid into position */
549 rlwimi r11,r4,16,20,24 /* put in API (abbrev page index) */
550#endif /* CONFIG_PPC64BRIDGE */
551 SET_V(r11) /* set V (valid) bit */ 517 SET_V(r11) /* set V (valid) bit */
552 518
553#ifdef CONFIG_SMP 519#ifdef CONFIG_SMP
diff --git a/arch/ppc/mm/init.c b/arch/ppc/mm/init.c
index cb1c294fb932..386e000bcb73 100644
--- a/arch/ppc/mm/init.c
+++ b/arch/ppc/mm/init.c
@@ -412,14 +412,6 @@ void __init mem_init(void)
412 } 412 }
413#endif /* CONFIG_BLK_DEV_INITRD */ 413#endif /* CONFIG_BLK_DEV_INITRD */
414 414
415#ifdef CONFIG_PPC_OF
416 /* mark the RTAS pages as reserved */
417 if ( rtas_data )
418 for (addr = (ulong)__va(rtas_data);
419 addr < PAGE_ALIGN((ulong)__va(rtas_data)+rtas_size) ;
420 addr += PAGE_SIZE)
421 SetPageReserved(virt_to_page(addr));
422#endif
423 for (addr = PAGE_OFFSET; addr < (unsigned long)high_memory; 415 for (addr = PAGE_OFFSET; addr < (unsigned long)high_memory;
424 addr += PAGE_SIZE) { 416 addr += PAGE_SIZE) {
425 if (!PageReserved(virt_to_page(addr))) 417 if (!PageReserved(virt_to_page(addr)))
@@ -494,11 +486,6 @@ set_phys_avail(unsigned long total_memory)
494 initrd_end - initrd_start, 1); 486 initrd_end - initrd_start, 1);
495 } 487 }
496#endif /* CONFIG_BLK_DEV_INITRD */ 488#endif /* CONFIG_BLK_DEV_INITRD */
497#ifdef CONFIG_PPC_OF
498 /* remove the RTAS pages from the available memory */
499 if (rtas_data)
500 mem_pieces_remove(&phys_avail, rtas_data, rtas_size, 1);
501#endif
502} 489}
503 490
504/* Mark some memory as reserved by removing it from phys_avail. */ 491/* Mark some memory as reserved by removing it from phys_avail. */
diff --git a/arch/ppc/mm/mmu_context.c b/arch/ppc/mm/mmu_context.c
index a8816e0f6a86..b4a4b3f02a1c 100644
--- a/arch/ppc/mm/mmu_context.c
+++ b/arch/ppc/mm/mmu_context.c
@@ -2,7 +2,7 @@
2 * This file contains the routines for handling the MMU on those 2 * This file contains the routines for handling the MMU on those
3 * PowerPC implementations where the MMU substantially follows the 3 * PowerPC implementations where the MMU substantially follows the
4 * architecture specification. This includes the 6xx, 7xx, 7xxx, 4 * architecture specification. This includes the 6xx, 7xx, 7xxx,
5 * 8260, and POWER3 implementations but excludes the 8xx and 4xx. 5 * 8260, and 83xx implementations but excludes the 8xx and 4xx.
6 * -- paulus 6 * -- paulus
7 * 7 *
8 * Derived from arch/ppc/mm/init.c: 8 * Derived from arch/ppc/mm/init.c:
diff --git a/arch/ppc/mm/pgtable.c b/arch/ppc/mm/pgtable.c
index 6ea9185fd120..706bca8eb144 100644
--- a/arch/ppc/mm/pgtable.c
+++ b/arch/ppc/mm/pgtable.c
@@ -39,7 +39,7 @@ unsigned long ioremap_base;
39unsigned long ioremap_bot; 39unsigned long ioremap_bot;
40int io_bat_index; 40int io_bat_index;
41 41
42#if defined(CONFIG_6xx) || defined(CONFIG_POWER3) 42#if defined(CONFIG_6xx)
43#define HAVE_BATS 1 43#define HAVE_BATS 1
44#endif 44#endif
45 45
@@ -368,7 +368,7 @@ void __init io_block_mapping(unsigned long virt, phys_addr_t phys,
368 * the PTE pointer is unmodified if PTE is not found. 368 * the PTE pointer is unmodified if PTE is not found.
369 */ 369 */
370int 370int
371get_pteptr(struct mm_struct *mm, unsigned long addr, pte_t **ptep) 371get_pteptr(struct mm_struct *mm, unsigned long addr, pte_t **ptep, pmd_t **pmdp)
372{ 372{
373 pgd_t *pgd; 373 pgd_t *pgd;
374 pmd_t *pmd; 374 pmd_t *pmd;
@@ -383,6 +383,8 @@ get_pteptr(struct mm_struct *mm, unsigned long addr, pte_t **ptep)
383 if (pte) { 383 if (pte) {
384 retval = 1; 384 retval = 1;
385 *ptep = pte; 385 *ptep = pte;
386 if (pmdp)
387 *pmdp = pmd;
386 /* XXX caller needs to do pte_unmap, yuck */ 388 /* XXX caller needs to do pte_unmap, yuck */
387 } 389 }
388 } 390 }
@@ -420,7 +422,7 @@ unsigned long iopa(unsigned long addr)
420 mm = &init_mm; 422 mm = &init_mm;
421 423
422 pa = 0; 424 pa = 0;
423 if (get_pteptr(mm, addr, &pte)) { 425 if (get_pteptr(mm, addr, &pte, NULL)) {
424 pa = (pte_val(*pte) & PAGE_MASK) | (addr & ~PAGE_MASK); 426 pa = (pte_val(*pte) & PAGE_MASK) | (addr & ~PAGE_MASK);
425 pte_unmap(pte); 427 pte_unmap(pte);
426 } 428 }
diff --git a/arch/ppc/mm/ppc_mmu.c b/arch/ppc/mm/ppc_mmu.c
index 9a381ed5eb21..25bb6f3347c1 100644
--- a/arch/ppc/mm/ppc_mmu.c
+++ b/arch/ppc/mm/ppc_mmu.c
@@ -2,7 +2,7 @@
2 * This file contains the routines for handling the MMU on those 2 * This file contains the routines for handling the MMU on those
3 * PowerPC implementations where the MMU substantially follows the 3 * PowerPC implementations where the MMU substantially follows the
4 * architecture specification. This includes the 6xx, 7xx, 7xxx, 4 * architecture specification. This includes the 6xx, 7xx, 7xxx,
5 * 8260, and POWER3 implementations but excludes the 8xx and 4xx. 5 * 8260, and 83xx implementations but excludes the 8xx and 4xx.
6 * -- paulus 6 * -- paulus
7 * 7 *
8 * Derived from arch/ppc/mm/init.c: 8 * Derived from arch/ppc/mm/init.c:
@@ -42,11 +42,7 @@ unsigned long _SDR1;
42 42
43union ubat { /* BAT register values to be loaded */ 43union ubat { /* BAT register values to be loaded */
44 BAT bat; 44 BAT bat;
45#ifdef CONFIG_PPC64BRIDGE
46 u64 word[2];
47#else
48 u32 word[2]; 45 u32 word[2];
49#endif
50} BATS[4][2]; /* 4 pairs of IBAT, DBAT */ 46} BATS[4][2]; /* 4 pairs of IBAT, DBAT */
51 47
52struct batrange { /* stores address ranges mapped by BATs */ 48struct batrange { /* stores address ranges mapped by BATs */
@@ -83,9 +79,6 @@ unsigned long p_mapped_by_bats(unsigned long pa)
83 79
84unsigned long __init mmu_mapin_ram(void) 80unsigned long __init mmu_mapin_ram(void)
85{ 81{
86#ifdef CONFIG_POWER4
87 return 0;
88#else
89 unsigned long tot, bl, done; 82 unsigned long tot, bl, done;
90 unsigned long max_size = (256<<20); 83 unsigned long max_size = (256<<20);
91 unsigned long align; 84 unsigned long align;
@@ -122,7 +115,6 @@ unsigned long __init mmu_mapin_ram(void)
122 } 115 }
123 116
124 return done; 117 return done;
125#endif
126} 118}
127 119
128/* 120/*
@@ -205,27 +197,10 @@ void __init MMU_init_hw(void)
205 197
206 if ( ppc_md.progress ) ppc_md.progress("hash:enter", 0x105); 198 if ( ppc_md.progress ) ppc_md.progress("hash:enter", 0x105);
207 199
208#ifdef CONFIG_PPC64BRIDGE
209#define LG_HPTEG_SIZE 7 /* 128 bytes per HPTEG */
210#define SDR1_LOW_BITS (lg_n_hpteg - 11)
211#define MIN_N_HPTEG 2048 /* min 256kB hash table */
212#else
213#define LG_HPTEG_SIZE 6 /* 64 bytes per HPTEG */ 200#define LG_HPTEG_SIZE 6 /* 64 bytes per HPTEG */
214#define SDR1_LOW_BITS ((n_hpteg - 1) >> 10) 201#define SDR1_LOW_BITS ((n_hpteg - 1) >> 10)
215#define MIN_N_HPTEG 1024 /* min 64kB hash table */ 202#define MIN_N_HPTEG 1024 /* min 64kB hash table */
216#endif
217
218#ifdef CONFIG_POWER4
219 /* The hash table has already been allocated and initialized
220 in prom.c */
221 n_hpteg = Hash_size >> LG_HPTEG_SIZE;
222 lg_n_hpteg = __ilog2(n_hpteg);
223
224 /* Remove the hash table from the available memory */
225 if (Hash)
226 reserve_phys_mem(__pa(Hash), Hash_size);
227 203
228#else /* CONFIG_POWER4 */
229 /* 204 /*
230 * Allow 1 HPTE (1/8 HPTEG) for each page of memory. 205 * Allow 1 HPTE (1/8 HPTEG) for each page of memory.
231 * This is less than the recommended amount, but then 206 * This is less than the recommended amount, but then
@@ -248,7 +223,6 @@ void __init MMU_init_hw(void)
248 Hash = mem_pieces_find(Hash_size, Hash_size); 223 Hash = mem_pieces_find(Hash_size, Hash_size);
249 cacheable_memzero(Hash, Hash_size); 224 cacheable_memzero(Hash, Hash_size);
250 _SDR1 = __pa(Hash) | SDR1_LOW_BITS; 225 _SDR1 = __pa(Hash) | SDR1_LOW_BITS;
251#endif /* CONFIG_POWER4 */
252 226
253 Hash_end = (PTE *) ((unsigned long)Hash + Hash_size); 227 Hash_end = (PTE *) ((unsigned long)Hash + Hash_size);
254 228
diff --git a/arch/ppc/platforms/Makefile b/arch/ppc/platforms/Makefile
index e8b91a33ce91..90c622294423 100644
--- a/arch/ppc/platforms/Makefile
+++ b/arch/ppc/platforms/Makefile
@@ -2,18 +2,10 @@
2# Makefile for the linux kernel. 2# Makefile for the linux kernel.
3# 3#
4 4
5# Extra CFLAGS so we don't have to do relative includes
6CFLAGS_chrp_setup.o += -Iarch/$(ARCH)/mm
7
8obj-$(CONFIG_APUS) += apus_setup.o 5obj-$(CONFIG_APUS) += apus_setup.o
9ifeq ($(CONFIG_APUS),y) 6ifeq ($(CONFIG_APUS),y)
10obj-$(CONFIG_PCI) += apus_pci.o 7obj-$(CONFIG_PCI) += apus_pci.o
11endif 8endif
12obj-$(CONFIG_PPC_CHRP) += chrp_setup.o chrp_time.o chrp_pci.o \
13 chrp_pegasos_eth.o
14ifeq ($(CONFIG_PPC_CHRP),y)
15obj-$(CONFIG_NVRAM) += chrp_nvram.o
16endif
17obj-$(CONFIG_PPC_PREP) += prep_pci.o prep_setup.o 9obj-$(CONFIG_PPC_PREP) += prep_pci.o prep_setup.o
18obj-$(CONFIG_PREP_RESIDUAL) += residual.o 10obj-$(CONFIG_PREP_RESIDUAL) += residual.o
19obj-$(CONFIG_PQ2ADS) += pq2ads.o 11obj-$(CONFIG_PQ2ADS) += pq2ads.o
@@ -40,7 +32,3 @@ obj-$(CONFIG_EV64360) += ev64360.o
40obj-$(CONFIG_MPC86XADS) += mpc866ads_setup.o 32obj-$(CONFIG_MPC86XADS) += mpc866ads_setup.o
41obj-$(CONFIG_MPC885ADS) += mpc885ads_setup.o 33obj-$(CONFIG_MPC885ADS) += mpc885ads_setup.o
42obj-$(CONFIG_ADS8272) += mpc8272ads_setup.o 34obj-$(CONFIG_ADS8272) += mpc8272ads_setup.o
43
44ifeq ($(CONFIG_SMP),y)
45obj-$(CONFIG_PPC_CHRP) += chrp_smp.o
46endif
diff --git a/arch/ppc/platforms/chrp_nvram.c b/arch/ppc/platforms/chrp_nvram.c
deleted file mode 100644
index 465ba9b090ef..000000000000
--- a/arch/ppc/platforms/chrp_nvram.c
+++ /dev/null
@@ -1,83 +0,0 @@
1/*
2 * c 2001 PPC 64 Team, IBM Corp
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version
7 * 2 of the License, or (at your option) any later version.
8 *
9 * /dev/nvram driver for PPC
10 *
11 */
12
13#include <linux/kernel.h>
14#include <linux/init.h>
15#include <linux/slab.h>
16#include <linux/spinlock.h>
17#include <asm/uaccess.h>
18#include <asm/prom.h>
19#include <asm/machdep.h>
20
21static unsigned int nvram_size;
22static unsigned char nvram_buf[4];
23static DEFINE_SPINLOCK(nvram_lock);
24
25static unsigned char chrp_nvram_read(int addr)
26{
27 unsigned long done, flags;
28 unsigned char ret;
29
30 if (addr >= nvram_size) {
31 printk(KERN_DEBUG "%s: read addr %d > nvram_size %u\n",
32 current->comm, addr, nvram_size);
33 return 0xff;
34 }
35 spin_lock_irqsave(&nvram_lock, flags);
36 if ((call_rtas("nvram-fetch", 3, 2, &done, addr, __pa(nvram_buf), 1) != 0) || 1 != done)
37 ret = 0xff;
38 else
39 ret = nvram_buf[0];
40 spin_unlock_irqrestore(&nvram_lock, flags);
41
42 return ret;
43}
44
45static void chrp_nvram_write(int addr, unsigned char val)
46{
47 unsigned long done, flags;
48
49 if (addr >= nvram_size) {
50 printk(KERN_DEBUG "%s: write addr %d > nvram_size %u\n",
51 current->comm, addr, nvram_size);
52 return;
53 }
54 spin_lock_irqsave(&nvram_lock, flags);
55 nvram_buf[0] = val;
56 if ((call_rtas("nvram-store", 3, 2, &done, addr, __pa(nvram_buf), 1) != 0) || 1 != done)
57 printk(KERN_DEBUG "rtas IO error storing 0x%02x at %d", val, addr);
58 spin_unlock_irqrestore(&nvram_lock, flags);
59}
60
61void __init chrp_nvram_init(void)
62{
63 struct device_node *nvram;
64 unsigned int *nbytes_p, proplen;
65
66 nvram = of_find_node_by_type(NULL, "nvram");
67 if (nvram == NULL)
68 return;
69
70 nbytes_p = (unsigned int *)get_property(nvram, "#bytes", &proplen);
71 if (nbytes_p == NULL || proplen != sizeof(unsigned int))
72 return;
73
74 nvram_size = *nbytes_p;
75
76 printk(KERN_INFO "CHRP nvram contains %u bytes\n", nvram_size);
77 of_node_put(nvram);
78
79 ppc_md.nvram_read_val = chrp_nvram_read;
80 ppc_md.nvram_write_val = chrp_nvram_write;
81
82 return;
83}
diff --git a/arch/ppc/platforms/chrp_pci.c b/arch/ppc/platforms/chrp_pci.c
deleted file mode 100644
index c7fe6182bb77..000000000000
--- a/arch/ppc/platforms/chrp_pci.c
+++ /dev/null
@@ -1,309 +0,0 @@
1/*
2 * CHRP pci routines.
3 */
4
5#include <linux/config.h>
6#include <linux/kernel.h>
7#include <linux/pci.h>
8#include <linux/delay.h>
9#include <linux/string.h>
10#include <linux/init.h>
11#include <linux/ide.h>
12
13#include <asm/io.h>
14#include <asm/pgtable.h>
15#include <asm/irq.h>
16#include <asm/hydra.h>
17#include <asm/prom.h>
18#include <asm/gg2.h>
19#include <asm/machdep.h>
20#include <asm/sections.h>
21#include <asm/pci-bridge.h>
22#include <asm/open_pic.h>
23
24/* LongTrail */
25void __iomem *gg2_pci_config_base;
26
27/*
28 * The VLSI Golden Gate II has only 512K of PCI configuration space, so we
29 * limit the bus number to 3 bits
30 */
31
32int gg2_read_config(struct pci_bus *bus, unsigned int devfn, int off,
33 int len, u32 *val)
34{
35 volatile void __iomem *cfg_data;
36 struct pci_controller *hose = bus->sysdata;
37
38 if (bus->number > 7)
39 return PCIBIOS_DEVICE_NOT_FOUND;
40 /*
41 * Note: the caller has already checked that off is
42 * suitably aligned and that len is 1, 2 or 4.
43 */
44 cfg_data = hose->cfg_data + ((bus->number<<16) | (devfn<<8) | off);
45 switch (len) {
46 case 1:
47 *val = in_8(cfg_data);
48 break;
49 case 2:
50 *val = in_le16(cfg_data);
51 break;
52 default:
53 *val = in_le32(cfg_data);
54 break;
55 }
56 return PCIBIOS_SUCCESSFUL;
57}
58
59int gg2_write_config(struct pci_bus *bus, unsigned int devfn, int off,
60 int len, u32 val)
61{
62 volatile void __iomem *cfg_data;
63 struct pci_controller *hose = bus->sysdata;
64
65 if (bus->number > 7)
66 return PCIBIOS_DEVICE_NOT_FOUND;
67 /*
68 * Note: the caller has already checked that off is
69 * suitably aligned and that len is 1, 2 or 4.
70 */
71 cfg_data = hose->cfg_data + ((bus->number<<16) | (devfn<<8) | off);
72 switch (len) {
73 case 1:
74 out_8(cfg_data, val);
75 break;
76 case 2:
77 out_le16(cfg_data, val);
78 break;
79 default:
80 out_le32(cfg_data, val);
81 break;
82 }
83 return PCIBIOS_SUCCESSFUL;
84}
85
86static struct pci_ops gg2_pci_ops =
87{
88 gg2_read_config,
89 gg2_write_config
90};
91
92/*
93 * Access functions for PCI config space using RTAS calls.
94 */
95int
96rtas_read_config(struct pci_bus *bus, unsigned int devfn, int offset,
97 int len, u32 *val)
98{
99 struct pci_controller *hose = bus->sysdata;
100 unsigned long addr = (offset & 0xff) | ((devfn & 0xff) << 8)
101 | (((bus->number - hose->first_busno) & 0xff) << 16)
102 | (hose->index << 24);
103 unsigned long ret = ~0UL;
104 int rval;
105
106 rval = call_rtas("read-pci-config", 2, 2, &ret, addr, len);
107 *val = ret;
108 return rval? PCIBIOS_DEVICE_NOT_FOUND: PCIBIOS_SUCCESSFUL;
109}
110
111int
112rtas_write_config(struct pci_bus *bus, unsigned int devfn, int offset,
113 int len, u32 val)
114{
115 struct pci_controller *hose = bus->sysdata;
116 unsigned long addr = (offset & 0xff) | ((devfn & 0xff) << 8)
117 | (((bus->number - hose->first_busno) & 0xff) << 16)
118 | (hose->index << 24);
119 int rval;
120
121 rval = call_rtas("write-pci-config", 3, 1, NULL, addr, len, val);
122 return rval? PCIBIOS_DEVICE_NOT_FOUND: PCIBIOS_SUCCESSFUL;
123}
124
125static struct pci_ops rtas_pci_ops =
126{
127 rtas_read_config,
128 rtas_write_config
129};
130
131volatile struct Hydra __iomem *Hydra = NULL;
132
133int __init
134hydra_init(void)
135{
136 struct device_node *np;
137
138 np = find_devices("mac-io");
139 if (np == NULL || np->n_addrs == 0)
140 return 0;
141 Hydra = ioremap(np->addrs[0].address, np->addrs[0].size);
142 printk("Hydra Mac I/O at %x\n", np->addrs[0].address);
143 printk("Hydra Feature_Control was %x",
144 in_le32(&Hydra->Feature_Control));
145 out_le32(&Hydra->Feature_Control, (HYDRA_FC_SCC_CELL_EN |
146 HYDRA_FC_SCSI_CELL_EN |
147 HYDRA_FC_SCCA_ENABLE |
148 HYDRA_FC_SCCB_ENABLE |
149 HYDRA_FC_ARB_BYPASS |
150 HYDRA_FC_MPIC_ENABLE |
151 HYDRA_FC_SLOW_SCC_PCLK |
152 HYDRA_FC_MPIC_IS_MASTER));
153 printk(", now %x\n", in_le32(&Hydra->Feature_Control));
154 return 1;
155}
156
157void __init
158chrp_pcibios_fixup(void)
159{
160 struct pci_dev *dev = NULL;
161 struct device_node *np;
162
163 /* PCI interrupts are controlled by the OpenPIC */
164 for_each_pci_dev(dev) {
165 np = pci_device_to_OF_node(dev);
166 if ((np != 0) && (np->n_intrs > 0) && (np->intrs[0].line != 0))
167 dev->irq = np->intrs[0].line;
168 pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
169 }
170}
171
172#define PRG_CL_RESET_VALID 0x00010000
173
174static void __init
175setup_python(struct pci_controller *hose, struct device_node *dev)
176{
177 u32 __iomem *reg;
178 u32 val;
179 unsigned long addr = dev->addrs[0].address;
180
181 setup_indirect_pci(hose, addr + 0xf8000, addr + 0xf8010);
182
183 /* Clear the magic go-slow bit */
184 reg = ioremap(dev->addrs[0].address + 0xf6000, 0x40);
185 val = in_be32(&reg[12]);
186 if (val & PRG_CL_RESET_VALID) {
187 out_be32(&reg[12], val & ~PRG_CL_RESET_VALID);
188 in_be32(&reg[12]);
189 }
190 iounmap(reg);
191}
192
193/* Marvell Discovery II based Pegasos 2 */
194static void __init setup_peg2(struct pci_controller *hose, struct device_node *dev)
195{
196 struct device_node *root = find_path_device("/");
197 struct device_node *rtas;
198
199 rtas = of_find_node_by_name (root, "rtas");
200 if (rtas) {
201 hose->ops = &rtas_pci_ops;
202 } else {
203 printk ("RTAS supporting Pegasos OF not found, please upgrade"
204 " your firmware\n");
205 }
206 pci_assign_all_buses = 1;
207}
208
209void __init
210chrp_find_bridges(void)
211{
212 struct device_node *dev;
213 int *bus_range;
214 int len, index = -1;
215 struct pci_controller *hose;
216 unsigned int *dma;
217 char *model, *machine;
218 int is_longtrail = 0, is_mot = 0, is_pegasos = 0;
219 struct device_node *root = find_path_device("/");
220
221 /*
222 * The PCI host bridge nodes on some machines don't have
223 * properties to adequately identify them, so we have to
224 * look at what sort of machine this is as well.
225 */
226 machine = get_property(root, "model", NULL);
227 if (machine != NULL) {
228 is_longtrail = strncmp(machine, "IBM,LongTrail", 13) == 0;
229 is_mot = strncmp(machine, "MOT", 3) == 0;
230 if (strncmp(machine, "Pegasos2", 8) == 0)
231 is_pegasos = 2;
232 else if (strncmp(machine, "Pegasos", 7) == 0)
233 is_pegasos = 1;
234 }
235 for (dev = root->child; dev != NULL; dev = dev->sibling) {
236 if (dev->type == NULL || strcmp(dev->type, "pci") != 0)
237 continue;
238 ++index;
239 /* The GG2 bridge on the LongTrail doesn't have an address */
240 if (dev->n_addrs < 1 && !is_longtrail) {
241 printk(KERN_WARNING "Can't use %s: no address\n",
242 dev->full_name);
243 continue;
244 }
245 bus_range = (int *) get_property(dev, "bus-range", &len);
246 if (bus_range == NULL || len < 2 * sizeof(int)) {
247 printk(KERN_WARNING "Can't get bus-range for %s\n",
248 dev->full_name);
249 continue;
250 }
251 if (bus_range[1] == bus_range[0])
252 printk(KERN_INFO "PCI bus %d", bus_range[0]);
253 else
254 printk(KERN_INFO "PCI buses %d..%d",
255 bus_range[0], bus_range[1]);
256 printk(" controlled by %s", dev->type);
257 if (dev->n_addrs > 0)
258 printk(" at %x", dev->addrs[0].address);
259 printk("\n");
260
261 hose = pcibios_alloc_controller();
262 if (!hose) {
263 printk("Can't allocate PCI controller structure for %s\n",
264 dev->full_name);
265 continue;
266 }
267 hose->arch_data = dev;
268 hose->first_busno = bus_range[0];
269 hose->last_busno = bus_range[1];
270
271 model = get_property(dev, "model", NULL);
272 if (model == NULL)
273 model = "<none>";
274 if (device_is_compatible(dev, "IBM,python")) {
275 setup_python(hose, dev);
276 } else if (is_mot
277 || strncmp(model, "Motorola, Grackle", 17) == 0) {
278 setup_indirect_pci(hose, 0xfec00000, 0xfee00000);
279 } else if (is_longtrail) {
280 void __iomem *p = ioremap(GG2_PCI_CONFIG_BASE, 0x80000);
281 hose->ops = &gg2_pci_ops;
282 hose->cfg_data = p;
283 gg2_pci_config_base = p;
284 } else if (is_pegasos == 1) {
285 setup_indirect_pci(hose, 0xfec00cf8, 0xfee00cfc);
286 } else if (is_pegasos == 2) {
287 setup_peg2(hose, dev);
288 } else {
289 printk("No methods for %s (model %s), using RTAS\n",
290 dev->full_name, model);
291 hose->ops = &rtas_pci_ops;
292 }
293
294 pci_process_bridge_OF_ranges(hose, dev, index == 0);
295
296 /* check the first bridge for a property that we can
297 use to set pci_dram_offset */
298 dma = (unsigned int *)
299 get_property(dev, "ibm,dma-ranges", &len);
300 if (index == 0 && dma != NULL && len >= 6 * sizeof(*dma)) {
301 pci_dram_offset = dma[2] - dma[3];
302 printk("pci_dram_offset = %lx\n", pci_dram_offset);
303 }
304 }
305
306 /* Do not fixup interrupts from OF tree on pegasos */
307 if (is_pegasos == 0)
308 ppc_md.pcibios_fixup = chrp_pcibios_fixup;
309}
diff --git a/arch/ppc/platforms/chrp_pegasos_eth.c b/arch/ppc/platforms/chrp_pegasos_eth.c
deleted file mode 100644
index 9305c8aa1373..000000000000
--- a/arch/ppc/platforms/chrp_pegasos_eth.c
+++ /dev/null
@@ -1,211 +0,0 @@
1/*
2 * Copyright (C) 2005 Sven Luther <sl@bplan-gmbh.de>
3 * Thanks to :
4 * Dale Farnsworth <dale@farnsworth.org>
5 * Mark A. Greer <mgreer@mvista.com>
6 * Nicolas DET <nd@bplan-gmbh.de>
7 * Benjamin Herrenschmidt <benh@kernel.crashing.org>
8 * And anyone else who helped me on this.
9 */
10
11#include <linux/types.h>
12#include <linux/init.h>
13#include <linux/ioport.h>
14#include <linux/platform_device.h>
15#include <linux/mv643xx.h>
16#include <linux/pci.h>
17
18#define PEGASOS2_MARVELL_REGBASE (0xf1000000)
19#define PEGASOS2_MARVELL_REGSIZE (0x00004000)
20#define PEGASOS2_SRAM_BASE (0xf2000000)
21#define PEGASOS2_SRAM_SIZE (256*1024)
22
23#define PEGASOS2_SRAM_BASE_ETH0 (PEGASOS2_SRAM_BASE)
24#define PEGASOS2_SRAM_BASE_ETH1 (PEGASOS2_SRAM_BASE_ETH0 + (PEGASOS2_SRAM_SIZE / 2) )
25
26
27#define PEGASOS2_SRAM_RXRING_SIZE (PEGASOS2_SRAM_SIZE/4)
28#define PEGASOS2_SRAM_TXRING_SIZE (PEGASOS2_SRAM_SIZE/4)
29
30#undef BE_VERBOSE
31
32static struct resource mv643xx_eth_shared_resources[] = {
33 [0] = {
34 .name = "ethernet shared base",
35 .start = 0xf1000000 + MV643XX_ETH_SHARED_REGS,
36 .end = 0xf1000000 + MV643XX_ETH_SHARED_REGS +
37 MV643XX_ETH_SHARED_REGS_SIZE - 1,
38 .flags = IORESOURCE_MEM,
39 },
40};
41
42static struct platform_device mv643xx_eth_shared_device = {
43 .name = MV643XX_ETH_SHARED_NAME,
44 .id = 0,
45 .num_resources = ARRAY_SIZE(mv643xx_eth_shared_resources),
46 .resource = mv643xx_eth_shared_resources,
47};
48
49static struct resource mv643xx_eth0_resources[] = {
50 [0] = {
51 .name = "eth0 irq",
52 .start = 9,
53 .end = 9,
54 .flags = IORESOURCE_IRQ,
55 },
56};
57
58
59static struct mv643xx_eth_platform_data eth0_pd = {
60 .tx_sram_addr = PEGASOS2_SRAM_BASE_ETH0,
61 .tx_sram_size = PEGASOS2_SRAM_TXRING_SIZE,
62 .tx_queue_size = PEGASOS2_SRAM_TXRING_SIZE/16,
63
64 .rx_sram_addr = PEGASOS2_SRAM_BASE_ETH0 + PEGASOS2_SRAM_TXRING_SIZE,
65 .rx_sram_size = PEGASOS2_SRAM_RXRING_SIZE,
66 .rx_queue_size = PEGASOS2_SRAM_RXRING_SIZE/16,
67};
68
69static struct platform_device eth0_device = {
70 .name = MV643XX_ETH_NAME,
71 .id = 0,
72 .num_resources = ARRAY_SIZE(mv643xx_eth0_resources),
73 .resource = mv643xx_eth0_resources,
74 .dev = {
75 .platform_data = &eth0_pd,
76 },
77};
78
79static struct resource mv643xx_eth1_resources[] = {
80 [0] = {
81 .name = "eth1 irq",
82 .start = 9,
83 .end = 9,
84 .flags = IORESOURCE_IRQ,
85 },
86};
87
88static struct mv643xx_eth_platform_data eth1_pd = {
89 .tx_sram_addr = PEGASOS2_SRAM_BASE_ETH1,
90 .tx_sram_size = PEGASOS2_SRAM_TXRING_SIZE,
91 .tx_queue_size = PEGASOS2_SRAM_TXRING_SIZE/16,
92
93 .rx_sram_addr = PEGASOS2_SRAM_BASE_ETH1 + PEGASOS2_SRAM_TXRING_SIZE,
94 .rx_sram_size = PEGASOS2_SRAM_RXRING_SIZE,
95 .rx_queue_size = PEGASOS2_SRAM_RXRING_SIZE/16,
96};
97
98static struct platform_device eth1_device = {
99 .name = MV643XX_ETH_NAME,
100 .id = 1,
101 .num_resources = ARRAY_SIZE(mv643xx_eth1_resources),
102 .resource = mv643xx_eth1_resources,
103 .dev = {
104 .platform_data = &eth1_pd,
105 },
106};
107
108static struct platform_device *mv643xx_eth_pd_devs[] __initdata = {
109 &mv643xx_eth_shared_device,
110 &eth0_device,
111 &eth1_device,
112};
113
114/***********/
115/***********/
116#define MV_READ(offset,val) { val = readl(mv643xx_reg_base + offset); }
117#define MV_WRITE(offset,data) writel(data, mv643xx_reg_base + offset)
118
119static void __iomem *mv643xx_reg_base;
120
121static int Enable_SRAM(void)
122{
123 u32 ALong;
124
125 if (mv643xx_reg_base == NULL)
126 mv643xx_reg_base = ioremap(PEGASOS2_MARVELL_REGBASE,
127 PEGASOS2_MARVELL_REGSIZE);
128
129 if (mv643xx_reg_base == NULL)
130 return -ENOMEM;
131
132#ifdef BE_VERBOSE
133 printk("Pegasos II/Marvell MV64361: register remapped from %p to %p\n",
134 (void *)PEGASOS2_MARVELL_REGBASE, (void *)mv643xx_reg_base);
135#endif
136
137 MV_WRITE(MV64340_SRAM_CONFIG, 0);
138
139 MV_WRITE(MV64340_INTEGRATED_SRAM_BASE_ADDR, PEGASOS2_SRAM_BASE >> 16);
140
141 MV_READ(MV64340_BASE_ADDR_ENABLE, ALong);
142 ALong &= ~(1 << 19);
143 MV_WRITE(MV64340_BASE_ADDR_ENABLE, ALong);
144
145 ALong = 0x02;
146 ALong |= PEGASOS2_SRAM_BASE & 0xffff0000;
147 MV_WRITE(MV643XX_ETH_BAR_4, ALong);
148
149 MV_WRITE(MV643XX_ETH_SIZE_REG_4, (PEGASOS2_SRAM_SIZE-1) & 0xffff0000);
150
151 MV_READ(MV643XX_ETH_BASE_ADDR_ENABLE_REG, ALong);
152 ALong &= ~(1 << 4);
153 MV_WRITE(MV643XX_ETH_BASE_ADDR_ENABLE_REG, ALong);
154
155#ifdef BE_VERBOSE
156 printk("Pegasos II/Marvell MV64361: register unmapped\n");
157 printk("Pegasos II/Marvell MV64361: SRAM at %p, size=%x\n", (void*) PEGASOS2_SRAM_BASE, PEGASOS2_SRAM_SIZE);
158#endif
159
160 iounmap(mv643xx_reg_base);
161 mv643xx_reg_base = NULL;
162
163 return 1;
164}
165
166
167/***********/
168/***********/
169int mv643xx_eth_add_pds(void)
170{
171 int ret = 0;
172 static struct pci_device_id pci_marvell_mv64360[] = {
173 { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, PCI_DEVICE_ID_MARVELL_MV64360) },
174 { }
175 };
176
177#ifdef BE_VERBOSE
178 printk("Pegasos II/Marvell MV64361: init\n");
179#endif
180
181 if (pci_dev_present(pci_marvell_mv64360)) {
182 ret = platform_add_devices(mv643xx_eth_pd_devs,
183 ARRAY_SIZE(mv643xx_eth_pd_devs));
184
185 if ( Enable_SRAM() < 0)
186 {
187 eth0_pd.tx_sram_addr = 0;
188 eth0_pd.tx_sram_size = 0;
189 eth0_pd.rx_sram_addr = 0;
190 eth0_pd.rx_sram_size = 0;
191
192 eth1_pd.tx_sram_addr = 0;
193 eth1_pd.tx_sram_size = 0;
194 eth1_pd.rx_sram_addr = 0;
195 eth1_pd.rx_sram_size = 0;
196
197#ifdef BE_VERBOSE
198 printk("Pegasos II/Marvell MV64361: Can't enable the "
199 "SRAM\n");
200#endif
201 }
202 }
203
204#ifdef BE_VERBOSE
205 printk("Pegasos II/Marvell MV64361: init is over\n");
206#endif
207
208 return ret;
209}
210
211device_initcall(mv643xx_eth_add_pds);
diff --git a/arch/ppc/platforms/chrp_setup.c b/arch/ppc/platforms/chrp_setup.c
deleted file mode 100644
index f9fd3f4f8e2e..000000000000
--- a/arch/ppc/platforms/chrp_setup.c
+++ /dev/null
@@ -1,669 +0,0 @@
1/*
2 * Copyright (C) 1995 Linus Torvalds
3 * Adapted from 'alpha' version by Gary Thomas
4 * Modified by Cort Dougan (cort@cs.nmt.edu)
5 */
6
7/*
8 * bootup setup stuff..
9 */
10
11#include <linux/config.h>
12#include <linux/errno.h>
13#include <linux/sched.h>
14#include <linux/kernel.h>
15#include <linux/mm.h>
16#include <linux/stddef.h>
17#include <linux/unistd.h>
18#include <linux/ptrace.h>
19#include <linux/slab.h>
20#include <linux/user.h>
21#include <linux/a.out.h>
22#include <linux/tty.h>
23#include <linux/major.h>
24#include <linux/interrupt.h>
25#include <linux/reboot.h>
26#include <linux/init.h>
27#include <linux/pci.h>
28#include <linux/version.h>
29#include <linux/adb.h>
30#include <linux/module.h>
31#include <linux/delay.h>
32#include <linux/ide.h>
33#include <linux/console.h>
34#include <linux/seq_file.h>
35#include <linux/root_dev.h>
36#include <linux/initrd.h>
37#include <linux/module.h>
38
39#include <asm/io.h>
40#include <asm/pgtable.h>
41#include <asm/prom.h>
42#include <asm/gg2.h>
43#include <asm/pci-bridge.h>
44#include <asm/dma.h>
45#include <asm/machdep.h>
46#include <asm/irq.h>
47#include <asm/hydra.h>
48#include <asm/sections.h>
49#include <asm/time.h>
50#include <asm/btext.h>
51#include <asm/i8259.h>
52#include <asm/open_pic.h>
53#include <asm/xmon.h>
54#include "mem_pieces.h"
55
56unsigned long chrp_get_rtc_time(void);
57int chrp_set_rtc_time(unsigned long nowtime);
58void chrp_calibrate_decr(void);
59long chrp_time_init(void);
60
61void chrp_find_bridges(void);
62void chrp_event_scan(void);
63void rtas_display_progress(char *, unsigned short);
64void rtas_indicator_progress(char *, unsigned short);
65void btext_progress(char *, unsigned short);
66
67extern int of_show_percpuinfo(struct seq_file *, int);
68
69int _chrp_type;
70EXPORT_SYMBOL(_chrp_type);
71
72/*
73 * XXX this should be in xmon.h, but putting it there means xmon.h
74 * has to include <linux/interrupt.h> (to get irqreturn_t), which
75 * causes all sorts of problems. -- paulus
76 */
77extern irqreturn_t xmon_irq(int, void *, struct pt_regs *);
78
79extern dev_t boot_dev;
80
81extern PTE *Hash, *Hash_end;
82extern unsigned long Hash_size, Hash_mask;
83extern int probingmem;
84extern unsigned long loops_per_jiffy;
85static int max_width;
86
87#ifdef CONFIG_SMP
88extern struct smp_ops_t chrp_smp_ops;
89#endif
90
91static const char *gg2_memtypes[4] = {
92 "FPM", "SDRAM", "EDO", "BEDO"
93};
94static const char *gg2_cachesizes[4] = {
95 "256 KB", "512 KB", "1 MB", "Reserved"
96};
97static const char *gg2_cachetypes[4] = {
98 "Asynchronous", "Reserved", "Flow-Through Synchronous",
99 "Pipelined Synchronous"
100};
101static const char *gg2_cachemodes[4] = {
102 "Disabled", "Write-Through", "Copy-Back", "Transparent Mode"
103};
104
105int
106chrp_show_cpuinfo(struct seq_file *m)
107{
108 int i, sdramen;
109 unsigned int t;
110 struct device_node *root;
111 const char *model = "";
112
113 root = find_path_device("/");
114 if (root)
115 model = get_property(root, "model", NULL);
116 seq_printf(m, "machine\t\t: CHRP %s\n", model);
117
118 /* longtrail (goldengate) stuff */
119 if (!strncmp(model, "IBM,LongTrail", 13)) {
120 /* VLSI VAS96011/12 `Golden Gate 2' */
121 /* Memory banks */
122 sdramen = (in_le32(gg2_pci_config_base + GG2_PCI_DRAM_CTRL)
123 >>31) & 1;
124 for (i = 0; i < (sdramen ? 4 : 6); i++) {
125 t = in_le32(gg2_pci_config_base+
126 GG2_PCI_DRAM_BANK0+
127 i*4);
128 if (!(t & 1))
129 continue;
130 switch ((t>>8) & 0x1f) {
131 case 0x1f:
132 model = "4 MB";
133 break;
134 case 0x1e:
135 model = "8 MB";
136 break;
137 case 0x1c:
138 model = "16 MB";
139 break;
140 case 0x18:
141 model = "32 MB";
142 break;
143 case 0x10:
144 model = "64 MB";
145 break;
146 case 0x00:
147 model = "128 MB";
148 break;
149 default:
150 model = "Reserved";
151 break;
152 }
153 seq_printf(m, "memory bank %d\t: %s %s\n", i, model,
154 gg2_memtypes[sdramen ? 1 : ((t>>1) & 3)]);
155 }
156 /* L2 cache */
157 t = in_le32(gg2_pci_config_base+GG2_PCI_CC_CTRL);
158 seq_printf(m, "board l2\t: %s %s (%s)\n",
159 gg2_cachesizes[(t>>7) & 3],
160 gg2_cachetypes[(t>>2) & 3],
161 gg2_cachemodes[t & 3]);
162 }
163 return 0;
164}
165
166/*
167 * Fixes for the National Semiconductor PC78308VUL SuperI/O
168 *
169 * Some versions of Open Firmware incorrectly initialize the IRQ settings
170 * for keyboard and mouse
171 */
172static inline void __init sio_write(u8 val, u8 index)
173{
174 outb(index, 0x15c);
175 outb(val, 0x15d);
176}
177
178static inline u8 __init sio_read(u8 index)
179{
180 outb(index, 0x15c);
181 return inb(0x15d);
182}
183
184static void __init sio_fixup_irq(const char *name, u8 device, u8 level,
185 u8 type)
186{
187 u8 level0, type0, active;
188
189 /* select logical device */
190 sio_write(device, 0x07);
191 active = sio_read(0x30);
192 level0 = sio_read(0x70);
193 type0 = sio_read(0x71);
194 if (level0 != level || type0 != type || !active) {
195 printk(KERN_WARNING "sio: %s irq level %d, type %d, %sactive: "
196 "remapping to level %d, type %d, active\n",
197 name, level0, type0, !active ? "in" : "", level, type);
198 sio_write(0x01, 0x30);
199 sio_write(level, 0x70);
200 sio_write(type, 0x71);
201 }
202}
203
204static void __init sio_init(void)
205{
206 struct device_node *root;
207
208 if ((root = find_path_device("/")) &&
209 !strncmp(get_property(root, "model", NULL), "IBM,LongTrail", 13)) {
210 /* logical device 0 (KBC/Keyboard) */
211 sio_fixup_irq("keyboard", 0, 1, 2);
212 /* select logical device 1 (KBC/Mouse) */
213 sio_fixup_irq("mouse", 1, 12, 2);
214 }
215}
216
217
218static void __init pegasos_set_l2cr(void)
219{
220 struct device_node *np;
221
222 /* On Pegasos, enable the l2 cache if needed, as the OF forgets it */
223 if (_chrp_type != _CHRP_Pegasos)
224 return;
225
226 /* Enable L2 cache if needed */
227 np = find_type_devices("cpu");
228 if (np != NULL) {
229 unsigned int *l2cr = (unsigned int *)
230 get_property (np, "l2cr", NULL);
231 if (l2cr == NULL) {
232 printk ("Pegasos l2cr : no cpu l2cr property found\n");
233 return;
234 }
235 if (!((*l2cr) & 0x80000000)) {
236 printk ("Pegasos l2cr : L2 cache was not active, "
237 "activating\n");
238 _set_L2CR(0);
239 _set_L2CR((*l2cr) | 0x80000000);
240 }
241 }
242}
243
244void __init chrp_setup_arch(void)
245{
246 struct device_node *device;
247
248 /* init to some ~sane value until calibrate_delay() runs */
249 loops_per_jiffy = 50000000/HZ;
250
251#ifdef CONFIG_BLK_DEV_INITRD
252 /* this is fine for chrp */
253 initrd_below_start_ok = 1;
254
255 if (initrd_start)
256 ROOT_DEV = Root_RAM0;
257 else
258#endif
259 ROOT_DEV = Root_SDA2; /* sda2 (sda1 is for the kernel) */
260
261 /* On pegasos, enable the L2 cache if not already done by OF */
262 pegasos_set_l2cr();
263
264 /* Lookup PCI host bridges */
265 chrp_find_bridges();
266
267#ifndef CONFIG_PPC64BRIDGE
268 /*
269 * Temporary fixes for PCI devices.
270 * -- Geert
271 */
272 hydra_init(); /* Mac I/O */
273
274#endif /* CONFIG_PPC64BRIDGE */
275
276 /*
277 * Fix the Super I/O configuration
278 */
279 sio_init();
280
281 /* Get the event scan rate for the rtas so we know how
282 * often it expects a heartbeat. -- Cort
283 */
284 if ( rtas_data ) {
285 struct property *p;
286 device = find_devices("rtas");
287 for ( p = device->properties;
288 p && strncmp(p->name, "rtas-event-scan-rate", 20);
289 p = p->next )
290 /* nothing */ ;
291 if ( p && *(unsigned long *)p->value ) {
292 ppc_md.heartbeat = chrp_event_scan;
293 ppc_md.heartbeat_reset = (HZ/(*(unsigned long *)p->value)*30)-1;
294 ppc_md.heartbeat_count = 1;
295 printk("RTAS Event Scan Rate: %lu (%lu jiffies)\n",
296 *(unsigned long *)p->value, ppc_md.heartbeat_reset );
297 }
298 }
299
300 pci_create_OF_bus_map();
301}
302
303void
304chrp_event_scan(void)
305{
306 unsigned char log[1024];
307 unsigned long ret = 0;
308 /* XXX: we should loop until the hardware says no more error logs -- Cort */
309 call_rtas( "event-scan", 4, 1, &ret, 0xffffffff, 0,
310 __pa(log), 1024 );
311 ppc_md.heartbeat_count = ppc_md.heartbeat_reset;
312}
313
314void
315chrp_restart(char *cmd)
316{
317 printk("RTAS system-reboot returned %d\n",
318 call_rtas("system-reboot", 0, 1, NULL));
319 for (;;);
320}
321
322void
323chrp_power_off(void)
324{
325 /* allow power on only with power button press */
326 printk("RTAS power-off returned %d\n",
327 call_rtas("power-off", 2, 1, NULL,0xffffffff,0xffffffff));
328 for (;;);
329}
330
331void
332chrp_halt(void)
333{
334 chrp_power_off();
335}
336
337/*
338 * Finds the open-pic node and sets OpenPIC_Addr based on its reg property.
339 * Then checks if it has an interrupt-ranges property. If it does then
340 * we have a distributed open-pic, so call openpic_set_sources to tell
341 * the openpic code where to find the interrupt source registers.
342 */
343static void __init chrp_find_openpic(void)
344{
345 struct device_node *np;
346 int len, i;
347 unsigned int *iranges;
348 void __iomem *isu;
349
350 np = find_type_devices("open-pic");
351 if (np == NULL || np->n_addrs == 0)
352 return;
353 printk(KERN_INFO "OpenPIC at %x (size %x)\n",
354 np->addrs[0].address, np->addrs[0].size);
355 OpenPIC_Addr = ioremap(np->addrs[0].address, 0x40000);
356 if (OpenPIC_Addr == NULL) {
357 printk(KERN_ERR "Failed to map OpenPIC!\n");
358 return;
359 }
360
361 iranges = (unsigned int *) get_property(np, "interrupt-ranges", &len);
362 if (iranges == NULL || len < 2 * sizeof(unsigned int))
363 return; /* not distributed */
364
365 /*
366 * The first pair of cells in interrupt-ranges refers to the
367 * IDU; subsequent pairs refer to the ISUs.
368 */
369 len /= 2 * sizeof(unsigned int);
370 if (np->n_addrs < len) {
371 printk(KERN_ERR "Insufficient addresses for distributed"
372 " OpenPIC (%d < %d)\n", np->n_addrs, len);
373 return;
374 }
375 if (iranges[1] != 0) {
376 printk(KERN_INFO "OpenPIC irqs %d..%d in IDU\n",
377 iranges[0], iranges[0] + iranges[1] - 1);
378 openpic_set_sources(iranges[0], iranges[1], NULL);
379 }
380 for (i = 1; i < len; ++i) {
381 iranges += 2;
382 printk(KERN_INFO "OpenPIC irqs %d..%d in ISU at %x (%x)\n",
383 iranges[0], iranges[0] + iranges[1] - 1,
384 np->addrs[i].address, np->addrs[i].size);
385 isu = ioremap(np->addrs[i].address, np->addrs[i].size);
386 if (isu != NULL)
387 openpic_set_sources(iranges[0], iranges[1], isu);
388 else
389 printk(KERN_ERR "Failed to map OpenPIC ISU at %x!\n",
390 np->addrs[i].address);
391 }
392}
393
394#if defined(CONFIG_VT) && defined(CONFIG_INPUT_ADBHID) && defined(XMON)
395static struct irqaction xmon_irqaction = {
396 .handler = xmon_irq,
397 .mask = CPU_MASK_NONE,
398 .name = "XMON break",
399};
400#endif
401
402void __init chrp_init_IRQ(void)
403{
404 struct device_node *np;
405 unsigned long chrp_int_ack = 0;
406 unsigned char init_senses[NR_IRQS - NUM_8259_INTERRUPTS];
407#if defined(CONFIG_VT) && defined(CONFIG_INPUT_ADBHID) && defined(XMON)
408 struct device_node *kbd;
409#endif
410
411 for (np = find_devices("pci"); np != NULL; np = np->next) {
412 unsigned int *addrp = (unsigned int *)
413 get_property(np, "8259-interrupt-acknowledge", NULL);
414
415 if (addrp == NULL)
416 continue;
417 chrp_int_ack = addrp[prom_n_addr_cells(np)-1];
418 break;
419 }
420 if (np == NULL)
421 printk(KERN_ERR "Cannot find PCI interrupt acknowledge address\n");
422
423 chrp_find_openpic();
424
425 if (OpenPIC_Addr) {
426 prom_get_irq_senses(init_senses, NUM_8259_INTERRUPTS, NR_IRQS);
427 OpenPIC_InitSenses = init_senses;
428 OpenPIC_NumInitSenses = NR_IRQS - NUM_8259_INTERRUPTS;
429
430 openpic_init(NUM_8259_INTERRUPTS);
431 /* We have a cascade on OpenPIC IRQ 0, Linux IRQ 16 */
432 openpic_hookup_cascade(NUM_8259_INTERRUPTS, "82c59 cascade",
433 i8259_irq);
434
435 }
436 i8259_init(chrp_int_ack, 0);
437
438#if defined(CONFIG_VT) && defined(CONFIG_INPUT_ADBHID) && defined(XMON)
439 /* see if there is a keyboard in the device tree
440 with a parent of type "adb" */
441 for (kbd = find_devices("keyboard"); kbd; kbd = kbd->next)
442 if (kbd->parent && kbd->parent->type
443 && strcmp(kbd->parent->type, "adb") == 0)
444 break;
445 if (kbd)
446 setup_irq(HYDRA_INT_ADB_NMI, &xmon_irqaction);
447#endif
448}
449
450void __init
451chrp_init2(void)
452{
453#ifdef CONFIG_NVRAM
454 chrp_nvram_init();
455#endif
456
457 request_region(0x20,0x20,"pic1");
458 request_region(0xa0,0x20,"pic2");
459 request_region(0x00,0x20,"dma1");
460 request_region(0x40,0x20,"timer");
461 request_region(0x80,0x10,"dma page reg");
462 request_region(0xc0,0x20,"dma2");
463
464 if (ppc_md.progress)
465 ppc_md.progress(" Have fun! ", 0x7777);
466}
467
468static struct device_node *memory_node;
469
470static int __init get_mem_prop(char *name, struct mem_pieces *mp)
471{
472 struct reg_property *rp;
473 int i, s;
474 unsigned int *ip;
475 int nac = prom_n_addr_cells(memory_node);
476 int nsc = prom_n_size_cells(memory_node);
477
478 ip = (unsigned int *) get_property(memory_node, name, &s);
479 if (ip == NULL) {
480 printk(KERN_ERR "error: couldn't get %s property on /memory\n",
481 name);
482 return 0;
483 }
484 s /= (nsc + nac) * 4;
485 rp = mp->regions;
486 for (i = 0; i < s; ++i, ip += nac+nsc) {
487 if (nac >= 2 && ip[nac-2] != 0)
488 continue;
489 rp->address = ip[nac-1];
490 if (nsc >= 2 && ip[nac+nsc-2] != 0)
491 rp->size = ~0U;
492 else
493 rp->size = ip[nac+nsc-1];
494 ++rp;
495 }
496 mp->n_regions = rp - mp->regions;
497
498 /* Make sure the pieces are sorted. */
499 mem_pieces_sort(mp);
500 mem_pieces_coalesce(mp);
501 return 1;
502}
503
504static unsigned long __init chrp_find_end_of_memory(void)
505{
506 unsigned long a, total;
507 struct mem_pieces phys_mem;
508
509 /*
510 * Find out where physical memory is, and check that it
511 * starts at 0 and is contiguous. It seems that RAM is
512 * always physically contiguous on Power Macintoshes.
513 *
514 * Supporting discontiguous physical memory isn't hard,
515 * it just makes the virtual <-> physical mapping functions
516 * more complicated (or else you end up wasting space
517 * in mem_map).
518 */
519 memory_node = find_devices("memory");
520 if (memory_node == NULL || !get_mem_prop("reg", &phys_mem)
521 || phys_mem.n_regions == 0)
522 panic("No RAM??");
523 a = phys_mem.regions[0].address;
524 if (a != 0)
525 panic("RAM doesn't start at physical address 0");
526 total = phys_mem.regions[0].size;
527
528 if (phys_mem.n_regions > 1) {
529 printk("RAM starting at 0x%x is not contiguous\n",
530 phys_mem.regions[1].address);
531 printk("Using RAM from 0 to 0x%lx\n", total-1);
532 }
533
534 return total;
535}
536
537void __init
538chrp_init(unsigned long r3, unsigned long r4, unsigned long r5,
539 unsigned long r6, unsigned long r7)
540{
541 struct device_node *root = find_path_device ("/");
542 char *machine = NULL;
543
544#ifdef CONFIG_BLK_DEV_INITRD
545 /* take care of initrd if we have one */
546 if ( r6 )
547 {
548 initrd_start = r6 + KERNELBASE;
549 initrd_end = r6 + r7 + KERNELBASE;
550 }
551#endif /* CONFIG_BLK_DEV_INITRD */
552
553 ISA_DMA_THRESHOLD = ~0L;
554 DMA_MODE_READ = 0x44;
555 DMA_MODE_WRITE = 0x48;
556 isa_io_base = CHRP_ISA_IO_BASE; /* default value */
557 ppc_do_canonicalize_irqs = 1;
558
559 if (root)
560 machine = get_property(root, "model", NULL);
561 if (machine && strncmp(machine, "Pegasos", 7) == 0) {
562 _chrp_type = _CHRP_Pegasos;
563 } else if (machine && strncmp(machine, "IBM", 3) == 0) {
564 _chrp_type = _CHRP_IBM;
565 } else if (machine && strncmp(machine, "MOT", 3) == 0) {
566 _chrp_type = _CHRP_Motorola;
567 } else {
568 /* Let's assume it is an IBM chrp if all else fails */
569 _chrp_type = _CHRP_IBM;
570 }
571
572 ppc_md.setup_arch = chrp_setup_arch;
573 ppc_md.show_percpuinfo = of_show_percpuinfo;
574 ppc_md.show_cpuinfo = chrp_show_cpuinfo;
575
576 ppc_md.init_IRQ = chrp_init_IRQ;
577 if (_chrp_type == _CHRP_Pegasos)
578 ppc_md.get_irq = i8259_irq;
579 else
580 ppc_md.get_irq = openpic_get_irq;
581
582 ppc_md.init = chrp_init2;
583
584 ppc_md.phys_mem_access_prot = pci_phys_mem_access_prot;
585
586 ppc_md.restart = chrp_restart;
587 ppc_md.power_off = chrp_power_off;
588 ppc_md.halt = chrp_halt;
589
590 ppc_md.time_init = chrp_time_init;
591 ppc_md.set_rtc_time = chrp_set_rtc_time;
592 ppc_md.get_rtc_time = chrp_get_rtc_time;
593 ppc_md.calibrate_decr = chrp_calibrate_decr;
594
595 ppc_md.find_end_of_memory = chrp_find_end_of_memory;
596
597 if (rtas_data) {
598 struct device_node *rtas;
599 unsigned int *p;
600
601 rtas = find_devices("rtas");
602 if (rtas != NULL) {
603 if (get_property(rtas, "display-character", NULL)) {
604 ppc_md.progress = rtas_display_progress;
605 p = (unsigned int *) get_property
606 (rtas, "ibm,display-line-length", NULL);
607 if (p)
608 max_width = *p;
609 } else if (get_property(rtas, "set-indicator", NULL))
610 ppc_md.progress = rtas_indicator_progress;
611 }
612 }
613#ifdef CONFIG_BOOTX_TEXT
614 if (ppc_md.progress == NULL && boot_text_mapped)
615 ppc_md.progress = btext_progress;
616#endif
617
618#ifdef CONFIG_SMP
619 smp_ops = &chrp_smp_ops;
620#endif /* CONFIG_SMP */
621
622 /*
623 * Print the banner, then scroll down so boot progress
624 * can be printed. -- Cort
625 */
626 if (ppc_md.progress) ppc_md.progress("Linux/PPC "UTS_RELEASE"\n", 0x0);
627}
628
629void
630rtas_display_progress(char *s, unsigned short hex)
631{
632 int width;
633 char *os = s;
634
635 if ( call_rtas( "display-character", 1, 1, NULL, '\r' ) )
636 return;
637
638 width = max_width;
639 while ( *os )
640 {
641 if ( (*os == '\n') || (*os == '\r') )
642 width = max_width;
643 else
644 width--;
645 call_rtas( "display-character", 1, 1, NULL, *os++ );
646 /* if we overwrite the screen length */
647 if ( width == 0 )
648 while ( (*os != 0) && (*os != '\n') && (*os != '\r') )
649 os++;
650 }
651
652 /*while ( width-- > 0 )*/
653 call_rtas( "display-character", 1, 1, NULL, ' ' );
654}
655
656void
657rtas_indicator_progress(char *s, unsigned short hex)
658{
659 call_rtas("set-indicator", 3, 1, NULL, 6, 0, hex);
660}
661
662#ifdef CONFIG_BOOTX_TEXT
663void
664btext_progress(char *s, unsigned short hex)
665{
666 prom_print(s);
667 prom_print("\n");
668}
669#endif /* CONFIG_BOOTX_TEXT */
diff --git a/arch/ppc/platforms/chrp_smp.c b/arch/ppc/platforms/chrp_smp.c
deleted file mode 100644
index 97e539557ecb..000000000000
--- a/arch/ppc/platforms/chrp_smp.c
+++ /dev/null
@@ -1,99 +0,0 @@
1/*
2 * Smp support for CHRP machines.
3 *
4 * Written by Cort Dougan (cort@cs.nmt.edu) borrowing a great
5 * deal of code from the sparc and intel versions.
6 *
7 * Copyright (C) 1999 Cort Dougan <cort@cs.nmt.edu>
8 *
9 */
10
11#include <linux/config.h>
12#include <linux/kernel.h>
13#include <linux/sched.h>
14#include <linux/smp.h>
15#include <linux/smp_lock.h>
16#include <linux/interrupt.h>
17#include <linux/kernel_stat.h>
18#include <linux/delay.h>
19#include <linux/init.h>
20#include <linux/spinlock.h>
21
22#include <asm/ptrace.h>
23#include <asm/atomic.h>
24#include <asm/irq.h>
25#include <asm/page.h>
26#include <asm/pgtable.h>
27#include <asm/sections.h>
28#include <asm/io.h>
29#include <asm/prom.h>
30#include <asm/smp.h>
31#include <asm/residual.h>
32#include <asm/time.h>
33#include <asm/open_pic.h>
34#include <asm/machdep.h>
35
36extern unsigned long smp_chrp_cpu_nr;
37
38static int __init
39smp_chrp_probe(void)
40{
41 if (smp_chrp_cpu_nr > 1)
42 openpic_request_IPIs();
43
44 return smp_chrp_cpu_nr;
45}
46
47static void __devinit
48smp_chrp_kick_cpu(int nr)
49{
50 *(unsigned long *)KERNELBASE = nr;
51 asm volatile("dcbf 0,%0"::"r"(KERNELBASE):"memory");
52}
53
54static void __devinit
55smp_chrp_setup_cpu(int cpu_nr)
56{
57 if (OpenPIC_Addr)
58 do_openpic_setup_cpu();
59}
60
61static DEFINE_SPINLOCK(timebase_lock);
62static unsigned int timebase_upper = 0, timebase_lower = 0;
63
64void __devinit
65smp_chrp_give_timebase(void)
66{
67 spin_lock(&timebase_lock);
68 call_rtas("freeze-time-base", 0, 1, NULL);
69 timebase_upper = get_tbu();
70 timebase_lower = get_tbl();
71 spin_unlock(&timebase_lock);
72
73 while (timebase_upper || timebase_lower)
74 barrier();
75 call_rtas("thaw-time-base", 0, 1, NULL);
76}
77
78void __devinit
79smp_chrp_take_timebase(void)
80{
81 while (!(timebase_upper || timebase_lower))
82 barrier();
83 spin_lock(&timebase_lock);
84 set_tb(timebase_upper, timebase_lower);
85 timebase_upper = 0;
86 timebase_lower = 0;
87 spin_unlock(&timebase_lock);
88 printk("CPU %i taken timebase\n", smp_processor_id());
89}
90
91/* CHRP with openpic */
92struct smp_ops_t chrp_smp_ops = {
93 .message_pass = smp_openpic_message_pass,
94 .probe = smp_chrp_probe,
95 .kick_cpu = smp_chrp_kick_cpu,
96 .setup_cpu = smp_chrp_setup_cpu,
97 .give_timebase = smp_chrp_give_timebase,
98 .take_timebase = smp_chrp_take_timebase,
99};
diff --git a/arch/ppc/platforms/chrp_time.c b/arch/ppc/platforms/chrp_time.c
deleted file mode 100644
index 51e06ad66168..000000000000
--- a/arch/ppc/platforms/chrp_time.c
+++ /dev/null
@@ -1,235 +0,0 @@
1/*
2 * Copyright (C) 1991, 1992, 1995 Linus Torvalds
3 *
4 * Adapted for PowerPC (PReP) by Gary Thomas
5 * Modified by Cort Dougan (cort@cs.nmt.edu).
6 * Copied and modified from arch/i386/kernel/time.c
7 *
8 */
9#include <linux/errno.h>
10#include <linux/sched.h>
11#include <linux/kernel.h>
12#include <linux/param.h>
13#include <linux/string.h>
14#include <linux/mm.h>
15#include <linux/interrupt.h>
16#include <linux/time.h>
17#include <linux/timex.h>
18#include <linux/kernel_stat.h>
19#include <linux/mc146818rtc.h>
20#include <linux/init.h>
21#include <linux/bcd.h>
22
23#include <asm/io.h>
24#include <asm/nvram.h>
25#include <asm/prom.h>
26#include <asm/sections.h>
27#include <asm/time.h>
28
29extern spinlock_t rtc_lock;
30
31static int nvram_as1 = NVRAM_AS1;
32static int nvram_as0 = NVRAM_AS0;
33static int nvram_data = NVRAM_DATA;
34
35long __init chrp_time_init(void)
36{
37 struct device_node *rtcs;
38 int base;
39
40 rtcs = find_compatible_devices("rtc", "pnpPNP,b00");
41 if (rtcs == NULL)
42 rtcs = find_compatible_devices("rtc", "ds1385-rtc");
43 if (rtcs == NULL || rtcs->addrs == NULL)
44 return 0;
45 base = rtcs->addrs[0].address;
46 nvram_as1 = 0;
47 nvram_as0 = base;
48 nvram_data = base + 1;
49
50 return 0;
51}
52
53int chrp_cmos_clock_read(int addr)
54{
55 if (nvram_as1 != 0)
56 outb(addr>>8, nvram_as1);
57 outb(addr, nvram_as0);
58 return (inb(nvram_data));
59}
60
61void chrp_cmos_clock_write(unsigned long val, int addr)
62{
63 if (nvram_as1 != 0)
64 outb(addr>>8, nvram_as1);
65 outb(addr, nvram_as0);
66 outb(val, nvram_data);
67 return;
68}
69
70/*
71 * Set the hardware clock. -- Cort
72 */
73int chrp_set_rtc_time(unsigned long nowtime)
74{
75 unsigned char save_control, save_freq_select;
76 struct rtc_time tm;
77
78 spin_lock(&rtc_lock);
79 to_tm(nowtime, &tm);
80
81 save_control = chrp_cmos_clock_read(RTC_CONTROL); /* tell the clock it's being set */
82
83 chrp_cmos_clock_write((save_control|RTC_SET), RTC_CONTROL);
84
85 save_freq_select = chrp_cmos_clock_read(RTC_FREQ_SELECT); /* stop and reset prescaler */
86
87 chrp_cmos_clock_write((save_freq_select|RTC_DIV_RESET2), RTC_FREQ_SELECT);
88
89 tm.tm_year -= 1900;
90 if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) {
91 BIN_TO_BCD(tm.tm_sec);
92 BIN_TO_BCD(tm.tm_min);
93 BIN_TO_BCD(tm.tm_hour);
94 BIN_TO_BCD(tm.tm_mon);
95 BIN_TO_BCD(tm.tm_mday);
96 BIN_TO_BCD(tm.tm_year);
97 }
98 chrp_cmos_clock_write(tm.tm_sec,RTC_SECONDS);
99 chrp_cmos_clock_write(tm.tm_min,RTC_MINUTES);
100 chrp_cmos_clock_write(tm.tm_hour,RTC_HOURS);
101 chrp_cmos_clock_write(tm.tm_mon,RTC_MONTH);
102 chrp_cmos_clock_write(tm.tm_mday,RTC_DAY_OF_MONTH);
103 chrp_cmos_clock_write(tm.tm_year,RTC_YEAR);
104
105 /* The following flags have to be released exactly in this order,
106 * otherwise the DS12887 (popular MC146818A clone with integrated
107 * battery and quartz) will not reset the oscillator and will not
108 * update precisely 500 ms later. You won't find this mentioned in
109 * the Dallas Semiconductor data sheets, but who believes data
110 * sheets anyway ... -- Markus Kuhn
111 */
112 chrp_cmos_clock_write(save_control, RTC_CONTROL);
113 chrp_cmos_clock_write(save_freq_select, RTC_FREQ_SELECT);
114
115 spin_unlock(&rtc_lock);
116 return 0;
117}
118
119unsigned long chrp_get_rtc_time(void)
120{
121 unsigned int year, mon, day, hour, min, sec;
122
123 do {
124 sec = chrp_cmos_clock_read(RTC_SECONDS);
125 min = chrp_cmos_clock_read(RTC_MINUTES);
126 hour = chrp_cmos_clock_read(RTC_HOURS);
127 day = chrp_cmos_clock_read(RTC_DAY_OF_MONTH);
128 mon = chrp_cmos_clock_read(RTC_MONTH);
129 year = chrp_cmos_clock_read(RTC_YEAR);
130 } while (sec != chrp_cmos_clock_read(RTC_SECONDS));
131
132 if (!(chrp_cmos_clock_read(RTC_CONTROL) & RTC_DM_BINARY)
133 || RTC_ALWAYS_BCD) {
134 BCD_TO_BIN(sec);
135 BCD_TO_BIN(min);
136 BCD_TO_BIN(hour);
137 BCD_TO_BIN(day);
138 BCD_TO_BIN(mon);
139 BCD_TO_BIN(year);
140 }
141
142 year += 1900;
143 if (year < 1970)
144 year += 100;
145 return mktime(year, mon, day, hour, min, sec);
146}
147
148/*
149 * Calibrate the decrementer frequency with the VIA timer 1.
150 */
151#define VIA_TIMER_FREQ_6 4700000 /* time 1 frequency * 6 */
152
153/* VIA registers */
154#define RS 0x200 /* skip between registers */
155#define T1CL (4*RS) /* Timer 1 ctr/latch (low 8 bits) */
156#define T1CH (5*RS) /* Timer 1 counter (high 8 bits) */
157#define T1LL (6*RS) /* Timer 1 latch (low 8 bits) */
158#define T1LH (7*RS) /* Timer 1 latch (high 8 bits) */
159#define ACR (11*RS) /* Auxiliary control register */
160#define IFR (13*RS) /* Interrupt flag register */
161
162/* Bits in ACR */
163#define T1MODE 0xc0 /* Timer 1 mode */
164#define T1MODE_CONT 0x40 /* continuous interrupts */
165
166/* Bits in IFR and IER */
167#define T1_INT 0x40 /* Timer 1 interrupt */
168
169static int __init chrp_via_calibrate_decr(void)
170{
171 struct device_node *vias;
172 volatile unsigned char __iomem *via;
173 int count = VIA_TIMER_FREQ_6 / 100;
174 unsigned int dstart, dend;
175
176 vias = find_devices("via-cuda");
177 if (vias == 0)
178 vias = find_devices("via");
179 if (vias == 0 || vias->n_addrs == 0)
180 return 0;
181 via = ioremap(vias->addrs[0].address, vias->addrs[0].size);
182
183 /* set timer 1 for continuous interrupts */
184 out_8(&via[ACR], (via[ACR] & ~T1MODE) | T1MODE_CONT);
185 /* set the counter to a small value */
186 out_8(&via[T1CH], 2);
187 /* set the latch to `count' */
188 out_8(&via[T1LL], count);
189 out_8(&via[T1LH], count >> 8);
190 /* wait until it hits 0 */
191 while ((in_8(&via[IFR]) & T1_INT) == 0)
192 ;
193 dstart = get_dec();
194 /* clear the interrupt & wait until it hits 0 again */
195 in_8(&via[T1CL]);
196 while ((in_8(&via[IFR]) & T1_INT) == 0)
197 ;
198 dend = get_dec();
199
200 tb_ticks_per_jiffy = (dstart - dend) / ((6 * HZ)/100);
201 tb_to_us = mulhwu_scale_factor(dstart - dend, 60000);
202
203 printk(KERN_INFO "via_calibrate_decr: ticks per jiffy = %u (%u ticks)\n",
204 tb_ticks_per_jiffy, dstart - dend);
205
206 iounmap(via);
207
208 return 1;
209}
210
211void __init chrp_calibrate_decr(void)
212{
213 struct device_node *cpu;
214 unsigned int freq, *fp;
215
216 if (chrp_via_calibrate_decr())
217 return;
218
219 /*
220 * The cpu node should have a timebase-frequency property
221 * to tell us the rate at which the decrementer counts.
222 */
223 freq = 16666000; /* hardcoded default */
224 cpu = find_type_devices("cpu");
225 if (cpu != 0) {
226 fp = (unsigned int *)
227 get_property(cpu, "timebase-frequency", NULL);
228 if (fp != 0)
229 freq = *fp;
230 }
231 printk("time_init: decrementer frequency = %u.%.6u MHz\n",
232 freq/1000000, freq%1000000);
233 tb_ticks_per_jiffy = freq / HZ;
234 tb_to_us = mulhwu_scale_factor(freq, 1000000);
235}
diff --git a/arch/ppc/platforms/lite5200.c b/arch/ppc/platforms/lite5200.c
index 5171b53bccb5..fecbe9adc9e0 100644
--- a/arch/ppc/platforms/lite5200.c
+++ b/arch/ppc/platforms/lite5200.c
@@ -34,8 +34,7 @@
34#include <asm/mpc52xx.h> 34#include <asm/mpc52xx.h>
35#include <asm/ppc_sys.h> 35#include <asm/ppc_sys.h>
36#include <asm/machdep.h> 36#include <asm/machdep.h>
37 37#include <asm/pci-bridge.h>
38#include <syslib/mpc52xx_pci.h>
39 38
40 39
41extern int powersave_nap; 40extern int powersave_nap;
@@ -68,44 +67,53 @@ lite5200_show_cpuinfo(struct seq_file *m)
68} 67}
69 68
70#ifdef CONFIG_PCI 69#ifdef CONFIG_PCI
70#ifdef CONFIG_LITE5200B
71static int
72lite5200_map_irq(struct pci_dev *dev, unsigned char idsel,
73 unsigned char pin)
74{
75 static char pci_irq_table[][4] =
76 /*
77 * PCI IDSEL/INTPIN->INTLINE
78 * A B C D
79 */
80 {
81 {MPC52xx_IRQ0, MPC52xx_IRQ1, MPC52xx_IRQ2, MPC52xx_IRQ3},
82 {MPC52xx_IRQ1, MPC52xx_IRQ2, MPC52xx_IRQ3, MPC52xx_IRQ0},
83 };
84
85 const long min_idsel = 24, max_idsel = 25, irqs_per_slot = 4;
86 return PCI_IRQ_TABLE_LOOKUP;
87}
88#else /* Original Lite */
71static int 89static int
72lite5200_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin) 90lite5200_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin)
73{ 91{
74 return (pin == 1) && (idsel==24) ? MPC52xx_IRQ0 : -1; 92 return (pin == 1) && (idsel==24) ? MPC52xx_IRQ0 : -1;
75} 93}
76#endif 94#endif
95#endif
77 96
78static void __init 97static void __init
79lite5200_setup_cpu(void) 98lite5200_setup_cpu(void)
80{ 99{
81 struct mpc52xx_cdm __iomem *cdm;
82 struct mpc52xx_gpio __iomem *gpio; 100 struct mpc52xx_gpio __iomem *gpio;
83 struct mpc52xx_intr __iomem *intr; 101 struct mpc52xx_intr __iomem *intr;
84 struct mpc52xx_xlb __iomem *xlb;
85 102
86 u32 port_config; 103 u32 port_config;
87 u32 intr_ctrl; 104 u32 intr_ctrl;
88 105
89 /* Map zones */ 106 /* Map zones */
90 cdm = ioremap(MPC52xx_PA(MPC52xx_CDM_OFFSET), MPC52xx_CDM_SIZE);
91 gpio = ioremap(MPC52xx_PA(MPC52xx_GPIO_OFFSET), MPC52xx_GPIO_SIZE); 107 gpio = ioremap(MPC52xx_PA(MPC52xx_GPIO_OFFSET), MPC52xx_GPIO_SIZE);
92 xlb = ioremap(MPC52xx_PA(MPC52xx_XLB_OFFSET), MPC52xx_XLB_SIZE);
93 intr = ioremap(MPC52xx_PA(MPC52xx_INTR_OFFSET), MPC52xx_INTR_SIZE); 108 intr = ioremap(MPC52xx_PA(MPC52xx_INTR_OFFSET), MPC52xx_INTR_SIZE);
94 109
95 if (!cdm || !gpio || !xlb || !intr) { 110 if (!gpio || !intr) {
96 printk("lite5200.c: Error while mapping CDM/GPIO/XLB/INTR during" 111 printk(KERN_ERR __FILE__ ": "
97 "lite5200_setup_cpu\n"); 112 "Error while mapping GPIO/INTR during "
113 "lite5200_setup_cpu\n");
98 goto unmap_regs; 114 goto unmap_regs;
99 } 115 }
100 116
101 /* Use internal 48 Mhz */
102 out_8(&cdm->ext_48mhz_en, 0x00);
103 out_8(&cdm->fd_enable, 0x01);
104 if (in_be32(&cdm->rstcfg) & 0x40) /* Assumes 33Mhz clock */
105 out_be16(&cdm->fd_counters, 0x0001);
106 else
107 out_be16(&cdm->fd_counters, 0x5555);
108
109 /* Get port mux config */ 117 /* Get port mux config */
110 port_config = in_be32(&gpio->port_config); 118 port_config = in_be32(&gpio->port_config);
111 119
@@ -116,29 +124,29 @@ lite5200_setup_cpu(void)
116 port_config &= ~0x00007000; /* Differential mode - USB1 only */ 124 port_config &= ~0x00007000; /* Differential mode - USB1 only */
117 port_config |= 0x00001000; 125 port_config |= 0x00001000;
118 126
127 /* ATA CS is on csb_4/5 */
128 port_config &= ~0x03000000;
129 port_config |= 0x01000000;
130
119 /* Commit port config */ 131 /* Commit port config */
120 out_be32(&gpio->port_config, port_config); 132 out_be32(&gpio->port_config, port_config);
121 133
122 /* Configure the XLB Arbiter */ 134 /* IRQ[0-3] setup */
123 out_be32(&xlb->master_pri_enable, 0xff);
124 out_be32(&xlb->master_priority, 0x11111111);
125
126 /* Enable ram snooping for 1GB window */
127 out_be32(&xlb->config, in_be32(&xlb->config) | MPC52xx_XLB_CFG_SNOOP);
128 out_be32(&xlb->snoop_window, MPC52xx_PCI_TARGET_MEM | 0x1d);
129
130 /* IRQ[0-3] setup : IRQ0 - Level Active Low */
131 /* IRQ[1-3] - Level Active High */
132 intr_ctrl = in_be32(&intr->ctrl); 135 intr_ctrl = in_be32(&intr->ctrl);
133 intr_ctrl &= ~0x00ff0000; 136 intr_ctrl &= ~0x00ff0000;
134 intr_ctrl |= 0x00c00000; 137#ifdef CONFIG_LITE5200B
138 /* IRQ[0-3] Level Active Low */
139 intr_ctrl |= 0x00ff0000;
140#else
141 /* IRQ0 Level Active Low
142 * IRQ[1-3] Level Active High */
143 intr_ctrl |= 0x00c00000;
144#endif
135 out_be32(&intr->ctrl, intr_ctrl); 145 out_be32(&intr->ctrl, intr_ctrl);
136 146
137 /* Unmap reg zone */ 147 /* Unmap reg zone */
138unmap_regs: 148unmap_regs:
139 if (cdm) iounmap(cdm);
140 if (gpio) iounmap(gpio); 149 if (gpio) iounmap(gpio);
141 if (xlb) iounmap(xlb);
142 if (intr) iounmap(intr); 150 if (intr) iounmap(intr);
143} 151}
144 152
@@ -146,7 +154,8 @@ static void __init
146lite5200_setup_arch(void) 154lite5200_setup_arch(void)
147{ 155{
148 /* CPU & Port mux setup */ 156 /* CPU & Port mux setup */
149 lite5200_setup_cpu(); 157 mpc52xx_setup_cpu(); /* Generic */
158 lite5200_setup_cpu(); /* Platform specific */
150 159
151#ifdef CONFIG_PCI 160#ifdef CONFIG_PCI
152 /* PCI Bridge setup */ 161 /* PCI Bridge setup */
diff --git a/arch/ppc/platforms/prep_setup.c b/arch/ppc/platforms/prep_setup.c
index d95c05d9824d..e86f6156d589 100644
--- a/arch/ppc/platforms/prep_setup.c
+++ b/arch/ppc/platforms/prep_setup.c
@@ -1067,15 +1067,13 @@ prep_map_io(void)
1067static int __init 1067static int __init
1068prep_request_io(void) 1068prep_request_io(void)
1069{ 1069{
1070 if (_machine == _MACH_prep) {
1071#ifdef CONFIG_NVRAM 1070#ifdef CONFIG_NVRAM
1072 request_region(PREP_NVRAM_AS0, 0x8, "nvram"); 1071 request_region(PREP_NVRAM_AS0, 0x8, "nvram");
1073#endif 1072#endif
1074 request_region(0x00,0x20,"dma1"); 1073 request_region(0x00,0x20,"dma1");
1075 request_region(0x40,0x20,"timer"); 1074 request_region(0x40,0x20,"timer");
1076 request_region(0x80,0x10,"dma page reg"); 1075 request_region(0x80,0x10,"dma page reg");
1077 request_region(0xc0,0x20,"dma2"); 1076 request_region(0xc0,0x20,"dma2");
1078 }
1079 1077
1080 return 0; 1078 return 0;
1081} 1079}
diff --git a/arch/ppc/syslib/Makefile b/arch/ppc/syslib/Makefile
index 5cb62c6a51c8..490749ca88f9 100644
--- a/arch/ppc/syslib/Makefile
+++ b/arch/ppc/syslib/Makefile
@@ -38,8 +38,6 @@ endif
38obj-$(CONFIG_8xx) += m8xx_setup.o ppc8xx_pic.o $(wdt-mpc8xx-y) \ 38obj-$(CONFIG_8xx) += m8xx_setup.o ppc8xx_pic.o $(wdt-mpc8xx-y) \
39 ppc_sys.o mpc8xx_devices.o mpc8xx_sys.o 39 ppc_sys.o mpc8xx_devices.o mpc8xx_sys.o
40obj-$(CONFIG_PCI_QSPAN) += qspan_pci.o 40obj-$(CONFIG_PCI_QSPAN) += qspan_pci.o
41obj-$(CONFIG_PPC_OF) += prom_init.o prom.o
42obj-$(CONFIG_PPC_CHRP) += open_pic.o
43obj-$(CONFIG_PPC_PREP) += open_pic.o todc_time.o 41obj-$(CONFIG_PPC_PREP) += open_pic.o todc_time.o
44obj-$(CONFIG_BAMBOO) += pci_auto.o todc_time.o 42obj-$(CONFIG_BAMBOO) += pci_auto.o todc_time.o
45obj-$(CONFIG_CPCI690) += todc_time.o pci_auto.o 43obj-$(CONFIG_CPCI690) += todc_time.o pci_auto.o
diff --git a/arch/ppc/syslib/mpc52xx_pci.c b/arch/ppc/syslib/mpc52xx_pci.c
index 9ec525f9fe98..5a5a7a9cd248 100644
--- a/arch/ppc/syslib/mpc52xx_pci.c
+++ b/arch/ppc/syslib/mpc52xx_pci.c
@@ -225,7 +225,8 @@ mpc52xx_pci_fixup_resources(struct pci_dev *dev)
225 /* The PCI Host bridge of MPC52xx has a prefetch memory resource 225 /* The PCI Host bridge of MPC52xx has a prefetch memory resource
226 fixed to 1Gb. Doesn't fit in the resource system so we remove it */ 226 fixed to 1Gb. Doesn't fit in the resource system so we remove it */
227 if ( (dev->vendor == PCI_VENDOR_ID_MOTOROLA) && 227 if ( (dev->vendor == PCI_VENDOR_ID_MOTOROLA) &&
228 (dev->device == PCI_DEVICE_ID_MOTOROLA_MPC5200) ) { 228 ( dev->device == PCI_DEVICE_ID_MOTOROLA_MPC5200
229 || dev->device == PCI_DEVICE_ID_MOTOROLA_MPC5200B) ) {
229 struct resource *res = &dev->resource[1]; 230 struct resource *res = &dev->resource[1];
230 res->start = res->end = res->flags = 0; 231 res->start = res->end = res->flags = 0;
231 } 232 }
diff --git a/arch/ppc/syslib/mpc52xx_setup.c b/arch/ppc/syslib/mpc52xx_setup.c
index 2ee48ce0a517..ee6379bb415e 100644
--- a/arch/ppc/syslib/mpc52xx_setup.c
+++ b/arch/ppc/syslib/mpc52xx_setup.c
@@ -24,6 +24,8 @@
24#include <asm/pgtable.h> 24#include <asm/pgtable.h>
25#include <asm/ppcboot.h> 25#include <asm/ppcboot.h>
26 26
27#include <syslib/mpc52xx_pci.h>
28
27extern bd_t __res; 29extern bd_t __res;
28 30
29static int core_mult[] = { /* CPU Frequency multiplier, taken */ 31static int core_mult[] = { /* CPU Frequency multiplier, taken */
@@ -216,6 +218,52 @@ mpc52xx_calibrate_decr(void)
216 tb_to_us = mulhwu_scale_factor(xlbfreq / divisor, 1000000); 218 tb_to_us = mulhwu_scale_factor(xlbfreq / divisor, 1000000);
217} 219}
218 220
221
222void __init
223mpc52xx_setup_cpu(void)
224{
225 struct mpc52xx_cdm __iomem *cdm;
226 struct mpc52xx_xlb __iomem *xlb;
227
228 /* Map zones */
229 cdm = ioremap(MPC52xx_PA(MPC52xx_CDM_OFFSET), MPC52xx_CDM_SIZE);
230 xlb = ioremap(MPC52xx_PA(MPC52xx_XLB_OFFSET), MPC52xx_XLB_SIZE);
231
232 if (!cdm || !xlb) {
233 printk(KERN_ERR __FILE__ ": "
234 "Error while mapping CDM/XLB during "
235 "mpc52xx_setup_cpu\n");
236 goto unmap_regs;
237 }
238
239 /* Use internal 48 Mhz */
240 out_8(&cdm->ext_48mhz_en, 0x00);
241 out_8(&cdm->fd_enable, 0x01);
242 if (in_be32(&cdm->rstcfg) & 0x40) /* Assumes 33Mhz clock */
243 out_be16(&cdm->fd_counters, 0x0001);
244 else
245 out_be16(&cdm->fd_counters, 0x5555);
246
247 /* Configure the XLB Arbiter priorities */
248 out_be32(&xlb->master_pri_enable, 0xff);
249 out_be32(&xlb->master_priority, 0x11111111);
250
251 /* Enable ram snooping for 1GB window */
252 out_be32(&xlb->config, in_be32(&xlb->config) | MPC52xx_XLB_CFG_SNOOP);
253 out_be32(&xlb->snoop_window, MPC52xx_PCI_TARGET_MEM | 0x1d);
254
255 /* Disable XLB pipelining */
256 /* (cfr errate 292. We could do this only just before ATA PIO
257 transaction and re-enable it after ...) */
258 out_be32(&xlb->config, in_be32(&xlb->config) | MPC52xx_XLB_CFG_PLDIS);
259
260 /* Unmap reg zone */
261unmap_regs:
262 if (cdm) iounmap(cdm);
263 if (xlb) iounmap(xlb);
264}
265
266
219int mpc52xx_match_psc_function(int psc_idx, const char *func) 267int mpc52xx_match_psc_function(int psc_idx, const char *func)
220{ 268{
221 struct mpc52xx_psc_func *cf = mpc52xx_psc_functions; 269 struct mpc52xx_psc_func *cf = mpc52xx_psc_functions;
diff --git a/arch/ppc/syslib/open_pic.c b/arch/ppc/syslib/open_pic.c
index 38e5b93fbe41..70456c8f998c 100644
--- a/arch/ppc/syslib/open_pic.c
+++ b/arch/ppc/syslib/open_pic.c
@@ -216,7 +216,7 @@ static void openpic_safe_writefield(volatile u_int __iomem *addr, u_int mask,
216u_int openpic_read_IPI(volatile u_int __iomem * addr) 216u_int openpic_read_IPI(volatile u_int __iomem * addr)
217{ 217{
218 u_int val = 0; 218 u_int val = 0;
219#if defined(OPENPIC_BIG_ENDIAN) || defined(CONFIG_POWER3) 219#if defined(OPENPIC_BIG_ENDIAN)
220 val = in_be32(addr); 220 val = in_be32(addr);
221#else 221#else
222 val = in_le32(addr); 222 val = in_le32(addr);
diff --git a/arch/ppc/syslib/prom.c b/arch/ppc/syslib/prom.c
deleted file mode 100644
index 482f837fd373..000000000000
--- a/arch/ppc/syslib/prom.c
+++ /dev/null
@@ -1,1429 +0,0 @@
1/*
2 * Procedures for interfacing to the Open Firmware PROM on
3 * Power Macintosh computers.
4 *
5 * In particular, we are interested in the device tree
6 * and in using some of its services (exit, write to stdout).
7 *
8 * Paul Mackerras August 1996.
9 * Copyright (C) 1996 Paul Mackerras.
10 */
11#include <stdarg.h>
12#include <linux/config.h>
13#include <linux/kernel.h>
14#include <linux/string.h>
15#include <linux/init.h>
16#include <linux/threads.h>
17#include <linux/spinlock.h>
18#include <linux/ioport.h>
19#include <linux/pci.h>
20#include <linux/slab.h>
21#include <linux/bitops.h>
22
23#include <asm/sections.h>
24#include <asm/prom.h>
25#include <asm/page.h>
26#include <asm/processor.h>
27#include <asm/irq.h>
28#include <asm/io.h>
29#include <asm/smp.h>
30#include <asm/bootx.h>
31#include <asm/system.h>
32#include <asm/mmu.h>
33#include <asm/pgtable.h>
34#include <asm/bootinfo.h>
35#include <asm/btext.h>
36#include <asm/pci-bridge.h>
37#include <asm/open_pic.h>
38
39
40struct pci_address {
41 unsigned a_hi;
42 unsigned a_mid;
43 unsigned a_lo;
44};
45
46struct pci_reg_property {
47 struct pci_address addr;
48 unsigned size_hi;
49 unsigned size_lo;
50};
51
52struct isa_reg_property {
53 unsigned space;
54 unsigned address;
55 unsigned size;
56};
57
58typedef unsigned long interpret_func(struct device_node *, unsigned long,
59 int, int);
60static interpret_func interpret_pci_props;
61static interpret_func interpret_dbdma_props;
62static interpret_func interpret_isa_props;
63static interpret_func interpret_macio_props;
64static interpret_func interpret_root_props;
65
66extern char *klimit;
67
68/* Set for a newworld or CHRP machine */
69int use_of_interrupt_tree;
70struct device_node *dflt_interrupt_controller;
71int num_interrupt_controllers;
72
73extern unsigned int rtas_entry; /* physical pointer */
74
75extern struct device_node *allnodes;
76
77static unsigned long finish_node(struct device_node *, unsigned long,
78 interpret_func *, int, int);
79static unsigned long finish_node_interrupts(struct device_node *, unsigned long);
80static struct device_node *find_phandle(phandle);
81
82extern void enter_rtas(void *);
83void phys_call_rtas(int, int, int, ...);
84
85extern char cmd_line[512]; /* XXX */
86extern boot_infos_t *boot_infos;
87unsigned long dev_tree_size;
88
89void
90phys_call_rtas(int service, int nargs, int nret, ...)
91{
92 va_list list;
93 union {
94 unsigned long words[16];
95 double align;
96 } u;
97 void (*rtas)(void *, unsigned long);
98 int i;
99
100 u.words[0] = service;
101 u.words[1] = nargs;
102 u.words[2] = nret;
103 va_start(list, nret);
104 for (i = 0; i < nargs; ++i)
105 u.words[i+3] = va_arg(list, unsigned long);
106 va_end(list);
107
108 rtas = (void (*)(void *, unsigned long)) rtas_entry;
109 rtas(&u, rtas_data);
110}
111
112/*
113 * finish_device_tree is called once things are running normally
114 * (i.e. with text and data mapped to the address they were linked at).
115 * It traverses the device tree and fills in the name, type,
116 * {n_}addrs and {n_}intrs fields of each node.
117 */
118void __init
119finish_device_tree(void)
120{
121 unsigned long mem = (unsigned long) klimit;
122 struct device_node *np;
123
124 /* All CHRPs now use the interrupt tree */
125 for (np = allnodes; np != NULL; np = np->allnext) {
126 if (get_property(np, "interrupt-parent", NULL)) {
127 use_of_interrupt_tree = 1;
128 break;
129 }
130 }
131
132 if (use_of_interrupt_tree) {
133 /*
134 * We want to find out here how many interrupt-controller
135 * nodes there are, and if we are booted from BootX,
136 * we need a pointer to the first (and hopefully only)
137 * such node. But we can't use find_devices here since
138 * np->name has not been set yet. -- paulus
139 */
140 int n = 0;
141 char *name, *ic;
142 int iclen;
143
144 for (np = allnodes; np != NULL; np = np->allnext) {
145 ic = get_property(np, "interrupt-controller", &iclen);
146 name = get_property(np, "name", NULL);
147 /* checking iclen makes sure we don't get a false
148 match on /chosen.interrupt_controller */
149 if ((name != NULL
150 && strcmp(name, "interrupt-controller") == 0)
151 || (ic != NULL && iclen == 0 && strcmp(name, "AppleKiwi"))) {
152 if (n == 0)
153 dflt_interrupt_controller = np;
154 ++n;
155 }
156 }
157 num_interrupt_controllers = n;
158 }
159
160 mem = finish_node(allnodes, mem, NULL, 1, 1);
161 dev_tree_size = mem - (unsigned long) allnodes;
162 klimit = (char *) mem;
163}
164
165static unsigned long __init
166finish_node(struct device_node *np, unsigned long mem_start,
167 interpret_func *ifunc, int naddrc, int nsizec)
168{
169 struct device_node *child;
170 int *ip;
171
172 np->name = get_property(np, "name", NULL);
173 np->type = get_property(np, "device_type", NULL);
174
175 if (!np->name)
176 np->name = "<NULL>";
177 if (!np->type)
178 np->type = "<NULL>";
179
180 /* get the device addresses and interrupts */
181 if (ifunc != NULL)
182 mem_start = ifunc(np, mem_start, naddrc, nsizec);
183
184 if (use_of_interrupt_tree)
185 mem_start = finish_node_interrupts(np, mem_start);
186
187 /* Look for #address-cells and #size-cells properties. */
188 ip = (int *) get_property(np, "#address-cells", NULL);
189 if (ip != NULL)
190 naddrc = *ip;
191 ip = (int *) get_property(np, "#size-cells", NULL);
192 if (ip != NULL)
193 nsizec = *ip;
194
195 if (np->parent == NULL)
196 ifunc = interpret_root_props;
197 else if (np->type == 0)
198 ifunc = NULL;
199 else if (!strcmp(np->type, "pci") || !strcmp(np->type, "vci"))
200 ifunc = interpret_pci_props;
201 else if (!strcmp(np->type, "dbdma"))
202 ifunc = interpret_dbdma_props;
203 else if (!strcmp(np->type, "mac-io")
204 || ifunc == interpret_macio_props)
205 ifunc = interpret_macio_props;
206 else if (!strcmp(np->type, "isa"))
207 ifunc = interpret_isa_props;
208 else if (!strcmp(np->name, "uni-n") || !strcmp(np->name, "u3"))
209 ifunc = interpret_root_props;
210 else if (!((ifunc == interpret_dbdma_props
211 || ifunc == interpret_macio_props)
212 && (!strcmp(np->type, "escc")
213 || !strcmp(np->type, "media-bay"))))
214 ifunc = NULL;
215
216 /* if we were booted from BootX, convert the full name */
217 if (boot_infos
218 && strncmp(np->full_name, "Devices:device-tree", 19) == 0) {
219 if (np->full_name[19] == 0) {
220 strcpy(np->full_name, "/");
221 } else if (np->full_name[19] == ':') {
222 char *p = np->full_name + 19;
223 np->full_name = p;
224 for (; *p; ++p)
225 if (*p == ':')
226 *p = '/';
227 }
228 }
229
230 for (child = np->child; child != NULL; child = child->sibling)
231 mem_start = finish_node(child, mem_start, ifunc,
232 naddrc, nsizec);
233
234 return mem_start;
235}
236
237/*
238 * Find the interrupt parent of a node.
239 */
240static struct device_node * __init
241intr_parent(struct device_node *p)
242{
243 phandle *parp;
244
245 parp = (phandle *) get_property(p, "interrupt-parent", NULL);
246 if (parp == NULL)
247 return p->parent;
248 p = find_phandle(*parp);
249 if (p != NULL)
250 return p;
251 /*
252 * On a powermac booted with BootX, we don't get to know the
253 * phandles for any nodes, so find_phandle will return NULL.
254 * Fortunately these machines only have one interrupt controller
255 * so there isn't in fact any ambiguity. -- paulus
256 */
257 if (num_interrupt_controllers == 1)
258 p = dflt_interrupt_controller;
259 return p;
260}
261
262/*
263 * Find out the size of each entry of the interrupts property
264 * for a node.
265 */
266static int __init
267prom_n_intr_cells(struct device_node *np)
268{
269 struct device_node *p;
270 unsigned int *icp;
271
272 for (p = np; (p = intr_parent(p)) != NULL; ) {
273 icp = (unsigned int *)
274 get_property(p, "#interrupt-cells", NULL);
275 if (icp != NULL)
276 return *icp;
277 if (get_property(p, "interrupt-controller", NULL) != NULL
278 || get_property(p, "interrupt-map", NULL) != NULL) {
279 printk("oops, node %s doesn't have #interrupt-cells\n",
280 p->full_name);
281 return 1;
282 }
283 }
284 printk("prom_n_intr_cells failed for %s\n", np->full_name);
285 return 1;
286}
287
288/*
289 * Map an interrupt from a device up to the platform interrupt
290 * descriptor.
291 */
292static int __init
293map_interrupt(unsigned int **irq, struct device_node **ictrler,
294 struct device_node *np, unsigned int *ints, int nintrc)
295{
296 struct device_node *p, *ipar;
297 unsigned int *imap, *imask, *ip;
298 int i, imaplen, match;
299 int newintrc = 1, newaddrc = 1;
300 unsigned int *reg;
301 int naddrc;
302
303 reg = (unsigned int *) get_property(np, "reg", NULL);
304 naddrc = prom_n_addr_cells(np);
305 p = intr_parent(np);
306 while (p != NULL) {
307 if (get_property(p, "interrupt-controller", NULL) != NULL)
308 /* this node is an interrupt controller, stop here */
309 break;
310 imap = (unsigned int *)
311 get_property(p, "interrupt-map", &imaplen);
312 if (imap == NULL) {
313 p = intr_parent(p);
314 continue;
315 }
316 imask = (unsigned int *)
317 get_property(p, "interrupt-map-mask", NULL);
318 if (imask == NULL) {
319 printk("oops, %s has interrupt-map but no mask\n",
320 p->full_name);
321 return 0;
322 }
323 imaplen /= sizeof(unsigned int);
324 match = 0;
325 ipar = NULL;
326 while (imaplen > 0 && !match) {
327 /* check the child-interrupt field */
328 match = 1;
329 for (i = 0; i < naddrc && match; ++i)
330 match = ((reg[i] ^ imap[i]) & imask[i]) == 0;
331 for (; i < naddrc + nintrc && match; ++i)
332 match = ((ints[i-naddrc] ^ imap[i]) & imask[i]) == 0;
333 imap += naddrc + nintrc;
334 imaplen -= naddrc + nintrc;
335 /* grab the interrupt parent */
336 ipar = find_phandle((phandle) *imap++);
337 --imaplen;
338 if (ipar == NULL && num_interrupt_controllers == 1)
339 /* cope with BootX not giving us phandles */
340 ipar = dflt_interrupt_controller;
341 if (ipar == NULL) {
342 printk("oops, no int parent %x in map of %s\n",
343 imap[-1], p->full_name);
344 return 0;
345 }
346 /* find the parent's # addr and intr cells */
347 ip = (unsigned int *)
348 get_property(ipar, "#interrupt-cells", NULL);
349 if (ip == NULL) {
350 printk("oops, no #interrupt-cells on %s\n",
351 ipar->full_name);
352 return 0;
353 }
354 newintrc = *ip;
355 ip = (unsigned int *)
356 get_property(ipar, "#address-cells", NULL);
357 newaddrc = (ip == NULL)? 0: *ip;
358 imap += newaddrc + newintrc;
359 imaplen -= newaddrc + newintrc;
360 }
361 if (imaplen < 0) {
362 printk("oops, error decoding int-map on %s, len=%d\n",
363 p->full_name, imaplen);
364 return 0;
365 }
366 if (!match) {
367 printk("oops, no match in %s int-map for %s\n",
368 p->full_name, np->full_name);
369 return 0;
370 }
371 p = ipar;
372 naddrc = newaddrc;
373 nintrc = newintrc;
374 ints = imap - nintrc;
375 reg = ints - naddrc;
376 }
377 if (p == NULL)
378 printk("hmmm, int tree for %s doesn't have ctrler\n",
379 np->full_name);
380 *irq = ints;
381 *ictrler = p;
382 return nintrc;
383}
384
385/*
386 * New version of finish_node_interrupts.
387 */
388static unsigned long __init
389finish_node_interrupts(struct device_node *np, unsigned long mem_start)
390{
391 unsigned int *ints;
392 int intlen, intrcells;
393 int i, j, n, offset;
394 unsigned int *irq;
395 struct device_node *ic;
396
397 ints = (unsigned int *) get_property(np, "interrupts", &intlen);
398 if (ints == NULL)
399 return mem_start;
400 intrcells = prom_n_intr_cells(np);
401 intlen /= intrcells * sizeof(unsigned int);
402 np->n_intrs = intlen;
403 np->intrs = (struct interrupt_info *) mem_start;
404 mem_start += intlen * sizeof(struct interrupt_info);
405
406 for (i = 0; i < intlen; ++i) {
407 np->intrs[i].line = 0;
408 np->intrs[i].sense = 1;
409 n = map_interrupt(&irq, &ic, np, ints, intrcells);
410 if (n <= 0)
411 continue;
412 offset = 0;
413 /*
414 * On a CHRP we have an 8259 which is subordinate to
415 * the openpic in the interrupt tree, but we want the
416 * openpic's interrupt numbers offsetted, not the 8259's.
417 * So we apply the offset if the controller is at the
418 * root of the interrupt tree, i.e. has no interrupt-parent.
419 * This doesn't cope with the general case of multiple
420 * cascaded interrupt controllers, but then neither will
421 * irq.c at the moment either. -- paulus
422 * The G5 triggers that code, I add a machine test. On
423 * those machines, we want to offset interrupts from the
424 * second openpic by 128 -- BenH
425 */
426 if (num_interrupt_controllers > 1
427 && ic != NULL
428 && get_property(ic, "interrupt-parent", NULL) == NULL)
429 offset = 16;
430
431 np->intrs[i].line = irq[0] + offset;
432 if (n > 1)
433 np->intrs[i].sense = irq[1];
434 if (n > 2) {
435 printk("hmmm, got %d intr cells for %s:", n,
436 np->full_name);
437 for (j = 0; j < n; ++j)
438 printk(" %d", irq[j]);
439 printk("\n");
440 }
441 ints += intrcells;
442 }
443
444 return mem_start;
445}
446
447/*
448 * When BootX makes a copy of the device tree from the MacOS
449 * Name Registry, it is in the format we use but all of the pointers
450 * are offsets from the start of the tree.
451 * This procedure updates the pointers.
452 */
453void __init
454relocate_nodes(void)
455{
456 unsigned long base;
457 struct device_node *np;
458 struct property *pp;
459
460#define ADDBASE(x) (x = (typeof (x))((x)? ((unsigned long)(x) + base): 0))
461
462 base = (unsigned long) boot_infos + boot_infos->deviceTreeOffset;
463 allnodes = (struct device_node *)(base + 4);
464 for (np = allnodes; np != 0; np = np->allnext) {
465 ADDBASE(np->full_name);
466 ADDBASE(np->properties);
467 ADDBASE(np->parent);
468 ADDBASE(np->child);
469 ADDBASE(np->sibling);
470 ADDBASE(np->allnext);
471 for (pp = np->properties; pp != 0; pp = pp->next) {
472 ADDBASE(pp->name);
473 ADDBASE(pp->value);
474 ADDBASE(pp->next);
475 }
476 }
477}
478
479int
480prom_n_addr_cells(struct device_node* np)
481{
482 int* ip;
483 do {
484 if (np->parent)
485 np = np->parent;
486 ip = (int *) get_property(np, "#address-cells", NULL);
487 if (ip != NULL)
488 return *ip;
489 } while (np->parent);
490 /* No #address-cells property for the root node, default to 1 */
491 return 1;
492}
493
494int
495prom_n_size_cells(struct device_node* np)
496{
497 int* ip;
498 do {
499 if (np->parent)
500 np = np->parent;
501 ip = (int *) get_property(np, "#size-cells", NULL);
502 if (ip != NULL)
503 return *ip;
504 } while (np->parent);
505 /* No #size-cells property for the root node, default to 1 */
506 return 1;
507}
508
509static unsigned long __init
510map_addr(struct device_node *np, unsigned long space, unsigned long addr)
511{
512 int na;
513 unsigned int *ranges;
514 int rlen = 0;
515 unsigned int type;
516
517 type = (space >> 24) & 3;
518 if (type == 0)
519 return addr;
520
521 while ((np = np->parent) != NULL) {
522 if (strcmp(np->type, "pci") != 0)
523 continue;
524 /* PCI bridge: map the address through the ranges property */
525 na = prom_n_addr_cells(np);
526 ranges = (unsigned int *) get_property(np, "ranges", &rlen);
527 while ((rlen -= (na + 5) * sizeof(unsigned int)) >= 0) {
528 if (((ranges[0] >> 24) & 3) == type
529 && ranges[2] <= addr
530 && addr - ranges[2] < ranges[na+4]) {
531 /* ok, this matches, translate it */
532 addr += ranges[na+2] - ranges[2];
533 break;
534 }
535 ranges += na + 5;
536 }
537 }
538 return addr;
539}
540
541static unsigned long __init
542interpret_pci_props(struct device_node *np, unsigned long mem_start,
543 int naddrc, int nsizec)
544{
545 struct address_range *adr;
546 struct pci_reg_property *pci_addrs;
547 int i, l, *ip;
548
549 pci_addrs = (struct pci_reg_property *)
550 get_property(np, "assigned-addresses", &l);
551 if (pci_addrs != 0 && l >= sizeof(struct pci_reg_property)) {
552 i = 0;
553 adr = (struct address_range *) mem_start;
554 while ((l -= sizeof(struct pci_reg_property)) >= 0) {
555 adr[i].space = pci_addrs[i].addr.a_hi;
556 adr[i].address = map_addr(np, pci_addrs[i].addr.a_hi,
557 pci_addrs[i].addr.a_lo);
558 adr[i].size = pci_addrs[i].size_lo;
559 ++i;
560 }
561 np->addrs = adr;
562 np->n_addrs = i;
563 mem_start += i * sizeof(struct address_range);
564 }
565
566 if (use_of_interrupt_tree)
567 return mem_start;
568
569 ip = (int *) get_property(np, "AAPL,interrupts", &l);
570 if (ip == 0 && np->parent)
571 ip = (int *) get_property(np->parent, "AAPL,interrupts", &l);
572 if (ip == 0)
573 ip = (int *) get_property(np, "interrupts", &l);
574 if (ip != 0) {
575 np->intrs = (struct interrupt_info *) mem_start;
576 np->n_intrs = l / sizeof(int);
577 mem_start += np->n_intrs * sizeof(struct interrupt_info);
578 for (i = 0; i < np->n_intrs; ++i) {
579 np->intrs[i].line = *ip++;
580 np->intrs[i].sense = 1;
581 }
582 }
583
584 return mem_start;
585}
586
587static unsigned long __init
588interpret_dbdma_props(struct device_node *np, unsigned long mem_start,
589 int naddrc, int nsizec)
590{
591 struct reg_property *rp;
592 struct address_range *adr;
593 unsigned long base_address;
594 int i, l, *ip;
595 struct device_node *db;
596
597 base_address = 0;
598 for (db = np->parent; db != NULL; db = db->parent) {
599 if (!strcmp(db->type, "dbdma") && db->n_addrs != 0) {
600 base_address = db->addrs[0].address;
601 break;
602 }
603 }
604
605 rp = (struct reg_property *) get_property(np, "reg", &l);
606 if (rp != 0 && l >= sizeof(struct reg_property)) {
607 i = 0;
608 adr = (struct address_range *) mem_start;
609 while ((l -= sizeof(struct reg_property)) >= 0) {
610 adr[i].space = 2;
611 adr[i].address = rp[i].address + base_address;
612 adr[i].size = rp[i].size;
613 ++i;
614 }
615 np->addrs = adr;
616 np->n_addrs = i;
617 mem_start += i * sizeof(struct address_range);
618 }
619
620 if (use_of_interrupt_tree)
621 return mem_start;
622
623 ip = (int *) get_property(np, "AAPL,interrupts", &l);
624 if (ip == 0)
625 ip = (int *) get_property(np, "interrupts", &l);
626 if (ip != 0) {
627 np->intrs = (struct interrupt_info *) mem_start;
628 np->n_intrs = l / sizeof(int);
629 mem_start += np->n_intrs * sizeof(struct interrupt_info);
630 for (i = 0; i < np->n_intrs; ++i) {
631 np->intrs[i].line = *ip++;
632 np->intrs[i].sense = 1;
633 }
634 }
635
636 return mem_start;
637}
638
639static unsigned long __init
640interpret_macio_props(struct device_node *np, unsigned long mem_start,
641 int naddrc, int nsizec)
642{
643 struct reg_property *rp;
644 struct address_range *adr;
645 unsigned long base_address;
646 int i, l, *ip;
647 struct device_node *db;
648
649 base_address = 0;
650 for (db = np->parent; db != NULL; db = db->parent) {
651 if (!strcmp(db->type, "mac-io") && db->n_addrs != 0) {
652 base_address = db->addrs[0].address;
653 break;
654 }
655 }
656
657 rp = (struct reg_property *) get_property(np, "reg", &l);
658 if (rp != 0 && l >= sizeof(struct reg_property)) {
659 i = 0;
660 adr = (struct address_range *) mem_start;
661 while ((l -= sizeof(struct reg_property)) >= 0) {
662 adr[i].space = 2;
663 adr[i].address = rp[i].address + base_address;
664 adr[i].size = rp[i].size;
665 ++i;
666 }
667 np->addrs = adr;
668 np->n_addrs = i;
669 mem_start += i * sizeof(struct address_range);
670 }
671
672 if (use_of_interrupt_tree)
673 return mem_start;
674
675 ip = (int *) get_property(np, "interrupts", &l);
676 if (ip == 0)
677 ip = (int *) get_property(np, "AAPL,interrupts", &l);
678 if (ip != 0) {
679 np->intrs = (struct interrupt_info *) mem_start;
680 np->n_intrs = l / sizeof(int);
681 for (i = 0; i < np->n_intrs; ++i) {
682 np->intrs[i].line = *ip++;
683 np->intrs[i].sense = 1;
684 }
685 mem_start += np->n_intrs * sizeof(struct interrupt_info);
686 }
687
688 return mem_start;
689}
690
691static unsigned long __init
692interpret_isa_props(struct device_node *np, unsigned long mem_start,
693 int naddrc, int nsizec)
694{
695 struct isa_reg_property *rp;
696 struct address_range *adr;
697 int i, l, *ip;
698
699 rp = (struct isa_reg_property *) get_property(np, "reg", &l);
700 if (rp != 0 && l >= sizeof(struct isa_reg_property)) {
701 i = 0;
702 adr = (struct address_range *) mem_start;
703 while ((l -= sizeof(struct reg_property)) >= 0) {
704 adr[i].space = rp[i].space;
705 adr[i].address = rp[i].address
706 + (adr[i].space? 0: _ISA_MEM_BASE);
707 adr[i].size = rp[i].size;
708 ++i;
709 }
710 np->addrs = adr;
711 np->n_addrs = i;
712 mem_start += i * sizeof(struct address_range);
713 }
714
715 if (use_of_interrupt_tree)
716 return mem_start;
717
718 ip = (int *) get_property(np, "interrupts", &l);
719 if (ip != 0) {
720 np->intrs = (struct interrupt_info *) mem_start;
721 np->n_intrs = l / (2 * sizeof(int));
722 mem_start += np->n_intrs * sizeof(struct interrupt_info);
723 for (i = 0; i < np->n_intrs; ++i) {
724 np->intrs[i].line = *ip++;
725 np->intrs[i].sense = *ip++;
726 }
727 }
728
729 return mem_start;
730}
731
732static unsigned long __init
733interpret_root_props(struct device_node *np, unsigned long mem_start,
734 int naddrc, int nsizec)
735{
736 struct address_range *adr;
737 int i, l, *ip;
738 unsigned int *rp;
739 int rpsize = (naddrc + nsizec) * sizeof(unsigned int);
740
741 rp = (unsigned int *) get_property(np, "reg", &l);
742 if (rp != 0 && l >= rpsize) {
743 i = 0;
744 adr = (struct address_range *) mem_start;
745 while ((l -= rpsize) >= 0) {
746 adr[i].space = (naddrc >= 2? rp[naddrc-2]: 2);
747 adr[i].address = rp[naddrc - 1];
748 adr[i].size = rp[naddrc + nsizec - 1];
749 ++i;
750 rp += naddrc + nsizec;
751 }
752 np->addrs = adr;
753 np->n_addrs = i;
754 mem_start += i * sizeof(struct address_range);
755 }
756
757 if (use_of_interrupt_tree)
758 return mem_start;
759
760 ip = (int *) get_property(np, "AAPL,interrupts", &l);
761 if (ip == 0)
762 ip = (int *) get_property(np, "interrupts", &l);
763 if (ip != 0) {
764 np->intrs = (struct interrupt_info *) mem_start;
765 np->n_intrs = l / sizeof(int);
766 mem_start += np->n_intrs * sizeof(struct interrupt_info);
767 for (i = 0; i < np->n_intrs; ++i) {
768 np->intrs[i].line = *ip++;
769 np->intrs[i].sense = 1;
770 }
771 }
772
773 return mem_start;
774}
775
776/*
777 * Work out the sense (active-low level / active-high edge)
778 * of each interrupt from the device tree.
779 */
780void __init
781prom_get_irq_senses(unsigned char *senses, int off, int max)
782{
783 struct device_node *np;
784 int i, j;
785
786 /* default to level-triggered */
787 memset(senses, 1, max - off);
788 if (!use_of_interrupt_tree)
789 return;
790
791 for (np = allnodes; np != 0; np = np->allnext) {
792 for (j = 0; j < np->n_intrs; j++) {
793 i = np->intrs[j].line;
794 if (i >= off && i < max) {
795 if (np->intrs[j].sense == 1)
796 senses[i-off] = (IRQ_SENSE_LEVEL
797 | IRQ_POLARITY_NEGATIVE);
798 else
799 senses[i-off] = (IRQ_SENSE_EDGE
800 | IRQ_POLARITY_POSITIVE);
801 }
802 }
803 }
804}
805
806/*
807 * Construct and return a list of the device_nodes with a given name.
808 */
809struct device_node *
810find_devices(const char *name)
811{
812 struct device_node *head, **prevp, *np;
813
814 prevp = &head;
815 for (np = allnodes; np != 0; np = np->allnext) {
816 if (np->name != 0 && strcasecmp(np->name, name) == 0) {
817 *prevp = np;
818 prevp = &np->next;
819 }
820 }
821 *prevp = NULL;
822 return head;
823}
824
825/*
826 * Construct and return a list of the device_nodes with a given type.
827 */
828struct device_node *
829find_type_devices(const char *type)
830{
831 struct device_node *head, **prevp, *np;
832
833 prevp = &head;
834 for (np = allnodes; np != 0; np = np->allnext) {
835 if (np->type != 0 && strcasecmp(np->type, type) == 0) {
836 *prevp = np;
837 prevp = &np->next;
838 }
839 }
840 *prevp = NULL;
841 return head;
842}
843
844/*
845 * Returns all nodes linked together
846 */
847struct device_node *
848find_all_nodes(void)
849{
850 struct device_node *head, **prevp, *np;
851
852 prevp = &head;
853 for (np = allnodes; np != 0; np = np->allnext) {
854 *prevp = np;
855 prevp = &np->next;
856 }
857 *prevp = NULL;
858 return head;
859}
860
861/* Checks if the given "compat" string matches one of the strings in
862 * the device's "compatible" property
863 */
864int
865device_is_compatible(struct device_node *device, const char *compat)
866{
867 const char* cp;
868 int cplen, l;
869
870 cp = (char *) get_property(device, "compatible", &cplen);
871 if (cp == NULL)
872 return 0;
873 while (cplen > 0) {
874 if (strncasecmp(cp, compat, strlen(compat)) == 0)
875 return 1;
876 l = strlen(cp) + 1;
877 cp += l;
878 cplen -= l;
879 }
880
881 return 0;
882}
883
884
885/*
886 * Indicates whether the root node has a given value in its
887 * compatible property.
888 */
889int
890machine_is_compatible(const char *compat)
891{
892 struct device_node *root;
893
894 root = find_path_device("/");
895 if (root == 0)
896 return 0;
897 return device_is_compatible(root, compat);
898}
899
900/*
901 * Construct and return a list of the device_nodes with a given type
902 * and compatible property.
903 */
904struct device_node *
905find_compatible_devices(const char *type, const char *compat)
906{
907 struct device_node *head, **prevp, *np;
908
909 prevp = &head;
910 for (np = allnodes; np != 0; np = np->allnext) {
911 if (type != NULL
912 && !(np->type != 0 && strcasecmp(np->type, type) == 0))
913 continue;
914 if (device_is_compatible(np, compat)) {
915 *prevp = np;
916 prevp = &np->next;
917 }
918 }
919 *prevp = NULL;
920 return head;
921}
922
923/*
924 * Find the device_node with a given full_name.
925 */
926struct device_node *
927find_path_device(const char *path)
928{
929 struct device_node *np;
930
931 for (np = allnodes; np != 0; np = np->allnext)
932 if (np->full_name != 0 && strcasecmp(np->full_name, path) == 0)
933 return np;
934 return NULL;
935}
936
937/*******
938 *
939 * New implementation of the OF "find" APIs, return a refcounted
940 * object, call of_node_put() when done. Currently, still lacks
941 * locking as old implementation, this is beeing done for ppc64.
942 *
943 * Note that property management will need some locking as well,
944 * this isn't dealt with yet
945 *
946 *******/
947
948/**
949 * of_find_node_by_name - Find a node by it's "name" property
950 * @from: The node to start searching from or NULL, the node
951 * you pass will not be searched, only the next one
952 * will; typically, you pass what the previous call
953 * returned. of_node_put() will be called on it
954 * @name: The name string to match against
955 *
956 * Returns a node pointer with refcount incremented, use
957 * of_node_put() on it when done.
958 */
959struct device_node *of_find_node_by_name(struct device_node *from,
960 const char *name)
961{
962 struct device_node *np = from ? from->allnext : allnodes;
963
964 for (; np != 0; np = np->allnext)
965 if (np->name != 0 && strcasecmp(np->name, name) == 0)
966 break;
967 if (from)
968 of_node_put(from);
969 return of_node_get(np);
970}
971
972/**
973 * of_find_node_by_type - Find a node by it's "device_type" property
974 * @from: The node to start searching from or NULL, the node
975 * you pass will not be searched, only the next one
976 * will; typically, you pass what the previous call
977 * returned. of_node_put() will be called on it
978 * @name: The type string to match against
979 *
980 * Returns a node pointer with refcount incremented, use
981 * of_node_put() on it when done.
982 */
983struct device_node *of_find_node_by_type(struct device_node *from,
984 const char *type)
985{
986 struct device_node *np = from ? from->allnext : allnodes;
987
988 for (; np != 0; np = np->allnext)
989 if (np->type != 0 && strcasecmp(np->type, type) == 0)
990 break;
991 if (from)
992 of_node_put(from);
993 return of_node_get(np);
994}
995
996/**
997 * of_find_compatible_node - Find a node based on type and one of the
998 * tokens in it's "compatible" property
999 * @from: The node to start searching from or NULL, the node
1000 * you pass will not be searched, only the next one
1001 * will; typically, you pass what the previous call
1002 * returned. of_node_put() will be called on it
1003 * @type: The type string to match "device_type" or NULL to ignore
1004 * @compatible: The string to match to one of the tokens in the device
1005 * "compatible" list.
1006 *
1007 * Returns a node pointer with refcount incremented, use
1008 * of_node_put() on it when done.
1009 */
1010struct device_node *of_find_compatible_node(struct device_node *from,
1011 const char *type, const char *compatible)
1012{
1013 struct device_node *np = from ? from->allnext : allnodes;
1014
1015 for (; np != 0; np = np->allnext) {
1016 if (type != NULL
1017 && !(np->type != 0 && strcasecmp(np->type, type) == 0))
1018 continue;
1019 if (device_is_compatible(np, compatible))
1020 break;
1021 }
1022 if (from)
1023 of_node_put(from);
1024 return of_node_get(np);
1025}
1026
1027/**
1028 * of_find_node_by_path - Find a node matching a full OF path
1029 * @path: The full path to match
1030 *
1031 * Returns a node pointer with refcount incremented, use
1032 * of_node_put() on it when done.
1033 */
1034struct device_node *of_find_node_by_path(const char *path)
1035{
1036 struct device_node *np = allnodes;
1037
1038 for (; np != 0; np = np->allnext)
1039 if (np->full_name != 0 && strcasecmp(np->full_name, path) == 0)
1040 break;
1041 return of_node_get(np);
1042}
1043
1044/**
1045 * of_find_all_nodes - Get next node in global list
1046 * @prev: Previous node or NULL to start iteration
1047 * of_node_put() will be called on it
1048 *
1049 * Returns a node pointer with refcount incremented, use
1050 * of_node_put() on it when done.
1051 */
1052struct device_node *of_find_all_nodes(struct device_node *prev)
1053{
1054 return of_node_get(prev ? prev->allnext : allnodes);
1055}
1056
1057/**
1058 * of_get_parent - Get a node's parent if any
1059 * @node: Node to get parent
1060 *
1061 * Returns a node pointer with refcount incremented, use
1062 * of_node_put() on it when done.
1063 */
1064struct device_node *of_get_parent(const struct device_node *node)
1065{
1066 return node ? of_node_get(node->parent) : NULL;
1067}
1068
1069/**
1070 * of_get_next_child - Iterate a node childs
1071 * @node: parent node
1072 * @prev: previous child of the parent node, or NULL to get first
1073 *
1074 * Returns a node pointer with refcount incremented, use
1075 * of_node_put() on it when done.
1076 */
1077struct device_node *of_get_next_child(const struct device_node *node,
1078 struct device_node *prev)
1079{
1080 struct device_node *next = prev ? prev->sibling : node->child;
1081
1082 for (; next != 0; next = next->sibling)
1083 if (of_node_get(next))
1084 break;
1085 if (prev)
1086 of_node_put(prev);
1087 return next;
1088}
1089
1090/**
1091 * of_node_get - Increment refcount of a node
1092 * @node: Node to inc refcount, NULL is supported to
1093 * simplify writing of callers
1094 *
1095 * Returns the node itself or NULL if gone. Current implementation
1096 * does nothing as we don't yet do dynamic node allocation on ppc32
1097 */
1098struct device_node *of_node_get(struct device_node *node)
1099{
1100 return node;
1101}
1102
1103/**
1104 * of_node_put - Decrement refcount of a node
1105 * @node: Node to dec refcount, NULL is supported to
1106 * simplify writing of callers
1107 *
1108 * Current implementation does nothing as we don't yet do dynamic node
1109 * allocation on ppc32
1110 */
1111void of_node_put(struct device_node *node)
1112{
1113}
1114
1115/*
1116 * Find the device_node with a given phandle.
1117 */
1118static struct device_node * __init
1119find_phandle(phandle ph)
1120{
1121 struct device_node *np;
1122
1123 for (np = allnodes; np != 0; np = np->allnext)
1124 if (np->node == ph)
1125 return np;
1126 return NULL;
1127}
1128
1129/*
1130 * Find a property with a given name for a given node
1131 * and return the value.
1132 */
1133unsigned char *
1134get_property(struct device_node *np, const char *name, int *lenp)
1135{
1136 struct property *pp;
1137
1138 for (pp = np->properties; pp != 0; pp = pp->next)
1139 if (pp->name != NULL && strcmp(pp->name, name) == 0) {
1140 if (lenp != 0)
1141 *lenp = pp->length;
1142 return pp->value;
1143 }
1144 return NULL;
1145}
1146
1147/*
1148 * Add a property to a node
1149 */
1150int
1151prom_add_property(struct device_node* np, struct property* prop)
1152{
1153 struct property **next = &np->properties;
1154
1155 prop->next = NULL;
1156 while (*next)
1157 next = &(*next)->next;
1158 *next = prop;
1159
1160 return 0;
1161}
1162
1163/* I quickly hacked that one, check against spec ! */
1164static inline unsigned long
1165bus_space_to_resource_flags(unsigned int bus_space)
1166{
1167 u8 space = (bus_space >> 24) & 0xf;
1168 if (space == 0)
1169 space = 0x02;
1170 if (space == 0x02)
1171 return IORESOURCE_MEM;
1172 else if (space == 0x01)
1173 return IORESOURCE_IO;
1174 else {
1175 printk(KERN_WARNING "prom.c: bus_space_to_resource_flags(), space: %x\n",
1176 bus_space);
1177 return 0;
1178 }
1179}
1180
1181static struct resource*
1182find_parent_pci_resource(struct pci_dev* pdev, struct address_range *range)
1183{
1184 unsigned long mask;
1185 int i;
1186
1187 /* Check this one */
1188 mask = bus_space_to_resource_flags(range->space);
1189 for (i=0; i<DEVICE_COUNT_RESOURCE; i++) {
1190 if ((pdev->resource[i].flags & mask) == mask &&
1191 pdev->resource[i].start <= range->address &&
1192 pdev->resource[i].end > range->address) {
1193 if ((range->address + range->size - 1) > pdev->resource[i].end) {
1194 /* Add better message */
1195 printk(KERN_WARNING "PCI/OF resource overlap !\n");
1196 return NULL;
1197 }
1198 break;
1199 }
1200 }
1201 if (i == DEVICE_COUNT_RESOURCE)
1202 return NULL;
1203 return &pdev->resource[i];
1204}
1205
1206/*
1207 * Request an OF device resource. Currently handles child of PCI devices,
1208 * or other nodes attached to the root node. Ultimately, put some
1209 * link to resources in the OF node.
1210 */
1211struct resource*
1212request_OF_resource(struct device_node* node, int index, const char* name_postfix)
1213{
1214 struct pci_dev* pcidev;
1215 u8 pci_bus, pci_devfn;
1216 unsigned long iomask;
1217 struct device_node* nd;
1218 struct resource* parent;
1219 struct resource *res = NULL;
1220 int nlen, plen;
1221
1222 if (index >= node->n_addrs)
1223 goto fail;
1224
1225 /* Sanity check on bus space */
1226 iomask = bus_space_to_resource_flags(node->addrs[index].space);
1227 if (iomask & IORESOURCE_MEM)
1228 parent = &iomem_resource;
1229 else if (iomask & IORESOURCE_IO)
1230 parent = &ioport_resource;
1231 else
1232 goto fail;
1233
1234 /* Find a PCI parent if any */
1235 nd = node;
1236 pcidev = NULL;
1237 while(nd) {
1238 if (!pci_device_from_OF_node(nd, &pci_bus, &pci_devfn))
1239 pcidev = pci_find_slot(pci_bus, pci_devfn);
1240 if (pcidev) break;
1241 nd = nd->parent;
1242 }
1243 if (pcidev)
1244 parent = find_parent_pci_resource(pcidev, &node->addrs[index]);
1245 if (!parent) {
1246 printk(KERN_WARNING "request_OF_resource(%s), parent not found\n",
1247 node->name);
1248 goto fail;
1249 }
1250
1251 res = __request_region(parent, node->addrs[index].address, node->addrs[index].size, NULL);
1252 if (!res)
1253 goto fail;
1254 nlen = strlen(node->name);
1255 plen = name_postfix ? strlen(name_postfix) : 0;
1256 res->name = (const char *)kmalloc(nlen+plen+1, GFP_KERNEL);
1257 if (res->name) {
1258 strcpy((char *)res->name, node->name);
1259 if (plen)
1260 strcpy((char *)res->name+nlen, name_postfix);
1261 }
1262 return res;
1263fail:
1264 return NULL;
1265}
1266
1267int
1268release_OF_resource(struct device_node* node, int index)
1269{
1270 struct pci_dev* pcidev;
1271 u8 pci_bus, pci_devfn;
1272 unsigned long iomask, start, end;
1273 struct device_node* nd;
1274 struct resource* parent;
1275 struct resource *res = NULL;
1276
1277 if (index >= node->n_addrs)
1278 return -EINVAL;
1279
1280 /* Sanity check on bus space */
1281 iomask = bus_space_to_resource_flags(node->addrs[index].space);
1282 if (iomask & IORESOURCE_MEM)
1283 parent = &iomem_resource;
1284 else if (iomask & IORESOURCE_IO)
1285 parent = &ioport_resource;
1286 else
1287 return -EINVAL;
1288
1289 /* Find a PCI parent if any */
1290 nd = node;
1291 pcidev = NULL;
1292 while(nd) {
1293 if (!pci_device_from_OF_node(nd, &pci_bus, &pci_devfn))
1294 pcidev = pci_find_slot(pci_bus, pci_devfn);
1295 if (pcidev) break;
1296 nd = nd->parent;
1297 }
1298 if (pcidev)
1299 parent = find_parent_pci_resource(pcidev, &node->addrs[index]);
1300 if (!parent) {
1301 printk(KERN_WARNING "release_OF_resource(%s), parent not found\n",
1302 node->name);
1303 return -ENODEV;
1304 }
1305
1306 /* Find us in the parent and its childs */
1307 res = parent->child;
1308 start = node->addrs[index].address;
1309 end = start + node->addrs[index].size - 1;
1310 while (res) {
1311 if (res->start == start && res->end == end &&
1312 (res->flags & IORESOURCE_BUSY))
1313 break;
1314 if (res->start <= start && res->end >= end)
1315 res = res->child;
1316 else
1317 res = res->sibling;
1318 }
1319 if (!res)
1320 return -ENODEV;
1321
1322 kfree(res->name);
1323 res->name = NULL;
1324 release_resource(res);
1325 kfree(res);
1326
1327 return 0;
1328}
1329
1330#if 0
1331void
1332print_properties(struct device_node *np)
1333{
1334 struct property *pp;
1335 char *cp;
1336 int i, n;
1337
1338 for (pp = np->properties; pp != 0; pp = pp->next) {
1339 printk(KERN_INFO "%s", pp->name);
1340 for (i = strlen(pp->name); i < 16; ++i)
1341 printk(" ");
1342 cp = (char *) pp->value;
1343 for (i = pp->length; i > 0; --i, ++cp)
1344 if ((i > 1 && (*cp < 0x20 || *cp > 0x7e))
1345 || (i == 1 && *cp != 0))
1346 break;
1347 if (i == 0 && pp->length > 1) {
1348 /* looks like a string */
1349 printk(" %s\n", (char *) pp->value);
1350 } else {
1351 /* dump it in hex */
1352 n = pp->length;
1353 if (n > 64)
1354 n = 64;
1355 if (pp->length % 4 == 0) {
1356 unsigned int *p = (unsigned int *) pp->value;
1357
1358 n /= 4;
1359 for (i = 0; i < n; ++i) {
1360 if (i != 0 && (i % 4) == 0)
1361 printk("\n ");
1362 printk(" %08x", *p++);
1363 }
1364 } else {
1365 unsigned char *bp = pp->value;
1366
1367 for (i = 0; i < n; ++i) {
1368 if (i != 0 && (i % 16) == 0)
1369 printk("\n ");
1370 printk(" %02x", *bp++);
1371 }
1372 }
1373 printk("\n");
1374 if (pp->length > 64)
1375 printk(" ... (length = %d)\n",
1376 pp->length);
1377 }
1378 }
1379}
1380#endif
1381
1382static DEFINE_SPINLOCK(rtas_lock);
1383
1384/* this can be called after setup -- Cort */
1385int
1386call_rtas(const char *service, int nargs, int nret,
1387 unsigned long *outputs, ...)
1388{
1389 va_list list;
1390 int i;
1391 unsigned long s;
1392 struct device_node *rtas;
1393 int *tokp;
1394 union {
1395 unsigned long words[16];
1396 double align;
1397 } u;
1398
1399 rtas = find_devices("rtas");
1400 if (rtas == NULL)
1401 return -1;
1402 tokp = (int *) get_property(rtas, service, NULL);
1403 if (tokp == NULL) {
1404 printk(KERN_ERR "No RTAS service called %s\n", service);
1405 return -1;
1406 }
1407 u.words[0] = *tokp;
1408 u.words[1] = nargs;
1409 u.words[2] = nret;
1410 va_start(list, outputs);
1411 for (i = 0; i < nargs; ++i)
1412 u.words[i+3] = va_arg(list, unsigned long);
1413 va_end(list);
1414
1415 /*
1416 * RTAS doesn't use floating point.
1417 * Or at least, according to the CHRP spec we enter RTAS
1418 * with FP disabled, and it doesn't change the FP registers.
1419 * -- paulus.
1420 */
1421 spin_lock_irqsave(&rtas_lock, s);
1422 enter_rtas((void *)__pa(&u));
1423 spin_unlock_irqrestore(&rtas_lock, s);
1424
1425 if (nret > 1 && outputs != NULL)
1426 for (i = 0; i < nret-1; ++i)
1427 outputs[i] = u.words[i+nargs+4];
1428 return u.words[nargs+3];
1429}
diff --git a/arch/ppc/syslib/prom_init.c b/arch/ppc/syslib/prom_init.c
deleted file mode 100644
index df14422ae1c6..000000000000
--- a/arch/ppc/syslib/prom_init.c
+++ /dev/null
@@ -1,1011 +0,0 @@
1/*
2 * Note that prom_init() and anything called from prom_init()
3 * may be running at an address that is different from the address
4 * that it was linked at. References to static data items are
5 * handled by compiling this file with -mrelocatable-lib.
6 */
7
8#include <linux/config.h>
9#include <linux/kernel.h>
10#include <linux/string.h>
11#include <linux/init.h>
12#include <linux/threads.h>
13#include <linux/spinlock.h>
14#include <linux/ioport.h>
15#include <linux/pci.h>
16#include <linux/slab.h>
17#include <linux/bitops.h>
18
19#include <asm/sections.h>
20#include <asm/prom.h>
21#include <asm/page.h>
22#include <asm/irq.h>
23#include <asm/io.h>
24#include <asm/smp.h>
25#include <asm/bootx.h>
26#include <asm/system.h>
27#include <asm/mmu.h>
28#include <asm/pgtable.h>
29#include <asm/bootinfo.h>
30#include <asm/btext.h>
31#include <asm/pci-bridge.h>
32#include <asm/open_pic.h>
33#include <asm/cacheflush.h>
34
35#ifdef CONFIG_LOGO_LINUX_CLUT224
36#include <linux/linux_logo.h>
37extern const struct linux_logo logo_linux_clut224;
38#endif
39
40/*
41 * Properties whose value is longer than this get excluded from our
42 * copy of the device tree. This way we don't waste space storing
43 * things like "driver,AAPL,MacOS,PowerPC" properties. But this value
44 * does need to be big enough to ensure that we don't lose things
45 * like the interrupt-map property on a PCI-PCI bridge.
46 */
47#define MAX_PROPERTY_LENGTH 4096
48
49#ifndef FB_MAX /* avoid pulling in all of the fb stuff */
50#define FB_MAX 8
51#endif
52
53#define ALIGNUL(x) (((x) + sizeof(unsigned long)-1) & -sizeof(unsigned long))
54
55typedef u32 prom_arg_t;
56
57struct prom_args {
58 const char *service;
59 int nargs;
60 int nret;
61 prom_arg_t args[10];
62};
63
64struct pci_address {
65 unsigned a_hi;
66 unsigned a_mid;
67 unsigned a_lo;
68};
69
70struct pci_reg_property {
71 struct pci_address addr;
72 unsigned size_hi;
73 unsigned size_lo;
74};
75
76struct pci_range {
77 struct pci_address addr;
78 unsigned phys;
79 unsigned size_hi;
80 unsigned size_lo;
81};
82
83struct isa_reg_property {
84 unsigned space;
85 unsigned address;
86 unsigned size;
87};
88
89struct pci_intr_map {
90 struct pci_address addr;
91 unsigned dunno;
92 phandle int_ctrler;
93 unsigned intr;
94};
95
96static void prom_exit(void);
97static int call_prom(const char *service, int nargs, int nret, ...);
98static int call_prom_ret(const char *service, int nargs, int nret,
99 prom_arg_t *rets, ...);
100static void prom_print_hex(unsigned int v);
101static int prom_set_color(ihandle ih, int i, int r, int g, int b);
102static int prom_next_node(phandle *nodep);
103static unsigned long check_display(unsigned long mem);
104static void setup_disp_fake_bi(ihandle dp);
105static unsigned long copy_device_tree(unsigned long mem_start,
106 unsigned long mem_end);
107static unsigned long inspect_node(phandle node, struct device_node *dad,
108 unsigned long mem_start, unsigned long mem_end,
109 struct device_node ***allnextpp);
110static void prom_hold_cpus(unsigned long mem);
111static void prom_instantiate_rtas(void);
112static void * early_get_property(unsigned long base, unsigned long node,
113 char *prop);
114
115prom_entry prom __initdata;
116ihandle prom_chosen __initdata;
117ihandle prom_stdout __initdata;
118
119static char *prom_display_paths[FB_MAX] __initdata;
120static phandle prom_display_nodes[FB_MAX] __initdata;
121static unsigned int prom_num_displays __initdata;
122static ihandle prom_disp_node __initdata;
123char *of_stdout_device __initdata;
124
125unsigned int rtas_data; /* physical pointer */
126unsigned int rtas_entry; /* physical pointer */
127unsigned int rtas_size;
128unsigned int old_rtas;
129
130boot_infos_t *boot_infos;
131char *bootpath;
132char *bootdevice;
133struct device_node *allnodes;
134
135extern char *klimit;
136
137static void __init
138prom_exit(void)
139{
140 struct prom_args args;
141
142 args.service = "exit";
143 args.nargs = 0;
144 args.nret = 0;
145 prom(&args);
146 for (;;) /* should never get here */
147 ;
148}
149
150static int __init
151call_prom(const char *service, int nargs, int nret, ...)
152{
153 va_list list;
154 int i;
155 struct prom_args prom_args;
156
157 prom_args.service = service;
158 prom_args.nargs = nargs;
159 prom_args.nret = nret;
160 va_start(list, nret);
161 for (i = 0; i < nargs; ++i)
162 prom_args.args[i] = va_arg(list, prom_arg_t);
163 va_end(list);
164 for (i = 0; i < nret; ++i)
165 prom_args.args[i + nargs] = 0;
166 prom(&prom_args);
167 return prom_args.args[nargs];
168}
169
170static int __init
171call_prom_ret(const char *service, int nargs, int nret, prom_arg_t *rets, ...)
172{
173 va_list list;
174 int i;
175 struct prom_args prom_args;
176
177 prom_args.service = service;
178 prom_args.nargs = nargs;
179 prom_args.nret = nret;
180 va_start(list, rets);
181 for (i = 0; i < nargs; ++i)
182 prom_args.args[i] = va_arg(list, int);
183 va_end(list);
184 for (i = 0; i < nret; ++i)
185 prom_args.args[i + nargs] = 0;
186 prom(&prom_args);
187 for (i = 1; i < nret; ++i)
188 rets[i-1] = prom_args.args[nargs + i];
189 return prom_args.args[nargs];
190}
191
192void __init
193prom_print(const char *msg)
194{
195 const char *p, *q;
196
197 if (prom_stdout == 0)
198 return;
199
200 for (p = msg; *p != 0; p = q) {
201 for (q = p; *q != 0 && *q != '\n'; ++q)
202 ;
203 if (q > p)
204 call_prom("write", 3, 1, prom_stdout, p, q - p);
205 if (*q != 0) {
206 ++q;
207 call_prom("write", 3, 1, prom_stdout, "\r\n", 2);
208 }
209 }
210}
211
212static void __init
213prom_print_hex(unsigned int v)
214{
215 char buf[16];
216 int i, c;
217
218 for (i = 0; i < 8; ++i) {
219 c = (v >> ((7-i)*4)) & 0xf;
220 c += (c >= 10)? ('a' - 10): '0';
221 buf[i] = c;
222 }
223 buf[i] = ' ';
224 buf[i+1] = 0;
225 prom_print(buf);
226}
227
228static int __init
229prom_set_color(ihandle ih, int i, int r, int g, int b)
230{
231 return call_prom("call-method", 6, 1, "color!", ih, i, b, g, r);
232}
233
234static int __init
235prom_next_node(phandle *nodep)
236{
237 phandle node;
238
239 if ((node = *nodep) != 0
240 && (*nodep = call_prom("child", 1, 1, node)) != 0)
241 return 1;
242 if ((*nodep = call_prom("peer", 1, 1, node)) != 0)
243 return 1;
244 for (;;) {
245 if ((node = call_prom("parent", 1, 1, node)) == 0)
246 return 0;
247 if ((*nodep = call_prom("peer", 1, 1, node)) != 0)
248 return 1;
249 }
250}
251
252#ifdef CONFIG_POWER4
253/*
254 * Set up a hash table with a set of entries in it to map the
255 * first 64MB of RAM. This is used on 64-bit machines since
256 * some of them don't have BATs.
257 */
258
259static inline void make_pte(unsigned long htab, unsigned int hsize,
260 unsigned int va, unsigned int pa, int mode)
261{
262 unsigned int *pteg;
263 unsigned int hash, i, vsid;
264
265 vsid = ((va >> 28) * 0x111) << 12;
266 hash = ((va ^ vsid) >> 5) & 0x7fff80;
267 pteg = (unsigned int *)(htab + (hash & (hsize - 1)));
268 for (i = 0; i < 8; ++i, pteg += 4) {
269 if ((pteg[1] & 1) == 0) {
270 pteg[1] = vsid | ((va >> 16) & 0xf80) | 1;
271 pteg[3] = pa | mode;
272 break;
273 }
274 }
275}
276
277extern unsigned long _SDR1;
278extern PTE *Hash;
279extern unsigned long Hash_size;
280
281static void __init
282prom_alloc_htab(void)
283{
284 unsigned int hsize;
285 unsigned long htab;
286 unsigned int addr;
287
288 /*
289 * Because of OF bugs we can't use the "claim" client
290 * interface to allocate memory for the hash table.
291 * This code is only used on 64-bit PPCs, and the only
292 * 64-bit PPCs at the moment are RS/6000s, and their
293 * OF is based at 0xc00000 (the 12M point), so we just
294 * arbitrarily use the 0x800000 - 0xc00000 region for the
295 * hash table.
296 * -- paulus.
297 */
298 hsize = 4 << 20; /* POWER4 has no BATs */
299 htab = (8 << 20);
300 call_prom("claim", 3, 1, htab, hsize, 0);
301 Hash = (void *)(htab + KERNELBASE);
302 Hash_size = hsize;
303 _SDR1 = htab + __ilog2(hsize) - 18;
304
305 /*
306 * Put in PTEs for the first 64MB of RAM
307 */
308 memset((void *)htab, 0, hsize);
309 for (addr = 0; addr < 0x4000000; addr += 0x1000)
310 make_pte(htab, hsize, addr + KERNELBASE, addr,
311 _PAGE_ACCESSED | _PAGE_COHERENT | PP_RWXX);
312#if 0 /* DEBUG stuff mapping the SCC */
313 make_pte(htab, hsize, 0x80013000, 0x80013000,
314 _PAGE_ACCESSED | _PAGE_NO_CACHE | _PAGE_GUARDED | PP_RWXX);
315#endif
316}
317#endif /* CONFIG_POWER4 */
318
319
320/*
321 * If we have a display that we don't know how to drive,
322 * we will want to try to execute OF's open method for it
323 * later. However, OF will probably fall over if we do that
324 * we've taken over the MMU.
325 * So we check whether we will need to open the display,
326 * and if so, open it now.
327 */
328static unsigned long __init
329check_display(unsigned long mem)
330{
331 phandle node;
332 ihandle ih;
333 int i, j;
334 char type[16], *path;
335 static unsigned char default_colors[] = {
336 0x00, 0x00, 0x00,
337 0x00, 0x00, 0xaa,
338 0x00, 0xaa, 0x00,
339 0x00, 0xaa, 0xaa,
340 0xaa, 0x00, 0x00,
341 0xaa, 0x00, 0xaa,
342 0xaa, 0xaa, 0x00,
343 0xaa, 0xaa, 0xaa,
344 0x55, 0x55, 0x55,
345 0x55, 0x55, 0xff,
346 0x55, 0xff, 0x55,
347 0x55, 0xff, 0xff,
348 0xff, 0x55, 0x55,
349 0xff, 0x55, 0xff,
350 0xff, 0xff, 0x55,
351 0xff, 0xff, 0xff
352 };
353 const unsigned char *clut;
354
355 prom_disp_node = 0;
356
357 for (node = 0; prom_next_node(&node); ) {
358 type[0] = 0;
359 call_prom("getprop", 4, 1, node, "device_type",
360 type, sizeof(type));
361 if (strcmp(type, "display") != 0)
362 continue;
363 /* It seems OF doesn't null-terminate the path :-( */
364 path = (char *) mem;
365 memset(path, 0, 256);
366 if (call_prom("package-to-path", 3, 1, node, path, 255) < 0)
367 continue;
368
369 /*
370 * If this display is the device that OF is using for stdout,
371 * move it to the front of the list.
372 */
373 mem += strlen(path) + 1;
374 i = prom_num_displays++;
375 if (of_stdout_device != 0 && i > 0
376 && strcmp(of_stdout_device, path) == 0) {
377 for (; i > 0; --i) {
378 prom_display_paths[i]
379 = prom_display_paths[i-1];
380 prom_display_nodes[i]
381 = prom_display_nodes[i-1];
382 }
383 }
384 prom_display_paths[i] = path;
385 prom_display_nodes[i] = node;
386 if (i == 0)
387 prom_disp_node = node;
388 if (prom_num_displays >= FB_MAX)
389 break;
390 }
391
392 for (j=0; j<prom_num_displays; j++) {
393 path = prom_display_paths[j];
394 node = prom_display_nodes[j];
395 prom_print("opening display ");
396 prom_print(path);
397 ih = call_prom("open", 1, 1, path);
398 if (ih == 0 || ih == (ihandle) -1) {
399 prom_print("... failed\n");
400 for (i=j+1; i<prom_num_displays; i++) {
401 prom_display_paths[i-1] = prom_display_paths[i];
402 prom_display_nodes[i-1] = prom_display_nodes[i];
403 }
404 if (--prom_num_displays > 0) {
405 prom_disp_node = prom_display_nodes[j];
406 j--;
407 } else
408 prom_disp_node = 0;
409 continue;
410 } else {
411 prom_print("... ok\n");
412 call_prom("setprop", 4, 1, node, "linux,opened", 0, 0);
413
414 /*
415 * Setup a usable color table when the appropriate
416 * method is available.
417 * Should update this to use set-colors.
418 */
419 clut = default_colors;
420 for (i = 0; i < 32; i++, clut += 3)
421 if (prom_set_color(ih, i, clut[0], clut[1],
422 clut[2]) != 0)
423 break;
424
425#ifdef CONFIG_LOGO_LINUX_CLUT224
426 clut = PTRRELOC(logo_linux_clut224.clut);
427 for (i = 0; i < logo_linux_clut224.clutsize;
428 i++, clut += 3)
429 if (prom_set_color(ih, i + 32, clut[0],
430 clut[1], clut[2]) != 0)
431 break;
432#endif /* CONFIG_LOGO_LINUX_CLUT224 */
433 }
434 }
435
436 if (prom_stdout) {
437 phandle p;
438 p = call_prom("instance-to-package", 1, 1, prom_stdout);
439 if (p && p != -1) {
440 type[0] = 0;
441 call_prom("getprop", 4, 1, p, "device_type",
442 type, sizeof(type));
443 if (strcmp(type, "display") == 0)
444 call_prom("setprop", 4, 1, p, "linux,boot-display",
445 0, 0);
446 }
447 }
448
449 return ALIGNUL(mem);
450}
451
452/* This function will enable the early boot text when doing OF booting. This
453 * way, xmon output should work too
454 */
455static void __init
456setup_disp_fake_bi(ihandle dp)
457{
458#ifdef CONFIG_BOOTX_TEXT
459 int width = 640, height = 480, depth = 8, pitch;
460 unsigned address;
461 struct pci_reg_property addrs[8];
462 int i, naddrs;
463 char name[32];
464 char *getprop = "getprop";
465
466 prom_print("Initializing fake screen: ");
467
468 memset(name, 0, sizeof(name));
469 call_prom(getprop, 4, 1, dp, "name", name, sizeof(name));
470 name[sizeof(name)-1] = 0;
471 prom_print(name);
472 prom_print("\n");
473 call_prom(getprop, 4, 1, dp, "width", &width, sizeof(width));
474 call_prom(getprop, 4, 1, dp, "height", &height, sizeof(height));
475 call_prom(getprop, 4, 1, dp, "depth", &depth, sizeof(depth));
476 pitch = width * ((depth + 7) / 8);
477 call_prom(getprop, 4, 1, dp, "linebytes",
478 &pitch, sizeof(pitch));
479 if (pitch == 1)
480 pitch = 0x1000; /* for strange IBM display */
481 address = 0;
482 call_prom(getprop, 4, 1, dp, "address",
483 &address, sizeof(address));
484 if (address == 0) {
485 /* look for an assigned address with a size of >= 1MB */
486 naddrs = call_prom(getprop, 4, 1, dp, "assigned-addresses",
487 addrs, sizeof(addrs));
488 naddrs /= sizeof(struct pci_reg_property);
489 for (i = 0; i < naddrs; ++i) {
490 if (addrs[i].size_lo >= (1 << 20)) {
491 address = addrs[i].addr.a_lo;
492 /* use the BE aperture if possible */
493 if (addrs[i].size_lo >= (16 << 20))
494 address += (8 << 20);
495 break;
496 }
497 }
498 if (address == 0) {
499 prom_print("Failed to get address\n");
500 return;
501 }
502 }
503 /* kludge for valkyrie */
504 if (strcmp(name, "valkyrie") == 0)
505 address += 0x1000;
506
507#ifdef CONFIG_POWER4
508#if CONFIG_TASK_SIZE > 0x80000000
509#error CONFIG_TASK_SIZE cannot be above 0x80000000 with BOOTX_TEXT on G5
510#endif
511 {
512 extern boot_infos_t disp_bi;
513 unsigned long va, pa, i, offset;
514 va = 0x90000000;
515 pa = address & 0xfffff000ul;
516 offset = address & 0x00000fff;
517
518 for (i=0; i<0x4000; i++) {
519 make_pte((unsigned long)Hash - KERNELBASE, Hash_size, va, pa,
520 _PAGE_ACCESSED | _PAGE_NO_CACHE |
521 _PAGE_GUARDED | PP_RWXX);
522 va += 0x1000;
523 pa += 0x1000;
524 }
525 btext_setup_display(width, height, depth, pitch, 0x90000000 | offset);
526 disp_bi.dispDeviceBase = (u8 *)address;
527 }
528#else /* CONFIG_POWER4 */
529 btext_setup_display(width, height, depth, pitch, address);
530 btext_prepare_BAT();
531#endif /* CONFIG_POWER4 */
532#endif /* CONFIG_BOOTX_TEXT */
533}
534
535/*
536 * Make a copy of the device tree from the PROM.
537 */
538static unsigned long __init
539copy_device_tree(unsigned long mem_start, unsigned long mem_end)
540{
541 phandle root;
542 unsigned long new_start;
543 struct device_node **allnextp;
544
545 root = call_prom("peer", 1, 1, (phandle)0);
546 if (root == (phandle)0) {
547 prom_print("couldn't get device tree root\n");
548 prom_exit();
549 }
550 allnextp = &allnodes;
551 mem_start = ALIGNUL(mem_start);
552 new_start = inspect_node(root, NULL, mem_start, mem_end, &allnextp);
553 *allnextp = NULL;
554 return new_start;
555}
556
557static unsigned long __init
558inspect_node(phandle node, struct device_node *dad,
559 unsigned long mem_start, unsigned long mem_end,
560 struct device_node ***allnextpp)
561{
562 int l;
563 phandle child;
564 struct device_node *np;
565 struct property *pp, **prev_propp;
566 char *prev_name, *namep;
567 unsigned char *valp;
568
569 np = (struct device_node *) mem_start;
570 mem_start += sizeof(struct device_node);
571 memset(np, 0, sizeof(*np));
572 np->node = node;
573 **allnextpp = PTRUNRELOC(np);
574 *allnextpp = &np->allnext;
575 if (dad != 0) {
576 np->parent = PTRUNRELOC(dad);
577 /* we temporarily use the `next' field as `last_child'. */
578 if (dad->next == 0)
579 dad->child = PTRUNRELOC(np);
580 else
581 dad->next->sibling = PTRUNRELOC(np);
582 dad->next = np;
583 }
584
585 /* get and store all properties */
586 prev_propp = &np->properties;
587 prev_name = "";
588 for (;;) {
589 pp = (struct property *) mem_start;
590 namep = (char *) (pp + 1);
591 pp->name = PTRUNRELOC(namep);
592 if (call_prom("nextprop", 3, 1, node, prev_name, namep) <= 0)
593 break;
594 mem_start = ALIGNUL((unsigned long)namep + strlen(namep) + 1);
595 prev_name = namep;
596 valp = (unsigned char *) mem_start;
597 pp->value = PTRUNRELOC(valp);
598 pp->length = call_prom("getprop", 4, 1, node, namep,
599 valp, mem_end - mem_start);
600 if (pp->length < 0)
601 continue;
602#ifdef MAX_PROPERTY_LENGTH
603 if (pp->length > MAX_PROPERTY_LENGTH)
604 continue; /* ignore this property */
605#endif
606 mem_start = ALIGNUL(mem_start + pp->length);
607 *prev_propp = PTRUNRELOC(pp);
608 prev_propp = &pp->next;
609 }
610 if (np->node != 0) {
611 /* Add a "linux,phandle" property" */
612 pp = (struct property *) mem_start;
613 *prev_propp = PTRUNRELOC(pp);
614 prev_propp = &pp->next;
615 namep = (char *) (pp + 1);
616 pp->name = PTRUNRELOC(namep);
617 strcpy(namep, "linux,phandle");
618 mem_start = ALIGNUL((unsigned long)namep + strlen(namep) + 1);
619 pp->value = (unsigned char *) PTRUNRELOC(&np->node);
620 pp->length = sizeof(np->node);
621 }
622 *prev_propp = NULL;
623
624 /* get the node's full name */
625 l = call_prom("package-to-path", 3, 1, node,
626 mem_start, mem_end - mem_start);
627 if (l >= 0) {
628 char *p, *ep;
629
630 np->full_name = PTRUNRELOC((char *) mem_start);
631 *(char *)(mem_start + l) = 0;
632 /* Fixup an Apple bug where they have bogus \0 chars in the
633 * middle of the path in some properties
634 */
635 for (p = (char *)mem_start, ep = p + l; p < ep; p++)
636 if ((*p) == '\0') {
637 memmove(p, p+1, ep - p);
638 ep--;
639 }
640 mem_start = ALIGNUL(mem_start + l + 1);
641 }
642
643 /* do all our children */
644 child = call_prom("child", 1, 1, node);
645 while (child != 0) {
646 mem_start = inspect_node(child, np, mem_start, mem_end,
647 allnextpp);
648 child = call_prom("peer", 1, 1, child);
649 }
650
651 return mem_start;
652}
653
654unsigned long smp_chrp_cpu_nr __initdata = 0;
655
656/*
657 * With CHRP SMP we need to use the OF to start the other
658 * processors so we can't wait until smp_boot_cpus (the OF is
659 * trashed by then) so we have to put the processors into
660 * a holding pattern controlled by the kernel (not OF) before
661 * we destroy the OF.
662 *
663 * This uses a chunk of high memory, puts some holding pattern
664 * code there and sends the other processors off to there until
665 * smp_boot_cpus tells them to do something. We do that by using
666 * physical address 0x0. The holding pattern checks that address
667 * until its cpu # is there, when it is that cpu jumps to
668 * __secondary_start(). smp_boot_cpus() takes care of setting those
669 * values.
670 *
671 * We also use physical address 0x4 here to tell when a cpu
672 * is in its holding pattern code.
673 *
674 * -- Cort
675 *
676 * Note that we have to do this if we have more than one CPU,
677 * even if this is a UP kernel. Otherwise when we trash OF
678 * the other CPUs will start executing some random instructions
679 * and crash the system. -- paulus
680 */
681static void __init
682prom_hold_cpus(unsigned long mem)
683{
684 extern void __secondary_hold(void);
685 unsigned long i;
686 int cpu;
687 phandle node;
688 char type[16], *path;
689 unsigned int reg;
690
691 /*
692 * XXX: hack to make sure we're chrp, assume that if we're
693 * chrp we have a device_type property -- Cort
694 */
695 node = call_prom("finddevice", 1, 1, "/");
696 if (call_prom("getprop", 4, 1, node,
697 "device_type", type, sizeof(type)) <= 0)
698 return;
699
700 /* copy the holding pattern code to someplace safe (0) */
701 /* the holding pattern is now within the first 0x100
702 bytes of the kernel image -- paulus */
703 memcpy((void *)0, _stext, 0x100);
704 flush_icache_range(0, 0x100);
705
706 /* look for cpus */
707 *(unsigned long *)(0x0) = 0;
708 asm volatile("dcbf 0,%0": : "r" (0) : "memory");
709 for (node = 0; prom_next_node(&node); ) {
710 type[0] = 0;
711 call_prom("getprop", 4, 1, node, "device_type",
712 type, sizeof(type));
713 if (strcmp(type, "cpu") != 0)
714 continue;
715 path = (char *) mem;
716 memset(path, 0, 256);
717 if (call_prom("package-to-path", 3, 1, node, path, 255) < 0)
718 continue;
719 reg = -1;
720 call_prom("getprop", 4, 1, node, "reg", &reg, sizeof(reg));
721 cpu = smp_chrp_cpu_nr++;
722#ifdef CONFIG_SMP
723 smp_hw_index[cpu] = reg;
724#endif /* CONFIG_SMP */
725 /* XXX: hack - don't start cpu 0, this cpu -- Cort */
726 if (cpu == 0)
727 continue;
728 prom_print("starting cpu ");
729 prom_print(path);
730 *(ulong *)(0x4) = 0;
731 call_prom("start-cpu", 3, 0, node,
732 (char *)__secondary_hold - _stext, cpu);
733 prom_print("...");
734 for ( i = 0 ; (i < 10000) && (*(ulong *)(0x4) == 0); i++ )
735 ;
736 if (*(ulong *)(0x4) == cpu)
737 prom_print("ok\n");
738 else {
739 prom_print("failed: ");
740 prom_print_hex(*(ulong *)0x4);
741 prom_print("\n");
742 }
743 }
744}
745
746static void __init
747prom_instantiate_rtas(void)
748{
749 ihandle prom_rtas;
750 prom_arg_t result;
751
752 prom_rtas = call_prom("finddevice", 1, 1, "/rtas");
753 if (prom_rtas == -1)
754 return;
755
756 rtas_size = 0;
757 call_prom("getprop", 4, 1, prom_rtas,
758 "rtas-size", &rtas_size, sizeof(rtas_size));
759 prom_print("instantiating rtas");
760 if (rtas_size == 0) {
761 rtas_data = 0;
762 } else {
763 /*
764 * Ask OF for some space for RTAS.
765 * Actually OF has bugs so we just arbitrarily
766 * use memory at the 6MB point.
767 */
768 rtas_data = 6 << 20;
769 prom_print(" at ");
770 prom_print_hex(rtas_data);
771 }
772
773 prom_rtas = call_prom("open", 1, 1, "/rtas");
774 prom_print("...");
775 rtas_entry = 0;
776 if (call_prom_ret("call-method", 3, 2, &result,
777 "instantiate-rtas", prom_rtas, rtas_data) == 0)
778 rtas_entry = result;
779 if ((rtas_entry == -1) || (rtas_entry == 0))
780 prom_print(" failed\n");
781 else
782 prom_print(" done\n");
783}
784
785/*
786 * We enter here early on, when the Open Firmware prom is still
787 * handling exceptions and the MMU hash table for us.
788 */
789unsigned long __init
790prom_init(int r3, int r4, prom_entry pp)
791{
792 unsigned long mem;
793 ihandle prom_mmu;
794 unsigned long offset = reloc_offset();
795 int i, l;
796 char *p, *d;
797 unsigned long phys;
798 prom_arg_t result[3];
799 char model[32];
800 phandle node;
801 int rc;
802
803 /* Default */
804 phys = (unsigned long) &_stext;
805
806 /* First get a handle for the stdout device */
807 prom = pp;
808 prom_chosen = call_prom("finddevice", 1, 1, "/chosen");
809 if (prom_chosen == -1)
810 prom_exit();
811 if (call_prom("getprop", 4, 1, prom_chosen, "stdout",
812 &prom_stdout, sizeof(prom_stdout)) <= 0)
813 prom_exit();
814
815 /* Get the full OF pathname of the stdout device */
816 mem = (unsigned long) klimit + offset;
817 p = (char *) mem;
818 memset(p, 0, 256);
819 call_prom("instance-to-path", 3, 1, prom_stdout, p, 255);
820 of_stdout_device = p;
821 mem += strlen(p) + 1;
822
823 /* Get the boot device and translate it to a full OF pathname. */
824 p = (char *) mem;
825 l = call_prom("getprop", 4, 1, prom_chosen, "bootpath", p, 1<<20);
826 if (l > 0) {
827 p[l] = 0; /* should already be null-terminated */
828 bootpath = PTRUNRELOC(p);
829 mem += l + 1;
830 d = (char *) mem;
831 *d = 0;
832 call_prom("canon", 3, 1, p, d, 1<<20);
833 bootdevice = PTRUNRELOC(d);
834 mem = ALIGNUL(mem + strlen(d) + 1);
835 }
836
837 prom_instantiate_rtas();
838
839#ifdef CONFIG_POWER4
840 /*
841 * Find out how much memory we have and allocate a
842 * suitably-sized hash table.
843 */
844 prom_alloc_htab();
845#endif
846 mem = check_display(mem);
847
848 prom_print("copying OF device tree...");
849 mem = copy_device_tree(mem, mem + (1<<20));
850 prom_print("done\n");
851
852 prom_hold_cpus(mem);
853
854 klimit = (char *) (mem - offset);
855
856 node = call_prom("finddevice", 1, 1, "/");
857 rc = call_prom("getprop", 4, 1, node, "model", model, sizeof(model));
858 if (rc > 0 && !strncmp (model, "Pegasos", 7)
859 && strncmp (model, "Pegasos2", 8)) {
860 /* Pegasos 1 has a broken translate method in the OF,
861 * and furthermore the BATs are mapped 1:1 so the phys
862 * address calculated above is correct, so let's use
863 * it directly.
864 */
865 } else if (offset == 0) {
866 /* If we are already running at 0xc0000000, we assume we were
867 * loaded by an OF bootloader which did set a BAT for us.
868 * This breaks OF translate so we force phys to be 0.
869 */
870 prom_print("(already at 0xc0000000) phys=0\n");
871 phys = 0;
872 } else if (call_prom("getprop", 4, 1, prom_chosen, "mmu",
873 &prom_mmu, sizeof(prom_mmu)) <= 0) {
874 prom_print(" no MMU found\n");
875 } else if (call_prom_ret("call-method", 4, 4, result, "translate",
876 prom_mmu, &_stext, 1) != 0) {
877 prom_print(" (translate failed)\n");
878 } else {
879 /* We assume the phys. address size is 3 cells */
880 phys = result[2];
881 }
882
883 if (prom_disp_node != 0)
884 setup_disp_fake_bi(prom_disp_node);
885
886 /* Use quiesce call to get OF to shut down any devices it's using */
887 prom_print("Calling quiesce ...\n");
888 call_prom("quiesce", 0, 0);
889
890 /* Relocate various pointers which will be used once the
891 kernel is running at the address it was linked at. */
892 for (i = 0; i < prom_num_displays; ++i)
893 prom_display_paths[i] = PTRUNRELOC(prom_display_paths[i]);
894
895#ifdef CONFIG_SERIAL_CORE_CONSOLE
896 /* Relocate the of stdout for console autodetection */
897 of_stdout_device = PTRUNRELOC(of_stdout_device);
898#endif
899
900 prom_print("returning 0x");
901 prom_print_hex(phys);
902 prom_print("from prom_init\n");
903 prom_stdout = 0;
904
905 return phys;
906}
907
908/*
909 * early_get_property is used to access the device tree image prepared
910 * by BootX very early on, before the pointers in it have been relocated.
911 */
912static void * __init
913early_get_property(unsigned long base, unsigned long node, char *prop)
914{
915 struct device_node *np = (struct device_node *)(base + node);
916 struct property *pp;
917
918 for (pp = np->properties; pp != 0; pp = pp->next) {
919 pp = (struct property *) (base + (unsigned long)pp);
920 if (strcmp((char *)((unsigned long)pp->name + base),
921 prop) == 0) {
922 return (void *)((unsigned long)pp->value + base);
923 }
924 }
925 return NULL;
926}
927
928/* Is boot-info compatible ? */
929#define BOOT_INFO_IS_COMPATIBLE(bi) ((bi)->compatible_version <= BOOT_INFO_VERSION)
930#define BOOT_INFO_IS_V2_COMPATIBLE(bi) ((bi)->version >= 2)
931#define BOOT_INFO_IS_V4_COMPATIBLE(bi) ((bi)->version >= 4)
932
933void __init
934bootx_init(unsigned long r4, unsigned long phys)
935{
936 boot_infos_t *bi = (boot_infos_t *) r4;
937 unsigned long space;
938 unsigned long ptr, x;
939 char *model;
940
941 boot_infos = PTRUNRELOC(bi);
942 if (!BOOT_INFO_IS_V2_COMPATIBLE(bi))
943 bi->logicalDisplayBase = NULL;
944
945#ifdef CONFIG_BOOTX_TEXT
946 btext_init(bi);
947
948 /*
949 * Test if boot-info is compatible. Done only in config
950 * CONFIG_BOOTX_TEXT since there is nothing much we can do
951 * with an incompatible version, except display a message
952 * and eventually hang the processor...
953 *
954 * I'll try to keep enough of boot-info compatible in the
955 * future to always allow display of this message;
956 */
957 if (!BOOT_INFO_IS_COMPATIBLE(bi)) {
958 btext_drawstring(" !!! WARNING - Incompatible version of BootX !!!\n\n\n");
959 btext_flushscreen();
960 }
961#endif /* CONFIG_BOOTX_TEXT */
962
963 /* New BootX enters kernel with MMU off, i/os are not allowed
964 here. This hack will have been done by the boostrap anyway.
965 */
966 if (bi->version < 4) {
967 /*
968 * XXX If this is an iMac, turn off the USB controller.
969 */
970 model = (char *) early_get_property
971 (r4 + bi->deviceTreeOffset, 4, "model");
972 if (model
973 && (strcmp(model, "iMac,1") == 0
974 || strcmp(model, "PowerMac1,1") == 0)) {
975 out_le32((unsigned *)0x80880008, 1); /* XXX */
976 }
977 }
978
979 /* Move klimit to enclose device tree, args, ramdisk, etc... */
980 if (bi->version < 5) {
981 space = bi->deviceTreeOffset + bi->deviceTreeSize;
982 if (bi->ramDisk)
983 space = bi->ramDisk + bi->ramDiskSize;
984 } else
985 space = bi->totalParamsSize;
986 klimit = PTRUNRELOC((char *) bi + space);
987
988 /* New BootX will have flushed all TLBs and enters kernel with
989 MMU switched OFF, so this should not be useful anymore.
990 */
991 if (bi->version < 4) {
992 /*
993 * Touch each page to make sure the PTEs for them
994 * are in the hash table - the aim is to try to avoid
995 * getting DSI exceptions while copying the kernel image.
996 */
997 for (ptr = ((unsigned long) &_stext) & PAGE_MASK;
998 ptr < (unsigned long)bi + space; ptr += PAGE_SIZE)
999 x = *(volatile unsigned long *)ptr;
1000 }
1001
1002#ifdef CONFIG_BOOTX_TEXT
1003 /*
1004 * Note that after we call btext_prepare_BAT, we can't do
1005 * prom_draw*, flushscreen or clearscreen until we turn the MMU
1006 * on, since btext_prepare_BAT sets disp_bi.logicalDisplayBase
1007 * to a virtual address.
1008 */
1009 btext_prepare_BAT();
1010#endif
1011}
diff --git a/arch/ppc/xmon/start.c b/arch/ppc/xmon/start.c
index ff86b2d814cb..cfc2d6ad464d 100644
--- a/arch/ppc/xmon/start.c
+++ b/arch/ppc/xmon/start.c
@@ -58,7 +58,7 @@ static struct sysrq_key_op sysrq_xmon_op =
58void 58void
59xmon_map_scc(void) 59xmon_map_scc(void)
60{ 60{
61#ifdef CONFIG_PPC_MULTIPLATFORM 61#ifdef CONFIG_PPC_PREP
62 volatile unsigned char *base; 62 volatile unsigned char *base;
63 63
64#elif defined(CONFIG_GEMINI) 64#elif defined(CONFIG_GEMINI)
diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c
index 2b8841f85534..343120c9223d 100644
--- a/arch/s390/kernel/smp.c
+++ b/arch/s390/kernel/smp.c
@@ -801,7 +801,7 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
801 */ 801 */
802 print_cpu_info(&S390_lowcore.cpu_data); 802 print_cpu_info(&S390_lowcore.cpu_data);
803 803
804 for_each_cpu(i) { 804 for_each_possible_cpu(i) {
805 lowcore_ptr[i] = (struct _lowcore *) 805 lowcore_ptr[i] = (struct _lowcore *)
806 __get_free_pages(GFP_KERNEL|GFP_DMA, 806 __get_free_pages(GFP_KERNEL|GFP_DMA,
807 sizeof(void*) == 8 ? 1 : 0); 807 sizeof(void*) == 8 ? 1 : 0);
@@ -831,7 +831,7 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
831#endif 831#endif
832 set_prefix((u32)(unsigned long) lowcore_ptr[smp_processor_id()]); 832 set_prefix((u32)(unsigned long) lowcore_ptr[smp_processor_id()]);
833 833
834 for_each_cpu(cpu) 834 for_each_possible_cpu(cpu)
835 if (cpu != smp_processor_id()) 835 if (cpu != smp_processor_id())
836 smp_create_idle(cpu); 836 smp_create_idle(cpu);
837} 837}
@@ -868,7 +868,7 @@ static int __init topology_init(void)
868 int cpu; 868 int cpu;
869 int ret; 869 int ret;
870 870
871 for_each_cpu(cpu) { 871 for_each_possible_cpu(cpu) {
872 ret = register_cpu(&per_cpu(cpu_devices, cpu), cpu, NULL); 872 ret = register_cpu(&per_cpu(cpu_devices, cpu), cpu, NULL);
873 if (ret) 873 if (ret)
874 printk(KERN_WARNING "topology_init: register_cpu %d " 874 printk(KERN_WARNING "topology_init: register_cpu %d "
diff --git a/arch/sh/kernel/cpu/init.c b/arch/sh/kernel/cpu/init.c
index cf94e8ef17c5..868e68b28880 100644
--- a/arch/sh/kernel/cpu/init.c
+++ b/arch/sh/kernel/cpu/init.c
@@ -30,7 +30,7 @@ static int x##_disabled __initdata = 0; \
30static int __init x##_setup(char *opts) \ 30static int __init x##_setup(char *opts) \
31{ \ 31{ \
32 x##_disabled = 1; \ 32 x##_disabled = 1; \
33 return 0; \ 33 return 1; \
34} \ 34} \
35__setup("no" __stringify(x), x##_setup); 35__setup("no" __stringify(x), x##_setup);
36 36
diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c
index 7ee4ca203616..bb229ef030f3 100644
--- a/arch/sh/kernel/setup.c
+++ b/arch/sh/kernel/setup.c
@@ -401,7 +401,7 @@ static int __init topology_init(void)
401{ 401{
402 int cpu_id; 402 int cpu_id;
403 403
404 for_each_cpu(cpu_id) 404 for_each_possible_cpu(cpu_id)
405 register_cpu(&cpu[cpu_id], cpu_id, NULL); 405 register_cpu(&cpu[cpu_id], cpu_id, NULL);
406 406
407 return 0; 407 return 0;
diff --git a/arch/um/Kconfig b/arch/um/Kconfig
index 5982fe2753e0..05fbb20636cb 100644
--- a/arch/um/Kconfig
+++ b/arch/um/Kconfig
@@ -22,6 +22,9 @@ config SBUS
22config PCI 22config PCI
23 bool 23 bool
24 24
25config PCMCIA
26 bool
27
25config GENERIC_CALIBRATE_DELAY 28config GENERIC_CALIBRATE_DELAY
26 bool 29 bool
27 default y 30 default y
diff --git a/arch/um/Makefile b/arch/um/Makefile
index 8d14c7a831be..24790bed2054 100644
--- a/arch/um/Makefile
+++ b/arch/um/Makefile
@@ -20,7 +20,7 @@ core-y += $(ARCH_DIR)/kernel/ \
20 20
21# Have to precede the include because the included Makefiles reference them. 21# Have to precede the include because the included Makefiles reference them.
22SYMLINK_HEADERS := archparam.h system.h sigcontext.h processor.h ptrace.h \ 22SYMLINK_HEADERS := archparam.h system.h sigcontext.h processor.h ptrace.h \
23 module.h vm-flags.h elf.h ldt.h 23 module.h vm-flags.h elf.h host_ldt.h
24SYMLINK_HEADERS := $(foreach header,$(SYMLINK_HEADERS),include/asm-um/$(header)) 24SYMLINK_HEADERS := $(foreach header,$(SYMLINK_HEADERS),include/asm-um/$(header))
25 25
26# XXX: The "os" symlink is only used by arch/um/include/os.h, which includes 26# XXX: The "os" symlink is only used by arch/um/include/os.h, which includes
@@ -129,7 +129,7 @@ CPPFLAGS_vmlinux.lds = -U$(SUBARCH) \
129 -DSTART=$(START) -DELF_ARCH=$(ELF_ARCH) \ 129 -DSTART=$(START) -DELF_ARCH=$(ELF_ARCH) \
130 -DELF_FORMAT="$(ELF_FORMAT)" $(CPP_MODE-y) \ 130 -DELF_FORMAT="$(ELF_FORMAT)" $(CPP_MODE-y) \
131 -DKERNEL_STACK_SIZE=$(STACK_SIZE) \ 131 -DKERNEL_STACK_SIZE=$(STACK_SIZE) \
132 -DUNMAP_PATH=arch/um/sys-$(SUBARCH)/unmap_fin.o 132 -DUNMAP_PATH=arch/um/sys-$(SUBARCH)/unmap.o
133 133
134#The wrappers will select whether using "malloc" or the kernel allocator. 134#The wrappers will select whether using "malloc" or the kernel allocator.
135LINK_WRAPS = -Wl,--wrap,malloc -Wl,--wrap,free -Wl,--wrap,calloc 135LINK_WRAPS = -Wl,--wrap,malloc -Wl,--wrap,free -Wl,--wrap,calloc
@@ -150,8 +150,7 @@ CLEAN_FILES += linux x.i gmon.out $(ARCH_DIR)/include/uml-config.h \
150 $(ARCH_DIR)/include/user_constants.h \ 150 $(ARCH_DIR)/include/user_constants.h \
151 $(ARCH_DIR)/include/kern_constants.h $(ARCH_DIR)/Kconfig.arch 151 $(ARCH_DIR)/include/kern_constants.h $(ARCH_DIR)/Kconfig.arch
152 152
153MRPROPER_FILES += $(SYMLINK_HEADERS) $(ARCH_SYMLINKS) \ 153MRPROPER_FILES += $(ARCH_SYMLINKS)
154 $(addprefix $(ARCH_DIR)/kernel/,$(KERN_SYMLINKS)) $(ARCH_DIR)/os
155 154
156archclean: 155archclean:
157 @find . \( -name '*.bb' -o -name '*.bbg' -o -name '*.da' \ 156 @find . \( -name '*.bb' -o -name '*.bbg' -o -name '*.da' \
diff --git a/arch/um/Makefile-x86_64 b/arch/um/Makefile-x86_64
index 38df311e75dc..dfd88b652fbe 100644
--- a/arch/um/Makefile-x86_64
+++ b/arch/um/Makefile-x86_64
@@ -1,7 +1,7 @@
1# Copyright 2003 - 2004 Pathscale, Inc 1# Copyright 2003 - 2004 Pathscale, Inc
2# Released under the GPL 2# Released under the GPL
3 3
4libs-y += arch/um/sys-x86_64/ 4core-y += arch/um/sys-x86_64/
5START := 0x60000000 5START := 0x60000000
6 6
7#We #undef __x86_64__ for kernelspace, not for userspace where 7#We #undef __x86_64__ for kernelspace, not for userspace where
diff --git a/arch/um/drivers/daemon_kern.c b/arch/um/drivers/daemon_kern.c
index a61b7b46bc02..53d09ed78b42 100644
--- a/arch/um/drivers/daemon_kern.c
+++ b/arch/um/drivers/daemon_kern.c
@@ -95,18 +95,7 @@ static struct transport daemon_transport = {
95static int register_daemon(void) 95static int register_daemon(void)
96{ 96{
97 register_transport(&daemon_transport); 97 register_transport(&daemon_transport);
98 return(1); 98 return 0;
99} 99}
100 100
101__initcall(register_daemon); 101__initcall(register_daemon);
102
103/*
104 * Overrides for Emacs so that we follow Linus's tabbing style.
105 * Emacs will notice this stuff at the end of the file and automatically
106 * adjust the settings for this buffer only. This must remain at the end
107 * of the file.
108 * ---------------------------------------------------------------------------
109 * Local variables:
110 * c-file-style: "linux"
111 * End:
112 */
diff --git a/arch/um/drivers/harddog_kern.c b/arch/um/drivers/harddog_kern.c
index 49acb2badf32..d18a974735e6 100644
--- a/arch/um/drivers/harddog_kern.c
+++ b/arch/um/drivers/harddog_kern.c
@@ -104,7 +104,7 @@ static int harddog_release(struct inode *inode, struct file *file)
104 104
105extern int ping_watchdog(int fd); 105extern int ping_watchdog(int fd);
106 106
107static ssize_t harddog_write(struct file *file, const char *data, size_t len, 107static ssize_t harddog_write(struct file *file, const char __user *data, size_t len,
108 loff_t *ppos) 108 loff_t *ppos)
109{ 109{
110 /* 110 /*
@@ -118,6 +118,7 @@ static ssize_t harddog_write(struct file *file, const char *data, size_t len,
118static int harddog_ioctl(struct inode *inode, struct file *file, 118static int harddog_ioctl(struct inode *inode, struct file *file,
119 unsigned int cmd, unsigned long arg) 119 unsigned int cmd, unsigned long arg)
120{ 120{
121 void __user *argp= (void __user *)arg;
121 static struct watchdog_info ident = { 122 static struct watchdog_info ident = {
122 WDIOC_SETTIMEOUT, 123 WDIOC_SETTIMEOUT,
123 0, 124 0,
@@ -127,13 +128,12 @@ static int harddog_ioctl(struct inode *inode, struct file *file,
127 default: 128 default:
128 return -ENOTTY; 129 return -ENOTTY;
129 case WDIOC_GETSUPPORT: 130 case WDIOC_GETSUPPORT:
130 if(copy_to_user((struct harddog_info *)arg, &ident, 131 if(copy_to_user(argp, &ident, sizeof(ident)))
131 sizeof(ident)))
132 return -EFAULT; 132 return -EFAULT;
133 return 0; 133 return 0;
134 case WDIOC_GETSTATUS: 134 case WDIOC_GETSTATUS:
135 case WDIOC_GETBOOTSTATUS: 135 case WDIOC_GETBOOTSTATUS:
136 return put_user(0,(int *)arg); 136 return put_user(0,(int __user *)argp);
137 case WDIOC_KEEPALIVE: 137 case WDIOC_KEEPALIVE:
138 return(ping_watchdog(harddog_out_fd)); 138 return(ping_watchdog(harddog_out_fd));
139 } 139 }
diff --git a/arch/um/drivers/hostaudio_kern.c b/arch/um/drivers/hostaudio_kern.c
index 59602b81b240..37232f908cd7 100644
--- a/arch/um/drivers/hostaudio_kern.c
+++ b/arch/um/drivers/hostaudio_kern.c
@@ -67,8 +67,8 @@ MODULE_PARM_DESC(mixer, MIXER_HELP);
67 67
68/* /dev/dsp file operations */ 68/* /dev/dsp file operations */
69 69
70static ssize_t hostaudio_read(struct file *file, char *buffer, size_t count, 70static ssize_t hostaudio_read(struct file *file, char __user *buffer,
71 loff_t *ppos) 71 size_t count, loff_t *ppos)
72{ 72{
73 struct hostaudio_state *state = file->private_data; 73 struct hostaudio_state *state = file->private_data;
74 void *kbuf; 74 void *kbuf;
@@ -94,7 +94,7 @@ static ssize_t hostaudio_read(struct file *file, char *buffer, size_t count,
94 return(err); 94 return(err);
95} 95}
96 96
97static ssize_t hostaudio_write(struct file *file, const char *buffer, 97static ssize_t hostaudio_write(struct file *file, const char __user *buffer,
98 size_t count, loff_t *ppos) 98 size_t count, loff_t *ppos)
99{ 99{
100 struct hostaudio_state *state = file->private_data; 100 struct hostaudio_state *state = file->private_data;
@@ -152,7 +152,7 @@ static int hostaudio_ioctl(struct inode *inode, struct file *file,
152 case SNDCTL_DSP_CHANNELS: 152 case SNDCTL_DSP_CHANNELS:
153 case SNDCTL_DSP_SUBDIVIDE: 153 case SNDCTL_DSP_SUBDIVIDE:
154 case SNDCTL_DSP_SETFRAGMENT: 154 case SNDCTL_DSP_SETFRAGMENT:
155 if(get_user(data, (int *) arg)) 155 if(get_user(data, (int __user *) arg))
156 return(-EFAULT); 156 return(-EFAULT);
157 break; 157 break;
158 default: 158 default:
@@ -168,7 +168,7 @@ static int hostaudio_ioctl(struct inode *inode, struct file *file,
168 case SNDCTL_DSP_CHANNELS: 168 case SNDCTL_DSP_CHANNELS:
169 case SNDCTL_DSP_SUBDIVIDE: 169 case SNDCTL_DSP_SUBDIVIDE:
170 case SNDCTL_DSP_SETFRAGMENT: 170 case SNDCTL_DSP_SETFRAGMENT:
171 if(put_user(data, (int *) arg)) 171 if(put_user(data, (int __user *) arg))
172 return(-EFAULT); 172 return(-EFAULT);
173 break; 173 break;
174 default: 174 default:
diff --git a/arch/um/drivers/mcast_kern.c b/arch/um/drivers/mcast_kern.c
index c9b078fba03e..3a7af18cf944 100644
--- a/arch/um/drivers/mcast_kern.c
+++ b/arch/um/drivers/mcast_kern.c
@@ -124,18 +124,7 @@ static struct transport mcast_transport = {
124static int register_mcast(void) 124static int register_mcast(void)
125{ 125{
126 register_transport(&mcast_transport); 126 register_transport(&mcast_transport);
127 return(1); 127 return 0;
128} 128}
129 129
130__initcall(register_mcast); 130__initcall(register_mcast);
131
132/*
133 * Overrides for Emacs so that we follow Linus's tabbing style.
134 * Emacs will notice this stuff at the end of the file and automatically
135 * adjust the settings for this buffer only. This must remain at the end
136 * of the file.
137 * ---------------------------------------------------------------------------
138 * Local variables:
139 * c-file-style: "linux"
140 * End:
141 */
diff --git a/arch/um/drivers/mconsole_kern.c b/arch/um/drivers/mconsole_kern.c
index 1488816588ea..28e3760e8b98 100644
--- a/arch/um/drivers/mconsole_kern.c
+++ b/arch/um/drivers/mconsole_kern.c
@@ -20,6 +20,8 @@
20#include "linux/namei.h" 20#include "linux/namei.h"
21#include "linux/proc_fs.h" 21#include "linux/proc_fs.h"
22#include "linux/syscalls.h" 22#include "linux/syscalls.h"
23#include "linux/list.h"
24#include "linux/mm.h"
23#include "linux/console.h" 25#include "linux/console.h"
24#include "asm/irq.h" 26#include "asm/irq.h"
25#include "asm/uaccess.h" 27#include "asm/uaccess.h"
@@ -347,6 +349,142 @@ static struct mc_device *mconsole_find_dev(char *name)
347 return(NULL); 349 return(NULL);
348} 350}
349 351
352#define UNPLUGGED_PER_PAGE \
353 ((PAGE_SIZE - sizeof(struct list_head)) / sizeof(unsigned long))
354
355struct unplugged_pages {
356 struct list_head list;
357 void *pages[UNPLUGGED_PER_PAGE];
358};
359
360static unsigned long long unplugged_pages_count = 0;
361static struct list_head unplugged_pages = LIST_HEAD_INIT(unplugged_pages);
362static int unplug_index = UNPLUGGED_PER_PAGE;
363
364static int mem_config(char *str)
365{
366 unsigned long long diff;
367 int err = -EINVAL, i, add;
368 char *ret;
369
370 if(str[0] != '=')
371 goto out;
372
373 str++;
374 if(str[0] == '-')
375 add = 0;
376 else if(str[0] == '+'){
377 add = 1;
378 }
379 else goto out;
380
381 str++;
382 diff = memparse(str, &ret);
383 if(*ret != '\0')
384 goto out;
385
386 diff /= PAGE_SIZE;
387
388 for(i = 0; i < diff; i++){
389 struct unplugged_pages *unplugged;
390 void *addr;
391
392 if(add){
393 if(list_empty(&unplugged_pages))
394 break;
395
396 unplugged = list_entry(unplugged_pages.next,
397 struct unplugged_pages, list);
398 if(unplug_index > 0)
399 addr = unplugged->pages[--unplug_index];
400 else {
401 list_del(&unplugged->list);
402 addr = unplugged;
403 unplug_index = UNPLUGGED_PER_PAGE;
404 }
405
406 free_page((unsigned long) addr);
407 unplugged_pages_count--;
408 }
409 else {
410 struct page *page;
411
412 page = alloc_page(GFP_ATOMIC);
413 if(page == NULL)
414 break;
415
416 unplugged = page_address(page);
417 if(unplug_index == UNPLUGGED_PER_PAGE){
418 INIT_LIST_HEAD(&unplugged->list);
419 list_add(&unplugged->list, &unplugged_pages);
420 unplug_index = 0;
421 }
422 else {
423 struct list_head *entry = unplugged_pages.next;
424 addr = unplugged;
425
426 unplugged = list_entry(entry,
427 struct unplugged_pages,
428 list);
429 unplugged->pages[unplug_index++] = addr;
430 err = os_drop_memory(addr, PAGE_SIZE);
431 if(err)
432 printk("Failed to release memory - "
433 "errno = %d\n", err);
434 }
435
436 unplugged_pages_count++;
437 }
438 }
439
440 err = 0;
441out:
442 return err;
443}
444
445static int mem_get_config(char *name, char *str, int size, char **error_out)
446{
447 char buf[sizeof("18446744073709551615")];
448 int len = 0;
449
450 sprintf(buf, "%ld", uml_physmem);
451 CONFIG_CHUNK(str, size, len, buf, 1);
452
453 return len;
454}
455
456static int mem_id(char **str, int *start_out, int *end_out)
457{
458 *start_out = 0;
459 *end_out = 0;
460
461 return 0;
462}
463
464static int mem_remove(int n)
465{
466 return -EBUSY;
467}
468
469static struct mc_device mem_mc = {
470 .name = "mem",
471 .config = mem_config,
472 .get_config = mem_get_config,
473 .id = mem_id,
474 .remove = mem_remove,
475};
476
477static int mem_mc_init(void)
478{
479 if(can_drop_memory())
480 mconsole_register_dev(&mem_mc);
481 else printk("Can't release memory to the host - memory hotplug won't "
482 "be supported\n");
483 return 0;
484}
485
486__initcall(mem_mc_init);
487
350#define CONFIG_BUF_SIZE 64 488#define CONFIG_BUF_SIZE 64
351 489
352static void mconsole_get_config(int (*get_config)(char *, char *, int, 490static void mconsole_get_config(int (*get_config)(char *, char *, int,
@@ -478,7 +616,7 @@ static void console_write(struct console *console, const char *string,
478 return; 616 return;
479 617
480 while(1){ 618 while(1){
481 n = min(len, ARRAY_SIZE(console_buf) - console_index); 619 n = min((size_t)len, ARRAY_SIZE(console_buf) - console_index);
482 strncpy(&console_buf[console_index], string, n); 620 strncpy(&console_buf[console_index], string, n);
483 console_index += n; 621 console_index += n;
484 string += n; 622 string += n;
diff --git a/arch/um/drivers/pcap_kern.c b/arch/um/drivers/pcap_kern.c
index 07c80f2156ef..466ff2c2f918 100644
--- a/arch/um/drivers/pcap_kern.c
+++ b/arch/um/drivers/pcap_kern.c
@@ -106,18 +106,7 @@ static struct transport pcap_transport = {
106static int register_pcap(void) 106static int register_pcap(void)
107{ 107{
108 register_transport(&pcap_transport); 108 register_transport(&pcap_transport);
109 return(1); 109 return 0;
110} 110}
111 111
112__initcall(register_pcap); 112__initcall(register_pcap);
113
114/*
115 * Overrides for Emacs so that we follow Linus's tabbing style.
116 * Emacs will notice this stuff at the end of the file and automatically
117 * adjust the settings for this buffer only. This must remain at the end
118 * of the file.
119 * ---------------------------------------------------------------------------
120 * Local variables:
121 * c-file-style: "linux"
122 * End:
123 */
diff --git a/arch/um/drivers/slip_kern.c b/arch/um/drivers/slip_kern.c
index a62f5ef445cf..163ee0d5f75e 100644
--- a/arch/um/drivers/slip_kern.c
+++ b/arch/um/drivers/slip_kern.c
@@ -93,18 +93,7 @@ static struct transport slip_transport = {
93static int register_slip(void) 93static int register_slip(void)
94{ 94{
95 register_transport(&slip_transport); 95 register_transport(&slip_transport);
96 return(1); 96 return 0;
97} 97}
98 98
99__initcall(register_slip); 99__initcall(register_slip);
100
101/*
102 * Overrides for Emacs so that we follow Linus's tabbing style.
103 * Emacs will notice this stuff at the end of the file and automatically
104 * adjust the settings for this buffer only. This must remain at the end
105 * of the file.
106 * ---------------------------------------------------------------------------
107 * Local variables:
108 * c-file-style: "linux"
109 * End:
110 */
diff --git a/arch/um/drivers/slirp_kern.c b/arch/um/drivers/slirp_kern.c
index 33d7982be5d3..95e50c943e14 100644
--- a/arch/um/drivers/slirp_kern.c
+++ b/arch/um/drivers/slirp_kern.c
@@ -77,7 +77,7 @@ static int slirp_setup(char *str, char **mac_out, void *data)
77 int i=0; 77 int i=0;
78 78
79 *init = ((struct slirp_init) 79 *init = ((struct slirp_init)
80 { argw : { { "slirp", NULL } } }); 80 { .argw = { { "slirp", NULL } } });
81 81
82 str = split_if_spec(str, mac_out, NULL); 82 str = split_if_spec(str, mac_out, NULL);
83 83
@@ -116,18 +116,7 @@ static struct transport slirp_transport = {
116static int register_slirp(void) 116static int register_slirp(void)
117{ 117{
118 register_transport(&slirp_transport); 118 register_transport(&slirp_transport);
119 return(1); 119 return 0;
120} 120}
121 121
122__initcall(register_slirp); 122__initcall(register_slirp);
123
124/*
125 * Overrides for Emacs so that we follow Linus's tabbing style.
126 * Emacs will notice this stuff at the end of the file and automatically
127 * adjust the settings for this buffer only. This must remain at the end
128 * of the file.
129 * ---------------------------------------------------------------------------
130 * Local variables:
131 * c-file-style: "linux"
132 * End:
133 */
diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c
index 0336575d2448..0897852b09a3 100644
--- a/arch/um/drivers/ubd_kern.c
+++ b/arch/um/drivers/ubd_kern.c
@@ -891,7 +891,7 @@ int ubd_driver_init(void){
891 SA_INTERRUPT, "ubd", ubd_dev); 891 SA_INTERRUPT, "ubd", ubd_dev);
892 if(err != 0) 892 if(err != 0)
893 printk(KERN_ERR "um_request_irq failed - errno = %d\n", -err); 893 printk(KERN_ERR "um_request_irq failed - errno = %d\n", -err);
894 return(err); 894 return 0;
895} 895}
896 896
897device_initcall(ubd_driver_init); 897device_initcall(ubd_driver_init);
diff --git a/arch/um/include/kern_util.h b/arch/um/include/kern_util.h
index 07176d92e1c9..42557130a408 100644
--- a/arch/um/include/kern_util.h
+++ b/arch/um/include/kern_util.h
@@ -116,7 +116,11 @@ extern void *get_current(void);
116extern struct task_struct *get_task(int pid, int require); 116extern struct task_struct *get_task(int pid, int require);
117extern void machine_halt(void); 117extern void machine_halt(void);
118extern int is_syscall(unsigned long addr); 118extern int is_syscall(unsigned long addr);
119extern void arch_switch(void); 119
120extern void arch_switch_to_tt(struct task_struct *from, struct task_struct *to);
121
122extern void arch_switch_to_skas(struct task_struct *from, struct task_struct *to);
123
120extern void free_irq(unsigned int, void *); 124extern void free_irq(unsigned int, void *);
121extern int cpu(void); 125extern int cpu(void);
122 126
diff --git a/arch/um/include/line.h b/arch/um/include/line.h
index 6f4d680dc1d4..6ac0f8252e21 100644
--- a/arch/um/include/line.h
+++ b/arch/um/include/line.h
@@ -58,23 +58,17 @@ struct line {
58}; 58};
59 59
60#define LINE_INIT(str, d) \ 60#define LINE_INIT(str, d) \
61 { init_str : str, \ 61 { .init_str = str, \
62 init_pri : INIT_STATIC, \ 62 .init_pri = INIT_STATIC, \
63 valid : 1, \ 63 .valid = 1, \
64 throttled : 0, \ 64 .lock = SPIN_LOCK_UNLOCKED, \
65 lock : SPIN_LOCK_UNLOCKED, \ 65 .driver = d }
66 buffer : NULL, \
67 head : NULL, \
68 tail : NULL, \
69 sigio : 0, \
70 driver : d, \
71 have_irq : 0 }
72 66
73struct lines { 67struct lines {
74 int num; 68 int num;
75}; 69};
76 70
77#define LINES_INIT(n) { num : n } 71#define LINES_INIT(n) { .num = n }
78 72
79extern void line_close(struct tty_struct *tty, struct file * filp); 73extern void line_close(struct tty_struct *tty, struct file * filp);
80extern int line_open(struct line *lines, struct tty_struct *tty); 74extern int line_open(struct line *lines, struct tty_struct *tty);
diff --git a/arch/um/include/mem_user.h b/arch/um/include/mem_user.h
index a1064c5823bf..a54514d2cc3a 100644
--- a/arch/um/include/mem_user.h
+++ b/arch/um/include/mem_user.h
@@ -49,7 +49,6 @@ extern int iomem_size;
49extern unsigned long host_task_size; 49extern unsigned long host_task_size;
50extern unsigned long task_size; 50extern unsigned long task_size;
51 51
52extern void check_devanon(void);
53extern int init_mem_user(void); 52extern int init_mem_user(void);
54extern void setup_memory(void *entry); 53extern void setup_memory(void *entry);
55extern unsigned long find_iomem(char *driver, unsigned long *len_out); 54extern unsigned long find_iomem(char *driver, unsigned long *len_out);
diff --git a/arch/um/include/os.h b/arch/um/include/os.h
index d3d1bc6074ef..f88856c28a66 100644
--- a/arch/um/include/os.h
+++ b/arch/um/include/os.h
@@ -13,6 +13,7 @@
13#include "kern_util.h" 13#include "kern_util.h"
14#include "skas/mm_id.h" 14#include "skas/mm_id.h"
15#include "irq_user.h" 15#include "irq_user.h"
16#include "sysdep/tls.h"
16 17
17#define OS_TYPE_FILE 1 18#define OS_TYPE_FILE 1
18#define OS_TYPE_DIR 2 19#define OS_TYPE_DIR 2
@@ -172,6 +173,7 @@ extern int os_fchange_dir(int fd);
172extern void os_early_checks(void); 173extern void os_early_checks(void);
173extern int can_do_skas(void); 174extern int can_do_skas(void);
174extern void os_check_bugs(void); 175extern void os_check_bugs(void);
176extern void check_host_supports_tls(int *supports_tls, int *tls_min);
175 177
176/* Make sure they are clear when running in TT mode. Required by 178/* Make sure they are clear when running in TT mode. Required by
177 * SEGV_MAYBE_FIXABLE */ 179 * SEGV_MAYBE_FIXABLE */
@@ -205,6 +207,8 @@ extern int os_map_memory(void *virt, int fd, unsigned long long off,
205extern int os_protect_memory(void *addr, unsigned long len, 207extern int os_protect_memory(void *addr, unsigned long len,
206 int r, int w, int x); 208 int r, int w, int x);
207extern int os_unmap_memory(void *addr, int len); 209extern int os_unmap_memory(void *addr, int len);
210extern int os_drop_memory(void *addr, int length);
211extern int can_drop_memory(void);
208extern void os_flush_stdout(void); 212extern void os_flush_stdout(void);
209 213
210/* tt.c 214/* tt.c
@@ -234,8 +238,12 @@ extern int run_helper_thread(int (*proc)(void *), void *arg,
234 int stack_order); 238 int stack_order);
235extern int helper_wait(int pid); 239extern int helper_wait(int pid);
236 240
237/* umid.c */
238 241
242/* tls.c */
243extern int os_set_thread_area(user_desc_t *info, int pid);
244extern int os_get_thread_area(user_desc_t *info, int pid);
245
246/* umid.c */
239extern int umid_file_name(char *name, char *buf, int len); 247extern int umid_file_name(char *name, char *buf, int len);
240extern int set_umid(char *name); 248extern int set_umid(char *name);
241extern char *get_umid(void); 249extern char *get_umid(void);
diff --git a/arch/um/include/sysdep-i386/checksum.h b/arch/um/include/sysdep-i386/checksum.h
index 7d3d202d7fff..052bb061a978 100644
--- a/arch/um/include/sysdep-i386/checksum.h
+++ b/arch/um/include/sysdep-i386/checksum.h
@@ -48,7 +48,8 @@ unsigned int csum_partial_copy_nocheck(const unsigned char *src, unsigned char *
48 */ 48 */
49 49
50static __inline__ 50static __inline__
51unsigned int csum_partial_copy_from_user(const unsigned char *src, unsigned char *dst, 51unsigned int csum_partial_copy_from_user(const unsigned char __user *src,
52 unsigned char *dst,
52 int len, int sum, int *err_ptr) 53 int len, int sum, int *err_ptr)
53{ 54{
54 if(copy_from_user(dst, src, len)){ 55 if(copy_from_user(dst, src, len)){
@@ -192,7 +193,7 @@ static __inline__ unsigned short int csum_ipv6_magic(struct in6_addr *saddr,
192 */ 193 */
193#define HAVE_CSUM_COPY_USER 194#define HAVE_CSUM_COPY_USER
194static __inline__ unsigned int csum_and_copy_to_user(const unsigned char *src, 195static __inline__ unsigned int csum_and_copy_to_user(const unsigned char *src,
195 unsigned char *dst, 196 unsigned char __user *dst,
196 int len, int sum, int *err_ptr) 197 int len, int sum, int *err_ptr)
197{ 198{
198 if (access_ok(VERIFY_WRITE, dst, len)){ 199 if (access_ok(VERIFY_WRITE, dst, len)){
diff --git a/arch/um/include/sysdep-i386/ptrace.h b/arch/um/include/sysdep-i386/ptrace.h
index c8ee9559f3ab..6670cc992ecb 100644
--- a/arch/um/include/sysdep-i386/ptrace.h
+++ b/arch/um/include/sysdep-i386/ptrace.h
@@ -14,7 +14,12 @@
14#define MAX_REG_NR (UM_FRAME_SIZE / sizeof(unsigned long)) 14#define MAX_REG_NR (UM_FRAME_SIZE / sizeof(unsigned long))
15#define MAX_REG_OFFSET (UM_FRAME_SIZE) 15#define MAX_REG_OFFSET (UM_FRAME_SIZE)
16 16
17#ifdef UML_CONFIG_PT_PROXY
17extern void update_debugregs(int seq); 18extern void update_debugregs(int seq);
19#else
20static inline void update_debugregs(int seq) {}
21#endif
22
18 23
19/* syscall emulation path in ptrace */ 24/* syscall emulation path in ptrace */
20 25
diff --git a/arch/um/include/sysdep-i386/tls.h b/arch/um/include/sysdep-i386/tls.h
new file mode 100644
index 000000000000..918fd3c5ff9c
--- /dev/null
+++ b/arch/um/include/sysdep-i386/tls.h
@@ -0,0 +1,32 @@
1#ifndef _SYSDEP_TLS_H
2#define _SYSDEP_TLS_H
3
4# ifndef __KERNEL__
5
6/* Change name to avoid conflicts with the original one from <asm/ldt.h>, which
7 * may be named user_desc (but in 2.4 and in header matching its API was named
8 * modify_ldt_ldt_s). */
9
10typedef struct um_dup_user_desc {
11 unsigned int entry_number;
12 unsigned int base_addr;
13 unsigned int limit;
14 unsigned int seg_32bit:1;
15 unsigned int contents:2;
16 unsigned int read_exec_only:1;
17 unsigned int limit_in_pages:1;
18 unsigned int seg_not_present:1;
19 unsigned int useable:1;
20} user_desc_t;
21
22# else /* __KERNEL__ */
23
24# include <asm/ldt.h>
25typedef struct user_desc user_desc_t;
26
27# endif /* __KERNEL__ */
28
29#define GDT_ENTRY_TLS_MIN_I386 6
30#define GDT_ENTRY_TLS_MIN_X86_64 12
31
32#endif /* _SYSDEP_TLS_H */
diff --git a/arch/um/include/sysdep-x86_64/tls.h b/arch/um/include/sysdep-x86_64/tls.h
new file mode 100644
index 000000000000..35f19f25bd3b
--- /dev/null
+++ b/arch/um/include/sysdep-x86_64/tls.h
@@ -0,0 +1,29 @@
1#ifndef _SYSDEP_TLS_H
2#define _SYSDEP_TLS_H
3
4# ifndef __KERNEL__
5
6/* Change name to avoid conflicts with the original one from <asm/ldt.h>, which
7 * may be named user_desc (but in 2.4 and in header matching its API was named
8 * modify_ldt_ldt_s). */
9
10typedef struct um_dup_user_desc {
11 unsigned int entry_number;
12 unsigned int base_addr;
13 unsigned int limit;
14 unsigned int seg_32bit:1;
15 unsigned int contents:2;
16 unsigned int read_exec_only:1;
17 unsigned int limit_in_pages:1;
18 unsigned int seg_not_present:1;
19 unsigned int useable:1;
20 unsigned int lm:1;
21} user_desc_t;
22
23# else /* __KERNEL__ */
24
25# include <asm/ldt.h>
26typedef struct user_desc user_desc_t;
27
28# endif /* __KERNEL__ */
29#endif /* _SYSDEP_TLS_H */
diff --git a/arch/um/include/user_util.h b/arch/um/include/user_util.h
index 992a7e1e0fca..fe0c29b5144d 100644
--- a/arch/um/include/user_util.h
+++ b/arch/um/include/user_util.h
@@ -8,6 +8,9 @@
8 8
9#include "sysdep/ptrace.h" 9#include "sysdep/ptrace.h"
10 10
11/* Copied from kernel.h */
12#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
13
11#define CATCH_EINTR(expr) while ((errno = 0, ((expr) < 0)) && (errno == EINTR)) 14#define CATCH_EINTR(expr) while ((errno = 0, ((expr) < 0)) && (errno == EINTR))
12 15
13extern int mode_tt; 16extern int mode_tt;
@@ -31,7 +34,7 @@ extern unsigned long uml_physmem;
31extern unsigned long uml_reserved; 34extern unsigned long uml_reserved;
32extern unsigned long end_vm; 35extern unsigned long end_vm;
33extern unsigned long start_vm; 36extern unsigned long start_vm;
34extern unsigned long highmem; 37extern unsigned long long highmem;
35 38
36extern char host_info[]; 39extern char host_info[];
37 40
diff --git a/arch/um/kernel/exec_kern.c b/arch/um/kernel/exec_kern.c
index 1ca84319317d..c0cb627bf594 100644
--- a/arch/um/kernel/exec_kern.c
+++ b/arch/um/kernel/exec_kern.c
@@ -22,6 +22,7 @@
22 22
23void flush_thread(void) 23void flush_thread(void)
24{ 24{
25 arch_flush_thread(&current->thread.arch);
25 CHOOSE_MODE(flush_thread_tt(), flush_thread_skas()); 26 CHOOSE_MODE(flush_thread_tt(), flush_thread_skas());
26} 27}
27 28
@@ -58,14 +59,14 @@ long um_execve(char *file, char __user *__user *argv, char __user *__user *env)
58 return(err); 59 return(err);
59} 60}
60 61
61long sys_execve(char *file, char __user *__user *argv, 62long sys_execve(char __user *file, char __user *__user *argv,
62 char __user *__user *env) 63 char __user *__user *env)
63{ 64{
64 long error; 65 long error;
65 char *filename; 66 char *filename;
66 67
67 lock_kernel(); 68 lock_kernel();
68 filename = getname((char __user *) file); 69 filename = getname(file);
69 error = PTR_ERR(filename); 70 error = PTR_ERR(filename);
70 if (IS_ERR(filename)) goto out; 71 if (IS_ERR(filename)) goto out;
71 error = execve1(filename, argv, env); 72 error = execve1(filename, argv, env);
@@ -74,14 +75,3 @@ long sys_execve(char *file, char __user *__user *argv,
74 unlock_kernel(); 75 unlock_kernel();
75 return(error); 76 return(error);
76} 77}
77
78/*
79 * Overrides for Emacs so that we follow Linus's tabbing style.
80 * Emacs will notice this stuff at the end of the file and automatically
81 * adjust the settings for this buffer only. This must remain at the end
82 * of the file.
83 * ---------------------------------------------------------------------------
84 * Local variables:
85 * c-file-style: "linux"
86 * End:
87 */
diff --git a/arch/um/kernel/mem.c b/arch/um/kernel/mem.c
index 92cce96b5e24..44e41a35f000 100644
--- a/arch/um/kernel/mem.c
+++ b/arch/um/kernel/mem.c
@@ -30,7 +30,7 @@ extern char __binary_start;
30unsigned long *empty_zero_page = NULL; 30unsigned long *empty_zero_page = NULL;
31unsigned long *empty_bad_page = NULL; 31unsigned long *empty_bad_page = NULL;
32pgd_t swapper_pg_dir[PTRS_PER_PGD]; 32pgd_t swapper_pg_dir[PTRS_PER_PGD];
33unsigned long highmem; 33unsigned long long highmem;
34int kmalloc_ok = 0; 34int kmalloc_ok = 0;
35 35
36static unsigned long brk_end; 36static unsigned long brk_end;
diff --git a/arch/um/kernel/process_kern.c b/arch/um/kernel/process_kern.c
index 3113cab8675e..f6a5a502120b 100644
--- a/arch/um/kernel/process_kern.c
+++ b/arch/um/kernel/process_kern.c
@@ -156,9 +156,25 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long sp,
156 unsigned long stack_top, struct task_struct * p, 156 unsigned long stack_top, struct task_struct * p,
157 struct pt_regs *regs) 157 struct pt_regs *regs)
158{ 158{
159 int ret;
160
159 p->thread = (struct thread_struct) INIT_THREAD; 161 p->thread = (struct thread_struct) INIT_THREAD;
160 return(CHOOSE_MODE_PROC(copy_thread_tt, copy_thread_skas, nr, 162 ret = CHOOSE_MODE_PROC(copy_thread_tt, copy_thread_skas, nr,
161 clone_flags, sp, stack_top, p, regs)); 163 clone_flags, sp, stack_top, p, regs);
164
165 if (ret || !current->thread.forking)
166 goto out;
167
168 clear_flushed_tls(p);
169
170 /*
171 * Set a new TLS for the child thread?
172 */
173 if (clone_flags & CLONE_SETTLS)
174 ret = arch_copy_tls(p);
175
176out:
177 return ret;
162} 178}
163 179
164void initial_thread_cb(void (*proc)(void *), void *arg) 180void initial_thread_cb(void (*proc)(void *), void *arg)
@@ -185,10 +201,6 @@ void default_idle(void)
185{ 201{
186 CHOOSE_MODE(uml_idle_timer(), (void) 0); 202 CHOOSE_MODE(uml_idle_timer(), (void) 0);
187 203
188 atomic_inc(&init_mm.mm_count);
189 current->mm = &init_mm;
190 current->active_mm = &init_mm;
191
192 while(1){ 204 while(1){
193 /* endless idle loop with no priority at all */ 205 /* endless idle loop with no priority at all */
194 206
@@ -407,7 +419,7 @@ static int proc_read_sysemu(char *buf, char **start, off_t offset, int size,int
407 return strlen(buf); 419 return strlen(buf);
408} 420}
409 421
410static int proc_write_sysemu(struct file *file,const char *buf, unsigned long count,void *data) 422static int proc_write_sysemu(struct file *file,const char __user *buf, unsigned long count,void *data)
411{ 423{
412 char tmp[2]; 424 char tmp[2];
413 425
diff --git a/arch/um/kernel/ptrace.c b/arch/um/kernel/ptrace.c
index 98e09395c093..60d2eda995c1 100644
--- a/arch/um/kernel/ptrace.c
+++ b/arch/um/kernel/ptrace.c
@@ -46,6 +46,7 @@ extern int poke_user(struct task_struct * child, long addr, long data);
46long arch_ptrace(struct task_struct *child, long request, long addr, long data) 46long arch_ptrace(struct task_struct *child, long request, long addr, long data)
47{ 47{
48 int i, ret; 48 int i, ret;
49 unsigned long __user *p = (void __user *)(unsigned long)data;
49 50
50 switch (request) { 51 switch (request) {
51 /* when I and D space are separate, these will need to be fixed. */ 52 /* when I and D space are separate, these will need to be fixed. */
@@ -58,7 +59,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
58 copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 0); 59 copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 0);
59 if (copied != sizeof(tmp)) 60 if (copied != sizeof(tmp))
60 break; 61 break;
61 ret = put_user(tmp, (unsigned long __user *) data); 62 ret = put_user(tmp, p);
62 break; 63 break;
63 } 64 }
64 65
@@ -136,15 +137,13 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
136 137
137#ifdef PTRACE_GETREGS 138#ifdef PTRACE_GETREGS
138 case PTRACE_GETREGS: { /* Get all gp regs from the child. */ 139 case PTRACE_GETREGS: { /* Get all gp regs from the child. */
139 if (!access_ok(VERIFY_WRITE, (unsigned long *)data, 140 if (!access_ok(VERIFY_WRITE, p, MAX_REG_OFFSET)) {
140 MAX_REG_OFFSET)) {
141 ret = -EIO; 141 ret = -EIO;
142 break; 142 break;
143 } 143 }
144 for ( i = 0; i < MAX_REG_OFFSET; i += sizeof(long) ) { 144 for ( i = 0; i < MAX_REG_OFFSET; i += sizeof(long) ) {
145 __put_user(getreg(child, i), 145 __put_user(getreg(child, i), p);
146 (unsigned long __user *) data); 146 p++;
147 data += sizeof(long);
148 } 147 }
149 ret = 0; 148 ret = 0;
150 break; 149 break;
@@ -153,15 +152,14 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
153#ifdef PTRACE_SETREGS 152#ifdef PTRACE_SETREGS
154 case PTRACE_SETREGS: { /* Set all gp regs in the child. */ 153 case PTRACE_SETREGS: { /* Set all gp regs in the child. */
155 unsigned long tmp = 0; 154 unsigned long tmp = 0;
156 if (!access_ok(VERIFY_READ, (unsigned *)data, 155 if (!access_ok(VERIFY_READ, p, MAX_REG_OFFSET)) {
157 MAX_REG_OFFSET)) {
158 ret = -EIO; 156 ret = -EIO;
159 break; 157 break;
160 } 158 }
161 for ( i = 0; i < MAX_REG_OFFSET; i += sizeof(long) ) { 159 for ( i = 0; i < MAX_REG_OFFSET; i += sizeof(long) ) {
162 __get_user(tmp, (unsigned long __user *) data); 160 __get_user(tmp, p);
163 putreg(child, i, tmp); 161 putreg(child, i, tmp);
164 data += sizeof(long); 162 p++;
165 } 163 }
166 ret = 0; 164 ret = 0;
167 break; 165 break;
@@ -187,14 +185,23 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
187 ret = set_fpxregs(data, child); 185 ret = set_fpxregs(data, child);
188 break; 186 break;
189#endif 187#endif
188 case PTRACE_GET_THREAD_AREA:
189 ret = ptrace_get_thread_area(child, addr,
190 (struct user_desc __user *) data);
191 break;
192
193 case PTRACE_SET_THREAD_AREA:
194 ret = ptrace_set_thread_area(child, addr,
195 (struct user_desc __user *) data);
196 break;
197
190 case PTRACE_FAULTINFO: { 198 case PTRACE_FAULTINFO: {
191 /* Take the info from thread->arch->faultinfo, 199 /* Take the info from thread->arch->faultinfo,
192 * but transfer max. sizeof(struct ptrace_faultinfo). 200 * but transfer max. sizeof(struct ptrace_faultinfo).
193 * On i386, ptrace_faultinfo is smaller! 201 * On i386, ptrace_faultinfo is smaller!
194 */ 202 */
195 ret = copy_to_user((unsigned long __user *) data, 203 ret = copy_to_user(p, &child->thread.arch.faultinfo,
196 &child->thread.arch.faultinfo, 204 sizeof(struct ptrace_faultinfo));
197 sizeof(struct ptrace_faultinfo));
198 if(ret) 205 if(ret)
199 break; 206 break;
200 break; 207 break;
@@ -204,8 +211,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
204 case PTRACE_LDT: { 211 case PTRACE_LDT: {
205 struct ptrace_ldt ldt; 212 struct ptrace_ldt ldt;
206 213
207 if(copy_from_user(&ldt, (unsigned long __user *) data, 214 if(copy_from_user(&ldt, p, sizeof(ldt))){
208 sizeof(ldt))){
209 ret = -EIO; 215 ret = -EIO;
210 break; 216 break;
211 } 217 }
diff --git a/arch/um/kernel/skas/process_kern.c b/arch/um/kernel/skas/process_kern.c
index 3f70a2e12f06..2135eaf98a93 100644
--- a/arch/um/kernel/skas/process_kern.c
+++ b/arch/um/kernel/skas/process_kern.c
@@ -35,6 +35,8 @@ void switch_to_skas(void *prev, void *next)
35 switch_threads(&from->thread.mode.skas.switch_buf, 35 switch_threads(&from->thread.mode.skas.switch_buf,
36 to->thread.mode.skas.switch_buf); 36 to->thread.mode.skas.switch_buf);
37 37
38 arch_switch_to_skas(current->thread.prev_sched, current);
39
38 if(current->pid == 0) 40 if(current->pid == 0)
39 switch_timers(1); 41 switch_timers(1);
40} 42}
@@ -89,10 +91,17 @@ void fork_handler(int sig)
89 panic("blech"); 91 panic("blech");
90 92
91 schedule_tail(current->thread.prev_sched); 93 schedule_tail(current->thread.prev_sched);
94
95 /* XXX: if interrupt_end() calls schedule, this call to
96 * arch_switch_to_skas isn't needed. We could want to apply this to
97 * improve performance. -bb */
98 arch_switch_to_skas(current->thread.prev_sched, current);
99
92 current->thread.prev_sched = NULL; 100 current->thread.prev_sched = NULL;
93 101
94/* Handle any immediate reschedules or signals */ 102/* Handle any immediate reschedules or signals */
95 interrupt_end(); 103 interrupt_end();
104
96 userspace(&current->thread.regs.regs); 105 userspace(&current->thread.regs.regs);
97} 106}
98 107
@@ -109,6 +118,8 @@ int copy_thread_skas(int nr, unsigned long clone_flags, unsigned long sp,
109 if(sp != 0) REGS_SP(p->thread.regs.regs.skas.regs) = sp; 118 if(sp != 0) REGS_SP(p->thread.regs.regs.skas.regs) = sp;
110 119
111 handler = fork_handler; 120 handler = fork_handler;
121
122 arch_copy_thread(&current->thread.arch, &p->thread.arch);
112 } 123 }
113 else { 124 else {
114 init_thread_registers(&p->thread.regs.regs); 125 init_thread_registers(&p->thread.regs.regs);
diff --git a/arch/um/kernel/syscall_kern.c b/arch/um/kernel/syscall_kern.c
index 8e1a3501ff46..37d3978337d8 100644
--- a/arch/um/kernel/syscall_kern.c
+++ b/arch/um/kernel/syscall_kern.c
@@ -104,7 +104,7 @@ long sys_pipe(unsigned long __user * fildes)
104} 104}
105 105
106 106
107long sys_uname(struct old_utsname * name) 107long sys_uname(struct old_utsname __user * name)
108{ 108{
109 long err; 109 long err;
110 if (!name) 110 if (!name)
@@ -115,7 +115,7 @@ long sys_uname(struct old_utsname * name)
115 return err?-EFAULT:0; 115 return err?-EFAULT:0;
116} 116}
117 117
118long sys_olduname(struct oldold_utsname * name) 118long sys_olduname(struct oldold_utsname __user * name)
119{ 119{
120 long error; 120 long error;
121 121
diff --git a/arch/um/kernel/trap_kern.c b/arch/um/kernel/trap_kern.c
index d56046c2aba2..02f6d4d8dc3a 100644
--- a/arch/um/kernel/trap_kern.c
+++ b/arch/um/kernel/trap_kern.c
@@ -198,7 +198,7 @@ unsigned long segv(struct faultinfo fi, unsigned long ip, int is_user, void *sc)
198 si.si_signo = SIGBUS; 198 si.si_signo = SIGBUS;
199 si.si_errno = 0; 199 si.si_errno = 0;
200 si.si_code = BUS_ADRERR; 200 si.si_code = BUS_ADRERR;
201 si.si_addr = (void *)address; 201 si.si_addr = (void __user *)address;
202 current->thread.arch.faultinfo = fi; 202 current->thread.arch.faultinfo = fi;
203 force_sig_info(SIGBUS, &si, current); 203 force_sig_info(SIGBUS, &si, current);
204 } else if (err == -ENOMEM) { 204 } else if (err == -ENOMEM) {
@@ -207,7 +207,7 @@ unsigned long segv(struct faultinfo fi, unsigned long ip, int is_user, void *sc)
207 } else { 207 } else {
208 BUG_ON(err != -EFAULT); 208 BUG_ON(err != -EFAULT);
209 si.si_signo = SIGSEGV; 209 si.si_signo = SIGSEGV;
210 si.si_addr = (void *) address; 210 si.si_addr = (void __user *) address;
211 current->thread.arch.faultinfo = fi; 211 current->thread.arch.faultinfo = fi;
212 force_sig_info(SIGSEGV, &si, current); 212 force_sig_info(SIGSEGV, &si, current);
213 } 213 }
@@ -220,8 +220,8 @@ void bad_segv(struct faultinfo fi, unsigned long ip)
220 220
221 si.si_signo = SIGSEGV; 221 si.si_signo = SIGSEGV;
222 si.si_code = SEGV_ACCERR; 222 si.si_code = SEGV_ACCERR;
223 si.si_addr = (void *) FAULT_ADDRESS(fi); 223 si.si_addr = (void __user *) FAULT_ADDRESS(fi);
224 current->thread.arch.faultinfo = fi; 224 current->thread.arch.faultinfo = fi;
225 force_sig_info(SIGSEGV, &si, current); 225 force_sig_info(SIGSEGV, &si, current);
226} 226}
227 227
diff --git a/arch/um/kernel/tt/process_kern.c b/arch/um/kernel/tt/process_kern.c
index 295c1ac817b3..a9c1443fc548 100644
--- a/arch/um/kernel/tt/process_kern.c
+++ b/arch/um/kernel/tt/process_kern.c
@@ -51,6 +51,13 @@ void switch_to_tt(void *prev, void *next)
51 51
52 c = 0; 52 c = 0;
53 53
54 /* Notice that here we "up" the semaphore on which "to" is waiting, and
55 * below (the read) we wait on this semaphore (which is implemented by
56 * switch_pipe) and go sleeping. Thus, after that, we have resumed in
57 * "to", and can't use any more the value of "from" (which is outdated),
58 * nor the value in "to" (since it was the task which stole us the CPU,
59 * which we don't care about). */
60
54 err = os_write_file(to->thread.mode.tt.switch_pipe[1], &c, sizeof(c)); 61 err = os_write_file(to->thread.mode.tt.switch_pipe[1], &c, sizeof(c));
55 if(err != sizeof(c)) 62 if(err != sizeof(c))
56 panic("write of switch_pipe failed, err = %d", -err); 63 panic("write of switch_pipe failed, err = %d", -err);
@@ -77,7 +84,7 @@ void switch_to_tt(void *prev, void *next)
77 change_sig(SIGALRM, alrm); 84 change_sig(SIGALRM, alrm);
78 change_sig(SIGPROF, prof); 85 change_sig(SIGPROF, prof);
79 86
80 arch_switch(); 87 arch_switch_to_tt(prev_sched, current);
81 88
82 flush_tlb_all(); 89 flush_tlb_all();
83 local_irq_restore(flags); 90 local_irq_restore(flags);
@@ -141,7 +148,6 @@ static void new_thread_handler(int sig)
141 set_cmdline("(kernel thread)"); 148 set_cmdline("(kernel thread)");
142 149
143 change_sig(SIGUSR1, 1); 150 change_sig(SIGUSR1, 1);
144 change_sig(SIGVTALRM, 1);
145 change_sig(SIGPROF, 1); 151 change_sig(SIGPROF, 1);
146 local_irq_enable(); 152 local_irq_enable();
147 if(!run_kernel_thread(fn, arg, &current->thread.exec_buf)) 153 if(!run_kernel_thread(fn, arg, &current->thread.exec_buf))
diff --git a/arch/um/os-Linux/Makefile b/arch/um/os-Linux/Makefile
index 1659386b42bb..f4bfc4c7ccac 100644
--- a/arch/um/os-Linux/Makefile
+++ b/arch/um/os-Linux/Makefile
@@ -4,7 +4,7 @@
4# 4#
5 5
6obj-y = aio.o elf_aux.o file.o helper.o irq.o main.o mem.o process.o sigio.o \ 6obj-y = aio.o elf_aux.o file.o helper.o irq.o main.o mem.o process.o sigio.o \
7 signal.o start_up.o time.o trap.o tt.o tty.o uaccess.o umid.o \ 7 signal.o start_up.o time.o trap.o tt.o tty.o uaccess.o umid.o tls.o \
8 user_syms.o util.o drivers/ sys-$(SUBARCH)/ 8 user_syms.o util.o drivers/ sys-$(SUBARCH)/
9 9
10obj-$(CONFIG_MODE_SKAS) += skas/ 10obj-$(CONFIG_MODE_SKAS) += skas/
@@ -12,12 +12,9 @@ obj-$(CONFIG_TTY_LOG) += tty_log.o
12user-objs-$(CONFIG_TTY_LOG) += tty_log.o 12user-objs-$(CONFIG_TTY_LOG) += tty_log.o
13 13
14USER_OBJS := $(user-objs-y) aio.o elf_aux.o file.o helper.o irq.o main.o mem.o \ 14USER_OBJS := $(user-objs-y) aio.o elf_aux.o file.o helper.o irq.o main.o mem.o \
15 process.o sigio.o signal.o start_up.o time.o trap.o tt.o tty.o \ 15 process.o sigio.o signal.o start_up.o time.o trap.o tt.o tty.o tls.o \
16 uaccess.o umid.o util.o 16 uaccess.o umid.o util.o
17 17
18elf_aux.o: $(ARCH_DIR)/kernel-offsets.h
19CFLAGS_elf_aux.o += -I$(objtree)/arch/um
20
21CFLAGS_user_syms.o += -DSUBARCH_$(SUBARCH) 18CFLAGS_user_syms.o += -DSUBARCH_$(SUBARCH)
22 19
23HAVE_AIO_ABI := $(shell [ -r /usr/include/linux/aio_abi.h ] && \ 20HAVE_AIO_ABI := $(shell [ -r /usr/include/linux/aio_abi.h ] && \
diff --git a/arch/um/os-Linux/drivers/ethertap_kern.c b/arch/um/os-Linux/drivers/ethertap_kern.c
index 6ae4b19d9f50..768606bec233 100644
--- a/arch/um/os-Linux/drivers/ethertap_kern.c
+++ b/arch/um/os-Linux/drivers/ethertap_kern.c
@@ -102,18 +102,7 @@ static struct transport ethertap_transport = {
102static int register_ethertap(void) 102static int register_ethertap(void)
103{ 103{
104 register_transport(&ethertap_transport); 104 register_transport(&ethertap_transport);
105 return(1); 105 return 0;
106} 106}
107 107
108__initcall(register_ethertap); 108__initcall(register_ethertap);
109
110/*
111 * Overrides for Emacs so that we follow Linus's tabbing style.
112 * Emacs will notice this stuff at the end of the file and automatically
113 * adjust the settings for this buffer only. This must remain at the end
114 * of the file.
115 * ---------------------------------------------------------------------------
116 * Local variables:
117 * c-file-style: "linux"
118 * End:
119 */
diff --git a/arch/um/os-Linux/drivers/tuntap_kern.c b/arch/um/os-Linux/drivers/tuntap_kern.c
index 4202b9ebad4c..190009a6f89c 100644
--- a/arch/um/os-Linux/drivers/tuntap_kern.c
+++ b/arch/um/os-Linux/drivers/tuntap_kern.c
@@ -87,18 +87,7 @@ static struct transport tuntap_transport = {
87static int register_tuntap(void) 87static int register_tuntap(void)
88{ 88{
89 register_transport(&tuntap_transport); 89 register_transport(&tuntap_transport);
90 return(1); 90 return 0;
91} 91}
92 92
93__initcall(register_tuntap); 93__initcall(register_tuntap);
94
95/*
96 * Overrides for Emacs so that we follow Linus's tabbing style.
97 * Emacs will notice this stuff at the end of the file and automatically
98 * adjust the settings for this buffer only. This must remain at the end
99 * of the file.
100 * ---------------------------------------------------------------------------
101 * Local variables:
102 * c-file-style: "linux"
103 * End:
104 */
diff --git a/arch/um/os-Linux/mem.c b/arch/um/os-Linux/mem.c
index 9d7d69a523bb..6ab372da9657 100644
--- a/arch/um/os-Linux/mem.c
+++ b/arch/um/os-Linux/mem.c
@@ -121,36 +121,11 @@ int create_tmp_file(unsigned long long len)
121 return(fd); 121 return(fd);
122} 122}
123 123
124static int create_anon_file(unsigned long long len)
125{
126 void *addr;
127 int fd;
128
129 fd = open("/dev/anon", O_RDWR);
130 if(fd < 0) {
131 perror("opening /dev/anon");
132 exit(1);
133 }
134
135 addr = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
136 if(addr == MAP_FAILED){
137 perror("mapping physmem file");
138 exit(1);
139 }
140 munmap(addr, len);
141
142 return(fd);
143}
144
145extern int have_devanon;
146
147int create_mem_file(unsigned long long len) 124int create_mem_file(unsigned long long len)
148{ 125{
149 int err, fd; 126 int err, fd;
150 127
151 if(have_devanon) 128 fd = create_tmp_file(len);
152 fd = create_anon_file(len);
153 else fd = create_tmp_file(len);
154 129
155 err = os_set_exec_close(fd, 1); 130 err = os_set_exec_close(fd, 1);
156 if(err < 0){ 131 if(err < 0){
diff --git a/arch/um/os-Linux/process.c b/arch/um/os-Linux/process.c
index d261888f39c4..8176b0b52047 100644
--- a/arch/um/os-Linux/process.c
+++ b/arch/um/os-Linux/process.c
@@ -11,6 +11,7 @@
11#include <linux/unistd.h> 11#include <linux/unistd.h>
12#include <sys/mman.h> 12#include <sys/mman.h>
13#include <sys/wait.h> 13#include <sys/wait.h>
14#include <sys/mman.h>
14#include "ptrace_user.h" 15#include "ptrace_user.h"
15#include "os.h" 16#include "os.h"
16#include "user.h" 17#include "user.h"
@@ -20,6 +21,7 @@
20#include "kern_util.h" 21#include "kern_util.h"
21#include "longjmp.h" 22#include "longjmp.h"
22#include "skas_ptrace.h" 23#include "skas_ptrace.h"
24#include "kern_constants.h"
23 25
24#define ARBITRARY_ADDR -1 26#define ARBITRARY_ADDR -1
25#define FAILURE_PID -1 27#define FAILURE_PID -1
@@ -187,6 +189,48 @@ int os_unmap_memory(void *addr, int len)
187 return(0); 189 return(0);
188} 190}
189 191
192#ifndef MADV_REMOVE
193#define MADV_REMOVE 0x5 /* remove these pages & resources */
194#endif
195
196int os_drop_memory(void *addr, int length)
197{
198 int err;
199
200 err = madvise(addr, length, MADV_REMOVE);
201 if(err < 0)
202 err = -errno;
203 return err;
204}
205
206int can_drop_memory(void)
207{
208 void *addr;
209 int fd;
210
211 printk("Checking host MADV_REMOVE support...");
212 fd = create_mem_file(UM_KERN_PAGE_SIZE);
213 if(fd < 0){
214 printk("Creating test memory file failed, err = %d\n", -fd);
215 return 0;
216 }
217
218 addr = mmap64(NULL, UM_KERN_PAGE_SIZE, PROT_READ | PROT_WRITE,
219 MAP_PRIVATE, fd, 0);
220 if(addr == MAP_FAILED){
221 printk("Mapping test memory file failed, err = %d\n", -errno);
222 return 0;
223 }
224
225 if(madvise(addr, UM_KERN_PAGE_SIZE, MADV_REMOVE) != 0){
226 printk("MADV_REMOVE failed, err = %d\n", -errno);
227 return 0;
228 }
229
230 printk("OK\n");
231 return 1;
232}
233
190void init_new_thread_stack(void *sig_stack, void (*usr1_handler)(int)) 234void init_new_thread_stack(void *sig_stack, void (*usr1_handler)(int))
191{ 235{
192 int flags = 0, pages; 236 int flags = 0, pages;
diff --git a/arch/um/os-Linux/start_up.c b/arch/um/os-Linux/start_up.c
index 32753131f8d8..387e26af301a 100644
--- a/arch/um/os-Linux/start_up.c
+++ b/arch/um/os-Linux/start_up.c
@@ -470,25 +470,6 @@ int can_do_skas(void)
470} 470}
471#endif 471#endif
472 472
473int have_devanon = 0;
474
475/* Runs on boot kernel stack - already safe to use printk. */
476
477void check_devanon(void)
478{
479 int fd;
480
481 printk("Checking for /dev/anon on the host...");
482 fd = open("/dev/anon", O_RDWR);
483 if(fd < 0){
484 printk("Not available (open failed with errno %d)\n", errno);
485 return;
486 }
487
488 printk("OK\n");
489 have_devanon = 1;
490}
491
492int __init parse_iomem(char *str, int *add) 473int __init parse_iomem(char *str, int *add)
493{ 474{
494 struct iomem_region *new; 475 struct iomem_region *new;
@@ -664,6 +645,5 @@ void os_check_bugs(void)
664{ 645{
665 check_ptrace(); 646 check_ptrace();
666 check_sigio(); 647 check_sigio();
667 check_devanon();
668} 648}
669 649
diff --git a/arch/um/os-Linux/sys-i386/Makefile b/arch/um/os-Linux/sys-i386/Makefile
index 340ef26f5944..b3213613c41c 100644
--- a/arch/um/os-Linux/sys-i386/Makefile
+++ b/arch/um/os-Linux/sys-i386/Makefile
@@ -3,7 +3,7 @@
3# Licensed under the GPL 3# Licensed under the GPL
4# 4#
5 5
6obj-$(CONFIG_MODE_SKAS) = registers.o 6obj-$(CONFIG_MODE_SKAS) = registers.o tls.o
7 7
8USER_OBJS := $(obj-y) 8USER_OBJS := $(obj-y)
9 9
diff --git a/arch/um/os-Linux/sys-i386/tls.c b/arch/um/os-Linux/sys-i386/tls.c
new file mode 100644
index 000000000000..ba21f0e04a2f
--- /dev/null
+++ b/arch/um/os-Linux/sys-i386/tls.c
@@ -0,0 +1,33 @@
1#include <linux/unistd.h>
2#include "sysdep/tls.h"
3#include "user_util.h"
4
5static _syscall1(int, get_thread_area, user_desc_t *, u_info);
6
7/* Checks whether host supports TLS, and sets *tls_min according to the value
8 * valid on the host.
9 * i386 host have it == 6; x86_64 host have it == 12, for i386 emulation. */
10void check_host_supports_tls(int *supports_tls, int *tls_min) {
11 /* Values for x86 and x86_64.*/
12 int val[] = {GDT_ENTRY_TLS_MIN_I386, GDT_ENTRY_TLS_MIN_X86_64};
13 int i;
14
15 for (i = 0; i < ARRAY_SIZE(val); i++) {
16 user_desc_t info;
17 info.entry_number = val[i];
18
19 if (get_thread_area(&info) == 0) {
20 *tls_min = val[i];
21 *supports_tls = 1;
22 return;
23 } else {
24 if (errno == EINVAL)
25 continue;
26 else if (errno == ENOSYS)
27 *supports_tls = 0;
28 return;
29 }
30 }
31
32 *supports_tls = 0;
33}
diff --git a/arch/um/os-Linux/tls.c b/arch/um/os-Linux/tls.c
new file mode 100644
index 000000000000..9cb09a45546b
--- /dev/null
+++ b/arch/um/os-Linux/tls.c
@@ -0,0 +1,76 @@
1#include <errno.h>
2#include <sys/ptrace.h>
3#include <asm/ldt.h>
4#include "sysdep/tls.h"
5#include "uml-config.h"
6
7/* TLS support - we basically rely on the host's one.*/
8
9/* In TT mode, this should be called only by the tracing thread, and makes sense
10 * only for PTRACE_SET_THREAD_AREA. In SKAS mode, it's used normally.
11 *
12 */
13
14#ifndef PTRACE_GET_THREAD_AREA
15#define PTRACE_GET_THREAD_AREA 25
16#endif
17
18#ifndef PTRACE_SET_THREAD_AREA
19#define PTRACE_SET_THREAD_AREA 26
20#endif
21
22int os_set_thread_area(user_desc_t *info, int pid)
23{
24 int ret;
25
26 ret = ptrace(PTRACE_SET_THREAD_AREA, pid, info->entry_number,
27 (unsigned long) info);
28 if (ret < 0)
29 ret = -errno;
30 return ret;
31}
32
33#ifdef UML_CONFIG_MODE_SKAS
34
35int os_get_thread_area(user_desc_t *info, int pid)
36{
37 int ret;
38
39 ret = ptrace(PTRACE_GET_THREAD_AREA, pid, info->entry_number,
40 (unsigned long) info);
41 if (ret < 0)
42 ret = -errno;
43 return ret;
44}
45
46#endif
47
48#ifdef UML_CONFIG_MODE_TT
49#include "linux/unistd.h"
50
51static _syscall1(int, get_thread_area, user_desc_t *, u_info);
52static _syscall1(int, set_thread_area, user_desc_t *, u_info);
53
54int do_set_thread_area_tt(user_desc_t *info)
55{
56 int ret;
57
58 ret = set_thread_area(info);
59 if (ret < 0) {
60 ret = -errno;
61 }
62 return ret;
63}
64
65int do_get_thread_area_tt(user_desc_t *info)
66{
67 int ret;
68
69 ret = get_thread_area(info);
70 if (ret < 0) {
71 ret = -errno;
72 }
73 return ret;
74}
75
76#endif /* UML_CONFIG_MODE_TT */
diff --git a/arch/um/scripts/Makefile.rules b/arch/um/scripts/Makefile.rules
index 2e41cabd3d93..b696b451774c 100644
--- a/arch/um/scripts/Makefile.rules
+++ b/arch/um/scripts/Makefile.rules
@@ -20,25 +20,7 @@ define unprofile
20 $(patsubst -pg,,$(patsubst -fprofile-arcs -ftest-coverage,,$(1))) 20 $(patsubst -pg,,$(patsubst -fprofile-arcs -ftest-coverage,,$(1)))
21endef 21endef
22 22
23 23ifdef subarch-obj-y
24# cmd_make_link checks to see if the $(foo-dir) variable starts with a /. If 24obj-y += subarch.o
25# so, it's considered to be a path relative to $(srcdir) rather than 25subarch-y = $(addprefix ../../$(SUBARCH)/,$(subarch-obj-y))
26# $(srcdir)/arch/$(SUBARCH). This is because x86_64 wants to get ldt.c from 26endif
27# arch/um/sys-i386 rather than arch/i386 like the other borrowed files. So,
28# it sets $(ldt.c-dir) to /arch/um/sys-i386.
29quiet_cmd_make_link = SYMLINK $@
30cmd_make_link = rm -f $@; ln -sf $(srctree)$(if $(filter-out /%,$($(notdir $@)-dir)),/arch/$(SUBARCH))/$($(notdir $@)-dir)/$(notdir $@) $@
31
32# this needs to be before the foreach, because targets does not accept
33# complete paths like $(obj)/$(f). To make sure this works, use a := assignment
34# or we will get $(obj)/$(f) in the "targets" value.
35# Also, this forces you to use the := syntax when assigning to targets.
36# Otherwise the line below will cause an infinite loop (if you don't know why,
37# just do it).
38
39targets := $(targets) $(SYMLINKS)
40
41SYMLINKS := $(foreach f,$(SYMLINKS),$(obj)/$(f))
42
43$(SYMLINKS): FORCE
44 $(call if_changed,make_link)
diff --git a/arch/um/scripts/Makefile.unmap b/arch/um/scripts/Makefile.unmap
deleted file mode 100644
index b2165188d942..000000000000
--- a/arch/um/scripts/Makefile.unmap
+++ /dev/null
@@ -1,22 +0,0 @@
1clean-files += unmap_tmp.o unmap_fin.o unmap.o
2
3ifdef CONFIG_MODE_TT
4
5#Always build unmap_fin.o
6extra-y += unmap_fin.o
7#Do dependency tracking for unmap.o (it will be always built, but won't get the tracking unless we use this).
8targets += unmap.o
9
10#XXX: partially copied from arch/um/scripts/Makefile.rules
11$(obj)/unmap.o: _c_flags = $(call unprofile,$(CFLAGS))
12
13quiet_cmd_wrapld = LD $@
14define cmd_wrapld
15 $(LD) $(LDFLAGS) -r -o $(obj)/unmap_tmp.o $< ; \
16 $(OBJCOPY) $(UML_OBJCOPYFLAGS) $(obj)/unmap_tmp.o $@ -G switcheroo
17endef
18
19$(obj)/unmap_fin.o : $(obj)/unmap.o FORCE
20 $(call if_changed,wrapld)
21
22endif
diff --git a/arch/um/sys-i386/Makefile b/arch/um/sys-i386/Makefile
index f5fd5b0156d0..98b20b7bba4f 100644
--- a/arch/um/sys-i386/Makefile
+++ b/arch/um/sys-i386/Makefile
@@ -1,23 +1,18 @@
1obj-y := bitops.o bugs.o checksum.o delay.o fault.o ksyms.o ldt.o ptrace.o \ 1obj-y = bugs.o checksum.o delay.o fault.o ksyms.o ldt.o ptrace.o \
2 ptrace_user.o semaphore.o signal.o sigcontext.o syscalls.o sysrq.o \ 2 ptrace_user.o signal.o sigcontext.o syscalls.o sysrq.o \
3 sys_call_table.o 3 sys_call_table.o tls.o
4 4
5obj-$(CONFIG_MODE_SKAS) += stub.o stub_segv.o 5obj-$(CONFIG_MODE_SKAS) += stub.o stub_segv.o
6 6
7obj-$(CONFIG_HIGHMEM) += highmem.o 7subarch-obj-y = lib/bitops.o kernel/semaphore.o
8obj-$(CONFIG_MODULES) += module.o 8subarch-obj-$(CONFIG_HIGHMEM) += mm/highmem.o
9subarch-obj-$(CONFIG_MODULES) += kernel/module.o
9 10
10USER_OBJS := bugs.o ptrace_user.o sigcontext.o fault.o stub_segv.o 11USER_OBJS := bugs.o ptrace_user.o sigcontext.o fault.o stub_segv.o
11 12
12SYMLINKS = bitops.c semaphore.c highmem.c module.c
13
14include arch/um/scripts/Makefile.rules 13include arch/um/scripts/Makefile.rules
15 14
16bitops.c-dir = lib 15extra-$(CONFIG_MODE_TT) += unmap.o
17semaphore.c-dir = kernel
18highmem.c-dir = mm
19module.c-dir = kernel
20
21$(obj)/stub_segv.o : _c_flags = $(call unprofile,$(CFLAGS))
22 16
23include arch/um/scripts/Makefile.unmap 17$(obj)/stub_segv.o $(obj)/unmap.o: \
18 _c_flags = $(call unprofile,$(CFLAGS))
diff --git a/arch/um/sys-i386/ptrace.c b/arch/um/sys-i386/ptrace.c
index 8032a105949a..6028bc7cc01b 100644
--- a/arch/um/sys-i386/ptrace.c
+++ b/arch/um/sys-i386/ptrace.c
@@ -15,9 +15,22 @@
15#include "sysdep/sigcontext.h" 15#include "sysdep/sigcontext.h"
16#include "sysdep/sc.h" 16#include "sysdep/sc.h"
17 17
18void arch_switch(void) 18void arch_switch_to_tt(struct task_struct *from, struct task_struct *to)
19{ 19{
20 update_debugregs(current->thread.arch.debugregs_seq); 20 update_debugregs(to->thread.arch.debugregs_seq);
21 arch_switch_tls_tt(from, to);
22}
23
24void arch_switch_to_skas(struct task_struct *from, struct task_struct *to)
25{
26 int err = arch_switch_tls_skas(from, to);
27 if (!err)
28 return;
29
30 if (err != -EINVAL)
31 printk(KERN_WARNING "arch_switch_tls_skas failed, errno %d, not EINVAL\n", -err);
32 else
33 printk(KERN_WARNING "arch_switch_tls_skas failed, errno = EINVAL\n");
21} 34}
22 35
23int is_syscall(unsigned long addr) 36int is_syscall(unsigned long addr)
@@ -124,22 +137,22 @@ unsigned long getreg(struct task_struct *child, int regno)
124int peek_user(struct task_struct *child, long addr, long data) 137int peek_user(struct task_struct *child, long addr, long data)
125{ 138{
126/* read the word at location addr in the USER area. */ 139/* read the word at location addr in the USER area. */
127 unsigned long tmp; 140 unsigned long tmp;
128 141
129 if ((addr & 3) || addr < 0) 142 if ((addr & 3) || addr < 0)
130 return -EIO; 143 return -EIO;
131 144
132 tmp = 0; /* Default return condition */ 145 tmp = 0; /* Default return condition */
133 if(addr < MAX_REG_OFFSET){ 146 if(addr < MAX_REG_OFFSET){
134 tmp = getreg(child, addr); 147 tmp = getreg(child, addr);
135 } 148 }
136 else if((addr >= offsetof(struct user, u_debugreg[0])) && 149 else if((addr >= offsetof(struct user, u_debugreg[0])) &&
137 (addr <= offsetof(struct user, u_debugreg[7]))){ 150 (addr <= offsetof(struct user, u_debugreg[7]))){
138 addr -= offsetof(struct user, u_debugreg[0]); 151 addr -= offsetof(struct user, u_debugreg[0]);
139 addr = addr >> 2; 152 addr = addr >> 2;
140 tmp = child->thread.arch.debugregs[addr]; 153 tmp = child->thread.arch.debugregs[addr];
141 } 154 }
142 return put_user(tmp, (unsigned long *) data); 155 return put_user(tmp, (unsigned long __user *) data);
143} 156}
144 157
145struct i387_fxsave_struct { 158struct i387_fxsave_struct {
diff --git a/arch/um/sys-i386/ptrace_user.c b/arch/um/sys-i386/ptrace_user.c
index 7c376c95de50..9f3bd8ed78f5 100644
--- a/arch/um/sys-i386/ptrace_user.c
+++ b/arch/um/sys-i386/ptrace_user.c
@@ -14,6 +14,7 @@
14#include "sysdep/thread.h" 14#include "sysdep/thread.h"
15#include "user.h" 15#include "user.h"
16#include "os.h" 16#include "os.h"
17#include "uml-config.h"
17 18
18int ptrace_getregs(long pid, unsigned long *regs_out) 19int ptrace_getregs(long pid, unsigned long *regs_out)
19{ 20{
@@ -43,6 +44,7 @@ int ptrace_setfpregs(long pid, unsigned long *regs)
43 return 0; 44 return 0;
44} 45}
45 46
47/* All the below stuff is of interest for TT mode only */
46static void write_debugregs(int pid, unsigned long *regs) 48static void write_debugregs(int pid, unsigned long *regs)
47{ 49{
48 struct user *dummy; 50 struct user *dummy;
@@ -75,7 +77,6 @@ static void read_debugregs(int pid, unsigned long *regs)
75 77
76/* Accessed only by the tracing thread */ 78/* Accessed only by the tracing thread */
77static unsigned long kernel_debugregs[8] = { [ 0 ... 7 ] = 0 }; 79static unsigned long kernel_debugregs[8] = { [ 0 ... 7 ] = 0 };
78static int debugregs_seq = 0;
79 80
80void arch_enter_kernel(void *task, int pid) 81void arch_enter_kernel(void *task, int pid)
81{ 82{
@@ -89,6 +90,11 @@ void arch_leave_kernel(void *task, int pid)
89 write_debugregs(pid, TASK_DEBUGREGS(task)); 90 write_debugregs(pid, TASK_DEBUGREGS(task));
90} 91}
91 92
93#ifdef UML_CONFIG_PT_PROXY
94/* Accessed only by the tracing thread */
95static int debugregs_seq;
96
97/* Only called by the ptrace proxy */
92void ptrace_pokeuser(unsigned long addr, unsigned long data) 98void ptrace_pokeuser(unsigned long addr, unsigned long data)
93{ 99{
94 if((addr < offsetof(struct user, u_debugreg[0])) || 100 if((addr < offsetof(struct user, u_debugreg[0])) ||
@@ -109,6 +115,7 @@ static void update_debugregs_cb(void *arg)
109 write_debugregs(pid, kernel_debugregs); 115 write_debugregs(pid, kernel_debugregs);
110} 116}
111 117
118/* Optimized out in its header when not defined */
112void update_debugregs(int seq) 119void update_debugregs(int seq)
113{ 120{
114 int me; 121 int me;
@@ -118,6 +125,7 @@ void update_debugregs(int seq)
118 me = os_getpid(); 125 me = os_getpid();
119 initial_thread_cb(update_debugregs_cb, &me); 126 initial_thread_cb(update_debugregs_cb, &me);
120} 127}
128#endif
121 129
122/* 130/*
123 * Overrides for Emacs so that we follow Linus's tabbing style. 131 * Overrides for Emacs so that we follow Linus's tabbing style.
diff --git a/arch/um/sys-i386/signal.c b/arch/um/sys-i386/signal.c
index 33a40f5ef0d2..f5d0e1c37ea2 100644
--- a/arch/um/sys-i386/signal.c
+++ b/arch/um/sys-i386/signal.c
@@ -19,7 +19,7 @@
19#include "skas.h" 19#include "skas.h"
20 20
21static int copy_sc_from_user_skas(struct pt_regs *regs, 21static int copy_sc_from_user_skas(struct pt_regs *regs,
22 struct sigcontext *from) 22 struct sigcontext __user *from)
23{ 23{
24 struct sigcontext sc; 24 struct sigcontext sc;
25 unsigned long fpregs[HOST_FP_SIZE]; 25 unsigned long fpregs[HOST_FP_SIZE];
@@ -57,7 +57,7 @@ static int copy_sc_from_user_skas(struct pt_regs *regs,
57 return(0); 57 return(0);
58} 58}
59 59
60int copy_sc_to_user_skas(struct sigcontext *to, struct _fpstate *to_fp, 60int copy_sc_to_user_skas(struct sigcontext *to, struct _fpstate __user *to_fp,
61 struct pt_regs *regs, unsigned long sp) 61 struct pt_regs *regs, unsigned long sp)
62{ 62{
63 struct sigcontext sc; 63 struct sigcontext sc;
@@ -92,7 +92,7 @@ int copy_sc_to_user_skas(struct sigcontext *to, struct _fpstate *to_fp,
92 "errno = %d\n", err); 92 "errno = %d\n", err);
93 return(1); 93 return(1);
94 } 94 }
95 to_fp = (to_fp ? to_fp : (struct _fpstate *) (to + 1)); 95 to_fp = (to_fp ? to_fp : (struct _fpstate __user *) (to + 1));
96 sc.fpstate = to_fp; 96 sc.fpstate = to_fp;
97 97
98 if(err) 98 if(err)
@@ -113,10 +113,11 @@ int copy_sc_to_user_skas(struct sigcontext *to, struct _fpstate *to_fp,
113 * saved pointer is in the kernel, but the sigcontext is in userspace, so we 113 * saved pointer is in the kernel, but the sigcontext is in userspace, so we
114 * copy_to_user it. 114 * copy_to_user it.
115 */ 115 */
116int copy_sc_from_user_tt(struct sigcontext *to, struct sigcontext *from, 116int copy_sc_from_user_tt(struct sigcontext *to, struct sigcontext __user *from,
117 int fpsize) 117 int fpsize)
118{ 118{
119 struct _fpstate *to_fp, *from_fp; 119 struct _fpstate *to_fp;
120 struct _fpstate __user *from_fp;
120 unsigned long sigs; 121 unsigned long sigs;
121 int err; 122 int err;
122 123
@@ -131,13 +132,14 @@ int copy_sc_from_user_tt(struct sigcontext *to, struct sigcontext *from,
131 return(err); 132 return(err);
132} 133}
133 134
134int copy_sc_to_user_tt(struct sigcontext *to, struct _fpstate *fp, 135int copy_sc_to_user_tt(struct sigcontext *to, struct _fpstate __user *fp,
135 struct sigcontext *from, int fpsize, unsigned long sp) 136 struct sigcontext *from, int fpsize, unsigned long sp)
136{ 137{
137 struct _fpstate *to_fp, *from_fp; 138 struct _fpstate __user *to_fp;
139 struct _fpstate *from_fp;
138 int err; 140 int err;
139 141
140 to_fp = (fp ? fp : (struct _fpstate *) (to + 1)); 142 to_fp = (fp ? fp : (struct _fpstate __user *) (to + 1));
141 from_fp = from->fpstate; 143 from_fp = from->fpstate;
142 err = copy_to_user(to, from, sizeof(*to)); 144 err = copy_to_user(to, from, sizeof(*to));
143 145
@@ -165,7 +167,7 @@ static int copy_sc_from_user(struct pt_regs *to, void __user *from)
165 return(ret); 167 return(ret);
166} 168}
167 169
168static int copy_sc_to_user(struct sigcontext *to, struct _fpstate *fp, 170static int copy_sc_to_user(struct sigcontext *to, struct _fpstate __user *fp,
169 struct pt_regs *from, unsigned long sp) 171 struct pt_regs *from, unsigned long sp)
170{ 172{
171 return(CHOOSE_MODE(copy_sc_to_user_tt(to, fp, UPT_SC(&from->regs), 173 return(CHOOSE_MODE(copy_sc_to_user_tt(to, fp, UPT_SC(&from->regs),
@@ -173,7 +175,7 @@ static int copy_sc_to_user(struct sigcontext *to, struct _fpstate *fp,
173 copy_sc_to_user_skas(to, fp, from, sp))); 175 copy_sc_to_user_skas(to, fp, from, sp)));
174} 176}
175 177
176static int copy_ucontext_to_user(struct ucontext *uc, struct _fpstate *fp, 178static int copy_ucontext_to_user(struct ucontext __user *uc, struct _fpstate __user *fp,
177 sigset_t *set, unsigned long sp) 179 sigset_t *set, unsigned long sp)
178{ 180{
179 int err = 0; 181 int err = 0;
@@ -188,7 +190,7 @@ static int copy_ucontext_to_user(struct ucontext *uc, struct _fpstate *fp,
188 190
189struct sigframe 191struct sigframe
190{ 192{
191 char *pretcode; 193 char __user *pretcode;
192 int sig; 194 int sig;
193 struct sigcontext sc; 195 struct sigcontext sc;
194 struct _fpstate fpstate; 196 struct _fpstate fpstate;
@@ -198,10 +200,10 @@ struct sigframe
198 200
199struct rt_sigframe 201struct rt_sigframe
200{ 202{
201 char *pretcode; 203 char __user *pretcode;
202 int sig; 204 int sig;
203 struct siginfo *pinfo; 205 struct siginfo __user *pinfo;
204 void *puc; 206 void __user *puc;
205 struct siginfo info; 207 struct siginfo info;
206 struct ucontext uc; 208 struct ucontext uc;
207 struct _fpstate fpstate; 209 struct _fpstate fpstate;
@@ -213,16 +215,16 @@ int setup_signal_stack_sc(unsigned long stack_top, int sig,
213 sigset_t *mask) 215 sigset_t *mask)
214{ 216{
215 struct sigframe __user *frame; 217 struct sigframe __user *frame;
216 void *restorer; 218 void __user *restorer;
217 unsigned long save_sp = PT_REGS_SP(regs); 219 unsigned long save_sp = PT_REGS_SP(regs);
218 int err = 0; 220 int err = 0;
219 221
220 stack_top &= -8UL; 222 stack_top &= -8UL;
221 frame = (struct sigframe *) stack_top - 1; 223 frame = (struct sigframe __user *) stack_top - 1;
222 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) 224 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
223 return 1; 225 return 1;
224 226
225 restorer = (void *) frame->retcode; 227 restorer = frame->retcode;
226 if(ka->sa.sa_flags & SA_RESTORER) 228 if(ka->sa.sa_flags & SA_RESTORER)
227 restorer = ka->sa.sa_restorer; 229 restorer = ka->sa.sa_restorer;
228 230
@@ -278,16 +280,16 @@ int setup_signal_stack_si(unsigned long stack_top, int sig,
278 siginfo_t *info, sigset_t *mask) 280 siginfo_t *info, sigset_t *mask)
279{ 281{
280 struct rt_sigframe __user *frame; 282 struct rt_sigframe __user *frame;
281 void *restorer; 283 void __user *restorer;
282 unsigned long save_sp = PT_REGS_SP(regs); 284 unsigned long save_sp = PT_REGS_SP(regs);
283 int err = 0; 285 int err = 0;
284 286
285 stack_top &= -8UL; 287 stack_top &= -8UL;
286 frame = (struct rt_sigframe *) stack_top - 1; 288 frame = (struct rt_sigframe __user *) stack_top - 1;
287 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) 289 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
288 return 1; 290 return 1;
289 291
290 restorer = (void *) frame->retcode; 292 restorer = frame->retcode;
291 if(ka->sa.sa_flags & SA_RESTORER) 293 if(ka->sa.sa_flags & SA_RESTORER)
292 restorer = ka->sa.sa_restorer; 294 restorer = ka->sa.sa_restorer;
293 295
@@ -333,7 +335,7 @@ err:
333long sys_sigreturn(struct pt_regs regs) 335long sys_sigreturn(struct pt_regs regs)
334{ 336{
335 unsigned long sp = PT_REGS_SP(&current->thread.regs); 337 unsigned long sp = PT_REGS_SP(&current->thread.regs);
336 struct sigframe __user *frame = (struct sigframe *)(sp - 8); 338 struct sigframe __user *frame = (struct sigframe __user *)(sp - 8);
337 sigset_t set; 339 sigset_t set;
338 struct sigcontext __user *sc = &frame->sc; 340 struct sigcontext __user *sc = &frame->sc;
339 unsigned long __user *oldmask = &sc->oldmask; 341 unsigned long __user *oldmask = &sc->oldmask;
@@ -365,8 +367,8 @@ long sys_sigreturn(struct pt_regs regs)
365 367
366long sys_rt_sigreturn(struct pt_regs regs) 368long sys_rt_sigreturn(struct pt_regs regs)
367{ 369{
368 unsigned long __user sp = PT_REGS_SP(&current->thread.regs); 370 unsigned long sp = PT_REGS_SP(&current->thread.regs);
369 struct rt_sigframe __user *frame = (struct rt_sigframe *) (sp - 4); 371 struct rt_sigframe __user *frame = (struct rt_sigframe __user *) (sp - 4);
370 sigset_t set; 372 sigset_t set;
371 struct ucontext __user *uc = &frame->uc; 373 struct ucontext __user *uc = &frame->uc;
372 int sig_size = _NSIG_WORDS * sizeof(unsigned long); 374 int sig_size = _NSIG_WORDS * sizeof(unsigned long);
diff --git a/arch/um/sys-i386/sys_call_table.S b/arch/um/sys-i386/sys_call_table.S
index ad75c27afe38..1ff61474b25c 100644
--- a/arch/um/sys-i386/sys_call_table.S
+++ b/arch/um/sys-i386/sys_call_table.S
@@ -6,8 +6,6 @@
6 6
7#define sys_vm86old sys_ni_syscall 7#define sys_vm86old sys_ni_syscall
8#define sys_vm86 sys_ni_syscall 8#define sys_vm86 sys_ni_syscall
9#define sys_set_thread_area sys_ni_syscall
10#define sys_get_thread_area sys_ni_syscall
11 9
12#define sys_stime um_stime 10#define sys_stime um_stime
13#define sys_time um_time 11#define sys_time um_time
diff --git a/arch/um/sys-i386/syscalls.c b/arch/um/sys-i386/syscalls.c
index 83e9be820a86..749dd1bfe60f 100644
--- a/arch/um/sys-i386/syscalls.c
+++ b/arch/um/sys-i386/syscalls.c
@@ -61,21 +61,27 @@ long old_select(struct sel_arg_struct __user *arg)
61 return sys_select(a.n, a.inp, a.outp, a.exp, a.tvp); 61 return sys_select(a.n, a.inp, a.outp, a.exp, a.tvp);
62} 62}
63 63
64/* The i386 version skips reading from %esi, the fourth argument. So we must do 64/*
65 * this, too. 65 * The prototype on i386 is:
66 *
67 * int clone(int flags, void * child_stack, int * parent_tidptr, struct user_desc * newtls, int * child_tidptr)
68 *
69 * and the "newtls" arg. on i386 is read by copy_thread directly from the
70 * register saved on the stack.
66 */ 71 */
67long sys_clone(unsigned long clone_flags, unsigned long newsp, 72long sys_clone(unsigned long clone_flags, unsigned long newsp,
68 int __user *parent_tid, int unused, int __user *child_tid) 73 int __user *parent_tid, void *newtls, int __user *child_tid)
69{ 74{
70 long ret; 75 long ret;
71 76
72 if (!newsp) 77 if (!newsp)
73 newsp = UPT_SP(&current->thread.regs.regs); 78 newsp = UPT_SP(&current->thread.regs.regs);
79
74 current->thread.forking = 1; 80 current->thread.forking = 1;
75 ret = do_fork(clone_flags, newsp, &current->thread.regs, 0, parent_tid, 81 ret = do_fork(clone_flags, newsp, &current->thread.regs, 0, parent_tid,
76 child_tid); 82 child_tid);
77 current->thread.forking = 0; 83 current->thread.forking = 0;
78 return(ret); 84 return ret;
79} 85}
80 86
81/* 87/*
@@ -104,7 +110,7 @@ long sys_ipc (uint call, int first, int second,
104 union semun fourth; 110 union semun fourth;
105 if (!ptr) 111 if (!ptr)
106 return -EINVAL; 112 return -EINVAL;
107 if (get_user(fourth.__pad, (void **) ptr)) 113 if (get_user(fourth.__pad, (void __user * __user *) ptr))
108 return -EFAULT; 114 return -EFAULT;
109 return sys_semctl (first, second, third, fourth); 115 return sys_semctl (first, second, third, fourth);
110 } 116 }
diff --git a/arch/um/sys-i386/tls.c b/arch/um/sys-i386/tls.c
new file mode 100644
index 000000000000..a3188e861cc7
--- /dev/null
+++ b/arch/um/sys-i386/tls.c
@@ -0,0 +1,384 @@
1/*
2 * Copyright (C) 2005 Paolo 'Blaisorblade' Giarrusso <blaisorblade@yahoo.it>
3 * Licensed under the GPL
4 */
5
6#include "linux/config.h"
7#include "linux/kernel.h"
8#include "linux/sched.h"
9#include "linux/slab.h"
10#include "linux/types.h"
11#include "asm/uaccess.h"
12#include "asm/ptrace.h"
13#include "asm/segment.h"
14#include "asm/smp.h"
15#include "asm/desc.h"
16#include "choose-mode.h"
17#include "kern.h"
18#include "kern_util.h"
19#include "mode_kern.h"
20#include "os.h"
21#include "mode.h"
22
23#ifdef CONFIG_MODE_SKAS
24#include "skas.h"
25#endif
26
27/* If needed we can detect when it's uninitialized. */
28static int host_supports_tls = -1;
29int host_gdt_entry_tls_min = -1;
30
31#ifdef CONFIG_MODE_SKAS
32int do_set_thread_area_skas(struct user_desc *info)
33{
34 int ret;
35 u32 cpu;
36
37 cpu = get_cpu();
38 ret = os_set_thread_area(info, userspace_pid[cpu]);
39 put_cpu();
40 return ret;
41}
42
43int do_get_thread_area_skas(struct user_desc *info)
44{
45 int ret;
46 u32 cpu;
47
48 cpu = get_cpu();
49 ret = os_get_thread_area(info, userspace_pid[cpu]);
50 put_cpu();
51 return ret;
52}
53#endif
54
55/*
56 * sys_get_thread_area: get a yet unused TLS descriptor index.
57 * XXX: Consider leaving one free slot for glibc usage at first place. This must
58 * be done here (and by changing GDT_ENTRY_TLS_* macros) and nowhere else.
59 *
60 * Also, this must be tested when compiling in SKAS mode with dinamic linking
61 * and running against NPTL.
62 */
63static int get_free_idx(struct task_struct* task)
64{
65 struct thread_struct *t = &task->thread;
66 int idx;
67
68 if (!t->arch.tls_array)
69 return GDT_ENTRY_TLS_MIN;
70
71 for (idx = 0; idx < GDT_ENTRY_TLS_ENTRIES; idx++)
72 if (!t->arch.tls_array[idx].present)
73 return idx + GDT_ENTRY_TLS_MIN;
74 return -ESRCH;
75}
76
77static inline void clear_user_desc(struct user_desc* info)
78{
79 /* Postcondition: LDT_empty(info) returns true. */
80 memset(info, 0, sizeof(*info));
81
82 /* Check the LDT_empty or the i386 sys_get_thread_area code - we obtain
83 * indeed an empty user_desc.
84 */
85 info->read_exec_only = 1;
86 info->seg_not_present = 1;
87}
88
89#define O_FORCE 1
90
91static int load_TLS(int flags, struct task_struct *to)
92{
93 int ret = 0;
94 int idx;
95
96 for (idx = GDT_ENTRY_TLS_MIN; idx < GDT_ENTRY_TLS_MAX; idx++) {
97 struct uml_tls_struct* curr = &to->thread.arch.tls_array[idx - GDT_ENTRY_TLS_MIN];
98
99 /* Actually, now if it wasn't flushed it gets cleared and
100 * flushed to the host, which will clear it.*/
101 if (!curr->present) {
102 if (!curr->flushed) {
103 clear_user_desc(&curr->tls);
104 curr->tls.entry_number = idx;
105 } else {
106 WARN_ON(!LDT_empty(&curr->tls));
107 continue;
108 }
109 }
110
111 if (!(flags & O_FORCE) && curr->flushed)
112 continue;
113
114 ret = do_set_thread_area(&curr->tls);
115 if (ret)
116 goto out;
117
118 curr->flushed = 1;
119 }
120out:
121 return ret;
122}
123
124/* Verify if we need to do a flush for the new process, i.e. if there are any
125 * present desc's, only if they haven't been flushed.
126 */
127static inline int needs_TLS_update(struct task_struct *task)
128{
129 int i;
130 int ret = 0;
131
132 for (i = GDT_ENTRY_TLS_MIN; i < GDT_ENTRY_TLS_MAX; i++) {
133 struct uml_tls_struct* curr = &task->thread.arch.tls_array[i - GDT_ENTRY_TLS_MIN];
134
135 /* Can't test curr->present, we may need to clear a descriptor
136 * which had a value. */
137 if (curr->flushed)
138 continue;
139 ret = 1;
140 break;
141 }
142 return ret;
143}
144
145/* On a newly forked process, the TLS descriptors haven't yet been flushed. So
146 * we mark them as such and the first switch_to will do the job.
147 */
148void clear_flushed_tls(struct task_struct *task)
149{
150 int i;
151
152 for (i = GDT_ENTRY_TLS_MIN; i < GDT_ENTRY_TLS_MAX; i++) {
153 struct uml_tls_struct* curr = &task->thread.arch.tls_array[i - GDT_ENTRY_TLS_MIN];
154
155 /* Still correct to do this, if it wasn't present on the host it
156 * will remain as flushed as it was. */
157 if (!curr->present)
158 continue;
159
160 curr->flushed = 0;
161 }
162}
163
164/* In SKAS0 mode, currently, multiple guest threads sharing the same ->mm have a
165 * common host process. So this is needed in SKAS0 too.
166 *
167 * However, if each thread had a different host process (and this was discussed
168 * for SMP support) this won't be needed.
169 *
170 * And this will not need be used when (and if) we'll add support to the host
171 * SKAS patch. */
172
173int arch_switch_tls_skas(struct task_struct *from, struct task_struct *to)
174{
175 if (!host_supports_tls)
176 return 0;
177
178 /* We have no need whatsoever to switch TLS for kernel threads; beyond
179 * that, that would also result in us calling os_set_thread_area with
180 * userspace_pid[cpu] == 0, which gives an error. */
181 if (likely(to->mm))
182 return load_TLS(O_FORCE, to);
183
184 return 0;
185}
186
187int arch_switch_tls_tt(struct task_struct *from, struct task_struct *to)
188{
189 if (!host_supports_tls)
190 return 0;
191
192 if (needs_TLS_update(to))
193 return load_TLS(0, to);
194
195 return 0;
196}
197
198static int set_tls_entry(struct task_struct* task, struct user_desc *info,
199 int idx, int flushed)
200{
201 struct thread_struct *t = &task->thread;
202
203 if (idx < GDT_ENTRY_TLS_MIN || idx > GDT_ENTRY_TLS_MAX)
204 return -EINVAL;
205
206 t->arch.tls_array[idx - GDT_ENTRY_TLS_MIN].tls = *info;
207 t->arch.tls_array[idx - GDT_ENTRY_TLS_MIN].present = 1;
208 t->arch.tls_array[idx - GDT_ENTRY_TLS_MIN].flushed = flushed;
209
210 return 0;
211}
212
213int arch_copy_tls(struct task_struct *new)
214{
215 struct user_desc info;
216 int idx, ret = -EFAULT;
217
218 if (copy_from_user(&info,
219 (void __user *) UPT_ESI(&new->thread.regs.regs),
220 sizeof(info)))
221 goto out;
222
223 ret = -EINVAL;
224 if (LDT_empty(&info))
225 goto out;
226
227 idx = info.entry_number;
228
229 ret = set_tls_entry(new, &info, idx, 0);
230out:
231 return ret;
232}
233
234/* XXX: use do_get_thread_area to read the host value? I'm not at all sure! */
235static int get_tls_entry(struct task_struct* task, struct user_desc *info, int idx)
236{
237 struct thread_struct *t = &task->thread;
238
239 if (!t->arch.tls_array)
240 goto clear;
241
242 if (idx < GDT_ENTRY_TLS_MIN || idx > GDT_ENTRY_TLS_MAX)
243 return -EINVAL;
244
245 if (!t->arch.tls_array[idx - GDT_ENTRY_TLS_MIN].present)
246 goto clear;
247
248 *info = t->arch.tls_array[idx - GDT_ENTRY_TLS_MIN].tls;
249
250out:
251 /* Temporary debugging check, to make sure that things have been
252 * flushed. This could be triggered if load_TLS() failed.
253 */
254 if (unlikely(task == current && !t->arch.tls_array[idx - GDT_ENTRY_TLS_MIN].flushed)) {
255 printk(KERN_ERR "get_tls_entry: task with pid %d got here "
256 "without flushed TLS.", current->pid);
257 }
258
259 return 0;
260clear:
261 /* When the TLS entry has not been set, the values read to user in the
262 * tls_array are 0 (because it's cleared at boot, see
263 * arch/i386/kernel/head.S:cpu_gdt_table). Emulate that.
264 */
265 clear_user_desc(info);
266 info->entry_number = idx;
267 goto out;
268}
269
270asmlinkage int sys_set_thread_area(struct user_desc __user *user_desc)
271{
272 struct user_desc info;
273 int idx, ret;
274
275 if (!host_supports_tls)
276 return -ENOSYS;
277
278 if (copy_from_user(&info, user_desc, sizeof(info)))
279 return -EFAULT;
280
281 idx = info.entry_number;
282
283 if (idx == -1) {
284 idx = get_free_idx(current);
285 if (idx < 0)
286 return idx;
287 info.entry_number = idx;
288 /* Tell the user which slot we chose for him.*/
289 if (put_user(idx, &user_desc->entry_number))
290 return -EFAULT;
291 }
292
293 ret = CHOOSE_MODE_PROC(do_set_thread_area_tt, do_set_thread_area_skas, &info);
294 if (ret)
295 return ret;
296 return set_tls_entry(current, &info, idx, 1);
297}
298
299/*
300 * Perform set_thread_area on behalf of the traced child.
301 * Note: error handling is not done on the deferred load, and this differ from
302 * i386. However the only possible error are caused by bugs.
303 */
304int ptrace_set_thread_area(struct task_struct *child, int idx,
305 struct user_desc __user *user_desc)
306{
307 struct user_desc info;
308
309 if (!host_supports_tls)
310 return -EIO;
311
312 if (copy_from_user(&info, user_desc, sizeof(info)))
313 return -EFAULT;
314
315 return set_tls_entry(child, &info, idx, 0);
316}
317
318asmlinkage int sys_get_thread_area(struct user_desc __user *user_desc)
319{
320 struct user_desc info;
321 int idx, ret;
322
323 if (!host_supports_tls)
324 return -ENOSYS;
325
326 if (get_user(idx, &user_desc->entry_number))
327 return -EFAULT;
328
329 ret = get_tls_entry(current, &info, idx);
330 if (ret < 0)
331 goto out;
332
333 if (copy_to_user(user_desc, &info, sizeof(info)))
334 ret = -EFAULT;
335
336out:
337 return ret;
338}
339
340/*
341 * Perform get_thread_area on behalf of the traced child.
342 */
343int ptrace_get_thread_area(struct task_struct *child, int idx,
344 struct user_desc __user *user_desc)
345{
346 struct user_desc info;
347 int ret;
348
349 if (!host_supports_tls)
350 return -EIO;
351
352 ret = get_tls_entry(child, &info, idx);
353 if (ret < 0)
354 goto out;
355
356 if (copy_to_user(user_desc, &info, sizeof(info)))
357 ret = -EFAULT;
358out:
359 return ret;
360}
361
362
363/* XXX: This part is probably common to i386 and x86-64. Don't create a common
364 * file for now, do that when implementing x86-64 support.*/
365static int __init __setup_host_supports_tls(void) {
366 check_host_supports_tls(&host_supports_tls, &host_gdt_entry_tls_min);
367 if (host_supports_tls) {
368 printk(KERN_INFO "Host TLS support detected\n");
369 printk(KERN_INFO "Detected host type: ");
370 switch (host_gdt_entry_tls_min) {
371 case GDT_ENTRY_TLS_MIN_I386:
372 printk("i386\n");
373 break;
374 case GDT_ENTRY_TLS_MIN_X86_64:
375 printk("x86_64\n");
376 break;
377 }
378 } else
379 printk(KERN_ERR " Host TLS support NOT detected! "
380 "TLS support inside UML will not work\n");
381 return 1;
382}
383
384__initcall(__setup_host_supports_tls);
diff --git a/arch/um/sys-x86_64/Makefile b/arch/um/sys-x86_64/Makefile
index a351091fbd99..b5fc22babddf 100644
--- a/arch/um/sys-x86_64/Makefile
+++ b/arch/um/sys-x86_64/Makefile
@@ -4,31 +4,23 @@
4# Licensed under the GPL 4# Licensed under the GPL
5# 5#
6 6
7#XXX: why into lib-y? 7obj-y = bugs.o delay.o fault.o ldt.o mem.o ptrace.o ptrace_user.o \
8lib-y = bitops.o bugs.o csum-partial.o delay.o fault.o ldt.o mem.o memcpy.o \ 8 sigcontext.o signal.o syscalls.o syscall_table.o sysrq.o ksyms.o \
9 ptrace.o ptrace_user.o sigcontext.o signal.o syscalls.o \ 9 tls.o
10 syscall_table.o sysrq.o thunk.o
11lib-$(CONFIG_MODE_SKAS) += stub.o stub_segv.o
12 10
13obj-y := ksyms.o 11obj-$(CONFIG_MODE_SKAS) += stub.o stub_segv.o
14obj-$(CONFIG_MODULES) += module.o um_module.o 12obj-$(CONFIG_MODULES) += um_module.o
15 13
16USER_OBJS := ptrace_user.o sigcontext.o stub_segv.o 14subarch-obj-y = lib/bitops.o lib/csum-partial.o lib/memcpy.o lib/thunk.o
15subarch-obj-$(CONFIG_MODULES) += kernel/module.o
17 16
18SYMLINKS = bitops.c csum-copy.S csum-partial.c csum-wrappers.c ldt.c memcpy.S \ 17ldt-y = ../sys-i386/ldt.o
19 thunk.S module.c
20 18
21include arch/um/scripts/Makefile.rules 19USER_OBJS := ptrace_user.o sigcontext.o stub_segv.o
22 20
23bitops.c-dir = lib 21include arch/um/scripts/Makefile.rules
24csum-copy.S-dir = lib
25csum-partial.c-dir = lib
26csum-wrappers.c-dir = lib
27ldt.c-dir = /arch/um/sys-i386
28memcpy.S-dir = lib
29thunk.S-dir = lib
30module.c-dir = kernel
31 22
32$(obj)/stub_segv.o: _c_flags = $(call unprofile,$(CFLAGS)) 23extra-$(CONFIG_MODE_TT) += unmap.o
33 24
34include arch/um/scripts/Makefile.unmap 25$(obj)/stub_segv.o $(obj)/unmap.o: \
26 _c_flags = $(call unprofile,$(CFLAGS))
diff --git a/arch/um/sys-x86_64/tls.c b/arch/um/sys-x86_64/tls.c
new file mode 100644
index 000000000000..ce1bf1b81c43
--- /dev/null
+++ b/arch/um/sys-x86_64/tls.c
@@ -0,0 +1,14 @@
1#include "linux/sched.h"
2
3void debug_arch_force_load_TLS(void)
4{
5}
6
7void clear_flushed_tls(struct task_struct *task)
8{
9}
10
11int arch_copy_tls(struct task_struct *t)
12{
13 return 0;
14}
diff --git a/arch/x86_64/ia32/vsyscall-sigreturn.S b/arch/x86_64/ia32/vsyscall-sigreturn.S
index d90321fe9bba..1384367cdbe1 100644
--- a/arch/x86_64/ia32/vsyscall-sigreturn.S
+++ b/arch/x86_64/ia32/vsyscall-sigreturn.S
@@ -32,9 +32,28 @@ __kernel_rt_sigreturn:
32 .size __kernel_rt_sigreturn,.-.LSTART_rt_sigreturn 32 .size __kernel_rt_sigreturn,.-.LSTART_rt_sigreturn
33 33
34 .section .eh_frame,"a",@progbits 34 .section .eh_frame,"a",@progbits
35.LSTARTFRAMES:
36 .long .LENDCIES-.LSTARTCIES
37.LSTARTCIES:
38 .long 0 /* CIE ID */
39 .byte 1 /* Version number */
40 .string "zRS" /* NUL-terminated augmentation string */
41 .uleb128 1 /* Code alignment factor */
42 .sleb128 -4 /* Data alignment factor */
43 .byte 8 /* Return address register column */
44 .uleb128 1 /* Augmentation value length */
45 .byte 0x1b /* DW_EH_PE_pcrel|DW_EH_PE_sdata4. */
46 .byte 0x0c /* DW_CFA_def_cfa */
47 .uleb128 4
48 .uleb128 4
49 .byte 0x88 /* DW_CFA_offset, column 0x8 */
50 .uleb128 1
51 .align 4
52.LENDCIES:
53
35 .long .LENDFDE2-.LSTARTFDE2 /* Length FDE */ 54 .long .LENDFDE2-.LSTARTFDE2 /* Length FDE */
36.LSTARTFDE2: 55.LSTARTFDE2:
37 .long .LSTARTFDE2-.LSTARTFRAME /* CIE pointer */ 56 .long .LSTARTFDE2-.LSTARTFRAMES /* CIE pointer */
38 /* HACK: The dwarf2 unwind routines will subtract 1 from the 57 /* HACK: The dwarf2 unwind routines will subtract 1 from the
39 return address to get an address in the middle of the 58 return address to get an address in the middle of the
40 presumed call instruction. Since we didn't get here via 59 presumed call instruction. Since we didn't get here via
@@ -97,7 +116,7 @@ __kernel_rt_sigreturn:
97 116
98 .long .LENDFDE3-.LSTARTFDE3 /* Length FDE */ 117 .long .LENDFDE3-.LSTARTFDE3 /* Length FDE */
99.LSTARTFDE3: 118.LSTARTFDE3:
100 .long .LSTARTFDE3-.LSTARTFRAME /* CIE pointer */ 119 .long .LSTARTFDE3-.LSTARTFRAMES /* CIE pointer */
101 /* HACK: See above wrt unwind library assumptions. */ 120 /* HACK: See above wrt unwind library assumptions. */
102 .long .LSTART_rt_sigreturn-1-. /* PC-relative start address */ 121 .long .LSTART_rt_sigreturn-1-. /* PC-relative start address */
103 .long .LEND_rt_sigreturn-.LSTART_rt_sigreturn+1 122 .long .LEND_rt_sigreturn-.LSTART_rt_sigreturn+1
diff --git a/arch/x86_64/kernel/apic.c b/arch/x86_64/kernel/apic.c
index d54620147e8e..100a30c40044 100644
--- a/arch/x86_64/kernel/apic.c
+++ b/arch/x86_64/kernel/apic.c
@@ -615,7 +615,7 @@ static int __init apic_set_verbosity(char *str)
615 printk(KERN_WARNING "APIC Verbosity level %s not recognised" 615 printk(KERN_WARNING "APIC Verbosity level %s not recognised"
616 " use apic=verbose or apic=debug", str); 616 " use apic=verbose or apic=debug", str);
617 617
618 return 0; 618 return 1;
619} 619}
620 620
621__setup("apic=", apic_set_verbosity); 621__setup("apic=", apic_set_verbosity);
@@ -1137,35 +1137,35 @@ int __init APIC_init_uniprocessor (void)
1137static __init int setup_disableapic(char *str) 1137static __init int setup_disableapic(char *str)
1138{ 1138{
1139 disable_apic = 1; 1139 disable_apic = 1;
1140 return 0; 1140 return 1;
1141} 1141}
1142 1142
1143static __init int setup_nolapic(char *str) 1143static __init int setup_nolapic(char *str)
1144{ 1144{
1145 disable_apic = 1; 1145 disable_apic = 1;
1146 return 0; 1146 return 1;
1147} 1147}
1148 1148
1149static __init int setup_noapictimer(char *str) 1149static __init int setup_noapictimer(char *str)
1150{ 1150{
1151 if (str[0] != ' ' && str[0] != 0) 1151 if (str[0] != ' ' && str[0] != 0)
1152 return -1; 1152 return 0;
1153 disable_apic_timer = 1; 1153 disable_apic_timer = 1;
1154 return 0; 1154 return 1;
1155} 1155}
1156 1156
1157static __init int setup_apicmaintimer(char *str) 1157static __init int setup_apicmaintimer(char *str)
1158{ 1158{
1159 apic_runs_main_timer = 1; 1159 apic_runs_main_timer = 1;
1160 nohpet = 1; 1160 nohpet = 1;
1161 return 0; 1161 return 1;
1162} 1162}
1163__setup("apicmaintimer", setup_apicmaintimer); 1163__setup("apicmaintimer", setup_apicmaintimer);
1164 1164
1165static __init int setup_noapicmaintimer(char *str) 1165static __init int setup_noapicmaintimer(char *str)
1166{ 1166{
1167 apic_runs_main_timer = -1; 1167 apic_runs_main_timer = -1;
1168 return 0; 1168 return 1;
1169} 1169}
1170__setup("noapicmaintimer", setup_noapicmaintimer); 1170__setup("noapicmaintimer", setup_noapicmaintimer);
1171 1171
diff --git a/arch/x86_64/kernel/early_printk.c b/arch/x86_64/kernel/early_printk.c
index 13af920b6594..b93ef5b51980 100644
--- a/arch/x86_64/kernel/early_printk.c
+++ b/arch/x86_64/kernel/early_printk.c
@@ -221,7 +221,7 @@ int __init setup_early_printk(char *opt)
221 char buf[256]; 221 char buf[256];
222 222
223 if (early_console_initialized) 223 if (early_console_initialized)
224 return -1; 224 return 1;
225 225
226 strlcpy(buf,opt,sizeof(buf)); 226 strlcpy(buf,opt,sizeof(buf));
227 space = strchr(buf, ' '); 227 space = strchr(buf, ' ');
diff --git a/arch/x86_64/kernel/mce.c b/arch/x86_64/kernel/mce.c
index 04282ef9fbd4..10b3e348fc99 100644
--- a/arch/x86_64/kernel/mce.c
+++ b/arch/x86_64/kernel/mce.c
@@ -501,7 +501,7 @@ static struct miscdevice mce_log_device = {
501static int __init mcheck_disable(char *str) 501static int __init mcheck_disable(char *str)
502{ 502{
503 mce_dont_init = 1; 503 mce_dont_init = 1;
504 return 0; 504 return 1;
505} 505}
506 506
507/* mce=off disables machine check. Note you can reenable it later 507/* mce=off disables machine check. Note you can reenable it later
@@ -521,7 +521,7 @@ static int __init mcheck_enable(char *str)
521 get_option(&str, &tolerant); 521 get_option(&str, &tolerant);
522 else 522 else
523 printk("mce= argument %s ignored. Please use /sys", str); 523 printk("mce= argument %s ignored. Please use /sys", str);
524 return 0; 524 return 1;
525} 525}
526 526
527__setup("nomce", mcheck_disable); 527__setup("nomce", mcheck_disable);
diff --git a/arch/x86_64/kernel/pmtimer.c b/arch/x86_64/kernel/pmtimer.c
index ee5ee4891f3d..b0444a415bd6 100644
--- a/arch/x86_64/kernel/pmtimer.c
+++ b/arch/x86_64/kernel/pmtimer.c
@@ -121,7 +121,7 @@ unsigned int do_gettimeoffset_pm(void)
121static int __init nopmtimer_setup(char *s) 121static int __init nopmtimer_setup(char *s)
122{ 122{
123 pmtmr_ioport = 0; 123 pmtmr_ioport = 0;
124 return 0; 124 return 1;
125} 125}
126 126
127__setup("nopmtimer", nopmtimer_setup); 127__setup("nopmtimer", nopmtimer_setup);
diff --git a/arch/x86_64/kernel/setup.c b/arch/x86_64/kernel/setup.c
index d1f3e9272c05..0856ad444f90 100644
--- a/arch/x86_64/kernel/setup.c
+++ b/arch/x86_64/kernel/setup.c
@@ -540,7 +540,7 @@ void __init alternative_instructions(void)
540static int __init noreplacement_setup(char *s) 540static int __init noreplacement_setup(char *s)
541{ 541{
542 no_replacement = 1; 542 no_replacement = 1;
543 return 0; 543 return 1;
544} 544}
545 545
546__setup("noreplacement", noreplacement_setup); 546__setup("noreplacement", noreplacement_setup);
diff --git a/arch/x86_64/kernel/setup64.c b/arch/x86_64/kernel/setup64.c
index eabdb63fec31..8a691fa6d393 100644
--- a/arch/x86_64/kernel/setup64.c
+++ b/arch/x86_64/kernel/setup64.c
@@ -55,7 +55,7 @@ int __init nonx_setup(char *str)
55 do_not_nx = 1; 55 do_not_nx = 1;
56 __supported_pte_mask &= ~_PAGE_NX; 56 __supported_pte_mask &= ~_PAGE_NX;
57 } 57 }
58 return 0; 58 return 1;
59} 59}
60__setup("noexec=", nonx_setup); /* parsed early actually */ 60__setup("noexec=", nonx_setup); /* parsed early actually */
61 61
@@ -74,7 +74,7 @@ static int __init nonx32_setup(char *str)
74 force_personality32 &= ~READ_IMPLIES_EXEC; 74 force_personality32 &= ~READ_IMPLIES_EXEC;
75 else if (!strcmp(str, "off")) 75 else if (!strcmp(str, "off"))
76 force_personality32 |= READ_IMPLIES_EXEC; 76 force_personality32 |= READ_IMPLIES_EXEC;
77 return 0; 77 return 1;
78} 78}
79__setup("noexec32=", nonx32_setup); 79__setup("noexec32=", nonx32_setup);
80 80
diff --git a/arch/x86_64/kernel/smpboot.c b/arch/x86_64/kernel/smpboot.c
index ea48fa638070..71a7222cf9ce 100644
--- a/arch/x86_64/kernel/smpboot.c
+++ b/arch/x86_64/kernel/smpboot.c
@@ -353,7 +353,7 @@ static void __cpuinit tsc_sync_wait(void)
353static __init int notscsync_setup(char *s) 353static __init int notscsync_setup(char *s)
354{ 354{
355 notscsync = 1; 355 notscsync = 1;
356 return 0; 356 return 1;
357} 357}
358__setup("notscsync", notscsync_setup); 358__setup("notscsync", notscsync_setup);
359 359
diff --git a/arch/x86_64/kernel/time.c b/arch/x86_64/kernel/time.c
index 473b514b66e4..ef8bc46dc140 100644
--- a/arch/x86_64/kernel/time.c
+++ b/arch/x86_64/kernel/time.c
@@ -1306,7 +1306,7 @@ irqreturn_t hpet_rtc_interrupt(int irq, void *dev_id, struct pt_regs *regs)
1306static int __init nohpet_setup(char *s) 1306static int __init nohpet_setup(char *s)
1307{ 1307{
1308 nohpet = 1; 1308 nohpet = 1;
1309 return 0; 1309 return 1;
1310} 1310}
1311 1311
1312__setup("nohpet", nohpet_setup); 1312__setup("nohpet", nohpet_setup);
@@ -1314,7 +1314,7 @@ __setup("nohpet", nohpet_setup);
1314int __init notsc_setup(char *s) 1314int __init notsc_setup(char *s)
1315{ 1315{
1316 notsc = 1; 1316 notsc = 1;
1317 return 0; 1317 return 1;
1318} 1318}
1319 1319
1320__setup("notsc", notsc_setup); 1320__setup("notsc", notsc_setup);
diff --git a/arch/x86_64/kernel/traps.c b/arch/x86_64/kernel/traps.c
index edaa9fe654dc..6bda322d3caf 100644
--- a/arch/x86_64/kernel/traps.c
+++ b/arch/x86_64/kernel/traps.c
@@ -973,14 +973,14 @@ void __init trap_init(void)
973static int __init oops_dummy(char *s) 973static int __init oops_dummy(char *s)
974{ 974{
975 panic_on_oops = 1; 975 panic_on_oops = 1;
976 return -1; 976 return 1;
977} 977}
978__setup("oops=", oops_dummy); 978__setup("oops=", oops_dummy);
979 979
980static int __init kstack_setup(char *s) 980static int __init kstack_setup(char *s)
981{ 981{
982 kstack_depth_to_print = simple_strtoul(s,NULL,0); 982 kstack_depth_to_print = simple_strtoul(s,NULL,0);
983 return 0; 983 return 1;
984} 984}
985__setup("kstack=", kstack_setup); 985__setup("kstack=", kstack_setup);
986 986
diff --git a/arch/x86_64/kernel/x8664_ksyms.c b/arch/x86_64/kernel/x8664_ksyms.c
index d96a9348e5a2..d78f46056bda 100644
--- a/arch/x86_64/kernel/x8664_ksyms.c
+++ b/arch/x86_64/kernel/x8664_ksyms.c
@@ -102,8 +102,6 @@ EXPORT_SYMBOL(cpu_callout_map);
102EXPORT_SYMBOL(screen_info); 102EXPORT_SYMBOL(screen_info);
103#endif 103#endif
104 104
105EXPORT_SYMBOL(get_wchan);
106
107EXPORT_SYMBOL(rtc_lock); 105EXPORT_SYMBOL(rtc_lock);
108 106
109EXPORT_SYMBOL_GPL(set_nmi_callback); 107EXPORT_SYMBOL_GPL(set_nmi_callback);
diff --git a/arch/x86_64/mm/fault.c b/arch/x86_64/mm/fault.c
index 316c53de47bd..55250593d8c9 100644
--- a/arch/x86_64/mm/fault.c
+++ b/arch/x86_64/mm/fault.c
@@ -623,6 +623,6 @@ void vmalloc_sync_all(void)
623static int __init enable_pagefaulttrace(char *str) 623static int __init enable_pagefaulttrace(char *str)
624{ 624{
625 page_fault_trace = 1; 625 page_fault_trace = 1;
626 return 0; 626 return 1;
627} 627}
628__setup("pagefaulttrace", enable_pagefaulttrace); 628__setup("pagefaulttrace", enable_pagefaulttrace);
diff --git a/arch/xtensa/kernel/xtensa_ksyms.c b/arch/xtensa/kernel/xtensa_ksyms.c
index efae56a51475..152b9370789b 100644
--- a/arch/xtensa/kernel/xtensa_ksyms.c
+++ b/arch/xtensa/kernel/xtensa_ksyms.c
@@ -113,8 +113,6 @@ EXPORT_SYMBOL(__xtensa_copy_user);
113// FIXME EXPORT_SYMBOL(screen_info); 113// FIXME EXPORT_SYMBOL(screen_info);
114#endif 114#endif
115 115
116EXPORT_SYMBOL(get_wchan);
117
118EXPORT_SYMBOL(outsb); 116EXPORT_SYMBOL(outsb);
119EXPORT_SYMBOL(outsw); 117EXPORT_SYMBOL(outsw);
120EXPORT_SYMBOL(outsl); 118EXPORT_SYMBOL(outsl);
diff --git a/block/Kconfig b/block/Kconfig
index 5536839886ff..b6f5f0a79655 100644
--- a/block/Kconfig
+++ b/block/Kconfig
@@ -27,10 +27,10 @@ config BLK_DEV_IO_TRACE
27config LSF 27config LSF
28 bool "Support for Large Single Files" 28 bool "Support for Large Single Files"
29 depends on X86 || (MIPS && 32BIT) || PPC32 || ARCH_S390_31 || SUPERH || UML 29 depends on X86 || (MIPS && 32BIT) || PPC32 || ARCH_S390_31 || SUPERH || UML
30 default n
31 help 30 help
32 When CONFIG_LBD is disabled, say Y here if you want to 31 Say Y here if you want to be able to handle very large files (bigger
33 handle large file(bigger than 2TB), otherwise say N. 32 than 2TB), otherwise say N.
34 When CONFIG_LBD is enabled, Y is set automatically. 33
34 If unsure, say Y.
35 35
36source block/Kconfig.iosched 36source block/Kconfig.iosched
diff --git a/block/elevator.c b/block/elevator.c
index 56c2ed06a9e2..0d6be03d929e 100644
--- a/block/elevator.c
+++ b/block/elevator.c
@@ -145,7 +145,7 @@ static int __init elevator_setup(char *str)
145 strcpy(chosen_elevator, "anticipatory"); 145 strcpy(chosen_elevator, "anticipatory");
146 else 146 else
147 strncpy(chosen_elevator, str, sizeof(chosen_elevator) - 1); 147 strncpy(chosen_elevator, str, sizeof(chosen_elevator) - 1);
148 return 0; 148 return 1;
149} 149}
150 150
151__setup("elevator=", elevator_setup); 151__setup("elevator=", elevator_setup);
diff --git a/block/genhd.c b/block/genhd.c
index db4c60c802d6..5a8d3bf02f17 100644
--- a/block/genhd.c
+++ b/block/genhd.c
@@ -17,8 +17,6 @@
17#include <linux/buffer_head.h> 17#include <linux/buffer_head.h>
18#include <linux/mutex.h> 18#include <linux/mutex.h>
19 19
20#define MAX_PROBE_HASH 255 /* random */
21
22static struct subsystem block_subsys; 20static struct subsystem block_subsys;
23 21
24static DEFINE_MUTEX(block_subsys_lock); 22static DEFINE_MUTEX(block_subsys_lock);
@@ -31,108 +29,29 @@ static struct blk_major_name {
31 struct blk_major_name *next; 29 struct blk_major_name *next;
32 int major; 30 int major;
33 char name[16]; 31 char name[16];
34} *major_names[MAX_PROBE_HASH]; 32} *major_names[BLKDEV_MAJOR_HASH_SIZE];
35 33
36/* index in the above - for now: assume no multimajor ranges */ 34/* index in the above - for now: assume no multimajor ranges */
37static inline int major_to_index(int major) 35static inline int major_to_index(int major)
38{ 36{
39 return major % MAX_PROBE_HASH; 37 return major % BLKDEV_MAJOR_HASH_SIZE;
40}
41
42struct blkdev_info {
43 int index;
44 struct blk_major_name *bd;
45};
46
47/*
48 * iterate over a list of blkdev_info structures. allows
49 * the major_names array to be iterated over from outside this file
50 * must be called with the block_subsys_lock held
51 */
52void *get_next_blkdev(void *dev)
53{
54 struct blkdev_info *info;
55
56 if (dev == NULL) {
57 info = kmalloc(sizeof(*info), GFP_KERNEL);
58 if (!info)
59 goto out;
60 info->index=0;
61 info->bd = major_names[info->index];
62 if (info->bd)
63 goto out;
64 } else {
65 info = dev;
66 }
67
68 while (info->index < ARRAY_SIZE(major_names)) {
69 if (info->bd)
70 info->bd = info->bd->next;
71 if (info->bd)
72 goto out;
73 /*
74 * No devices on this chain, move to the next
75 */
76 info->index++;
77 info->bd = (info->index < ARRAY_SIZE(major_names)) ?
78 major_names[info->index] : NULL;
79 if (info->bd)
80 goto out;
81 }
82
83out:
84 return info;
85}
86
87void *acquire_blkdev_list(void)
88{
89 mutex_lock(&block_subsys_lock);
90 return get_next_blkdev(NULL);
91}
92
93void release_blkdev_list(void *dev)
94{
95 mutex_unlock(&block_subsys_lock);
96 kfree(dev);
97} 38}
98 39
40#ifdef CONFIG_PROC_FS
99 41
100/* 42void blkdev_show(struct seq_file *f, off_t offset)
101 * Count the number of records in the blkdev_list.
102 * must be called with the block_subsys_lock held
103 */
104int count_blkdev_list(void)
105{ 43{
106 struct blk_major_name *n; 44 struct blk_major_name *dp;
107 int i, count;
108 45
109 count = 0; 46 if (offset < BLKDEV_MAJOR_HASH_SIZE) {
110 47 mutex_lock(&block_subsys_lock);
111 for (i = 0; i < ARRAY_SIZE(major_names); i++) { 48 for (dp = major_names[offset]; dp; dp = dp->next)
112 for (n = major_names[i]; n; n = n->next) 49 seq_printf(f, "%3d %s\n", dp->major, dp->name);
113 count++; 50 mutex_unlock(&block_subsys_lock);
114 } 51 }
115
116 return count;
117}
118
119/*
120 * extract the major and name values from a blkdev_info struct
121 * passed in as a void to *dev. Must be called with
122 * block_subsys_lock held
123 */
124int get_blkdev_info(void *dev, int *major, char **name)
125{
126 struct blkdev_info *info = dev;
127
128 if (info->bd == NULL)
129 return 1;
130
131 *major = info->bd->major;
132 *name = info->bd->name;
133 return 0;
134} 52}
135 53
54#endif /* CONFIG_PROC_FS */
136 55
137int register_blkdev(unsigned int major, const char *name) 56int register_blkdev(unsigned int major, const char *name)
138{ 57{
diff --git a/drivers/Kconfig b/drivers/Kconfig
index 9f5c0da57c90..5c91d6afb117 100644
--- a/drivers/Kconfig
+++ b/drivers/Kconfig
@@ -64,6 +64,8 @@ source "drivers/usb/Kconfig"
64 64
65source "drivers/mmc/Kconfig" 65source "drivers/mmc/Kconfig"
66 66
67source "drivers/leds/Kconfig"
68
67source "drivers/infiniband/Kconfig" 69source "drivers/infiniband/Kconfig"
68 70
69source "drivers/sn/Kconfig" 71source "drivers/sn/Kconfig"
diff --git a/drivers/Makefile b/drivers/Makefile
index 424955274e60..d6e8ffbd8132 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -69,6 +69,7 @@ obj-$(CONFIG_MCA) += mca/
69obj-$(CONFIG_EISA) += eisa/ 69obj-$(CONFIG_EISA) += eisa/
70obj-$(CONFIG_CPU_FREQ) += cpufreq/ 70obj-$(CONFIG_CPU_FREQ) += cpufreq/
71obj-$(CONFIG_MMC) += mmc/ 71obj-$(CONFIG_MMC) += mmc/
72obj-$(CONFIG_NEW_LEDS) += leds/
72obj-$(CONFIG_INFINIBAND) += infiniband/ 73obj-$(CONFIG_INFINIBAND) += infiniband/
73obj-$(CONFIG_SGI_SN) += sn/ 74obj-$(CONFIG_SGI_SN) += sn/
74obj-y += firmware/ 75obj-y += firmware/
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
index 79b09d76c180..eee0864ba300 100644
--- a/drivers/acpi/ec.c
+++ b/drivers/acpi/ec.c
@@ -1572,7 +1572,7 @@ static void __exit acpi_ec_exit(void)
1572static int __init acpi_fake_ecdt_setup(char *str) 1572static int __init acpi_fake_ecdt_setup(char *str)
1573{ 1573{
1574 acpi_fake_ecdt_enabled = 1; 1574 acpi_fake_ecdt_enabled = 1;
1575 return 0; 1575 return 1;
1576} 1576}
1577 1577
1578__setup("acpi_fake_ecdt", acpi_fake_ecdt_setup); 1578__setup("acpi_fake_ecdt", acpi_fake_ecdt_setup);
@@ -1591,7 +1591,7 @@ static int __init acpi_ec_set_intr_mode(char *str)
1591 acpi_ec_driver.ops.add = acpi_ec_poll_add; 1591 acpi_ec_driver.ops.add = acpi_ec_poll_add;
1592 } 1592 }
1593 printk(KERN_INFO PREFIX "EC %s mode.\n", intr ? "interrupt" : "polling"); 1593 printk(KERN_INFO PREFIX "EC %s mode.\n", intr ? "interrupt" : "polling");
1594 return 0; 1594 return 1;
1595} 1595}
1596 1596
1597__setup("ec_intr=", acpi_ec_set_intr_mode); 1597__setup("ec_intr=", acpi_ec_set_intr_mode);
diff --git a/drivers/block/amiflop.c b/drivers/block/amiflop.c
index b6e290956214..2a8af685926f 100644
--- a/drivers/block/amiflop.c
+++ b/drivers/block/amiflop.c
@@ -1850,6 +1850,7 @@ static int __init amiga_floppy_setup (char *str)
1850 return 0; 1850 return 0;
1851 printk (KERN_INFO "amiflop: Setting default df0 to %x\n", n); 1851 printk (KERN_INFO "amiflop: Setting default df0 to %x\n", n);
1852 fd_def_df0 = n; 1852 fd_def_df0 = n;
1853 return 1;
1853} 1854}
1854 1855
1855__setup("floppy=", amiga_floppy_setup); 1856__setup("floppy=", amiga_floppy_setup);
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig
index 73d30bf01582..889cad07774e 100644
--- a/drivers/char/Kconfig
+++ b/drivers/char/Kconfig
@@ -561,14 +561,31 @@ config TIPAR
561 561
562 If unsure, say N. 562 If unsure, say N.
563 563
564config HVC_DRIVER
565 bool
566 help
567 Users of pSeries machines that want to utilize the hvc console front-end
568 module for their backend console driver should select this option.
569 It will automatically be selected if one of the back-end console drivers
570 is selected.
571
572
564config HVC_CONSOLE 573config HVC_CONSOLE
565 bool "pSeries Hypervisor Virtual Console support" 574 bool "pSeries Hypervisor Virtual Console support"
566 depends on PPC_PSERIES 575 depends on PPC_PSERIES
576 select HVC_DRIVER
567 help 577 help
568 pSeries machines when partitioned support a hypervisor virtual 578 pSeries machines when partitioned support a hypervisor virtual
569 console. This driver allows each pSeries partition to have a console 579 console. This driver allows each pSeries partition to have a console
570 which is accessed via the HMC. 580 which is accessed via the HMC.
571 581
582config HVC_RTAS
583 bool "IBM RTAS Console support"
584 depends on PPC_RTAS
585 select HVC_DRIVER
586 help
587 IBM Console device driver which makes use of RTAS
588
572config HVCS 589config HVCS
573 tristate "IBM Hypervisor Virtual Console Server support" 590 tristate "IBM Hypervisor Virtual Console Server support"
574 depends on PPC_PSERIES 591 depends on PPC_PSERIES
diff --git a/drivers/char/Makefile b/drivers/char/Makefile
index b2a11245fa95..a73cb4956928 100644
--- a/drivers/char/Makefile
+++ b/drivers/char/Makefile
@@ -41,7 +41,9 @@ obj-$(CONFIG_N_HDLC) += n_hdlc.o
41obj-$(CONFIG_AMIGA_BUILTIN_SERIAL) += amiserial.o 41obj-$(CONFIG_AMIGA_BUILTIN_SERIAL) += amiserial.o
42obj-$(CONFIG_SX) += sx.o generic_serial.o 42obj-$(CONFIG_SX) += sx.o generic_serial.o
43obj-$(CONFIG_RIO) += rio/ generic_serial.o 43obj-$(CONFIG_RIO) += rio/ generic_serial.o
44obj-$(CONFIG_HVC_CONSOLE) += hvc_console.o hvc_vio.o hvsi.o 44obj-$(CONFIG_HVC_DRIVER) += hvc_console.o
45obj-$(CONFIG_HVC_CONSOLE) += hvc_vio.o hvsi.o
46obj-$(CONFIG_HVC_RTAS) += hvc_rtas.o
45obj-$(CONFIG_RAW_DRIVER) += raw.o 47obj-$(CONFIG_RAW_DRIVER) += raw.o
46obj-$(CONFIG_SGI_SNSC) += snsc.o snsc_event.o 48obj-$(CONFIG_SGI_SNSC) += snsc.o snsc_event.o
47obj-$(CONFIG_MMTIMER) += mmtimer.o 49obj-$(CONFIG_MMTIMER) += mmtimer.o
diff --git a/drivers/char/drm/drmP.h b/drivers/char/drm/drmP.h
index 107df9fdba4e..edc72a6348a7 100644
--- a/drivers/char/drm/drmP.h
+++ b/drivers/char/drm/drmP.h
@@ -357,6 +357,12 @@ typedef struct drm_freelist {
357 spinlock_t lock; 357 spinlock_t lock;
358} drm_freelist_t; 358} drm_freelist_t;
359 359
360typedef struct drm_dma_handle {
361 dma_addr_t busaddr;
362 void *vaddr;
363 size_t size;
364} drm_dma_handle_t;
365
360/** 366/**
361 * Buffer entry. There is one of this for each buffer size order. 367 * Buffer entry. There is one of this for each buffer size order.
362 */ 368 */
@@ -366,7 +372,7 @@ typedef struct drm_buf_entry {
366 drm_buf_t *buflist; /**< buffer list */ 372 drm_buf_t *buflist; /**< buffer list */
367 int seg_count; 373 int seg_count;
368 int page_order; 374 int page_order;
369 unsigned long *seglist; 375 drm_dma_handle_t **seglist;
370 376
371 drm_freelist_t freelist; 377 drm_freelist_t freelist;
372} drm_buf_entry_t; 378} drm_buf_entry_t;
@@ -483,12 +489,6 @@ typedef struct drm_sigdata {
483 drm_hw_lock_t *lock; 489 drm_hw_lock_t *lock;
484} drm_sigdata_t; 490} drm_sigdata_t;
485 491
486typedef struct drm_dma_handle {
487 dma_addr_t busaddr;
488 void *vaddr;
489 size_t size;
490} drm_dma_handle_t;
491
492/** 492/**
493 * Mappings list 493 * Mappings list
494 */ 494 */
@@ -813,8 +813,6 @@ extern void drm_mem_init(void);
813extern int drm_mem_info(char *buf, char **start, off_t offset, 813extern int drm_mem_info(char *buf, char **start, off_t offset,
814 int request, int *eof, void *data); 814 int request, int *eof, void *data);
815extern void *drm_realloc(void *oldpt, size_t oldsize, size_t size, int area); 815extern void *drm_realloc(void *oldpt, size_t oldsize, size_t size, int area);
816extern unsigned long drm_alloc_pages(int order, int area);
817extern void drm_free_pages(unsigned long address, int order, int area);
818extern void *drm_ioremap(unsigned long offset, unsigned long size, 816extern void *drm_ioremap(unsigned long offset, unsigned long size,
819 drm_device_t * dev); 817 drm_device_t * dev);
820extern void *drm_ioremap_nocache(unsigned long offset, unsigned long size, 818extern void *drm_ioremap_nocache(unsigned long offset, unsigned long size,
diff --git a/drivers/char/drm/drm_bufs.c b/drivers/char/drm/drm_bufs.c
index e2637b4d51de..8a9cf12e6183 100644
--- a/drivers/char/drm/drm_bufs.c
+++ b/drivers/char/drm/drm_bufs.c
@@ -474,8 +474,7 @@ static void drm_cleanup_buf_error(drm_device_t * dev, drm_buf_entry_t * entry)
474 if (entry->seg_count) { 474 if (entry->seg_count) {
475 for (i = 0; i < entry->seg_count; i++) { 475 for (i = 0; i < entry->seg_count; i++) {
476 if (entry->seglist[i]) { 476 if (entry->seglist[i]) {
477 drm_free_pages(entry->seglist[i], 477 drm_pci_free(dev, entry->seglist[i]);
478 entry->page_order, DRM_MEM_DMA);
479 } 478 }
480 } 479 }
481 drm_free(entry->seglist, 480 drm_free(entry->seglist,
@@ -678,7 +677,7 @@ int drm_addbufs_pci(drm_device_t * dev, drm_buf_desc_t * request)
678 int total; 677 int total;
679 int page_order; 678 int page_order;
680 drm_buf_entry_t *entry; 679 drm_buf_entry_t *entry;
681 unsigned long page; 680 drm_dma_handle_t *dmah;
682 drm_buf_t *buf; 681 drm_buf_t *buf;
683 int alignment; 682 int alignment;
684 unsigned long offset; 683 unsigned long offset;
@@ -781,8 +780,10 @@ int drm_addbufs_pci(drm_device_t * dev, drm_buf_desc_t * request)
781 page_count = 0; 780 page_count = 0;
782 781
783 while (entry->buf_count < count) { 782 while (entry->buf_count < count) {
784 page = drm_alloc_pages(page_order, DRM_MEM_DMA); 783
785 if (!page) { 784 dmah = drm_pci_alloc(dev, PAGE_SIZE << page_order, 0x1000, 0xfffffffful);
785
786 if (!dmah) {
786 /* Set count correctly so we free the proper amount. */ 787 /* Set count correctly so we free the proper amount. */
787 entry->buf_count = count; 788 entry->buf_count = count;
788 entry->seg_count = count; 789 entry->seg_count = count;
@@ -794,13 +795,13 @@ int drm_addbufs_pci(drm_device_t * dev, drm_buf_desc_t * request)
794 atomic_dec(&dev->buf_alloc); 795 atomic_dec(&dev->buf_alloc);
795 return -ENOMEM; 796 return -ENOMEM;
796 } 797 }
797 entry->seglist[entry->seg_count++] = page; 798 entry->seglist[entry->seg_count++] = dmah;
798 for (i = 0; i < (1 << page_order); i++) { 799 for (i = 0; i < (1 << page_order); i++) {
799 DRM_DEBUG("page %d @ 0x%08lx\n", 800 DRM_DEBUG("page %d @ 0x%08lx\n",
800 dma->page_count + page_count, 801 dma->page_count + page_count,
801 page + PAGE_SIZE * i); 802 (unsigned long)dmah->vaddr + PAGE_SIZE * i);
802 temp_pagelist[dma->page_count + page_count++] 803 temp_pagelist[dma->page_count + page_count++]
803 = page + PAGE_SIZE * i; 804 = (unsigned long)dmah->vaddr + PAGE_SIZE * i;
804 } 805 }
805 for (offset = 0; 806 for (offset = 0;
806 offset + size <= total && entry->buf_count < count; 807 offset + size <= total && entry->buf_count < count;
@@ -811,7 +812,8 @@ int drm_addbufs_pci(drm_device_t * dev, drm_buf_desc_t * request)
811 buf->order = order; 812 buf->order = order;
812 buf->used = 0; 813 buf->used = 0;
813 buf->offset = (dma->byte_count + byte_count + offset); 814 buf->offset = (dma->byte_count + byte_count + offset);
814 buf->address = (void *)(page + offset); 815 buf->address = (void *)(dmah->vaddr + offset);
816 buf->bus_address = dmah->busaddr + offset;
815 buf->next = NULL; 817 buf->next = NULL;
816 buf->waiting = 0; 818 buf->waiting = 0;
817 buf->pending = 0; 819 buf->pending = 0;
diff --git a/drivers/char/drm/drm_dma.c b/drivers/char/drm/drm_dma.c
index 2afab95ca036..892db7096986 100644
--- a/drivers/char/drm/drm_dma.c
+++ b/drivers/char/drm/drm_dma.c
@@ -85,9 +85,7 @@ void drm_dma_takedown(drm_device_t * dev)
85 dma->bufs[i].seg_count); 85 dma->bufs[i].seg_count);
86 for (j = 0; j < dma->bufs[i].seg_count; j++) { 86 for (j = 0; j < dma->bufs[i].seg_count; j++) {
87 if (dma->bufs[i].seglist[j]) { 87 if (dma->bufs[i].seglist[j]) {
88 drm_free_pages(dma->bufs[i].seglist[j], 88 drm_pci_free(dev, dma->bufs[i].seglist[j]);
89 dma->bufs[i].page_order,
90 DRM_MEM_DMA);
91 } 89 }
92 } 90 }
93 drm_free(dma->bufs[i].seglist, 91 drm_free(dma->bufs[i].seglist,
diff --git a/drivers/char/drm/drm_memory.c b/drivers/char/drm/drm_memory.c
index 8074771e348f..dddf8de66143 100644
--- a/drivers/char/drm/drm_memory.c
+++ b/drivers/char/drm/drm_memory.c
@@ -79,65 +79,6 @@ void *drm_realloc(void *oldpt, size_t oldsize, size_t size, int area)
79 return pt; 79 return pt;
80} 80}
81 81
82/**
83 * Allocate pages.
84 *
85 * \param order size order.
86 * \param area memory area. (Not used.)
87 * \return page address on success, or zero on failure.
88 *
89 * Allocate and reserve free pages.
90 */
91unsigned long drm_alloc_pages(int order, int area)
92{
93 unsigned long address;
94 unsigned long bytes = PAGE_SIZE << order;
95 unsigned long addr;
96 unsigned int sz;
97
98 address = __get_free_pages(GFP_KERNEL|__GFP_COMP, order);
99 if (!address)
100 return 0;
101
102 /* Zero */
103 memset((void *)address, 0, bytes);
104
105 /* Reserve */
106 for (addr = address, sz = bytes;
107 sz > 0; addr += PAGE_SIZE, sz -= PAGE_SIZE) {
108 SetPageReserved(virt_to_page(addr));
109 }
110
111 return address;
112}
113
114/**
115 * Free pages.
116 *
117 * \param address address of the pages to free.
118 * \param order size order.
119 * \param area memory area. (Not used.)
120 *
121 * Unreserve and free pages allocated by alloc_pages().
122 */
123void drm_free_pages(unsigned long address, int order, int area)
124{
125 unsigned long bytes = PAGE_SIZE << order;
126 unsigned long addr;
127 unsigned int sz;
128
129 if (!address)
130 return;
131
132 /* Unreserve */
133 for (addr = address, sz = bytes;
134 sz > 0; addr += PAGE_SIZE, sz -= PAGE_SIZE) {
135 ClearPageReserved(virt_to_page(addr));
136 }
137
138 free_pages(address, order);
139}
140
141#if __OS_HAS_AGP 82#if __OS_HAS_AGP
142/** Wrapper around agp_allocate_memory() */ 83/** Wrapper around agp_allocate_memory() */
143DRM_AGP_MEM *drm_alloc_agp(drm_device_t * dev, int pages, u32 type) 84DRM_AGP_MEM *drm_alloc_agp(drm_device_t * dev, int pages, u32 type)
diff --git a/drivers/char/drm/drm_memory_debug.h b/drivers/char/drm/drm_memory_debug.h
index e84605fc54af..7868341817da 100644
--- a/drivers/char/drm/drm_memory_debug.h
+++ b/drivers/char/drm/drm_memory_debug.h
@@ -206,76 +206,6 @@ void drm_free (void *pt, size_t size, int area) {
206 } 206 }
207} 207}
208 208
209unsigned long drm_alloc_pages (int order, int area) {
210 unsigned long address;
211 unsigned long bytes = PAGE_SIZE << order;
212 unsigned long addr;
213 unsigned int sz;
214
215 spin_lock(&drm_mem_lock);
216 if ((drm_ram_used >> PAGE_SHIFT)
217 > (DRM_RAM_PERCENT * drm_ram_available) / 100) {
218 spin_unlock(&drm_mem_lock);
219 return 0;
220 }
221 spin_unlock(&drm_mem_lock);
222
223 address = __get_free_pages(GFP_KERNEL|__GFP_COMP, order);
224 if (!address) {
225 spin_lock(&drm_mem_lock);
226 ++drm_mem_stats[area].fail_count;
227 spin_unlock(&drm_mem_lock);
228 return 0;
229 }
230 spin_lock(&drm_mem_lock);
231 ++drm_mem_stats[area].succeed_count;
232 drm_mem_stats[area].bytes_allocated += bytes;
233 drm_ram_used += bytes;
234 spin_unlock(&drm_mem_lock);
235
236 /* Zero outside the lock */
237 memset((void *)address, 0, bytes);
238
239 /* Reserve */
240 for (addr = address, sz = bytes;
241 sz > 0; addr += PAGE_SIZE, sz -= PAGE_SIZE) {
242 SetPageReserved(virt_to_page(addr));
243 }
244
245 return address;
246}
247
248void drm_free_pages (unsigned long address, int order, int area) {
249 unsigned long bytes = PAGE_SIZE << order;
250 int alloc_count;
251 int free_count;
252 unsigned long addr;
253 unsigned int sz;
254
255 if (!address) {
256 DRM_MEM_ERROR(area, "Attempt to free address 0\n");
257 } else {
258 /* Unreserve */
259 for (addr = address, sz = bytes;
260 sz > 0; addr += PAGE_SIZE, sz -= PAGE_SIZE) {
261 ClearPageReserved(virt_to_page(addr));
262 }
263 free_pages(address, order);
264 }
265
266 spin_lock(&drm_mem_lock);
267 free_count = ++drm_mem_stats[area].free_count;
268 alloc_count = drm_mem_stats[area].succeed_count;
269 drm_mem_stats[area].bytes_freed += bytes;
270 drm_ram_used -= bytes;
271 spin_unlock(&drm_mem_lock);
272 if (free_count > alloc_count) {
273 DRM_MEM_ERROR(area,
274 "Excess frees: %d frees, %d allocs\n",
275 free_count, alloc_count);
276 }
277}
278
279void *drm_ioremap (unsigned long offset, unsigned long size, 209void *drm_ioremap (unsigned long offset, unsigned long size,
280 drm_device_t * dev) { 210 drm_device_t * dev) {
281 void *pt; 211 void *pt;
diff --git a/drivers/char/drm/drm_pci.c b/drivers/char/drm/drm_pci.c
index 1fd7ff164817..b28ca9cea8a2 100644
--- a/drivers/char/drm/drm_pci.c
+++ b/drivers/char/drm/drm_pci.c
@@ -50,6 +50,10 @@ drm_dma_handle_t *drm_pci_alloc(drm_device_t * dev, size_t size, size_t align,
50 dma_addr_t maxaddr) 50 dma_addr_t maxaddr)
51{ 51{
52 drm_dma_handle_t *dmah; 52 drm_dma_handle_t *dmah;
53#if 1
54 unsigned long addr;
55 size_t sz;
56#endif
53#ifdef DRM_DEBUG_MEMORY 57#ifdef DRM_DEBUG_MEMORY
54 int area = DRM_MEM_DMA; 58 int area = DRM_MEM_DMA;
55 59
@@ -79,7 +83,7 @@ drm_dma_handle_t *drm_pci_alloc(drm_device_t * dev, size_t size, size_t align,
79 return NULL; 83 return NULL;
80 84
81 dmah->size = size; 85 dmah->size = size;
82 dmah->vaddr = pci_alloc_consistent(dev->pdev, size, &dmah->busaddr); 86 dmah->vaddr = dma_alloc_coherent(&dev->pdev->dev, size, &dmah->busaddr, GFP_KERNEL | __GFP_COMP);
83 87
84#ifdef DRM_DEBUG_MEMORY 88#ifdef DRM_DEBUG_MEMORY
85 if (dmah->vaddr == NULL) { 89 if (dmah->vaddr == NULL) {
@@ -104,18 +108,29 @@ drm_dma_handle_t *drm_pci_alloc(drm_device_t * dev, size_t size, size_t align,
104 108
105 memset(dmah->vaddr, 0, size); 109 memset(dmah->vaddr, 0, size);
106 110
111 /* XXX - Is virt_to_page() legal for consistent mem? */
112 /* Reserve */
113 for (addr = (unsigned long)dmah->vaddr, sz = size;
114 sz > 0; addr += PAGE_SIZE, sz -= PAGE_SIZE) {
115 SetPageReserved(virt_to_page(addr));
116 }
117
107 return dmah; 118 return dmah;
108} 119}
109 120
110EXPORT_SYMBOL(drm_pci_alloc); 121EXPORT_SYMBOL(drm_pci_alloc);
111 122
112/** 123/**
113 * \brief Free a PCI consistent memory block with freeing its descriptor. 124 * \brief Free a PCI consistent memory block without freeing its descriptor.
114 * 125 *
115 * This function is for internal use in the Linux-specific DRM core code. 126 * This function is for internal use in the Linux-specific DRM core code.
116 */ 127 */
117void __drm_pci_free(drm_device_t * dev, drm_dma_handle_t * dmah) 128void __drm_pci_free(drm_device_t * dev, drm_dma_handle_t * dmah)
118{ 129{
130#if 1
131 unsigned long addr;
132 size_t sz;
133#endif
119#ifdef DRM_DEBUG_MEMORY 134#ifdef DRM_DEBUG_MEMORY
120 int area = DRM_MEM_DMA; 135 int area = DRM_MEM_DMA;
121 int alloc_count; 136 int alloc_count;
@@ -127,8 +142,14 @@ void __drm_pci_free(drm_device_t * dev, drm_dma_handle_t * dmah)
127 DRM_MEM_ERROR(area, "Attempt to free address 0\n"); 142 DRM_MEM_ERROR(area, "Attempt to free address 0\n");
128#endif 143#endif
129 } else { 144 } else {
130 pci_free_consistent(dev->pdev, dmah->size, dmah->vaddr, 145 /* XXX - Is virt_to_page() legal for consistent mem? */
131 dmah->busaddr); 146 /* Unreserve */
147 for (addr = (unsigned long)dmah->vaddr, sz = dmah->size;
148 sz > 0; addr += PAGE_SIZE, sz -= PAGE_SIZE) {
149 ClearPageReserved(virt_to_page(addr));
150 }
151 dma_free_coherent(&dev->pdev->dev, dmah->size, dmah->vaddr,
152 dmah->busaddr);
132 } 153 }
133 154
134#ifdef DRM_DEBUG_MEMORY 155#ifdef DRM_DEBUG_MEMORY
diff --git a/drivers/char/drm/drm_pciids.h b/drivers/char/drm/drm_pciids.h
index 2c17e88a8847..b1bb3c7b568d 100644
--- a/drivers/char/drm/drm_pciids.h
+++ b/drivers/char/drm/drm_pciids.h
@@ -3,49 +3,69 @@
3 Please contact dri-devel@lists.sf.net to add new cards to this list 3 Please contact dri-devel@lists.sf.net to add new cards to this list
4*/ 4*/
5#define radeon_PCI_IDS \ 5#define radeon_PCI_IDS \
6 {0x1002, 0x3150, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350},\ 6 {0x1002, 0x3150, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|CHIP_IS_MOBILITY}, \
7 {0x1002, 0x3152, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|CHIP_IS_MOBILITY|CHIP_NEW_MEMMAP}, \
8 {0x1002, 0x3154, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|CHIP_IS_MOBILITY|CHIP_NEW_MEMMAP}, \
9 {0x1002, 0x3E50, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|CHIP_NEW_MEMMAP}, \
10 {0x1002, 0x3E54, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|CHIP_NEW_MEMMAP}, \
7 {0x1002, 0x4136, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS100|CHIP_IS_IGP}, \ 11 {0x1002, 0x4136, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS100|CHIP_IS_IGP}, \
8 {0x1002, 0x4137, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS200|CHIP_IS_IGP}, \ 12 {0x1002, 0x4137, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS200|CHIP_IS_IGP}, \
9 {0x1002, 0x4144, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R300}, \ 13 {0x1002, 0x4144, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R300}, \
10 {0x1002, 0x4145, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R300}, \ 14 {0x1002, 0x4145, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R300}, \
11 {0x1002, 0x4146, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R300}, \ 15 {0x1002, 0x4146, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R300}, \
12 {0x1002, 0x4147, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R300}, \ 16 {0x1002, 0x4147, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R300}, \
17 {0x1002, 0x4148, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R350}, \
18 {0x1002, 0x4149, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R350}, \
19 {0x1002, 0x414A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R350}, \
20 {0x1002, 0x414B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R350}, \
13 {0x1002, 0x4150, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350}, \ 21 {0x1002, 0x4150, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350}, \
14 {0x1002, 0x4151, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350}, \ 22 {0x1002, 0x4151, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350}, \
15 {0x1002, 0x4152, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350}, \ 23 {0x1002, 0x4152, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350}, \
16 {0x1002, 0x4153, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350}, \ 24 {0x1002, 0x4153, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350}, \
17 {0x1002, 0x4154, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350}, \ 25 {0x1002, 0x4154, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350}, \
26 {0x1002, 0x4155, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350}, \
18 {0x1002, 0x4156, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350}, \ 27 {0x1002, 0x4156, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350}, \
19 {0x1002, 0x4237, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS250|CHIP_IS_IGP}, \ 28 {0x1002, 0x4237, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS200|CHIP_IS_IGP}, \
20 {0x1002, 0x4242, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R200}, \ 29 {0x1002, 0x4242, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R200}, \
21 {0x1002, 0x4243, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R200}, \ 30 {0x1002, 0x4243, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R200}, \
22 {0x1002, 0x4336, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS100|CHIP_IS_IGP|CHIP_IS_MOBILITY}, \ 31 {0x1002, 0x4336, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS100|CHIP_IS_IGP|CHIP_IS_MOBILITY}, \
23 {0x1002, 0x4337, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS200|CHIP_IS_IGP|CHIP_IS_MOBILITY}, \ 32 {0x1002, 0x4337, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS200|CHIP_IS_IGP|CHIP_IS_MOBILITY}, \
24 {0x1002, 0x4437, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS250|CHIP_IS_IGP|CHIP_IS_MOBILITY}, \ 33 {0x1002, 0x4437, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS200|CHIP_IS_IGP|CHIP_IS_MOBILITY}, \
25 {0x1002, 0x4964, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R250}, \ 34 {0x1002, 0x4966, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV250}, \
26 {0x1002, 0x4965, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R250}, \ 35 {0x1002, 0x4967, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV250}, \
27 {0x1002, 0x4966, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R250}, \ 36 {0x1002, 0x4A48, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \
28 {0x1002, 0x4967, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R250}, \ 37 {0x1002, 0x4A49, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \
29 {0x1002, 0x4A49, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420}, \ 38 {0x1002, 0x4A4A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \
30 {0x1002, 0x4A4B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420}, \ 39 {0x1002, 0x4A4B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \
40 {0x1002, 0x4A4C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \
41 {0x1002, 0x4A4D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \
42 {0x1002, 0x4A4E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_IS_MOBILITY|CHIP_NEW_MEMMAP}, \
43 {0x1002, 0x4A4F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \
44 {0x1002, 0x4A50, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \
45 {0x1002, 0x4A54, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \
46 {0x1002, 0x4B49, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \
47 {0x1002, 0x4B4A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \
48 {0x1002, 0x4B4B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \
49 {0x1002, 0x4B4C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \
31 {0x1002, 0x4C57, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV200|CHIP_IS_MOBILITY}, \ 50 {0x1002, 0x4C57, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV200|CHIP_IS_MOBILITY}, \
32 {0x1002, 0x4C58, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV200|CHIP_IS_MOBILITY}, \ 51 {0x1002, 0x4C58, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV200|CHIP_IS_MOBILITY}, \
33 {0x1002, 0x4C59, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV100|CHIP_IS_MOBILITY}, \ 52 {0x1002, 0x4C59, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV100|CHIP_IS_MOBILITY}, \
34 {0x1002, 0x4C5A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV100|CHIP_IS_MOBILITY}, \ 53 {0x1002, 0x4C5A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV100|CHIP_IS_MOBILITY}, \
35 {0x1002, 0x4C64, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R250|CHIP_IS_MOBILITY}, \ 54 {0x1002, 0x4C64, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV250|CHIP_IS_MOBILITY}, \
36 {0x1002, 0x4C65, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R250|CHIP_IS_MOBILITY}, \ 55 {0x1002, 0x4C66, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV250|CHIP_IS_MOBILITY}, \
37 {0x1002, 0x4C66, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R250|CHIP_IS_MOBILITY}, \ 56 {0x1002, 0x4C67, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV250|CHIP_IS_MOBILITY}, \
38 {0x1002, 0x4C67, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R250|CHIP_IS_MOBILITY}, \
39 {0x1002, 0x4E44, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R300}, \ 57 {0x1002, 0x4E44, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R300}, \
40 {0x1002, 0x4E45, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R300}, \ 58 {0x1002, 0x4E45, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R300}, \
41 {0x1002, 0x4E46, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350}, \ 59 {0x1002, 0x4E46, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R300}, \
42 {0x1002, 0x4E47, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R300}, \ 60 {0x1002, 0x4E47, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R300}, \
43 {0x1002, 0x4E48, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R350}, \ 61 {0x1002, 0x4E48, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R350}, \
44 {0x1002, 0x4E49, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R350}, \ 62 {0x1002, 0x4E49, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R350}, \
45 {0x1002, 0x4E4A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350}, \ 63 {0x1002, 0x4E4A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R350}, \
46 {0x1002, 0x4E4B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R350}, \ 64 {0x1002, 0x4E4B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R350}, \
47 {0x1002, 0x4E50, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350|CHIP_IS_MOBILITY}, \ 65 {0x1002, 0x4E50, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350|CHIP_IS_MOBILITY}, \
48 {0x1002, 0x4E51, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350|CHIP_IS_MOBILITY}, \ 66 {0x1002, 0x4E51, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350|CHIP_IS_MOBILITY}, \
67 {0x1002, 0x4E52, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350|CHIP_IS_MOBILITY}, \
68 {0x1002, 0x4E53, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350|CHIP_IS_MOBILITY}, \
49 {0x1002, 0x4E54, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350|CHIP_IS_MOBILITY}, \ 69 {0x1002, 0x4E54, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350|CHIP_IS_MOBILITY}, \
50 {0x1002, 0x4E56, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350|CHIP_IS_MOBILITY}, \ 70 {0x1002, 0x4E56, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350|CHIP_IS_MOBILITY}, \
51 {0x1002, 0x5144, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R100|CHIP_SINGLE_CRTC}, \ 71 {0x1002, 0x5144, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R100|CHIP_SINGLE_CRTC}, \
@@ -53,44 +73,66 @@
53 {0x1002, 0x5146, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R100|CHIP_SINGLE_CRTC}, \ 73 {0x1002, 0x5146, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R100|CHIP_SINGLE_CRTC}, \
54 {0x1002, 0x5147, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R100|CHIP_SINGLE_CRTC}, \ 74 {0x1002, 0x5147, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R100|CHIP_SINGLE_CRTC}, \
55 {0x1002, 0x5148, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R200}, \ 75 {0x1002, 0x5148, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R200}, \
56 {0x1002, 0x5149, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R200}, \
57 {0x1002, 0x514A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R200}, \
58 {0x1002, 0x514B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R200}, \
59 {0x1002, 0x514C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R200}, \ 76 {0x1002, 0x514C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R200}, \
60 {0x1002, 0x514D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R200}, \ 77 {0x1002, 0x514D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R200}, \
61 {0x1002, 0x514E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R200}, \
62 {0x1002, 0x514F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R200}, \
63 {0x1002, 0x5157, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV200}, \ 78 {0x1002, 0x5157, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV200}, \
64 {0x1002, 0x5158, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV200}, \ 79 {0x1002, 0x5158, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV200}, \
65 {0x1002, 0x5159, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV100}, \ 80 {0x1002, 0x5159, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV100}, \
66 {0x1002, 0x515A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV100}, \ 81 {0x1002, 0x515A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV100}, \
67 {0x1002, 0x515E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV100}, \ 82 {0x1002, 0x515E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV100}, \
68 {0x1002, 0x5168, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R200}, \ 83 {0x1002, 0x5460, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|CHIP_IS_MOBILITY}, \
69 {0x1002, 0x5169, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R200}, \ 84 {0x1002, 0x5462, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|CHIP_IS_MOBILITY}, \
70 {0x1002, 0x516A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R200}, \ 85 {0x1002, 0x5464, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|CHIP_IS_MOBILITY}, \
71 {0x1002, 0x516B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R200}, \ 86 {0x1002, 0x5548, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \
72 {0x1002, 0x516C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R200}, \ 87 {0x1002, 0x5549, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \
73 {0x1002, 0x5460, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350}, \ 88 {0x1002, 0x554A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \
74 {0x1002, 0x554F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R350}, \ 89 {0x1002, 0x554B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \
90 {0x1002, 0x554C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \
91 {0x1002, 0x554D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \
92 {0x1002, 0x554E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \
93 {0x1002, 0x554F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \
94 {0x1002, 0x5550, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \
95 {0x1002, 0x5551, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \
96 {0x1002, 0x5552, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \
97 {0x1002, 0x5554, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \
98 {0x1002, 0x564A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|CHIP_IS_MOBILITY|CHIP_NEW_MEMMAP}, \
99 {0x1002, 0x564B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|CHIP_IS_MOBILITY|CHIP_NEW_MEMMAP}, \
100 {0x1002, 0x564F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|CHIP_IS_MOBILITY|CHIP_NEW_MEMMAP}, \
101 {0x1002, 0x5652, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|CHIP_IS_MOBILITY|CHIP_NEW_MEMMAP}, \
102 {0x1002, 0x5653, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|CHIP_IS_MOBILITY|CHIP_NEW_MEMMAP}, \
75 {0x1002, 0x5834, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|CHIP_IS_IGP}, \ 103 {0x1002, 0x5834, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|CHIP_IS_IGP}, \
76 {0x1002, 0x5835, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|CHIP_IS_IGP|CHIP_IS_MOBILITY}, \ 104 {0x1002, 0x5835, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|CHIP_IS_IGP|CHIP_IS_MOBILITY}, \
77 {0x1002, 0x5836, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|CHIP_IS_IGP}, \
78 {0x1002, 0x5837, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|CHIP_IS_IGP}, \
79 {0x1002, 0x5960, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \ 105 {0x1002, 0x5960, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \
80 {0x1002, 0x5961, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \ 106 {0x1002, 0x5961, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \
81 {0x1002, 0x5962, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \ 107 {0x1002, 0x5962, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \
82 {0x1002, 0x5963, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \
83 {0x1002, 0x5964, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \ 108 {0x1002, 0x5964, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \
84 {0x1002, 0x5968, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \ 109 {0x1002, 0x5965, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \
85 {0x1002, 0x5969, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV100}, \ 110 {0x1002, 0x5969, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV100}, \
86 {0x1002, 0x596A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \ 111 {0x1002, 0x5b60, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|CHIP_NEW_MEMMAP}, \
87 {0x1002, 0x596B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \ 112 {0x1002, 0x5b62, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|CHIP_NEW_MEMMAP}, \
113 {0x1002, 0x5b63, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|CHIP_NEW_MEMMAP}, \
114 {0x1002, 0x5b64, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|CHIP_NEW_MEMMAP}, \
115 {0x1002, 0x5b65, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|CHIP_NEW_MEMMAP}, \
88 {0x1002, 0x5c61, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280|CHIP_IS_MOBILITY}, \ 116 {0x1002, 0x5c61, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280|CHIP_IS_MOBILITY}, \
89 {0x1002, 0x5c62, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \
90 {0x1002, 0x5c63, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280|CHIP_IS_MOBILITY}, \ 117 {0x1002, 0x5c63, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280|CHIP_IS_MOBILITY}, \
91 {0x1002, 0x5c64, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \ 118 {0x1002, 0x5d48, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_IS_MOBILITY|CHIP_NEW_MEMMAP}, \
92 {0x1002, 0x5d4d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R350}, \ 119 {0x1002, 0x5d49, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_IS_MOBILITY|CHIP_NEW_MEMMAP}, \
93 {0x1002, 0x5e4b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420}, \ 120 {0x1002, 0x5d4a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_IS_MOBILITY|CHIP_NEW_MEMMAP}, \
121 {0x1002, 0x5d4c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \
122 {0x1002, 0x5d4d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \
123 {0x1002, 0x5d4e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \
124 {0x1002, 0x5d4f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \
125 {0x1002, 0x5d50, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \
126 {0x1002, 0x5d52, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \
127 {0x1002, 0x5d57, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \
128 {0x1002, 0x5e48, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|CHIP_NEW_MEMMAP}, \
129 {0x1002, 0x5e4a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|CHIP_NEW_MEMMAP}, \
130 {0x1002, 0x5e4b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|CHIP_NEW_MEMMAP}, \
131 {0x1002, 0x5e4c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|CHIP_NEW_MEMMAP}, \
132 {0x1002, 0x5e4d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|CHIP_NEW_MEMMAP}, \
133 {0x1002, 0x5e4f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|CHIP_NEW_MEMMAP}, \
134 {0x1002, 0x7834, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|CHIP_IS_IGP|CHIP_NEW_MEMMAP}, \
135 {0x1002, 0x7835, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|CHIP_IS_IGP|CHIP_IS_MOBILITY|CHIP_NEW_MEMMAP}, \
94 {0, 0, 0} 136 {0, 0, 0}
95 137
96#define r128_PCI_IDS \ 138#define r128_PCI_IDS \
diff --git a/drivers/char/drm/i915_dma.c b/drivers/char/drm/i915_dma.c
index 1ff4c7ca0bff..9f4b8ce4c05e 100644
--- a/drivers/char/drm/i915_dma.c
+++ b/drivers/char/drm/i915_dma.c
@@ -495,8 +495,6 @@ static int i915_dispatch_batchbuffer(drm_device_t * dev,
495 } 495 }
496 } 496 }
497 497
498 dev_priv->sarea_priv->last_enqueue = dev_priv->counter++;
499
500 i915_emit_breadcrumb(dev); 498 i915_emit_breadcrumb(dev);
501 499
502 return 0; 500 return 0;
diff --git a/drivers/char/drm/i915_irq.c b/drivers/char/drm/i915_irq.c
index d3879ac9970f..a752afd86ab8 100644
--- a/drivers/char/drm/i915_irq.c
+++ b/drivers/char/drm/i915_irq.c
@@ -53,6 +53,8 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
53 53
54 I915_WRITE16(I915REG_INT_IDENTITY_R, temp); 54 I915_WRITE16(I915REG_INT_IDENTITY_R, temp);
55 55
56 dev_priv->sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv);
57
56 if (temp & USER_INT_FLAG) 58 if (temp & USER_INT_FLAG)
57 DRM_WAKEUP(&dev_priv->irq_queue); 59 DRM_WAKEUP(&dev_priv->irq_queue);
58 60
diff --git a/drivers/char/drm/r300_cmdbuf.c b/drivers/char/drm/r300_cmdbuf.c
index c08fa5076f05..b108c7f913b2 100644
--- a/drivers/char/drm/r300_cmdbuf.c
+++ b/drivers/char/drm/r300_cmdbuf.c
@@ -214,13 +214,13 @@ void r300_init_reg_flags(void)
214 ADD_RANGE(0x4F54, 1); 214 ADD_RANGE(0x4F54, 1);
215 215
216 ADD_RANGE(R300_TX_FILTER_0, 16); 216 ADD_RANGE(R300_TX_FILTER_0, 16);
217 ADD_RANGE(R300_TX_UNK1_0, 16); 217 ADD_RANGE(R300_TX_FILTER1_0, 16);
218 ADD_RANGE(R300_TX_SIZE_0, 16); 218 ADD_RANGE(R300_TX_SIZE_0, 16);
219 ADD_RANGE(R300_TX_FORMAT_0, 16); 219 ADD_RANGE(R300_TX_FORMAT_0, 16);
220 ADD_RANGE(R300_TX_PITCH_0, 16); 220 ADD_RANGE(R300_TX_PITCH_0, 16);
221 /* Texture offset is dangerous and needs more checking */ 221 /* Texture offset is dangerous and needs more checking */
222 ADD_RANGE_MARK(R300_TX_OFFSET_0, 16, MARK_CHECK_OFFSET); 222 ADD_RANGE_MARK(R300_TX_OFFSET_0, 16, MARK_CHECK_OFFSET);
223 ADD_RANGE(R300_TX_UNK4_0, 16); 223 ADD_RANGE(R300_TX_CHROMA_KEY_0, 16);
224 ADD_RANGE(R300_TX_BORDER_COLOR_0, 16); 224 ADD_RANGE(R300_TX_BORDER_COLOR_0, 16);
225 225
226 /* Sporadic registers used as primitives are emitted */ 226 /* Sporadic registers used as primitives are emitted */
@@ -242,8 +242,10 @@ static __inline__ int r300_check_range(unsigned reg, int count)
242 return 0; 242 return 0;
243} 243}
244 244
245 /* we expect offsets passed to the framebuffer to be either within video memory or 245/*
246 within AGP space */ 246 * we expect offsets passed to the framebuffer to be either within video
247 * memory or within AGP space
248 */
247static __inline__ int r300_check_offset(drm_radeon_private_t *dev_priv, 249static __inline__ int r300_check_offset(drm_radeon_private_t *dev_priv,
248 u32 offset) 250 u32 offset)
249{ 251{
@@ -251,11 +253,11 @@ static __inline__ int r300_check_offset(drm_radeon_private_t *dev_priv,
251 but this value is not being kept. 253 but this value is not being kept.
252 This code is correct for now (does the same thing as the 254 This code is correct for now (does the same thing as the
253 code that sets MC_FB_LOCATION) in radeon_cp.c */ 255 code that sets MC_FB_LOCATION) in radeon_cp.c */
254 if ((offset >= dev_priv->fb_location) && 256 if (offset >= dev_priv->fb_location &&
255 (offset < dev_priv->gart_vm_start)) 257 offset < (dev_priv->fb_location + dev_priv->fb_size))
256 return 0; 258 return 0;
257 if ((offset >= dev_priv->gart_vm_start) && 259 if (offset >= dev_priv->gart_vm_start &&
258 (offset < dev_priv->gart_vm_start + dev_priv->gart_size)) 260 offset < (dev_priv->gart_vm_start + dev_priv->gart_size))
259 return 0; 261 return 0;
260 return 1; 262 return 1;
261} 263}
@@ -490,6 +492,7 @@ static __inline__ int r300_emit_3d_load_vbpntr(drm_radeon_private_t *dev_priv,
490 492
491 return 0; 493 return 0;
492} 494}
495
493static __inline__ int r300_emit_bitblt_multi(drm_radeon_private_t *dev_priv, 496static __inline__ int r300_emit_bitblt_multi(drm_radeon_private_t *dev_priv,
494 drm_radeon_kcmd_buffer_t *cmdbuf) 497 drm_radeon_kcmd_buffer_t *cmdbuf)
495{ 498{
@@ -701,6 +704,64 @@ static void r300_discard_buffer(drm_device_t * dev, drm_buf_t * buf)
701 buf->used = 0; 704 buf->used = 0;
702} 705}
703 706
707static int r300_scratch(drm_radeon_private_t *dev_priv,
708 drm_radeon_kcmd_buffer_t *cmdbuf,
709 drm_r300_cmd_header_t header)
710{
711 u32 *ref_age_base;
712 u32 i, buf_idx, h_pending;
713 RING_LOCALS;
714
715 if (cmdbuf->bufsz <
716 (sizeof(u64) + header.scratch.n_bufs * sizeof(buf_idx))) {
717 return DRM_ERR(EINVAL);
718 }
719
720 if (header.scratch.reg >= 5) {
721 return DRM_ERR(EINVAL);
722 }
723
724 dev_priv->scratch_ages[header.scratch.reg]++;
725
726 ref_age_base = *(u32 **)cmdbuf->buf;
727
728 cmdbuf->buf += sizeof(u64);
729 cmdbuf->bufsz -= sizeof(u64);
730
731 for (i=0; i < header.scratch.n_bufs; i++) {
732 buf_idx = *(u32 *)cmdbuf->buf;
733 buf_idx *= 2; /* 8 bytes per buf */
734
735 if (DRM_COPY_TO_USER(ref_age_base + buf_idx, &dev_priv->scratch_ages[header.scratch.reg], sizeof(u32))) {
736 return DRM_ERR(EINVAL);
737 }
738
739 if (DRM_COPY_FROM_USER(&h_pending, ref_age_base + buf_idx + 1, sizeof(u32))) {
740 return DRM_ERR(EINVAL);
741 }
742
743 if (h_pending == 0) {
744 return DRM_ERR(EINVAL);
745 }
746
747 h_pending--;
748
749 if (DRM_COPY_TO_USER(ref_age_base + buf_idx + 1, &h_pending, sizeof(u32))) {
750 return DRM_ERR(EINVAL);
751 }
752
753 cmdbuf->buf += sizeof(buf_idx);
754 cmdbuf->bufsz -= sizeof(buf_idx);
755 }
756
757 BEGIN_RING(2);
758 OUT_RING(CP_PACKET0(RADEON_SCRATCH_REG0 + header.scratch.reg * 4, 0));
759 OUT_RING(dev_priv->scratch_ages[header.scratch.reg]);
760 ADVANCE_RING();
761
762 return 0;
763}
764
704/** 765/**
705 * Parses and validates a user-supplied command buffer and emits appropriate 766 * Parses and validates a user-supplied command buffer and emits appropriate
706 * commands on the DMA ring buffer. 767 * commands on the DMA ring buffer.
@@ -838,6 +899,15 @@ int r300_do_cp_cmdbuf(drm_device_t *dev,
838 } 899 }
839 break; 900 break;
840 901
902 case R300_CMD_SCRATCH:
903 DRM_DEBUG("R300_CMD_SCRATCH\n");
904 ret = r300_scratch(dev_priv, cmdbuf, header);
905 if (ret) {
906 DRM_ERROR("r300_scratch failed\n");
907 goto cleanup;
908 }
909 break;
910
841 default: 911 default:
842 DRM_ERROR("bad cmd_type %i at %p\n", 912 DRM_ERROR("bad cmd_type %i at %p\n",
843 header.header.cmd_type, 913 header.header.cmd_type,
diff --git a/drivers/char/drm/r300_reg.h b/drivers/char/drm/r300_reg.h
index d1e19954406b..a881f96c983e 100644
--- a/drivers/char/drm/r300_reg.h
+++ b/drivers/char/drm/r300_reg.h
@@ -711,8 +711,22 @@ I am fairly certain that they are correct unless stated otherwise in comments.
711# define R300_TX_MAX_ANISO_16_TO_1 (8 << 21) 711# define R300_TX_MAX_ANISO_16_TO_1 (8 << 21)
712# define R300_TX_MAX_ANISO_MASK (14 << 21) 712# define R300_TX_MAX_ANISO_MASK (14 << 21)
713 713
714#define R300_TX_UNK1_0 0x4440 714#define R300_TX_FILTER1_0 0x4440
715# define R300_CHROMA_KEY_MODE_DISABLE 0
716# define R300_CHROMA_KEY_FORCE 1
717# define R300_CHROMA_KEY_BLEND 2
718# define R300_MC_ROUND_NORMAL (0<<2)
719# define R300_MC_ROUND_MPEG4 (1<<2)
715# define R300_LOD_BIAS_MASK 0x1fff 720# define R300_LOD_BIAS_MASK 0x1fff
721# define R300_EDGE_ANISO_EDGE_DIAG (0<<13)
722# define R300_EDGE_ANISO_EDGE_ONLY (1<<13)
723# define R300_MC_COORD_TRUNCATE_DISABLE (0<<14)
724# define R300_MC_COORD_TRUNCATE_MPEG (1<<14)
725# define R300_TX_TRI_PERF_0_8 (0<<15)
726# define R300_TX_TRI_PERF_1_8 (1<<15)
727# define R300_TX_TRI_PERF_1_4 (2<<15)
728# define R300_TX_TRI_PERF_3_8 (3<<15)
729# define R300_ANISO_THRESHOLD_MASK (7<<17)
716 730
717#define R300_TX_SIZE_0 0x4480 731#define R300_TX_SIZE_0 0x4480
718# define R300_TX_WIDTHMASK_SHIFT 0 732# define R300_TX_WIDTHMASK_SHIFT 0
@@ -722,6 +736,8 @@ I am fairly certain that they are correct unless stated otherwise in comments.
722# define R300_TX_UNK23 (1 << 23) 736# define R300_TX_UNK23 (1 << 23)
723# define R300_TX_SIZE_SHIFT 26 /* largest of width, height */ 737# define R300_TX_SIZE_SHIFT 26 /* largest of width, height */
724# define R300_TX_SIZE_MASK (15 << 26) 738# define R300_TX_SIZE_MASK (15 << 26)
739# define R300_TX_SIZE_PROJECTED (1<<30)
740# define R300_TX_SIZE_TXPITCH_EN (1<<31)
725#define R300_TX_FORMAT_0 0x44C0 741#define R300_TX_FORMAT_0 0x44C0
726 /* The interpretation of the format word by Wladimir van der Laan */ 742 /* The interpretation of the format word by Wladimir van der Laan */
727 /* The X, Y, Z and W refer to the layout of the components. 743 /* The X, Y, Z and W refer to the layout of the components.
@@ -750,7 +766,8 @@ I am fairly certain that they are correct unless stated otherwise in comments.
750# define R300_TX_FORMAT_B8G8_B8G8 0x14 /* no swizzle */ 766# define R300_TX_FORMAT_B8G8_B8G8 0x14 /* no swizzle */
751# define R300_TX_FORMAT_G8R8_G8B8 0x15 /* no swizzle */ 767# define R300_TX_FORMAT_G8R8_G8B8 0x15 /* no swizzle */
752 /* 0x16 - some 16 bit green format.. ?? */ 768 /* 0x16 - some 16 bit green format.. ?? */
753# define R300_TX_FORMAT_UNK25 (1 << 25) /* no swizzle */ 769# define R300_TX_FORMAT_UNK25 (1 << 25) /* no swizzle */
770# define R300_TX_FORMAT_CUBIC_MAP (1 << 26)
754 771
755 /* gap */ 772 /* gap */
756 /* Floating point formats */ 773 /* Floating point formats */
@@ -800,18 +817,20 @@ I am fairly certain that they are correct unless stated otherwise in comments.
800 817
801# define R300_TX_FORMAT_YUV_MODE 0x00800000 818# define R300_TX_FORMAT_YUV_MODE 0x00800000
802 819
803#define R300_TX_PITCH_0 0x4500 820#define R300_TX_PITCH_0 0x4500 /* obvious missing in gap */
804#define R300_TX_OFFSET_0 0x4540 821#define R300_TX_OFFSET_0 0x4540
805/* BEGIN: Guess from R200 */ 822/* BEGIN: Guess from R200 */
806# define R300_TXO_ENDIAN_NO_SWAP (0 << 0) 823# define R300_TXO_ENDIAN_NO_SWAP (0 << 0)
807# define R300_TXO_ENDIAN_BYTE_SWAP (1 << 0) 824# define R300_TXO_ENDIAN_BYTE_SWAP (1 << 0)
808# define R300_TXO_ENDIAN_WORD_SWAP (2 << 0) 825# define R300_TXO_ENDIAN_WORD_SWAP (2 << 0)
809# define R300_TXO_ENDIAN_HALFDW_SWAP (3 << 0) 826# define R300_TXO_ENDIAN_HALFDW_SWAP (3 << 0)
827# define R300_TXO_MACRO_TILE (1 << 2)
828# define R300_TXO_MICRO_TILE (1 << 3)
810# define R300_TXO_OFFSET_MASK 0xffffffe0 829# define R300_TXO_OFFSET_MASK 0xffffffe0
811# define R300_TXO_OFFSET_SHIFT 5 830# define R300_TXO_OFFSET_SHIFT 5
812/* END */ 831/* END */
813#define R300_TX_UNK4_0 0x4580 832#define R300_TX_CHROMA_KEY_0 0x4580 /* 32 bit chroma key */
814#define R300_TX_BORDER_COLOR_0 0x45C0 //ff00ff00 == { 0, 1.0, 0, 1.0 } 833#define R300_TX_BORDER_COLOR_0 0x45C0 //ff00ff00 == { 0, 1.0, 0, 1.0 }
815 834
816/* END */ 835/* END */
817 836
@@ -868,7 +887,9 @@ I am fairly certain that they are correct unless stated otherwise in comments.
868# define R300_PFS_NODE_TEX_OFFSET_MASK (31 << 12) 887# define R300_PFS_NODE_TEX_OFFSET_MASK (31 << 12)
869# define R300_PFS_NODE_TEX_END_SHIFT 17 888# define R300_PFS_NODE_TEX_END_SHIFT 17
870# define R300_PFS_NODE_TEX_END_MASK (31 << 17) 889# define R300_PFS_NODE_TEX_END_MASK (31 << 17)
871# define R300_PFS_NODE_LAST_NODE (1 << 22) 890/*# define R300_PFS_NODE_LAST_NODE (1 << 22) */
891# define R300_PFS_NODE_OUTPUT_COLOR (1 << 22)
892# define R300_PFS_NODE_OUTPUT_DEPTH (1 << 23)
872 893
873/* TEX 894/* TEX
874// As far as I can tell, texture instructions cannot write into output 895// As far as I can tell, texture instructions cannot write into output
@@ -887,6 +908,7 @@ I am fairly certain that they are correct unless stated otherwise in comments.
887 */ 908 */
888# define R300_FPITX_OPCODE_SHIFT 15 909# define R300_FPITX_OPCODE_SHIFT 15
889# define R300_FPITX_OP_TEX 1 910# define R300_FPITX_OP_TEX 1
911# define R300_FPITX_OP_KIL 2
890# define R300_FPITX_OP_TXP 3 912# define R300_FPITX_OP_TXP 3
891# define R300_FPITX_OP_TXB 4 913# define R300_FPITX_OP_TXB 4
892 914
@@ -962,9 +984,11 @@ I am fairly certain that they are correct unless stated otherwise in comments.
962# define R300_FPI1_SRC2C_CONST (1 << 17) 984# define R300_FPI1_SRC2C_CONST (1 << 17)
963# define R300_FPI1_DSTC_SHIFT 18 985# define R300_FPI1_DSTC_SHIFT 18
964# define R300_FPI1_DSTC_MASK (31 << 18) 986# define R300_FPI1_DSTC_MASK (31 << 18)
987# define R300_FPI1_DSTC_REG_MASK_SHIFT 23
965# define R300_FPI1_DSTC_REG_X (1 << 23) 988# define R300_FPI1_DSTC_REG_X (1 << 23)
966# define R300_FPI1_DSTC_REG_Y (1 << 24) 989# define R300_FPI1_DSTC_REG_Y (1 << 24)
967# define R300_FPI1_DSTC_REG_Z (1 << 25) 990# define R300_FPI1_DSTC_REG_Z (1 << 25)
991# define R300_FPI1_DSTC_OUTPUT_MASK_SHIFT 26
968# define R300_FPI1_DSTC_OUTPUT_X (1 << 26) 992# define R300_FPI1_DSTC_OUTPUT_X (1 << 26)
969# define R300_FPI1_DSTC_OUTPUT_Y (1 << 27) 993# define R300_FPI1_DSTC_OUTPUT_Y (1 << 27)
970# define R300_FPI1_DSTC_OUTPUT_Z (1 << 28) 994# define R300_FPI1_DSTC_OUTPUT_Z (1 << 28)
@@ -983,6 +1007,7 @@ I am fairly certain that they are correct unless stated otherwise in comments.
983# define R300_FPI3_DSTA_MASK (31 << 18) 1007# define R300_FPI3_DSTA_MASK (31 << 18)
984# define R300_FPI3_DSTA_REG (1 << 23) 1008# define R300_FPI3_DSTA_REG (1 << 23)
985# define R300_FPI3_DSTA_OUTPUT (1 << 24) 1009# define R300_FPI3_DSTA_OUTPUT (1 << 24)
1010# define R300_FPI3_DSTA_DEPTH (1 << 27)
986 1011
987#define R300_PFS_INSTR0_0 0x48C0 1012#define R300_PFS_INSTR0_0 0x48C0
988# define R300_FPI0_ARGC_SRC0C_XYZ 0 1013# define R300_FPI0_ARGC_SRC0C_XYZ 0
@@ -1036,7 +1061,7 @@ I am fairly certain that they are correct unless stated otherwise in comments.
1036# define R300_FPI0_OUTC_FRC (9 << 23) 1061# define R300_FPI0_OUTC_FRC (9 << 23)
1037# define R300_FPI0_OUTC_REPL_ALPHA (10 << 23) 1062# define R300_FPI0_OUTC_REPL_ALPHA (10 << 23)
1038# define R300_FPI0_OUTC_SAT (1 << 30) 1063# define R300_FPI0_OUTC_SAT (1 << 30)
1039# define R300_FPI0_UNKNOWN_31 (1 << 31) 1064# define R300_FPI0_INSERT_NOP (1 << 31)
1040 1065
1041#define R300_PFS_INSTR2_0 0x49C0 1066#define R300_PFS_INSTR2_0 0x49C0
1042# define R300_FPI2_ARGA_SRC0C_X 0 1067# define R300_FPI2_ARGA_SRC0C_X 0
diff --git a/drivers/char/drm/radeon_cp.c b/drivers/char/drm/radeon_cp.c
index 9bb8ae0c1c27..7f949c9c9691 100644
--- a/drivers/char/drm/radeon_cp.c
+++ b/drivers/char/drm/radeon_cp.c
@@ -1118,14 +1118,20 @@ static void radeon_cp_init_ring_buffer(drm_device_t * dev,
1118{ 1118{
1119 u32 ring_start, cur_read_ptr; 1119 u32 ring_start, cur_read_ptr;
1120 u32 tmp; 1120 u32 tmp;
1121 1121
1122 /* Initialize the memory controller */ 1122 /* Initialize the memory controller. With new memory map, the fb location
1123 RADEON_WRITE(RADEON_MC_FB_LOCATION, 1123 * is not changed, it should have been properly initialized already. Part
1124 ((dev_priv->gart_vm_start - 1) & 0xffff0000) 1124 * of the problem is that the code below is bogus, assuming the GART is
1125 | (dev_priv->fb_location >> 16)); 1125 * always appended to the fb which is not necessarily the case
1126 */
1127 if (!dev_priv->new_memmap)
1128 RADEON_WRITE(RADEON_MC_FB_LOCATION,
1129 ((dev_priv->gart_vm_start - 1) & 0xffff0000)
1130 | (dev_priv->fb_location >> 16));
1126 1131
1127#if __OS_HAS_AGP 1132#if __OS_HAS_AGP
1128 if (dev_priv->flags & CHIP_IS_AGP) { 1133 if (dev_priv->flags & CHIP_IS_AGP) {
1134 RADEON_WRITE(RADEON_AGP_BASE, (unsigned int)dev->agp->base);
1129 RADEON_WRITE(RADEON_MC_AGP_LOCATION, 1135 RADEON_WRITE(RADEON_MC_AGP_LOCATION,
1130 (((dev_priv->gart_vm_start - 1 + 1136 (((dev_priv->gart_vm_start - 1 +
1131 dev_priv->gart_size) & 0xffff0000) | 1137 dev_priv->gart_size) & 0xffff0000) |
@@ -1153,8 +1159,6 @@ static void radeon_cp_init_ring_buffer(drm_device_t * dev,
1153 1159
1154#if __OS_HAS_AGP 1160#if __OS_HAS_AGP
1155 if (dev_priv->flags & CHIP_IS_AGP) { 1161 if (dev_priv->flags & CHIP_IS_AGP) {
1156 /* set RADEON_AGP_BASE here instead of relying on X from user space */
1157 RADEON_WRITE(RADEON_AGP_BASE, (unsigned int)dev->agp->base);
1158 RADEON_WRITE(RADEON_CP_RB_RPTR_ADDR, 1162 RADEON_WRITE(RADEON_CP_RB_RPTR_ADDR,
1159 dev_priv->ring_rptr->offset 1163 dev_priv->ring_rptr->offset
1160 - dev->agp->base + dev_priv->gart_vm_start); 1164 - dev->agp->base + dev_priv->gart_vm_start);
@@ -1174,6 +1178,17 @@ static void radeon_cp_init_ring_buffer(drm_device_t * dev,
1174 entry->handle + tmp_ofs); 1178 entry->handle + tmp_ofs);
1175 } 1179 }
1176 1180
1181 /* Set ring buffer size */
1182#ifdef __BIG_ENDIAN
1183 RADEON_WRITE(RADEON_CP_RB_CNTL,
1184 dev_priv->ring.size_l2qw | RADEON_BUF_SWAP_32BIT);
1185#else
1186 RADEON_WRITE(RADEON_CP_RB_CNTL, dev_priv->ring.size_l2qw);
1187#endif
1188
1189 /* Start with assuming that writeback doesn't work */
1190 dev_priv->writeback_works = 0;
1191
1177 /* Initialize the scratch register pointer. This will cause 1192 /* Initialize the scratch register pointer. This will cause
1178 * the scratch register values to be written out to memory 1193 * the scratch register values to be written out to memory
1179 * whenever they are updated. 1194 * whenever they are updated.
@@ -1190,28 +1205,9 @@ static void radeon_cp_init_ring_buffer(drm_device_t * dev,
1190 1205
1191 RADEON_WRITE(RADEON_SCRATCH_UMSK, 0x7); 1206 RADEON_WRITE(RADEON_SCRATCH_UMSK, 0x7);
1192 1207
1193 /* Writeback doesn't seem to work everywhere, test it first */ 1208 /* Turn on bus mastering */
1194 DRM_WRITE32(dev_priv->ring_rptr, RADEON_SCRATCHOFF(1), 0); 1209 tmp = RADEON_READ(RADEON_BUS_CNTL) & ~RADEON_BUS_MASTER_DIS;
1195 RADEON_WRITE(RADEON_SCRATCH_REG1, 0xdeadbeef); 1210 RADEON_WRITE(RADEON_BUS_CNTL, tmp);
1196
1197 for (tmp = 0; tmp < dev_priv->usec_timeout; tmp++) {
1198 if (DRM_READ32(dev_priv->ring_rptr, RADEON_SCRATCHOFF(1)) ==
1199 0xdeadbeef)
1200 break;
1201 DRM_UDELAY(1);
1202 }
1203
1204 if (tmp < dev_priv->usec_timeout) {
1205 dev_priv->writeback_works = 1;
1206 DRM_DEBUG("writeback test succeeded, tmp=%d\n", tmp);
1207 } else {
1208 dev_priv->writeback_works = 0;
1209 DRM_DEBUG("writeback test failed\n");
1210 }
1211 if (radeon_no_wb == 1) {
1212 dev_priv->writeback_works = 0;
1213 DRM_DEBUG("writeback forced off\n");
1214 }
1215 1211
1216 dev_priv->sarea_priv->last_frame = dev_priv->scratch[0] = 0; 1212 dev_priv->sarea_priv->last_frame = dev_priv->scratch[0] = 0;
1217 RADEON_WRITE(RADEON_LAST_FRAME_REG, dev_priv->sarea_priv->last_frame); 1213 RADEON_WRITE(RADEON_LAST_FRAME_REG, dev_priv->sarea_priv->last_frame);
@@ -1223,26 +1219,45 @@ static void radeon_cp_init_ring_buffer(drm_device_t * dev,
1223 dev_priv->sarea_priv->last_clear = dev_priv->scratch[2] = 0; 1219 dev_priv->sarea_priv->last_clear = dev_priv->scratch[2] = 0;
1224 RADEON_WRITE(RADEON_LAST_CLEAR_REG, dev_priv->sarea_priv->last_clear); 1220 RADEON_WRITE(RADEON_LAST_CLEAR_REG, dev_priv->sarea_priv->last_clear);
1225 1221
1226 /* Set ring buffer size */
1227#ifdef __BIG_ENDIAN
1228 RADEON_WRITE(RADEON_CP_RB_CNTL,
1229 dev_priv->ring.size_l2qw | RADEON_BUF_SWAP_32BIT);
1230#else
1231 RADEON_WRITE(RADEON_CP_RB_CNTL, dev_priv->ring.size_l2qw);
1232#endif
1233
1234 radeon_do_wait_for_idle(dev_priv); 1222 radeon_do_wait_for_idle(dev_priv);
1235 1223
1236 /* Turn on bus mastering */
1237 tmp = RADEON_READ(RADEON_BUS_CNTL) & ~RADEON_BUS_MASTER_DIS;
1238 RADEON_WRITE(RADEON_BUS_CNTL, tmp);
1239
1240 /* Sync everything up */ 1224 /* Sync everything up */
1241 RADEON_WRITE(RADEON_ISYNC_CNTL, 1225 RADEON_WRITE(RADEON_ISYNC_CNTL,
1242 (RADEON_ISYNC_ANY2D_IDLE3D | 1226 (RADEON_ISYNC_ANY2D_IDLE3D |
1243 RADEON_ISYNC_ANY3D_IDLE2D | 1227 RADEON_ISYNC_ANY3D_IDLE2D |
1244 RADEON_ISYNC_WAIT_IDLEGUI | 1228 RADEON_ISYNC_WAIT_IDLEGUI |
1245 RADEON_ISYNC_CPSCRATCH_IDLEGUI)); 1229 RADEON_ISYNC_CPSCRATCH_IDLEGUI));
1230
1231}
1232
1233static void radeon_test_writeback(drm_radeon_private_t * dev_priv)
1234{
1235 u32 tmp;
1236
1237 /* Writeback doesn't seem to work everywhere, test it here and possibly
1238 * enable it if it appears to work
1239 */
1240 DRM_WRITE32(dev_priv->ring_rptr, RADEON_SCRATCHOFF(1), 0);
1241 RADEON_WRITE(RADEON_SCRATCH_REG1, 0xdeadbeef);
1242
1243 for (tmp = 0; tmp < dev_priv->usec_timeout; tmp++) {
1244 if (DRM_READ32(dev_priv->ring_rptr, RADEON_SCRATCHOFF(1)) ==
1245 0xdeadbeef)
1246 break;
1247 DRM_UDELAY(1);
1248 }
1249
1250 if (tmp < dev_priv->usec_timeout) {
1251 dev_priv->writeback_works = 1;
1252 DRM_INFO("writeback test succeeded in %d usecs\n", tmp);
1253 } else {
1254 dev_priv->writeback_works = 0;
1255 DRM_INFO("writeback test failed\n");
1256 }
1257 if (radeon_no_wb == 1) {
1258 dev_priv->writeback_works = 0;
1259 DRM_INFO("writeback forced off\n");
1260 }
1246} 1261}
1247 1262
1248/* Enable or disable PCI-E GART on the chip */ 1263/* Enable or disable PCI-E GART on the chip */
@@ -1317,6 +1332,14 @@ static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init)
1317 1332
1318 DRM_DEBUG("\n"); 1333 DRM_DEBUG("\n");
1319 1334
1335 /* if we require new memory map but we don't have it fail */
1336 if ((dev_priv->flags & CHIP_NEW_MEMMAP) && !dev_priv->new_memmap)
1337 {
1338 DRM_ERROR("Cannot initialise DRM on this card\nThis card requires a new X.org DDX\n");
1339 radeon_do_cleanup_cp(dev);
1340 return DRM_ERR(EINVAL);
1341 }
1342
1320 if (init->is_pci && (dev_priv->flags & CHIP_IS_AGP)) 1343 if (init->is_pci && (dev_priv->flags & CHIP_IS_AGP))
1321 { 1344 {
1322 DRM_DEBUG("Forcing AGP card to PCI mode\n"); 1345 DRM_DEBUG("Forcing AGP card to PCI mode\n");
@@ -1496,6 +1519,9 @@ static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init)
1496 1519
1497 dev_priv->fb_location = (RADEON_READ(RADEON_MC_FB_LOCATION) 1520 dev_priv->fb_location = (RADEON_READ(RADEON_MC_FB_LOCATION)
1498 & 0xffff) << 16; 1521 & 0xffff) << 16;
1522 dev_priv->fb_size =
1523 ((RADEON_READ(RADEON_MC_FB_LOCATION) & 0xffff0000u) + 0x10000)
1524 - dev_priv->fb_location;
1499 1525
1500 dev_priv->front_pitch_offset = (((dev_priv->front_pitch / 64) << 22) | 1526 dev_priv->front_pitch_offset = (((dev_priv->front_pitch / 64) << 22) |
1501 ((dev_priv->front_offset 1527 ((dev_priv->front_offset
@@ -1510,8 +1536,46 @@ static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init)
1510 + dev_priv->fb_location) >> 10)); 1536 + dev_priv->fb_location) >> 10));
1511 1537
1512 dev_priv->gart_size = init->gart_size; 1538 dev_priv->gart_size = init->gart_size;
1513 dev_priv->gart_vm_start = dev_priv->fb_location 1539
1514 + RADEON_READ(RADEON_CONFIG_APER_SIZE); 1540 /* New let's set the memory map ... */
1541 if (dev_priv->new_memmap) {
1542 u32 base = 0;
1543
1544 DRM_INFO("Setting GART location based on new memory map\n");
1545
1546 /* If using AGP, try to locate the AGP aperture at the same
1547 * location in the card and on the bus, though we have to
1548 * align it down.
1549 */
1550#if __OS_HAS_AGP
1551 if (dev_priv->flags & CHIP_IS_AGP) {
1552 base = dev->agp->base;
1553 /* Check if valid */
1554 if ((base + dev_priv->gart_size) > dev_priv->fb_location &&
1555 base < (dev_priv->fb_location + dev_priv->fb_size)) {
1556 DRM_INFO("Can't use AGP base @0x%08lx, won't fit\n",
1557 dev->agp->base);
1558 base = 0;
1559 }
1560 }
1561#endif
1562 /* If not or if AGP is at 0 (Macs), try to put it elsewhere */
1563 if (base == 0) {
1564 base = dev_priv->fb_location + dev_priv->fb_size;
1565 if (((base + dev_priv->gart_size) & 0xfffffffful)
1566 < base)
1567 base = dev_priv->fb_location
1568 - dev_priv->gart_size;
1569 }
1570 dev_priv->gart_vm_start = base & 0xffc00000u;
1571 if (dev_priv->gart_vm_start != base)
1572 DRM_INFO("GART aligned down from 0x%08x to 0x%08x\n",
1573 base, dev_priv->gart_vm_start);
1574 } else {
1575 DRM_INFO("Setting GART location based on old memory map\n");
1576 dev_priv->gart_vm_start = dev_priv->fb_location +
1577 RADEON_READ(RADEON_CONFIG_APER_SIZE);
1578 }
1515 1579
1516#if __OS_HAS_AGP 1580#if __OS_HAS_AGP
1517 if (dev_priv->flags & CHIP_IS_AGP) 1581 if (dev_priv->flags & CHIP_IS_AGP)
@@ -1596,6 +1660,7 @@ static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init)
1596 dev_priv->last_buf = 0; 1660 dev_priv->last_buf = 0;
1597 1661
1598 radeon_do_engine_reset(dev); 1662 radeon_do_engine_reset(dev);
1663 radeon_test_writeback(dev_priv);
1599 1664
1600 return 0; 1665 return 0;
1601} 1666}
diff --git a/drivers/char/drm/radeon_drm.h b/drivers/char/drm/radeon_drm.h
index 9c177a6b2a4c..c8e279e89c2e 100644
--- a/drivers/char/drm/radeon_drm.h
+++ b/drivers/char/drm/radeon_drm.h
@@ -222,6 +222,7 @@ typedef union {
222# define R300_WAIT_3D 0x2 222# define R300_WAIT_3D 0x2
223# define R300_WAIT_2D_CLEAN 0x3 223# define R300_WAIT_2D_CLEAN 0x3
224# define R300_WAIT_3D_CLEAN 0x4 224# define R300_WAIT_3D_CLEAN 0x4
225#define R300_CMD_SCRATCH 8
225 226
226typedef union { 227typedef union {
227 unsigned int u; 228 unsigned int u;
@@ -247,6 +248,9 @@ typedef union {
247 struct { 248 struct {
248 unsigned char cmd_type, flags, pad0, pad1; 249 unsigned char cmd_type, flags, pad0, pad1;
249 } wait; 250 } wait;
251 struct {
252 unsigned char cmd_type, reg, n_bufs, flags;
253 } scratch;
250} drm_r300_cmd_header_t; 254} drm_r300_cmd_header_t;
251 255
252#define RADEON_FRONT 0x1 256#define RADEON_FRONT 0x1
@@ -697,6 +701,7 @@ typedef struct drm_radeon_setparam {
697#define RADEON_SETPARAM_FB_LOCATION 1 /* determined framebuffer location */ 701#define RADEON_SETPARAM_FB_LOCATION 1 /* determined framebuffer location */
698#define RADEON_SETPARAM_SWITCH_TILING 2 /* enable/disable color tiling */ 702#define RADEON_SETPARAM_SWITCH_TILING 2 /* enable/disable color tiling */
699#define RADEON_SETPARAM_PCIGART_LOCATION 3 /* PCI Gart Location */ 703#define RADEON_SETPARAM_PCIGART_LOCATION 3 /* PCI Gart Location */
704#define RADEON_SETPARAM_NEW_MEMMAP 4 /* Use new memory map */
700 705
701/* 1.14: Clients can allocate/free a surface 706/* 1.14: Clients can allocate/free a surface
702 */ 707 */
diff --git a/drivers/char/drm/radeon_drv.h b/drivers/char/drm/radeon_drv.h
index 1f7d2ab8c4fc..78345cee8f8e 100644
--- a/drivers/char/drm/radeon_drv.h
+++ b/drivers/char/drm/radeon_drv.h
@@ -38,7 +38,7 @@
38 38
39#define DRIVER_NAME "radeon" 39#define DRIVER_NAME "radeon"
40#define DRIVER_DESC "ATI Radeon" 40#define DRIVER_DESC "ATI Radeon"
41#define DRIVER_DATE "20051229" 41#define DRIVER_DATE "20060225"
42 42
43/* Interface history: 43/* Interface history:
44 * 44 *
@@ -91,9 +91,11 @@
91 * 1.20- Add support for r300 texrect 91 * 1.20- Add support for r300 texrect
92 * 1.21- Add support for card type getparam 92 * 1.21- Add support for card type getparam
93 * 1.22- Add support for texture cache flushes (R300_TX_CNTL) 93 * 1.22- Add support for texture cache flushes (R300_TX_CNTL)
94 * 1.23- Add new radeon memory map work from benh
95 * 1.24- Add general-purpose packet for manipulating scratch registers (r300)
94 */ 96 */
95#define DRIVER_MAJOR 1 97#define DRIVER_MAJOR 1
96#define DRIVER_MINOR 22 98#define DRIVER_MINOR 24
97#define DRIVER_PATCHLEVEL 0 99#define DRIVER_PATCHLEVEL 0
98 100
99/* 101/*
@@ -101,20 +103,21 @@
101 */ 103 */
102enum radeon_family { 104enum radeon_family {
103 CHIP_R100, 105 CHIP_R100,
104 CHIP_RS100,
105 CHIP_RV100, 106 CHIP_RV100,
107 CHIP_RS100,
106 CHIP_RV200, 108 CHIP_RV200,
107 CHIP_R200,
108 CHIP_RS200, 109 CHIP_RS200,
109 CHIP_R250, 110 CHIP_R200,
110 CHIP_RS250,
111 CHIP_RV250, 111 CHIP_RV250,
112 CHIP_RS300,
112 CHIP_RV280, 113 CHIP_RV280,
113 CHIP_R300, 114 CHIP_R300,
114 CHIP_RS300,
115 CHIP_R350, 115 CHIP_R350,
116 CHIP_RV350, 116 CHIP_RV350,
117 CHIP_RV380,
117 CHIP_R420, 118 CHIP_R420,
119 CHIP_RV410,
120 CHIP_RS400,
118 CHIP_LAST, 121 CHIP_LAST,
119}; 122};
120 123
@@ -136,9 +139,11 @@ enum radeon_chip_flags {
136 CHIP_IS_AGP = 0x00080000UL, 139 CHIP_IS_AGP = 0x00080000UL,
137 CHIP_HAS_HIERZ = 0x00100000UL, 140 CHIP_HAS_HIERZ = 0x00100000UL,
138 CHIP_IS_PCIE = 0x00200000UL, 141 CHIP_IS_PCIE = 0x00200000UL,
142 CHIP_NEW_MEMMAP = 0x00400000UL,
139}; 143};
140 144
141#define GET_RING_HEAD(dev_priv) DRM_READ32( (dev_priv)->ring_rptr, 0 ) 145#define GET_RING_HEAD(dev_priv) (dev_priv->writeback_works ? \
146 DRM_READ32( (dev_priv)->ring_rptr, 0 ) : RADEON_READ(RADEON_CP_RB_RPTR))
142#define SET_RING_HEAD(dev_priv,val) DRM_WRITE32( (dev_priv)->ring_rptr, 0, (val) ) 147#define SET_RING_HEAD(dev_priv,val) DRM_WRITE32( (dev_priv)->ring_rptr, 0, (val) )
143 148
144typedef struct drm_radeon_freelist { 149typedef struct drm_radeon_freelist {
@@ -199,6 +204,8 @@ typedef struct drm_radeon_private {
199 drm_radeon_sarea_t *sarea_priv; 204 drm_radeon_sarea_t *sarea_priv;
200 205
201 u32 fb_location; 206 u32 fb_location;
207 u32 fb_size;
208 int new_memmap;
202 209
203 int gart_size; 210 int gart_size;
204 u32 gart_vm_start; 211 u32 gart_vm_start;
@@ -272,6 +279,8 @@ typedef struct drm_radeon_private {
272 unsigned long pcigart_offset; 279 unsigned long pcigart_offset;
273 drm_ati_pcigart_info gart_info; 280 drm_ati_pcigart_info gart_info;
274 281
282 u32 scratch_ages[5];
283
275 /* starting from here on, data is preserved accross an open */ 284 /* starting from here on, data is preserved accross an open */
276 uint32_t flags; /* see radeon_chip_flags */ 285 uint32_t flags; /* see radeon_chip_flags */
277} drm_radeon_private_t; 286} drm_radeon_private_t;
diff --git a/drivers/char/drm/radeon_state.c b/drivers/char/drm/radeon_state.c
index 7bc27516d425..c5b8f774a599 100644
--- a/drivers/char/drm/radeon_state.c
+++ b/drivers/char/drm/radeon_state.c
@@ -45,22 +45,53 @@ static __inline__ int radeon_check_and_fixup_offset(drm_radeon_private_t *
45 u32 off = *offset; 45 u32 off = *offset;
46 struct drm_radeon_driver_file_fields *radeon_priv; 46 struct drm_radeon_driver_file_fields *radeon_priv;
47 47
48 if (off >= dev_priv->fb_location && 48 /* Hrm ... the story of the offset ... So this function converts
49 off < (dev_priv->gart_vm_start + dev_priv->gart_size)) 49 * the various ideas of what userland clients might have for an
50 return 0; 50 * offset in the card address space into an offset into the card
51 51 * address space :) So with a sane client, it should just keep
52 radeon_priv = filp_priv->driver_priv; 52 * the value intact and just do some boundary checking. However,
53 off += radeon_priv->radeon_fb_delta; 53 * not all clients are sane. Some older clients pass us 0 based
54 * offsets relative to the start of the framebuffer and some may
55 * assume the AGP aperture it appended to the framebuffer, so we
56 * try to detect those cases and fix them up.
57 *
58 * Note: It might be a good idea here to make sure the offset lands
59 * in some "allowed" area to protect things like the PCIE GART...
60 */
54 61
55 DRM_DEBUG("offset fixed up to 0x%x\n", off); 62 /* First, the best case, the offset already lands in either the
63 * framebuffer or the GART mapped space
64 */
65 if ((off >= dev_priv->fb_location &&
66 off < (dev_priv->fb_location + dev_priv->fb_size)) ||
67 (off >= dev_priv->gart_vm_start &&
68 off < (dev_priv->gart_vm_start + dev_priv->gart_size)))
69 return 0;
56 70
57 if (off < dev_priv->fb_location || 71 /* Ok, that didn't happen... now check if we have a zero based
58 off >= (dev_priv->gart_vm_start + dev_priv->gart_size)) 72 * offset that fits in the framebuffer + gart space, apply the
59 return DRM_ERR(EINVAL); 73 * magic offset we get from SETPARAM or calculated from fb_location
74 */
75 if (off < (dev_priv->fb_size + dev_priv->gart_size)) {
76 radeon_priv = filp_priv->driver_priv;
77 off += radeon_priv->radeon_fb_delta;
78 }
60 79
61 *offset = off; 80 /* Finally, assume we aimed at a GART offset if beyond the fb */
81 if (off > (dev_priv->fb_location + dev_priv->fb_size))
82 off = off - (dev_priv->fb_location + dev_priv->fb_size) +
83 dev_priv->gart_vm_start;
62 84
63 return 0; 85 /* Now recheck and fail if out of bounds */
86 if ((off >= dev_priv->fb_location &&
87 off < (dev_priv->fb_location + dev_priv->fb_size)) ||
88 (off >= dev_priv->gart_vm_start &&
89 off < (dev_priv->gart_vm_start + dev_priv->gart_size))) {
90 DRM_DEBUG("offset fixed up to 0x%x\n", off);
91 *offset = off;
92 return 0;
93 }
94 return DRM_ERR(EINVAL);
64} 95}
65 96
66static __inline__ int radeon_check_and_fixup_packets(drm_radeon_private_t * 97static __inline__ int radeon_check_and_fixup_packets(drm_radeon_private_t *
@@ -1939,11 +1970,6 @@ static int radeon_surface_alloc(DRM_IOCTL_ARGS)
1939 drm_radeon_private_t *dev_priv = dev->dev_private; 1970 drm_radeon_private_t *dev_priv = dev->dev_private;
1940 drm_radeon_surface_alloc_t alloc; 1971 drm_radeon_surface_alloc_t alloc;
1941 1972
1942 if (!dev_priv) {
1943 DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
1944 return DRM_ERR(EINVAL);
1945 }
1946
1947 DRM_COPY_FROM_USER_IOCTL(alloc, 1973 DRM_COPY_FROM_USER_IOCTL(alloc,
1948 (drm_radeon_surface_alloc_t __user *) data, 1974 (drm_radeon_surface_alloc_t __user *) data,
1949 sizeof(alloc)); 1975 sizeof(alloc));
@@ -1960,12 +1986,7 @@ static int radeon_surface_free(DRM_IOCTL_ARGS)
1960 drm_radeon_private_t *dev_priv = dev->dev_private; 1986 drm_radeon_private_t *dev_priv = dev->dev_private;
1961 drm_radeon_surface_free_t memfree; 1987 drm_radeon_surface_free_t memfree;
1962 1988
1963 if (!dev_priv) { 1989 DRM_COPY_FROM_USER_IOCTL(memfree, (drm_radeon_surface_free_t __user *) data,
1964 DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
1965 return DRM_ERR(EINVAL);
1966 }
1967
1968 DRM_COPY_FROM_USER_IOCTL(memfree, (drm_radeon_mem_free_t __user *) data,
1969 sizeof(memfree)); 1990 sizeof(memfree));
1970 1991
1971 if (free_surface(filp, dev_priv, memfree.address)) 1992 if (free_surface(filp, dev_priv, memfree.address))
@@ -2100,11 +2121,6 @@ static int radeon_cp_vertex(DRM_IOCTL_ARGS)
2100 2121
2101 LOCK_TEST_WITH_RETURN(dev, filp); 2122 LOCK_TEST_WITH_RETURN(dev, filp);
2102 2123
2103 if (!dev_priv) {
2104 DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
2105 return DRM_ERR(EINVAL);
2106 }
2107
2108 DRM_GET_PRIV_WITH_RETURN(filp_priv, filp); 2124 DRM_GET_PRIV_WITH_RETURN(filp_priv, filp);
2109 2125
2110 DRM_COPY_FROM_USER_IOCTL(vertex, (drm_radeon_vertex_t __user *) data, 2126 DRM_COPY_FROM_USER_IOCTL(vertex, (drm_radeon_vertex_t __user *) data,
@@ -2189,11 +2205,6 @@ static int radeon_cp_indices(DRM_IOCTL_ARGS)
2189 2205
2190 LOCK_TEST_WITH_RETURN(dev, filp); 2206 LOCK_TEST_WITH_RETURN(dev, filp);
2191 2207
2192 if (!dev_priv) {
2193 DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
2194 return DRM_ERR(EINVAL);
2195 }
2196
2197 DRM_GET_PRIV_WITH_RETURN(filp_priv, filp); 2208 DRM_GET_PRIV_WITH_RETURN(filp_priv, filp);
2198 2209
2199 DRM_COPY_FROM_USER_IOCTL(elts, (drm_radeon_indices_t __user *) data, 2210 DRM_COPY_FROM_USER_IOCTL(elts, (drm_radeon_indices_t __user *) data,
@@ -2340,11 +2351,6 @@ static int radeon_cp_indirect(DRM_IOCTL_ARGS)
2340 2351
2341 LOCK_TEST_WITH_RETURN(dev, filp); 2352 LOCK_TEST_WITH_RETURN(dev, filp);
2342 2353
2343 if (!dev_priv) {
2344 DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
2345 return DRM_ERR(EINVAL);
2346 }
2347
2348 DRM_COPY_FROM_USER_IOCTL(indirect, 2354 DRM_COPY_FROM_USER_IOCTL(indirect,
2349 (drm_radeon_indirect_t __user *) data, 2355 (drm_radeon_indirect_t __user *) data,
2350 sizeof(indirect)); 2356 sizeof(indirect));
@@ -2417,11 +2423,6 @@ static int radeon_cp_vertex2(DRM_IOCTL_ARGS)
2417 2423
2418 LOCK_TEST_WITH_RETURN(dev, filp); 2424 LOCK_TEST_WITH_RETURN(dev, filp);
2419 2425
2420 if (!dev_priv) {
2421 DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
2422 return DRM_ERR(EINVAL);
2423 }
2424
2425 DRM_GET_PRIV_WITH_RETURN(filp_priv, filp); 2426 DRM_GET_PRIV_WITH_RETURN(filp_priv, filp);
2426 2427
2427 DRM_COPY_FROM_USER_IOCTL(vertex, (drm_radeon_vertex2_t __user *) data, 2428 DRM_COPY_FROM_USER_IOCTL(vertex, (drm_radeon_vertex2_t __user *) data,
@@ -2738,11 +2739,6 @@ static int radeon_cp_cmdbuf(DRM_IOCTL_ARGS)
2738 2739
2739 LOCK_TEST_WITH_RETURN(dev, filp); 2740 LOCK_TEST_WITH_RETURN(dev, filp);
2740 2741
2741 if (!dev_priv) {
2742 DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
2743 return DRM_ERR(EINVAL);
2744 }
2745
2746 DRM_GET_PRIV_WITH_RETURN(filp_priv, filp); 2742 DRM_GET_PRIV_WITH_RETURN(filp_priv, filp);
2747 2743
2748 DRM_COPY_FROM_USER_IOCTL(cmdbuf, 2744 DRM_COPY_FROM_USER_IOCTL(cmdbuf,
@@ -2897,11 +2893,6 @@ static int radeon_cp_getparam(DRM_IOCTL_ARGS)
2897 drm_radeon_getparam_t param; 2893 drm_radeon_getparam_t param;
2898 int value; 2894 int value;
2899 2895
2900 if (!dev_priv) {
2901 DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
2902 return DRM_ERR(EINVAL);
2903 }
2904
2905 DRM_COPY_FROM_USER_IOCTL(param, (drm_radeon_getparam_t __user *) data, 2896 DRM_COPY_FROM_USER_IOCTL(param, (drm_radeon_getparam_t __user *) data,
2906 sizeof(param)); 2897 sizeof(param));
2907 2898
@@ -2981,11 +2972,6 @@ static int radeon_cp_setparam(DRM_IOCTL_ARGS)
2981 drm_radeon_setparam_t sp; 2972 drm_radeon_setparam_t sp;
2982 struct drm_radeon_driver_file_fields *radeon_priv; 2973 struct drm_radeon_driver_file_fields *radeon_priv;
2983 2974
2984 if (!dev_priv) {
2985 DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
2986 return DRM_ERR(EINVAL);
2987 }
2988
2989 DRM_GET_PRIV_WITH_RETURN(filp_priv, filp); 2975 DRM_GET_PRIV_WITH_RETURN(filp_priv, filp);
2990 2976
2991 DRM_COPY_FROM_USER_IOCTL(sp, (drm_radeon_setparam_t __user *) data, 2977 DRM_COPY_FROM_USER_IOCTL(sp, (drm_radeon_setparam_t __user *) data,
@@ -3012,6 +2998,9 @@ static int radeon_cp_setparam(DRM_IOCTL_ARGS)
3012 case RADEON_SETPARAM_PCIGART_LOCATION: 2998 case RADEON_SETPARAM_PCIGART_LOCATION:
3013 dev_priv->pcigart_offset = sp.value; 2999 dev_priv->pcigart_offset = sp.value;
3014 break; 3000 break;
3001 case RADEON_SETPARAM_NEW_MEMMAP:
3002 dev_priv->new_memmap = sp.value;
3003 break;
3015 default: 3004 default:
3016 DRM_DEBUG("Invalid parameter %d\n", sp.param); 3005 DRM_DEBUG("Invalid parameter %d\n", sp.param);
3017 return DRM_ERR(EINVAL); 3006 return DRM_ERR(EINVAL);
diff --git a/drivers/char/drm/sis_mm.c b/drivers/char/drm/sis_mm.c
index 6774d2fe3452..5e9936bc307f 100644
--- a/drivers/char/drm/sis_mm.c
+++ b/drivers/char/drm/sis_mm.c
@@ -110,7 +110,7 @@ static int sis_fb_alloc(DRM_IOCTL_ARGS)
110 110
111 DRM_COPY_TO_USER_IOCTL(argp, fb, sizeof(fb)); 111 DRM_COPY_TO_USER_IOCTL(argp, fb, sizeof(fb));
112 112
113 DRM_DEBUG("alloc fb, size = %d, offset = %ld\n", fb.size, req.offset); 113 DRM_DEBUG("alloc fb, size = %d, offset = %d\n", fb.size, req.offset);
114 114
115 return retval; 115 return retval;
116} 116}
diff --git a/drivers/char/generic_nvram.c b/drivers/char/generic_nvram.c
index 1b5e01e6e129..43ff59816511 100644
--- a/drivers/char/generic_nvram.c
+++ b/drivers/char/generic_nvram.c
@@ -22,6 +22,9 @@
22#include <linux/smp_lock.h> 22#include <linux/smp_lock.h>
23#include <asm/uaccess.h> 23#include <asm/uaccess.h>
24#include <asm/nvram.h> 24#include <asm/nvram.h>
25#ifdef CONFIG_PPC_PMAC
26#include <asm/machdep.h>
27#endif
25 28
26#define NVRAM_SIZE 8192 29#define NVRAM_SIZE 8192
27 30
@@ -92,7 +95,7 @@ static int nvram_ioctl(struct inode *inode, struct file *file,
92 case IOC_NVRAM_GET_OFFSET: { 95 case IOC_NVRAM_GET_OFFSET: {
93 int part, offset; 96 int part, offset;
94 97
95 if (_machine != _MACH_Pmac) 98 if (!machine_is(powermac))
96 return -EINVAL; 99 return -EINVAL;
97 if (copy_from_user(&part, (void __user*)arg, sizeof(part)) != 0) 100 if (copy_from_user(&part, (void __user*)arg, sizeof(part)) != 0)
98 return -EFAULT; 101 return -EFAULT;
diff --git a/drivers/char/hvc_console.c b/drivers/char/hvc_console.c
index f65b2e14a485..2b6a56b2bf35 100644
--- a/drivers/char/hvc_console.c
+++ b/drivers/char/hvc_console.c
@@ -39,8 +39,10 @@
39#include <linux/sched.h> 39#include <linux/sched.h>
40#include <linux/spinlock.h> 40#include <linux/spinlock.h>
41#include <linux/delay.h> 41#include <linux/delay.h>
42
42#include <asm/uaccess.h> 43#include <asm/uaccess.h>
43#include <asm/hvconsole.h> 44
45#include "hvc_console.h"
44 46
45#define HVC_MAJOR 229 47#define HVC_MAJOR 229
46#define HVC_MINOR 0 48#define HVC_MINOR 0
@@ -54,17 +56,14 @@
54#define HVC_CLOSE_WAIT (HZ/100) /* 1/10 of a second */ 56#define HVC_CLOSE_WAIT (HZ/100) /* 1/10 of a second */
55 57
56/* 58/*
57 * The Linux TTY code does not support dynamic addition of tty derived devices 59 * These sizes are most efficient for vio, because they are the
58 * so we need to know how many tty devices we might need when space is allocated 60 * native transfer size. We could make them selectable in the
59 * for the tty device. Since this driver supports hotplug of vty adapters we 61 * future to better deal with backends that want other buffer sizes.
60 * need to make sure we have enough allocated.
61 */ 62 */
62#define HVC_ALLOC_TTY_ADAPTERS 8
63
64#define N_OUTBUF 16 63#define N_OUTBUF 16
65#define N_INBUF 16 64#define N_INBUF 16
66 65
67#define __ALIGNED__ __attribute__((__aligned__(8))) 66#define __ALIGNED__ __attribute__((__aligned__(sizeof(long))))
68 67
69static struct tty_driver *hvc_driver; 68static struct tty_driver *hvc_driver;
70static struct task_struct *hvc_task; 69static struct task_struct *hvc_task;
@@ -154,7 +153,7 @@ static uint32_t vtermnos[MAX_NR_HVC_CONSOLES] =
154 153
155void hvc_console_print(struct console *co, const char *b, unsigned count) 154void hvc_console_print(struct console *co, const char *b, unsigned count)
156{ 155{
157 char c[16] __ALIGNED__; 156 char c[N_OUTBUF] __ALIGNED__;
158 unsigned i = 0, n = 0; 157 unsigned i = 0, n = 0;
159 int r, donecr = 0, index = co->index; 158 int r, donecr = 0, index = co->index;
160 159
@@ -473,8 +472,10 @@ static void hvc_push(struct hvc_struct *hp)
473 472
474 n = hp->ops->put_chars(hp->vtermno, hp->outbuf, hp->n_outbuf); 473 n = hp->ops->put_chars(hp->vtermno, hp->outbuf, hp->n_outbuf);
475 if (n <= 0) { 474 if (n <= 0) {
476 if (n == 0) 475 if (n == 0) {
476 hp->do_wakeup = 1;
477 return; 477 return;
478 }
478 /* throw away output on error; this happens when 479 /* throw away output on error; this happens when
479 there is no session connected to the vterm. */ 480 there is no session connected to the vterm. */
480 hp->n_outbuf = 0; 481 hp->n_outbuf = 0;
@@ -486,12 +487,19 @@ static void hvc_push(struct hvc_struct *hp)
486 hp->do_wakeup = 1; 487 hp->do_wakeup = 1;
487} 488}
488 489
489static inline int __hvc_write_kernel(struct hvc_struct *hp, 490static int hvc_write(struct tty_struct *tty, const unsigned char *buf, int count)
490 const unsigned char *buf, int count)
491{ 491{
492 struct hvc_struct *hp = tty->driver_data;
492 unsigned long flags; 493 unsigned long flags;
493 int rsize, written = 0; 494 int rsize, written = 0;
494 495
496 /* This write was probably executed during a tty close. */
497 if (!hp)
498 return -EPIPE;
499
500 if (hp->count <= 0)
501 return -EIO;
502
495 spin_lock_irqsave(&hp->lock, flags); 503 spin_lock_irqsave(&hp->lock, flags);
496 504
497 /* Push pending writes */ 505 /* Push pending writes */
@@ -510,26 +518,8 @@ static inline int __hvc_write_kernel(struct hvc_struct *hp,
510 } 518 }
511 spin_unlock_irqrestore(&hp->lock, flags); 519 spin_unlock_irqrestore(&hp->lock, flags);
512 520
513 return written;
514}
515static int hvc_write(struct tty_struct *tty, const unsigned char *buf, int count)
516{
517 struct hvc_struct *hp = tty->driver_data;
518 int written;
519
520 /* This write was probably executed during a tty close. */
521 if (!hp)
522 return -EPIPE;
523
524 if (hp->count <= 0)
525 return -EIO;
526
527 written = __hvc_write_kernel(hp, buf, count);
528
529 /* 521 /*
530 * Racy, but harmless, kick thread if there is still pending data. 522 * Racy, but harmless, kick thread if there is still pending data.
531 * There really is nothing wrong with kicking the thread, even if there
532 * is no buffered data.
533 */ 523 */
534 if (hp->n_outbuf) 524 if (hp->n_outbuf)
535 hvc_kick(); 525 hvc_kick();
@@ -614,6 +604,13 @@ static int hvc_poll(struct hvc_struct *hp)
614 spin_unlock_irqrestore(&hp->lock, flags); 604 spin_unlock_irqrestore(&hp->lock, flags);
615 tty_hangup(tty); 605 tty_hangup(tty);
616 spin_lock_irqsave(&hp->lock, flags); 606 spin_lock_irqsave(&hp->lock, flags);
607 } else if ( n == -EAGAIN ) {
608 /*
609 * Some back-ends can only ensure a certain min
610 * num of bytes read, which may be > 'count'.
611 * Let the tty clear the flip buff to make room.
612 */
613 poll_mask |= HVC_POLL_READ;
617 } 614 }
618 break; 615 break;
619 } 616 }
@@ -635,16 +632,7 @@ static int hvc_poll(struct hvc_struct *hp)
635 tty_insert_flip_char(tty, buf[i], 0); 632 tty_insert_flip_char(tty, buf[i], 0);
636 } 633 }
637 634
638 /*
639 * Account for the total amount read in one loop, and if above
640 * 64 bytes, we do a quick schedule loop to let the tty grok
641 * the data and eventually throttle us.
642 */
643 read_total += n; 635 read_total += n;
644 if (read_total >= 64) {
645 poll_mask |= HVC_POLL_QUICK;
646 break;
647 }
648 } 636 }
649 throttled: 637 throttled:
650 /* Wakeup write queue if necessary */ 638 /* Wakeup write queue if necessary */
@@ -767,7 +755,8 @@ struct hvc_struct __devinit *hvc_alloc(uint32_t vtermno, int irq,
767 * see if this vterm id matches one registered for console. 755 * see if this vterm id matches one registered for console.
768 */ 756 */
769 for (i=0; i < MAX_NR_HVC_CONSOLES; i++) 757 for (i=0; i < MAX_NR_HVC_CONSOLES; i++)
770 if (vtermnos[i] == hp->vtermno) 758 if (vtermnos[i] == hp->vtermno &&
759 cons_ops[i] == hp->ops)
771 break; 760 break;
772 761
773 /* no matching slot, just use a counter */ 762 /* no matching slot, just use a counter */
@@ -823,34 +812,38 @@ EXPORT_SYMBOL(hvc_remove);
823 * interfaces start to become available. */ 812 * interfaces start to become available. */
824int __init hvc_init(void) 813int __init hvc_init(void)
825{ 814{
815 struct tty_driver *drv;
816
826 /* We need more than hvc_count adapters due to hotplug additions. */ 817 /* We need more than hvc_count adapters due to hotplug additions. */
827 hvc_driver = alloc_tty_driver(HVC_ALLOC_TTY_ADAPTERS); 818 drv = alloc_tty_driver(HVC_ALLOC_TTY_ADAPTERS);
828 if (!hvc_driver) 819 if (!drv)
829 return -ENOMEM; 820 return -ENOMEM;
830 821
831 hvc_driver->owner = THIS_MODULE; 822 drv->owner = THIS_MODULE;
832 hvc_driver->devfs_name = "hvc/"; 823 drv->devfs_name = "hvc/";
833 hvc_driver->driver_name = "hvc"; 824 drv->driver_name = "hvc";
834 hvc_driver->name = "hvc"; 825 drv->name = "hvc";
835 hvc_driver->major = HVC_MAJOR; 826 drv->major = HVC_MAJOR;
836 hvc_driver->minor_start = HVC_MINOR; 827 drv->minor_start = HVC_MINOR;
837 hvc_driver->type = TTY_DRIVER_TYPE_SYSTEM; 828 drv->type = TTY_DRIVER_TYPE_SYSTEM;
838 hvc_driver->init_termios = tty_std_termios; 829 drv->init_termios = tty_std_termios;
839 hvc_driver->flags = TTY_DRIVER_REAL_RAW; 830 drv->flags = TTY_DRIVER_REAL_RAW;
840 tty_set_operations(hvc_driver, &hvc_ops); 831 tty_set_operations(drv, &hvc_ops);
841 832
842 /* Always start the kthread because there can be hotplug vty adapters 833 /* Always start the kthread because there can be hotplug vty adapters
843 * added later. */ 834 * added later. */
844 hvc_task = kthread_run(khvcd, NULL, "khvcd"); 835 hvc_task = kthread_run(khvcd, NULL, "khvcd");
845 if (IS_ERR(hvc_task)) { 836 if (IS_ERR(hvc_task)) {
846 panic("Couldn't create kthread for console.\n"); 837 panic("Couldn't create kthread for console.\n");
847 put_tty_driver(hvc_driver); 838 put_tty_driver(drv);
848 return -EIO; 839 return -EIO;
849 } 840 }
850 841
851 if (tty_register_driver(hvc_driver)) 842 if (tty_register_driver(drv))
852 panic("Couldn't register hvc console driver\n"); 843 panic("Couldn't register hvc console driver\n");
853 844
845 mb();
846 hvc_driver = drv;
854 return 0; 847 return 0;
855} 848}
856module_init(hvc_init); 849module_init(hvc_init);
diff --git a/drivers/char/hvc_console.h b/drivers/char/hvc_console.h
new file mode 100644
index 000000000000..96b7401319c1
--- /dev/null
+++ b/drivers/char/hvc_console.h
@@ -0,0 +1,63 @@
1/*
2 * hvc_console.h
3 * Copyright (C) 2005 IBM Corporation
4 *
5 * Author(s):
6 * Ryan S. Arnold <rsa@us.ibm.com>
7 *
8 * hvc_console header information:
9 * moved here from include/asm-powerpc/hvconsole.h
10 * and drivers/char/hvc_console.c
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 */
26
27#ifndef HVC_CONSOLE_H
28#define HVC_CONSOLE_H
29
30/*
31 * This is the max number of console adapters that can/will be found as
32 * console devices on first stage console init. Any number beyond this range
33 * can't be used as a console device but is still a valid tty device.
34 */
35#define MAX_NR_HVC_CONSOLES 16
36
37/*
38 * The Linux TTY code does not support dynamic addition of tty derived devices
39 * so we need to know how many tty devices we might need when space is allocated
40 * for the tty device. Since this driver supports hotplug of vty adapters we
41 * need to make sure we have enough allocated.
42 */
43#define HVC_ALLOC_TTY_ADAPTERS 8
44
45
46/* implemented by a low level driver */
47struct hv_ops {
48 int (*get_chars)(uint32_t vtermno, char *buf, int count);
49 int (*put_chars)(uint32_t vtermno, const char *buf, int count);
50};
51
52struct hvc_struct;
53
54/* Register a vterm and a slot index for use as a console (console_init) */
55extern int hvc_instantiate(uint32_t vtermno, int index, struct hv_ops *ops);
56
57/* register a vterm for hvc tty operation (module_init or hotplug add) */
58extern struct hvc_struct * __devinit hvc_alloc(uint32_t vtermno, int irq,
59 struct hv_ops *ops);
60/* remove a vterm from hvc tty operation (modele_exit or hotplug remove) */
61extern int __devexit hvc_remove(struct hvc_struct *hp);
62
63#endif // HVC_CONSOLE_H
diff --git a/drivers/char/hvc_rtas.c b/drivers/char/hvc_rtas.c
new file mode 100644
index 000000000000..83364ea63cba
--- /dev/null
+++ b/drivers/char/hvc_rtas.c
@@ -0,0 +1,138 @@
1/*
2 * IBM RTAS driver interface to hvc_console.c
3 *
4 * (C) Copyright IBM Corporation 2001-2005
5 * (C) Copyright Red Hat, Inc. 2005
6 *
7 * Author(s): Maximino Augilar <IBM STI Design Center>
8 * : Ryan S. Arnold <rsa@us.ibm.com>
9 * : Utz Bacher <utz.bacher@de.ibm.com>
10 * : David Woodhouse <dwmw2@infradead.org>
11 *
12 * inspired by drivers/char/hvc_console.c
13 * written by Anton Blanchard and Paul Mackerras
14 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2 of the License, or
18 * (at your option) any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, write to the Free Software
27 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28 */
29
30#include <linux/console.h>
31#include <linux/delay.h>
32#include <linux/err.h>
33#include <linux/init.h>
34#include <linux/moduleparam.h>
35#include <linux/types.h>
36
37#include <asm/irq.h>
38#include <asm/rtas.h>
39#include "hvc_console.h"
40
41#define hvc_rtas_cookie 0x67781e15
42struct hvc_struct *hvc_rtas_dev;
43
44#define RTASCONS_PUT_ATTEMPTS 16
45
46static int rtascons_put_char_token = RTAS_UNKNOWN_SERVICE;
47static int rtascons_get_char_token = RTAS_UNKNOWN_SERVICE;
48static int rtascons_put_delay = 100;
49module_param_named(put_delay, rtascons_put_delay, int, 0644);
50
51static inline int hvc_rtas_write_console(uint32_t vtermno, const char *buf, int count)
52{
53 int done;
54
55 /* if there is more than one character to be displayed, wait a bit */
56 for (done = 0; done < count; done++) {
57 int result;
58 result = rtas_call(rtascons_put_char_token, 1, 1, NULL, buf[done]);
59 if (result)
60 break;
61 }
62 /* the calling routine expects to receive the number of bytes sent */
63 return done;
64}
65
66static int hvc_rtas_read_console(uint32_t vtermno, char *buf, int count)
67{
68 int i;
69
70 for (i = 0; i < count; i++) {
71 int c, err;
72
73 err = rtas_call(rtascons_get_char_token, 0, 2, &c);
74 if (err)
75 break;
76
77 buf[i] = c;
78 }
79
80 return i;
81}
82
83static struct hv_ops hvc_rtas_get_put_ops = {
84 .get_chars = hvc_rtas_read_console,
85 .put_chars = hvc_rtas_write_console,
86};
87
88static int hvc_rtas_init(void)
89{
90 struct hvc_struct *hp;
91
92 if (rtascons_put_char_token == RTAS_UNKNOWN_SERVICE)
93 rtascons_put_char_token = rtas_token("put-term-char");
94 if (rtascons_put_char_token == RTAS_UNKNOWN_SERVICE)
95 return -EIO;
96
97 if (rtascons_get_char_token == RTAS_UNKNOWN_SERVICE)
98 rtascons_get_char_token = rtas_token("get-term-char");
99 if (rtascons_get_char_token == RTAS_UNKNOWN_SERVICE)
100 return -EIO;
101
102 BUG_ON(hvc_rtas_dev);
103
104 /* Allocate an hvc_struct for the console device we instantiated
105 * earlier. Save off hp so that we can return it on exit */
106 hp = hvc_alloc(hvc_rtas_cookie, NO_IRQ, &hvc_rtas_get_put_ops);
107 if (IS_ERR(hp))
108 return PTR_ERR(hp);
109 hvc_rtas_dev = hp;
110 return 0;
111}
112module_init(hvc_rtas_init);
113
114/* This will tear down the tty portion of the driver */
115static void __exit hvc_rtas_exit(void)
116{
117 /* Really the fun isn't over until the worker thread breaks down and the
118 * tty cleans up */
119 if (hvc_rtas_dev)
120 hvc_remove(hvc_rtas_dev);
121}
122module_exit(hvc_rtas_exit);
123
124/* This will happen prior to module init. There is no tty at this time? */
125static int hvc_rtas_console_init(void)
126{
127 rtascons_put_char_token = rtas_token("put-term-char");
128 if (rtascons_put_char_token == RTAS_UNKNOWN_SERVICE)
129 return -EIO;
130 rtascons_get_char_token = rtas_token("get-term-char");
131 if (rtascons_get_char_token == RTAS_UNKNOWN_SERVICE)
132 return -EIO;
133
134 hvc_instantiate(hvc_rtas_cookie, 0, &hvc_rtas_get_put_ops );
135 add_preferred_console("hvc", 0, NULL);
136 return 0;
137}
138console_initcall(hvc_rtas_console_init);
diff --git a/drivers/char/hvc_vio.c b/drivers/char/hvc_vio.c
index f5212eb2b41d..9add81ceb440 100644
--- a/drivers/char/hvc_vio.c
+++ b/drivers/char/hvc_vio.c
@@ -31,10 +31,13 @@
31 31
32#include <linux/types.h> 32#include <linux/types.h>
33#include <linux/init.h> 33#include <linux/init.h>
34
34#include <asm/hvconsole.h> 35#include <asm/hvconsole.h>
35#include <asm/vio.h> 36#include <asm/vio.h>
36#include <asm/prom.h> 37#include <asm/prom.h>
37 38
39#include "hvc_console.h"
40
38char hvc_driver_name[] = "hvc_console"; 41char hvc_driver_name[] = "hvc_console";
39 42
40static struct vio_device_id hvc_driver_table[] __devinitdata = { 43static struct vio_device_id hvc_driver_table[] __devinitdata = {
@@ -48,6 +51,14 @@ static int filtered_get_chars(uint32_t vtermno, char *buf, int count)
48 unsigned long got; 51 unsigned long got;
49 int i; 52 int i;
50 53
54 /*
55 * Vio firmware will read up to SIZE_VIO_GET_CHARS at its own discretion
56 * so we play safe and avoid the situation where got > count which could
57 * overload the flip buffer.
58 */
59 if (count < SIZE_VIO_GET_CHARS)
60 return -EAGAIN;
61
51 got = hvc_get_chars(vtermno, buf, count); 62 got = hvc_get_chars(vtermno, buf, count);
52 63
53 /* 64 /*
diff --git a/drivers/char/hvcs.c b/drivers/char/hvcs.c
index f7ac31856572..327b00c3c45e 100644
--- a/drivers/char/hvcs.c
+++ b/drivers/char/hvcs.c
@@ -439,7 +439,6 @@ static int hvcs_io(struct hvcs_struct *hvcsd)
439 char buf[HVCS_BUFF_LEN] __ALIGNED__; 439 char buf[HVCS_BUFF_LEN] __ALIGNED__;
440 unsigned long flags; 440 unsigned long flags;
441 int got = 0; 441 int got = 0;
442 int i;
443 442
444 spin_lock_irqsave(&hvcsd->lock, flags); 443 spin_lock_irqsave(&hvcsd->lock, flags);
445 444
diff --git a/drivers/char/ipmi/ipmi_devintf.c b/drivers/char/ipmi/ipmi_devintf.c
index 932feedda262..e1c95374984c 100644
--- a/drivers/char/ipmi/ipmi_devintf.c
+++ b/drivers/char/ipmi/ipmi_devintf.c
@@ -42,7 +42,7 @@
42#include <linux/slab.h> 42#include <linux/slab.h>
43#include <linux/devfs_fs_kernel.h> 43#include <linux/devfs_fs_kernel.h>
44#include <linux/ipmi.h> 44#include <linux/ipmi.h>
45#include <asm/semaphore.h> 45#include <linux/mutex.h>
46#include <linux/init.h> 46#include <linux/init.h>
47#include <linux/device.h> 47#include <linux/device.h>
48#include <linux/compat.h> 48#include <linux/compat.h>
@@ -55,7 +55,7 @@ struct ipmi_file_private
55 struct file *file; 55 struct file *file;
56 struct fasync_struct *fasync_queue; 56 struct fasync_struct *fasync_queue;
57 wait_queue_head_t wait; 57 wait_queue_head_t wait;
58 struct semaphore recv_sem; 58 struct mutex recv_mutex;
59 int default_retries; 59 int default_retries;
60 unsigned int default_retry_time_ms; 60 unsigned int default_retry_time_ms;
61}; 61};
@@ -141,7 +141,7 @@ static int ipmi_open(struct inode *inode, struct file *file)
141 INIT_LIST_HEAD(&(priv->recv_msgs)); 141 INIT_LIST_HEAD(&(priv->recv_msgs));
142 init_waitqueue_head(&priv->wait); 142 init_waitqueue_head(&priv->wait);
143 priv->fasync_queue = NULL; 143 priv->fasync_queue = NULL;
144 sema_init(&(priv->recv_sem), 1); 144 mutex_init(&priv->recv_mutex);
145 145
146 /* Use the low-level defaults. */ 146 /* Use the low-level defaults. */
147 priv->default_retries = -1; 147 priv->default_retries = -1;
@@ -285,15 +285,15 @@ static int ipmi_ioctl(struct inode *inode,
285 break; 285 break;
286 } 286 }
287 287
288 /* We claim a semaphore because we don't want two 288 /* We claim a mutex because we don't want two
289 users getting something from the queue at a time. 289 users getting something from the queue at a time.
290 Since we have to release the spinlock before we can 290 Since we have to release the spinlock before we can
291 copy the data to the user, it's possible another 291 copy the data to the user, it's possible another
292 user will grab something from the queue, too. Then 292 user will grab something from the queue, too. Then
293 the messages might get out of order if something 293 the messages might get out of order if something
294 fails and the message gets put back onto the 294 fails and the message gets put back onto the
295 queue. This semaphore prevents that problem. */ 295 queue. This mutex prevents that problem. */
296 down(&(priv->recv_sem)); 296 mutex_lock(&priv->recv_mutex);
297 297
298 /* Grab the message off the list. */ 298 /* Grab the message off the list. */
299 spin_lock_irqsave(&(priv->recv_msg_lock), flags); 299 spin_lock_irqsave(&(priv->recv_msg_lock), flags);
@@ -352,7 +352,7 @@ static int ipmi_ioctl(struct inode *inode,
352 goto recv_putback_on_err; 352 goto recv_putback_on_err;
353 } 353 }
354 354
355 up(&(priv->recv_sem)); 355 mutex_unlock(&priv->recv_mutex);
356 ipmi_free_recv_msg(msg); 356 ipmi_free_recv_msg(msg);
357 break; 357 break;
358 358
@@ -362,11 +362,11 @@ static int ipmi_ioctl(struct inode *inode,
362 spin_lock_irqsave(&(priv->recv_msg_lock), flags); 362 spin_lock_irqsave(&(priv->recv_msg_lock), flags);
363 list_add(entry, &(priv->recv_msgs)); 363 list_add(entry, &(priv->recv_msgs));
364 spin_unlock_irqrestore(&(priv->recv_msg_lock), flags); 364 spin_unlock_irqrestore(&(priv->recv_msg_lock), flags);
365 up(&(priv->recv_sem)); 365 mutex_unlock(&priv->recv_mutex);
366 break; 366 break;
367 367
368 recv_err: 368 recv_err:
369 up(&(priv->recv_sem)); 369 mutex_unlock(&priv->recv_mutex);
370 break; 370 break;
371 } 371 }
372 372
diff --git a/drivers/char/ipmi/ipmi_kcs_sm.c b/drivers/char/ipmi/ipmi_kcs_sm.c
index da1554194d3d..2062675f9e99 100644
--- a/drivers/char/ipmi/ipmi_kcs_sm.c
+++ b/drivers/char/ipmi/ipmi_kcs_sm.c
@@ -227,7 +227,7 @@ static inline int check_ibf(struct si_sm_data *kcs, unsigned char status,
227static inline int check_obf(struct si_sm_data *kcs, unsigned char status, 227static inline int check_obf(struct si_sm_data *kcs, unsigned char status,
228 long time) 228 long time)
229{ 229{
230 if (! GET_STATUS_OBF(status)) { 230 if (!GET_STATUS_OBF(status)) {
231 kcs->obf_timeout -= time; 231 kcs->obf_timeout -= time;
232 if (kcs->obf_timeout < 0) { 232 if (kcs->obf_timeout < 0) {
233 start_error_recovery(kcs, "OBF not ready in time"); 233 start_error_recovery(kcs, "OBF not ready in time");
@@ -407,7 +407,7 @@ static enum si_sm_result kcs_event(struct si_sm_data *kcs, long time)
407 } 407 }
408 408
409 if (state == KCS_READ_STATE) { 409 if (state == KCS_READ_STATE) {
410 if (! check_obf(kcs, status, time)) 410 if (!check_obf(kcs, status, time))
411 return SI_SM_CALL_WITH_DELAY; 411 return SI_SM_CALL_WITH_DELAY;
412 read_next_byte(kcs); 412 read_next_byte(kcs);
413 } else { 413 } else {
@@ -447,7 +447,7 @@ static enum si_sm_result kcs_event(struct si_sm_data *kcs, long time)
447 "Not in read state for error2"); 447 "Not in read state for error2");
448 break; 448 break;
449 } 449 }
450 if (! check_obf(kcs, status, time)) 450 if (!check_obf(kcs, status, time))
451 return SI_SM_CALL_WITH_DELAY; 451 return SI_SM_CALL_WITH_DELAY;
452 452
453 clear_obf(kcs, status); 453 clear_obf(kcs, status);
@@ -462,7 +462,7 @@ static enum si_sm_result kcs_event(struct si_sm_data *kcs, long time)
462 break; 462 break;
463 } 463 }
464 464
465 if (! check_obf(kcs, status, time)) 465 if (!check_obf(kcs, status, time))
466 return SI_SM_CALL_WITH_DELAY; 466 return SI_SM_CALL_WITH_DELAY;
467 467
468 clear_obf(kcs, status); 468 clear_obf(kcs, status);
diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c
index 40eb005b9d77..0ded046d5aa8 100644
--- a/drivers/char/ipmi/ipmi_msghandler.c
+++ b/drivers/char/ipmi/ipmi_msghandler.c
@@ -38,6 +38,7 @@
38#include <linux/sched.h> 38#include <linux/sched.h>
39#include <linux/poll.h> 39#include <linux/poll.h>
40#include <linux/spinlock.h> 40#include <linux/spinlock.h>
41#include <linux/mutex.h>
41#include <linux/slab.h> 42#include <linux/slab.h>
42#include <linux/ipmi.h> 43#include <linux/ipmi.h>
43#include <linux/ipmi_smi.h> 44#include <linux/ipmi_smi.h>
@@ -234,7 +235,7 @@ struct ipmi_smi
234 235
235 /* The list of command receivers that are registered for commands 236 /* The list of command receivers that are registered for commands
236 on this interface. */ 237 on this interface. */
237 struct semaphore cmd_rcvrs_lock; 238 struct mutex cmd_rcvrs_mutex;
238 struct list_head cmd_rcvrs; 239 struct list_head cmd_rcvrs;
239 240
240 /* Events that were queues because no one was there to receive 241 /* Events that were queues because no one was there to receive
@@ -387,10 +388,10 @@ static void clean_up_interface_data(ipmi_smi_t intf)
387 388
388 /* Wholesale remove all the entries from the list in the 389 /* Wholesale remove all the entries from the list in the
389 * interface and wait for RCU to know that none are in use. */ 390 * interface and wait for RCU to know that none are in use. */
390 down(&intf->cmd_rcvrs_lock); 391 mutex_lock(&intf->cmd_rcvrs_mutex);
391 list_add_rcu(&list, &intf->cmd_rcvrs); 392 list_add_rcu(&list, &intf->cmd_rcvrs);
392 list_del_rcu(&intf->cmd_rcvrs); 393 list_del_rcu(&intf->cmd_rcvrs);
393 up(&intf->cmd_rcvrs_lock); 394 mutex_unlock(&intf->cmd_rcvrs_mutex);
394 synchronize_rcu(); 395 synchronize_rcu();
395 396
396 list_for_each_entry_safe(rcvr, rcvr2, &list, link) 397 list_for_each_entry_safe(rcvr, rcvr2, &list, link)
@@ -557,7 +558,7 @@ unsigned int ipmi_addr_length(int addr_type)
557 558
558static void deliver_response(struct ipmi_recv_msg *msg) 559static void deliver_response(struct ipmi_recv_msg *msg)
559{ 560{
560 if (! msg->user) { 561 if (!msg->user) {
561 ipmi_smi_t intf = msg->user_msg_data; 562 ipmi_smi_t intf = msg->user_msg_data;
562 unsigned long flags; 563 unsigned long flags;
563 564
@@ -598,11 +599,11 @@ static int intf_next_seq(ipmi_smi_t intf,
598 (i+1)%IPMI_IPMB_NUM_SEQ != intf->curr_seq; 599 (i+1)%IPMI_IPMB_NUM_SEQ != intf->curr_seq;
599 i = (i+1)%IPMI_IPMB_NUM_SEQ) 600 i = (i+1)%IPMI_IPMB_NUM_SEQ)
600 { 601 {
601 if (! intf->seq_table[i].inuse) 602 if (!intf->seq_table[i].inuse)
602 break; 603 break;
603 } 604 }
604 605
605 if (! intf->seq_table[i].inuse) { 606 if (!intf->seq_table[i].inuse) {
606 intf->seq_table[i].recv_msg = recv_msg; 607 intf->seq_table[i].recv_msg = recv_msg;
607 608
608 /* Start with the maximum timeout, when the send response 609 /* Start with the maximum timeout, when the send response
@@ -763,7 +764,7 @@ int ipmi_create_user(unsigned int if_num,
763 } 764 }
764 765
765 new_user = kmalloc(sizeof(*new_user), GFP_KERNEL); 766 new_user = kmalloc(sizeof(*new_user), GFP_KERNEL);
766 if (! new_user) 767 if (!new_user)
767 return -ENOMEM; 768 return -ENOMEM;
768 769
769 spin_lock_irqsave(&interfaces_lock, flags); 770 spin_lock_irqsave(&interfaces_lock, flags);
@@ -819,14 +820,13 @@ static void free_user(struct kref *ref)
819 820
820int ipmi_destroy_user(ipmi_user_t user) 821int ipmi_destroy_user(ipmi_user_t user)
821{ 822{
822 int rv = -ENODEV;
823 ipmi_smi_t intf = user->intf; 823 ipmi_smi_t intf = user->intf;
824 int i; 824 int i;
825 unsigned long flags; 825 unsigned long flags;
826 struct cmd_rcvr *rcvr; 826 struct cmd_rcvr *rcvr;
827 struct cmd_rcvr *rcvrs = NULL; 827 struct cmd_rcvr *rcvrs = NULL;
828 828
829 user->valid = 1; 829 user->valid = 0;
830 830
831 /* Remove the user from the interface's sequence table. */ 831 /* Remove the user from the interface's sequence table. */
832 spin_lock_irqsave(&intf->seq_lock, flags); 832 spin_lock_irqsave(&intf->seq_lock, flags);
@@ -847,7 +847,7 @@ int ipmi_destroy_user(ipmi_user_t user)
847 * since other things may be using it till we do 847 * since other things may be using it till we do
848 * synchronize_rcu()) then free everything in that list. 848 * synchronize_rcu()) then free everything in that list.
849 */ 849 */
850 down(&intf->cmd_rcvrs_lock); 850 mutex_lock(&intf->cmd_rcvrs_mutex);
851 list_for_each_entry_rcu(rcvr, &intf->cmd_rcvrs, link) { 851 list_for_each_entry_rcu(rcvr, &intf->cmd_rcvrs, link) {
852 if (rcvr->user == user) { 852 if (rcvr->user == user) {
853 list_del_rcu(&rcvr->link); 853 list_del_rcu(&rcvr->link);
@@ -855,7 +855,7 @@ int ipmi_destroy_user(ipmi_user_t user)
855 rcvrs = rcvr; 855 rcvrs = rcvr;
856 } 856 }
857 } 857 }
858 up(&intf->cmd_rcvrs_lock); 858 mutex_unlock(&intf->cmd_rcvrs_mutex);
859 synchronize_rcu(); 859 synchronize_rcu();
860 while (rcvrs) { 860 while (rcvrs) {
861 rcvr = rcvrs; 861 rcvr = rcvrs;
@@ -871,7 +871,7 @@ int ipmi_destroy_user(ipmi_user_t user)
871 871
872 kref_put(&user->refcount, free_user); 872 kref_put(&user->refcount, free_user);
873 873
874 return rv; 874 return 0;
875} 875}
876 876
877void ipmi_get_version(ipmi_user_t user, 877void ipmi_get_version(ipmi_user_t user,
@@ -936,7 +936,8 @@ int ipmi_set_gets_events(ipmi_user_t user, int val)
936 936
937 if (val) { 937 if (val) {
938 /* Deliver any queued events. */ 938 /* Deliver any queued events. */
939 list_for_each_entry_safe(msg, msg2, &intf->waiting_events, link) { 939 list_for_each_entry_safe(msg, msg2, &intf->waiting_events,
940 link) {
940 list_del(&msg->link); 941 list_del(&msg->link);
941 list_add_tail(&msg->link, &msgs); 942 list_add_tail(&msg->link, &msgs);
942 } 943 }
@@ -978,13 +979,13 @@ int ipmi_register_for_cmd(ipmi_user_t user,
978 979
979 980
980 rcvr = kmalloc(sizeof(*rcvr), GFP_KERNEL); 981 rcvr = kmalloc(sizeof(*rcvr), GFP_KERNEL);
981 if (! rcvr) 982 if (!rcvr)
982 return -ENOMEM; 983 return -ENOMEM;
983 rcvr->cmd = cmd; 984 rcvr->cmd = cmd;
984 rcvr->netfn = netfn; 985 rcvr->netfn = netfn;
985 rcvr->user = user; 986 rcvr->user = user;
986 987
987 down(&intf->cmd_rcvrs_lock); 988 mutex_lock(&intf->cmd_rcvrs_mutex);
988 /* Make sure the command/netfn is not already registered. */ 989 /* Make sure the command/netfn is not already registered. */
989 entry = find_cmd_rcvr(intf, netfn, cmd); 990 entry = find_cmd_rcvr(intf, netfn, cmd);
990 if (entry) { 991 if (entry) {
@@ -995,7 +996,7 @@ int ipmi_register_for_cmd(ipmi_user_t user,
995 list_add_rcu(&rcvr->link, &intf->cmd_rcvrs); 996 list_add_rcu(&rcvr->link, &intf->cmd_rcvrs);
996 997
997 out_unlock: 998 out_unlock:
998 up(&intf->cmd_rcvrs_lock); 999 mutex_unlock(&intf->cmd_rcvrs_mutex);
999 if (rv) 1000 if (rv)
1000 kfree(rcvr); 1001 kfree(rcvr);
1001 1002
@@ -1009,17 +1010,17 @@ int ipmi_unregister_for_cmd(ipmi_user_t user,
1009 ipmi_smi_t intf = user->intf; 1010 ipmi_smi_t intf = user->intf;
1010 struct cmd_rcvr *rcvr; 1011 struct cmd_rcvr *rcvr;
1011 1012
1012 down(&intf->cmd_rcvrs_lock); 1013 mutex_lock(&intf->cmd_rcvrs_mutex);
1013 /* Make sure the command/netfn is not already registered. */ 1014 /* Make sure the command/netfn is not already registered. */
1014 rcvr = find_cmd_rcvr(intf, netfn, cmd); 1015 rcvr = find_cmd_rcvr(intf, netfn, cmd);
1015 if ((rcvr) && (rcvr->user == user)) { 1016 if ((rcvr) && (rcvr->user == user)) {
1016 list_del_rcu(&rcvr->link); 1017 list_del_rcu(&rcvr->link);
1017 up(&intf->cmd_rcvrs_lock); 1018 mutex_unlock(&intf->cmd_rcvrs_mutex);
1018 synchronize_rcu(); 1019 synchronize_rcu();
1019 kfree(rcvr); 1020 kfree(rcvr);
1020 return 0; 1021 return 0;
1021 } else { 1022 } else {
1022 up(&intf->cmd_rcvrs_lock); 1023 mutex_unlock(&intf->cmd_rcvrs_mutex);
1023 return -ENOENT; 1024 return -ENOENT;
1024 } 1025 }
1025} 1026}
@@ -1514,7 +1515,7 @@ int ipmi_request_settime(ipmi_user_t user,
1514 unsigned char saddr, lun; 1515 unsigned char saddr, lun;
1515 int rv; 1516 int rv;
1516 1517
1517 if (! user) 1518 if (!user)
1518 return -EINVAL; 1519 return -EINVAL;
1519 rv = check_addr(user->intf, addr, &saddr, &lun); 1520 rv = check_addr(user->intf, addr, &saddr, &lun);
1520 if (rv) 1521 if (rv)
@@ -1545,7 +1546,7 @@ int ipmi_request_supply_msgs(ipmi_user_t user,
1545 unsigned char saddr, lun; 1546 unsigned char saddr, lun;
1546 int rv; 1547 int rv;
1547 1548
1548 if (! user) 1549 if (!user)
1549 return -EINVAL; 1550 return -EINVAL;
1550 rv = check_addr(user->intf, addr, &saddr, &lun); 1551 rv = check_addr(user->intf, addr, &saddr, &lun);
1551 if (rv) 1552 if (rv)
@@ -1570,7 +1571,7 @@ static int ipmb_file_read_proc(char *page, char **start, off_t off,
1570 char *out = (char *) page; 1571 char *out = (char *) page;
1571 ipmi_smi_t intf = data; 1572 ipmi_smi_t intf = data;
1572 int i; 1573 int i;
1573 int rv= 0; 1574 int rv = 0;
1574 1575
1575 for (i = 0; i < IPMI_MAX_CHANNELS; i++) 1576 for (i = 0; i < IPMI_MAX_CHANNELS; i++)
1576 rv += sprintf(out+rv, "%x ", intf->channels[i].address); 1577 rv += sprintf(out+rv, "%x ", intf->channels[i].address);
@@ -1989,7 +1990,7 @@ static int ipmi_bmc_register(ipmi_smi_t intf)
1989 } else { 1990 } else {
1990 bmc->dev = platform_device_alloc("ipmi_bmc", 1991 bmc->dev = platform_device_alloc("ipmi_bmc",
1991 bmc->id.device_id); 1992 bmc->id.device_id);
1992 if (! bmc->dev) { 1993 if (!bmc->dev) {
1993 printk(KERN_ERR 1994 printk(KERN_ERR
1994 "ipmi_msghandler:" 1995 "ipmi_msghandler:"
1995 " Unable to allocate platform device\n"); 1996 " Unable to allocate platform device\n");
@@ -2305,8 +2306,7 @@ int ipmi_register_smi(struct ipmi_smi_handlers *handlers,
2305 void *send_info, 2306 void *send_info,
2306 struct ipmi_device_id *device_id, 2307 struct ipmi_device_id *device_id,
2307 struct device *si_dev, 2308 struct device *si_dev,
2308 unsigned char slave_addr, 2309 unsigned char slave_addr)
2309 ipmi_smi_t *new_intf)
2310{ 2310{
2311 int i, j; 2311 int i, j;
2312 int rv; 2312 int rv;
@@ -2366,7 +2366,7 @@ int ipmi_register_smi(struct ipmi_smi_handlers *handlers,
2366 spin_lock_init(&intf->events_lock); 2366 spin_lock_init(&intf->events_lock);
2367 INIT_LIST_HEAD(&intf->waiting_events); 2367 INIT_LIST_HEAD(&intf->waiting_events);
2368 intf->waiting_events_count = 0; 2368 intf->waiting_events_count = 0;
2369 init_MUTEX(&intf->cmd_rcvrs_lock); 2369 mutex_init(&intf->cmd_rcvrs_mutex);
2370 INIT_LIST_HEAD(&intf->cmd_rcvrs); 2370 INIT_LIST_HEAD(&intf->cmd_rcvrs);
2371 init_waitqueue_head(&intf->waitq); 2371 init_waitqueue_head(&intf->waitq);
2372 2372
@@ -2388,9 +2388,9 @@ int ipmi_register_smi(struct ipmi_smi_handlers *handlers,
2388 if (rv) 2388 if (rv)
2389 goto out; 2389 goto out;
2390 2390
2391 /* FIXME - this is an ugly kludge, this sets the intf for the 2391 rv = handlers->start_processing(send_info, intf);
2392 caller before sending any messages with it. */ 2392 if (rv)
2393 *new_intf = intf; 2393 goto out;
2394 2394
2395 get_guid(intf); 2395 get_guid(intf);
2396 2396
@@ -2622,7 +2622,7 @@ static int handle_ipmb_get_msg_cmd(ipmi_smi_t intf,
2622 spin_unlock_irqrestore(&intf->counter_lock, flags); 2622 spin_unlock_irqrestore(&intf->counter_lock, flags);
2623 2623
2624 recv_msg = ipmi_alloc_recv_msg(); 2624 recv_msg = ipmi_alloc_recv_msg();
2625 if (! recv_msg) { 2625 if (!recv_msg) {
2626 /* We couldn't allocate memory for the 2626 /* We couldn't allocate memory for the
2627 message, so requeue it for handling 2627 message, so requeue it for handling
2628 later. */ 2628 later. */
@@ -2777,7 +2777,7 @@ static int handle_lan_get_msg_cmd(ipmi_smi_t intf,
2777 spin_unlock_irqrestore(&intf->counter_lock, flags); 2777 spin_unlock_irqrestore(&intf->counter_lock, flags);
2778 2778
2779 recv_msg = ipmi_alloc_recv_msg(); 2779 recv_msg = ipmi_alloc_recv_msg();
2780 if (! recv_msg) { 2780 if (!recv_msg) {
2781 /* We couldn't allocate memory for the 2781 /* We couldn't allocate memory for the
2782 message, so requeue it for handling 2782 message, so requeue it for handling
2783 later. */ 2783 later. */
@@ -2869,13 +2869,14 @@ static int handle_read_event_rsp(ipmi_smi_t intf,
2869 events. */ 2869 events. */
2870 rcu_read_lock(); 2870 rcu_read_lock();
2871 list_for_each_entry_rcu(user, &intf->users, link) { 2871 list_for_each_entry_rcu(user, &intf->users, link) {
2872 if (! user->gets_events) 2872 if (!user->gets_events)
2873 continue; 2873 continue;
2874 2874
2875 recv_msg = ipmi_alloc_recv_msg(); 2875 recv_msg = ipmi_alloc_recv_msg();
2876 if (! recv_msg) { 2876 if (!recv_msg) {
2877 rcu_read_unlock(); 2877 rcu_read_unlock();
2878 list_for_each_entry_safe(recv_msg, recv_msg2, &msgs, link) { 2878 list_for_each_entry_safe(recv_msg, recv_msg2, &msgs,
2879 link) {
2879 list_del(&recv_msg->link); 2880 list_del(&recv_msg->link);
2880 ipmi_free_recv_msg(recv_msg); 2881 ipmi_free_recv_msg(recv_msg);
2881 } 2882 }
@@ -2905,7 +2906,7 @@ static int handle_read_event_rsp(ipmi_smi_t intf,
2905 /* No one to receive the message, put it in queue if there's 2906 /* No one to receive the message, put it in queue if there's
2906 not already too many things in the queue. */ 2907 not already too many things in the queue. */
2907 recv_msg = ipmi_alloc_recv_msg(); 2908 recv_msg = ipmi_alloc_recv_msg();
2908 if (! recv_msg) { 2909 if (!recv_msg) {
2909 /* We couldn't allocate memory for the 2910 /* We couldn't allocate memory for the
2910 message, so requeue it for handling 2911 message, so requeue it for handling
2911 later. */ 2912 later. */
@@ -3190,7 +3191,7 @@ void ipmi_smi_watchdog_pretimeout(ipmi_smi_t intf)
3190 3191
3191 rcu_read_lock(); 3192 rcu_read_lock();
3192 list_for_each_entry_rcu(user, &intf->users, link) { 3193 list_for_each_entry_rcu(user, &intf->users, link) {
3193 if (! user->handler->ipmi_watchdog_pretimeout) 3194 if (!user->handler->ipmi_watchdog_pretimeout)
3194 continue; 3195 continue;
3195 3196
3196 user->handler->ipmi_watchdog_pretimeout(user->handler_data); 3197 user->handler->ipmi_watchdog_pretimeout(user->handler_data);
@@ -3278,7 +3279,7 @@ static void check_msg_timeout(ipmi_smi_t intf, struct seq_table *ent,
3278 3279
3279 smi_msg = smi_from_recv_msg(intf, ent->recv_msg, slot, 3280 smi_msg = smi_from_recv_msg(intf, ent->recv_msg, slot,
3280 ent->seqid); 3281 ent->seqid);
3281 if (! smi_msg) 3282 if (!smi_msg)
3282 return; 3283 return;
3283 3284
3284 spin_unlock_irqrestore(&intf->seq_lock, *flags); 3285 spin_unlock_irqrestore(&intf->seq_lock, *flags);
@@ -3314,8 +3315,9 @@ static void ipmi_timeout_handler(long timeout_period)
3314 3315
3315 /* See if any waiting messages need to be processed. */ 3316 /* See if any waiting messages need to be processed. */
3316 spin_lock_irqsave(&intf->waiting_msgs_lock, flags); 3317 spin_lock_irqsave(&intf->waiting_msgs_lock, flags);
3317 list_for_each_entry_safe(smi_msg, smi_msg2, &intf->waiting_msgs, link) { 3318 list_for_each_entry_safe(smi_msg, smi_msg2,
3318 if (! handle_new_recv_msg(intf, smi_msg)) { 3319 &intf->waiting_msgs, link) {
3320 if (!handle_new_recv_msg(intf, smi_msg)) {
3319 list_del(&smi_msg->link); 3321 list_del(&smi_msg->link);
3320 ipmi_free_smi_msg(smi_msg); 3322 ipmi_free_smi_msg(smi_msg);
3321 } else { 3323 } else {
diff --git a/drivers/char/ipmi/ipmi_poweroff.c b/drivers/char/ipmi/ipmi_poweroff.c
index 786a2802ca34..d0b5c08e7b4e 100644
--- a/drivers/char/ipmi/ipmi_poweroff.c
+++ b/drivers/char/ipmi/ipmi_poweroff.c
@@ -346,7 +346,7 @@ static int ipmi_dell_chassis_detect (ipmi_user_t user)
346{ 346{
347 const char ipmi_version_major = ipmi_version & 0xF; 347 const char ipmi_version_major = ipmi_version & 0xF;
348 const char ipmi_version_minor = (ipmi_version >> 4) & 0xF; 348 const char ipmi_version_minor = (ipmi_version >> 4) & 0xF;
349 const char mfr[3]=DELL_IANA_MFR_ID; 349 const char mfr[3] = DELL_IANA_MFR_ID;
350 if (!memcmp(mfr, &mfg_id, sizeof(mfr)) && 350 if (!memcmp(mfr, &mfg_id, sizeof(mfr)) &&
351 ipmi_version_major <= 1 && 351 ipmi_version_major <= 1 &&
352 ipmi_version_minor < 5) 352 ipmi_version_minor < 5)
diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c
index 35fbd4d8ed4b..a86c0f29953e 100644
--- a/drivers/char/ipmi/ipmi_si_intf.c
+++ b/drivers/char/ipmi/ipmi_si_intf.c
@@ -803,7 +803,7 @@ static int ipmi_thread(void *data)
803 set_user_nice(current, 19); 803 set_user_nice(current, 19);
804 while (!kthread_should_stop()) { 804 while (!kthread_should_stop()) {
805 spin_lock_irqsave(&(smi_info->si_lock), flags); 805 spin_lock_irqsave(&(smi_info->si_lock), flags);
806 smi_result=smi_event_handler(smi_info, 0); 806 smi_result = smi_event_handler(smi_info, 0);
807 spin_unlock_irqrestore(&(smi_info->si_lock), flags); 807 spin_unlock_irqrestore(&(smi_info->si_lock), flags);
808 if (smi_result == SI_SM_CALL_WITHOUT_DELAY) { 808 if (smi_result == SI_SM_CALL_WITHOUT_DELAY) {
809 /* do nothing */ 809 /* do nothing */
@@ -972,10 +972,37 @@ static irqreturn_t si_bt_irq_handler(int irq, void *data, struct pt_regs *regs)
972 return si_irq_handler(irq, data, regs); 972 return si_irq_handler(irq, data, regs);
973} 973}
974 974
975static int smi_start_processing(void *send_info,
976 ipmi_smi_t intf)
977{
978 struct smi_info *new_smi = send_info;
979
980 new_smi->intf = intf;
981
982 /* Set up the timer that drives the interface. */
983 setup_timer(&new_smi->si_timer, smi_timeout, (long)new_smi);
984 new_smi->last_timeout_jiffies = jiffies;
985 mod_timer(&new_smi->si_timer, jiffies + SI_TIMEOUT_JIFFIES);
986
987 if (new_smi->si_type != SI_BT) {
988 new_smi->thread = kthread_run(ipmi_thread, new_smi,
989 "kipmi%d", new_smi->intf_num);
990 if (IS_ERR(new_smi->thread)) {
991 printk(KERN_NOTICE "ipmi_si_intf: Could not start"
992 " kernel thread due to error %ld, only using"
993 " timers to drive the interface\n",
994 PTR_ERR(new_smi->thread));
995 new_smi->thread = NULL;
996 }
997 }
998
999 return 0;
1000}
975 1001
976static struct ipmi_smi_handlers handlers = 1002static struct ipmi_smi_handlers handlers =
977{ 1003{
978 .owner = THIS_MODULE, 1004 .owner = THIS_MODULE,
1005 .start_processing = smi_start_processing,
979 .sender = sender, 1006 .sender = sender,
980 .request_events = request_events, 1007 .request_events = request_events,
981 .set_run_to_completion = set_run_to_completion, 1008 .set_run_to_completion = set_run_to_completion,
@@ -987,7 +1014,7 @@ static struct ipmi_smi_handlers handlers =
987 1014
988#define SI_MAX_PARMS 4 1015#define SI_MAX_PARMS 4
989static LIST_HEAD(smi_infos); 1016static LIST_HEAD(smi_infos);
990static DECLARE_MUTEX(smi_infos_lock); 1017static DEFINE_MUTEX(smi_infos_lock);
991static int smi_num; /* Used to sequence the SMIs */ 1018static int smi_num; /* Used to sequence the SMIs */
992 1019
993#define DEFAULT_REGSPACING 1 1020#define DEFAULT_REGSPACING 1
@@ -2162,9 +2189,13 @@ static void setup_xaction_handlers(struct smi_info *smi_info)
2162 2189
2163static inline void wait_for_timer_and_thread(struct smi_info *smi_info) 2190static inline void wait_for_timer_and_thread(struct smi_info *smi_info)
2164{ 2191{
2165 if (smi_info->thread != NULL && smi_info->thread != ERR_PTR(-ENOMEM)) 2192 if (smi_info->intf) {
2166 kthread_stop(smi_info->thread); 2193 /* The timer and thread are only running if the
2167 del_timer_sync(&smi_info->si_timer); 2194 interface has been started up and registered. */
2195 if (smi_info->thread != NULL)
2196 kthread_stop(smi_info->thread);
2197 del_timer_sync(&smi_info->si_timer);
2198 }
2168} 2199}
2169 2200
2170static struct ipmi_default_vals 2201static struct ipmi_default_vals
@@ -2245,7 +2276,7 @@ static int try_smi_init(struct smi_info *new_smi)
2245 new_smi->slave_addr, new_smi->irq); 2276 new_smi->slave_addr, new_smi->irq);
2246 } 2277 }
2247 2278
2248 down(&smi_infos_lock); 2279 mutex_lock(&smi_infos_lock);
2249 if (!is_new_interface(new_smi)) { 2280 if (!is_new_interface(new_smi)) {
2250 printk(KERN_WARNING "ipmi_si: duplicate interface\n"); 2281 printk(KERN_WARNING "ipmi_si: duplicate interface\n");
2251 rv = -EBUSY; 2282 rv = -EBUSY;
@@ -2341,21 +2372,6 @@ static int try_smi_init(struct smi_info *new_smi)
2341 if (new_smi->irq) 2372 if (new_smi->irq)
2342 new_smi->si_state = SI_CLEARING_FLAGS_THEN_SET_IRQ; 2373 new_smi->si_state = SI_CLEARING_FLAGS_THEN_SET_IRQ;
2343 2374
2344 /* The ipmi_register_smi() code does some operations to
2345 determine the channel information, so we must be ready to
2346 handle operations before it is called. This means we have
2347 to stop the timer if we get an error after this point. */
2348 init_timer(&(new_smi->si_timer));
2349 new_smi->si_timer.data = (long) new_smi;
2350 new_smi->si_timer.function = smi_timeout;
2351 new_smi->last_timeout_jiffies = jiffies;
2352 new_smi->si_timer.expires = jiffies + SI_TIMEOUT_JIFFIES;
2353
2354 add_timer(&(new_smi->si_timer));
2355 if (new_smi->si_type != SI_BT)
2356 new_smi->thread = kthread_run(ipmi_thread, new_smi,
2357 "kipmi%d", new_smi->intf_num);
2358
2359 if (!new_smi->dev) { 2375 if (!new_smi->dev) {
2360 /* If we don't already have a device from something 2376 /* If we don't already have a device from something
2361 * else (like PCI), then register a new one. */ 2377 * else (like PCI), then register a new one. */
@@ -2365,7 +2381,7 @@ static int try_smi_init(struct smi_info *new_smi)
2365 printk(KERN_ERR 2381 printk(KERN_ERR
2366 "ipmi_si_intf:" 2382 "ipmi_si_intf:"
2367 " Unable to allocate platform device\n"); 2383 " Unable to allocate platform device\n");
2368 goto out_err_stop_timer; 2384 goto out_err;
2369 } 2385 }
2370 new_smi->dev = &new_smi->pdev->dev; 2386 new_smi->dev = &new_smi->pdev->dev;
2371 new_smi->dev->driver = &ipmi_driver; 2387 new_smi->dev->driver = &ipmi_driver;
@@ -2377,7 +2393,7 @@ static int try_smi_init(struct smi_info *new_smi)
2377 " Unable to register system interface device:" 2393 " Unable to register system interface device:"
2378 " %d\n", 2394 " %d\n",
2379 rv); 2395 rv);
2380 goto out_err_stop_timer; 2396 goto out_err;
2381 } 2397 }
2382 new_smi->dev_registered = 1; 2398 new_smi->dev_registered = 1;
2383 } 2399 }
@@ -2386,8 +2402,7 @@ static int try_smi_init(struct smi_info *new_smi)
2386 new_smi, 2402 new_smi,
2387 &new_smi->device_id, 2403 &new_smi->device_id,
2388 new_smi->dev, 2404 new_smi->dev,
2389 new_smi->slave_addr, 2405 new_smi->slave_addr);
2390 &(new_smi->intf));
2391 if (rv) { 2406 if (rv) {
2392 printk(KERN_ERR 2407 printk(KERN_ERR
2393 "ipmi_si: Unable to register device: error %d\n", 2408 "ipmi_si: Unable to register device: error %d\n",
@@ -2417,7 +2432,7 @@ static int try_smi_init(struct smi_info *new_smi)
2417 2432
2418 list_add_tail(&new_smi->link, &smi_infos); 2433 list_add_tail(&new_smi->link, &smi_infos);
2419 2434
2420 up(&smi_infos_lock); 2435 mutex_unlock(&smi_infos_lock);
2421 2436
2422 printk(" IPMI %s interface initialized\n",si_to_str[new_smi->si_type]); 2437 printk(" IPMI %s interface initialized\n",si_to_str[new_smi->si_type]);
2423 2438
@@ -2454,7 +2469,7 @@ static int try_smi_init(struct smi_info *new_smi)
2454 2469
2455 kfree(new_smi); 2470 kfree(new_smi);
2456 2471
2457 up(&smi_infos_lock); 2472 mutex_unlock(&smi_infos_lock);
2458 2473
2459 return rv; 2474 return rv;
2460} 2475}
@@ -2512,26 +2527,26 @@ static __devinit int init_ipmi_si(void)
2512#endif 2527#endif
2513 2528
2514 if (si_trydefaults) { 2529 if (si_trydefaults) {
2515 down(&smi_infos_lock); 2530 mutex_lock(&smi_infos_lock);
2516 if (list_empty(&smi_infos)) { 2531 if (list_empty(&smi_infos)) {
2517 /* No BMC was found, try defaults. */ 2532 /* No BMC was found, try defaults. */
2518 up(&smi_infos_lock); 2533 mutex_unlock(&smi_infos_lock);
2519 default_find_bmc(); 2534 default_find_bmc();
2520 } else { 2535 } else {
2521 up(&smi_infos_lock); 2536 mutex_unlock(&smi_infos_lock);
2522 } 2537 }
2523 } 2538 }
2524 2539
2525 down(&smi_infos_lock); 2540 mutex_lock(&smi_infos_lock);
2526 if (list_empty(&smi_infos)) { 2541 if (list_empty(&smi_infos)) {
2527 up(&smi_infos_lock); 2542 mutex_unlock(&smi_infos_lock);
2528#ifdef CONFIG_PCI 2543#ifdef CONFIG_PCI
2529 pci_unregister_driver(&ipmi_pci_driver); 2544 pci_unregister_driver(&ipmi_pci_driver);
2530#endif 2545#endif
2531 printk("ipmi_si: Unable to find any System Interface(s)\n"); 2546 printk("ipmi_si: Unable to find any System Interface(s)\n");
2532 return -ENODEV; 2547 return -ENODEV;
2533 } else { 2548 } else {
2534 up(&smi_infos_lock); 2549 mutex_unlock(&smi_infos_lock);
2535 return 0; 2550 return 0;
2536 } 2551 }
2537} 2552}
@@ -2607,10 +2622,10 @@ static __exit void cleanup_ipmi_si(void)
2607 pci_unregister_driver(&ipmi_pci_driver); 2622 pci_unregister_driver(&ipmi_pci_driver);
2608#endif 2623#endif
2609 2624
2610 down(&smi_infos_lock); 2625 mutex_lock(&smi_infos_lock);
2611 list_for_each_entry_safe(e, tmp_e, &smi_infos, link) 2626 list_for_each_entry_safe(e, tmp_e, &smi_infos, link)
2612 cleanup_one_si(e); 2627 cleanup_one_si(e);
2613 up(&smi_infos_lock); 2628 mutex_unlock(&smi_infos_lock);
2614 2629
2615 driver_unregister(&ipmi_driver); 2630 driver_unregister(&ipmi_driver);
2616} 2631}
diff --git a/drivers/char/ipmi/ipmi_watchdog.c b/drivers/char/ipmi/ipmi_watchdog.c
index 7ece9f3c8f70..2d11ddd99e55 100644
--- a/drivers/char/ipmi/ipmi_watchdog.c
+++ b/drivers/char/ipmi/ipmi_watchdog.c
@@ -39,6 +39,7 @@
39#include <linux/watchdog.h> 39#include <linux/watchdog.h>
40#include <linux/miscdevice.h> 40#include <linux/miscdevice.h>
41#include <linux/init.h> 41#include <linux/init.h>
42#include <linux/completion.h>
42#include <linux/rwsem.h> 43#include <linux/rwsem.h>
43#include <linux/errno.h> 44#include <linux/errno.h>
44#include <asm/uaccess.h> 45#include <asm/uaccess.h>
@@ -303,21 +304,22 @@ static int ipmi_heartbeat(void);
303static void panic_halt_ipmi_heartbeat(void); 304static void panic_halt_ipmi_heartbeat(void);
304 305
305 306
306/* We use a semaphore to make sure that only one thing can send a set 307/* We use a mutex to make sure that only one thing can send a set
307 timeout at one time, because we only have one copy of the data. 308 timeout at one time, because we only have one copy of the data.
308 The semaphore is claimed when the set_timeout is sent and freed 309 The mutex is claimed when the set_timeout is sent and freed
309 when both messages are free. */ 310 when both messages are free. */
310static atomic_t set_timeout_tofree = ATOMIC_INIT(0); 311static atomic_t set_timeout_tofree = ATOMIC_INIT(0);
311static DECLARE_MUTEX(set_timeout_lock); 312static DEFINE_MUTEX(set_timeout_lock);
313static DECLARE_COMPLETION(set_timeout_wait);
312static void set_timeout_free_smi(struct ipmi_smi_msg *msg) 314static void set_timeout_free_smi(struct ipmi_smi_msg *msg)
313{ 315{
314 if (atomic_dec_and_test(&set_timeout_tofree)) 316 if (atomic_dec_and_test(&set_timeout_tofree))
315 up(&set_timeout_lock); 317 complete(&set_timeout_wait);
316} 318}
317static void set_timeout_free_recv(struct ipmi_recv_msg *msg) 319static void set_timeout_free_recv(struct ipmi_recv_msg *msg)
318{ 320{
319 if (atomic_dec_and_test(&set_timeout_tofree)) 321 if (atomic_dec_and_test(&set_timeout_tofree))
320 up(&set_timeout_lock); 322 complete(&set_timeout_wait);
321} 323}
322static struct ipmi_smi_msg set_timeout_smi_msg = 324static struct ipmi_smi_msg set_timeout_smi_msg =
323{ 325{
@@ -399,7 +401,7 @@ static int ipmi_set_timeout(int do_heartbeat)
399 401
400 402
401 /* We can only send one of these at a time. */ 403 /* We can only send one of these at a time. */
402 down(&set_timeout_lock); 404 mutex_lock(&set_timeout_lock);
403 405
404 atomic_set(&set_timeout_tofree, 2); 406 atomic_set(&set_timeout_tofree, 2);
405 407
@@ -407,16 +409,21 @@ static int ipmi_set_timeout(int do_heartbeat)
407 &set_timeout_recv_msg, 409 &set_timeout_recv_msg,
408 &send_heartbeat_now); 410 &send_heartbeat_now);
409 if (rv) { 411 if (rv) {
410 up(&set_timeout_lock); 412 mutex_unlock(&set_timeout_lock);
411 } else { 413 goto out;
412 if ((do_heartbeat == IPMI_SET_TIMEOUT_FORCE_HB)
413 || ((send_heartbeat_now)
414 && (do_heartbeat == IPMI_SET_TIMEOUT_HB_IF_NECESSARY)))
415 {
416 rv = ipmi_heartbeat();
417 }
418 } 414 }
419 415
416 wait_for_completion(&set_timeout_wait);
417
418 if ((do_heartbeat == IPMI_SET_TIMEOUT_FORCE_HB)
419 || ((send_heartbeat_now)
420 && (do_heartbeat == IPMI_SET_TIMEOUT_HB_IF_NECESSARY)))
421 {
422 rv = ipmi_heartbeat();
423 }
424 mutex_unlock(&set_timeout_lock);
425
426out:
420 return rv; 427 return rv;
421} 428}
422 429
@@ -458,17 +465,17 @@ static void panic_halt_ipmi_set_timeout(void)
458 The semaphore is claimed when the set_timeout is sent and freed 465 The semaphore is claimed when the set_timeout is sent and freed
459 when both messages are free. */ 466 when both messages are free. */
460static atomic_t heartbeat_tofree = ATOMIC_INIT(0); 467static atomic_t heartbeat_tofree = ATOMIC_INIT(0);
461static DECLARE_MUTEX(heartbeat_lock); 468static DEFINE_MUTEX(heartbeat_lock);
462static DECLARE_MUTEX_LOCKED(heartbeat_wait_lock); 469static DECLARE_COMPLETION(heartbeat_wait);
463static void heartbeat_free_smi(struct ipmi_smi_msg *msg) 470static void heartbeat_free_smi(struct ipmi_smi_msg *msg)
464{ 471{
465 if (atomic_dec_and_test(&heartbeat_tofree)) 472 if (atomic_dec_and_test(&heartbeat_tofree))
466 up(&heartbeat_wait_lock); 473 complete(&heartbeat_wait);
467} 474}
468static void heartbeat_free_recv(struct ipmi_recv_msg *msg) 475static void heartbeat_free_recv(struct ipmi_recv_msg *msg)
469{ 476{
470 if (atomic_dec_and_test(&heartbeat_tofree)) 477 if (atomic_dec_and_test(&heartbeat_tofree))
471 up(&heartbeat_wait_lock); 478 complete(&heartbeat_wait);
472} 479}
473static struct ipmi_smi_msg heartbeat_smi_msg = 480static struct ipmi_smi_msg heartbeat_smi_msg =
474{ 481{
@@ -511,14 +518,14 @@ static int ipmi_heartbeat(void)
511 return ipmi_set_timeout(IPMI_SET_TIMEOUT_HB_IF_NECESSARY); 518 return ipmi_set_timeout(IPMI_SET_TIMEOUT_HB_IF_NECESSARY);
512 } 519 }
513 520
514 down(&heartbeat_lock); 521 mutex_lock(&heartbeat_lock);
515 522
516 atomic_set(&heartbeat_tofree, 2); 523 atomic_set(&heartbeat_tofree, 2);
517 524
518 /* Don't reset the timer if we have the timer turned off, that 525 /* Don't reset the timer if we have the timer turned off, that
519 re-enables the watchdog. */ 526 re-enables the watchdog. */
520 if (ipmi_watchdog_state == WDOG_TIMEOUT_NONE) { 527 if (ipmi_watchdog_state == WDOG_TIMEOUT_NONE) {
521 up(&heartbeat_lock); 528 mutex_unlock(&heartbeat_lock);
522 return 0; 529 return 0;
523 } 530 }
524 531
@@ -539,14 +546,14 @@ static int ipmi_heartbeat(void)
539 &heartbeat_recv_msg, 546 &heartbeat_recv_msg,
540 1); 547 1);
541 if (rv) { 548 if (rv) {
542 up(&heartbeat_lock); 549 mutex_unlock(&heartbeat_lock);
543 printk(KERN_WARNING PFX "heartbeat failure: %d\n", 550 printk(KERN_WARNING PFX "heartbeat failure: %d\n",
544 rv); 551 rv);
545 return rv; 552 return rv;
546 } 553 }
547 554
548 /* Wait for the heartbeat to be sent. */ 555 /* Wait for the heartbeat to be sent. */
549 down(&heartbeat_wait_lock); 556 wait_for_completion(&heartbeat_wait);
550 557
551 if (heartbeat_recv_msg.msg.data[0] != 0) { 558 if (heartbeat_recv_msg.msg.data[0] != 0) {
552 /* Got an error in the heartbeat response. It was already 559 /* Got an error in the heartbeat response. It was already
@@ -555,7 +562,7 @@ static int ipmi_heartbeat(void)
555 rv = -EINVAL; 562 rv = -EINVAL;
556 } 563 }
557 564
558 up(&heartbeat_lock); 565 mutex_unlock(&heartbeat_lock);
559 566
560 return rv; 567 return rv;
561} 568}
@@ -589,7 +596,7 @@ static void panic_halt_ipmi_heartbeat(void)
589 1); 596 1);
590} 597}
591 598
592static struct watchdog_info ident= 599static struct watchdog_info ident =
593{ 600{
594 .options = 0, /* WDIOF_SETTIMEOUT, */ 601 .options = 0, /* WDIOF_SETTIMEOUT, */
595 .firmware_version = 1, 602 .firmware_version = 1,
@@ -790,13 +797,13 @@ static int ipmi_fasync(int fd, struct file *file, int on)
790 797
791static int ipmi_close(struct inode *ino, struct file *filep) 798static int ipmi_close(struct inode *ino, struct file *filep)
792{ 799{
793 if (iminor(ino)==WATCHDOG_MINOR) 800 if (iminor(ino) == WATCHDOG_MINOR) {
794 {
795 if (expect_close == 42) { 801 if (expect_close == 42) {
796 ipmi_watchdog_state = WDOG_TIMEOUT_NONE; 802 ipmi_watchdog_state = WDOG_TIMEOUT_NONE;
797 ipmi_set_timeout(IPMI_SET_TIMEOUT_NO_HB); 803 ipmi_set_timeout(IPMI_SET_TIMEOUT_NO_HB);
798 } else { 804 } else {
799 printk(KERN_CRIT PFX "Unexpected close, not stopping watchdog!\n"); 805 printk(KERN_CRIT PFX
806 "Unexpected close, not stopping watchdog!\n");
800 ipmi_heartbeat(); 807 ipmi_heartbeat();
801 } 808 }
802 clear_bit(0, &ipmi_wdog_open); 809 clear_bit(0, &ipmi_wdog_open);
diff --git a/drivers/char/istallion.c b/drivers/char/istallion.c
index e5247f85a446..ef20c1fc9c4c 100644
--- a/drivers/char/istallion.c
+++ b/drivers/char/istallion.c
@@ -706,7 +706,6 @@ static int stli_portcmdstats(stliport_t *portp);
706static int stli_clrportstats(stliport_t *portp, comstats_t __user *cp); 706static int stli_clrportstats(stliport_t *portp, comstats_t __user *cp);
707static int stli_getportstruct(stliport_t __user *arg); 707static int stli_getportstruct(stliport_t __user *arg);
708static int stli_getbrdstruct(stlibrd_t __user *arg); 708static int stli_getbrdstruct(stlibrd_t __user *arg);
709static void *stli_memalloc(int len);
710static stlibrd_t *stli_allocbrd(void); 709static stlibrd_t *stli_allocbrd(void);
711 710
712static void stli_ecpinit(stlibrd_t *brdp); 711static void stli_ecpinit(stlibrd_t *brdp);
@@ -997,17 +996,6 @@ static int stli_parsebrd(stlconf_t *confp, char **argp)
997 996
998/*****************************************************************************/ 997/*****************************************************************************/
999 998
1000/*
1001 * Local driver kernel malloc routine.
1002 */
1003
1004static void *stli_memalloc(int len)
1005{
1006 return((void *) kmalloc(len, GFP_KERNEL));
1007}
1008
1009/*****************************************************************************/
1010
1011static int stli_open(struct tty_struct *tty, struct file *filp) 999static int stli_open(struct tty_struct *tty, struct file *filp)
1012{ 1000{
1013 stlibrd_t *brdp; 1001 stlibrd_t *brdp;
@@ -3227,13 +3215,12 @@ static int stli_initports(stlibrd_t *brdp)
3227#endif 3215#endif
3228 3216
3229 for (i = 0, panelnr = 0, panelport = 0; (i < brdp->nrports); i++) { 3217 for (i = 0, panelnr = 0, panelport = 0; (i < brdp->nrports); i++) {
3230 portp = (stliport_t *) stli_memalloc(sizeof(stliport_t)); 3218 portp = kzalloc(sizeof(stliport_t), GFP_KERNEL);
3231 if (portp == (stliport_t *) NULL) { 3219 if (!portp) {
3232 printk("STALLION: failed to allocate port structure\n"); 3220 printk("STALLION: failed to allocate port structure\n");
3233 continue; 3221 continue;
3234 } 3222 }
3235 3223
3236 memset(portp, 0, sizeof(stliport_t));
3237 portp->magic = STLI_PORTMAGIC; 3224 portp->magic = STLI_PORTMAGIC;
3238 portp->portnr = i; 3225 portp->portnr = i;
3239 portp->brdnr = brdp->brdnr; 3226 portp->brdnr = brdp->brdnr;
@@ -4610,14 +4597,13 @@ static stlibrd_t *stli_allocbrd(void)
4610{ 4597{
4611 stlibrd_t *brdp; 4598 stlibrd_t *brdp;
4612 4599
4613 brdp = (stlibrd_t *) stli_memalloc(sizeof(stlibrd_t)); 4600 brdp = kzalloc(sizeof(stlibrd_t), GFP_KERNEL);
4614 if (brdp == (stlibrd_t *) NULL) { 4601 if (!brdp) {
4615 printk(KERN_ERR "STALLION: failed to allocate memory " 4602 printk(KERN_ERR "STALLION: failed to allocate memory "
4616 "(size=%d)\n", sizeof(stlibrd_t)); 4603 "(size=%d)\n", sizeof(stlibrd_t));
4617 return((stlibrd_t *) NULL); 4604 return NULL;
4618 } 4605 }
4619 4606
4620 memset(brdp, 0, sizeof(stlibrd_t));
4621 brdp->magic = STLI_BOARDMAGIC; 4607 brdp->magic = STLI_BOARDMAGIC;
4622 return(brdp); 4608 return(brdp);
4623} 4609}
@@ -5210,12 +5196,12 @@ int __init stli_init(void)
5210/* 5196/*
5211 * Allocate a temporary write buffer. 5197 * Allocate a temporary write buffer.
5212 */ 5198 */
5213 stli_tmpwritebuf = (char *) stli_memalloc(STLI_TXBUFSIZE); 5199 stli_tmpwritebuf = kmalloc(STLI_TXBUFSIZE, GFP_KERNEL);
5214 if (stli_tmpwritebuf == (char *) NULL) 5200 if (!stli_tmpwritebuf)
5215 printk(KERN_ERR "STALLION: failed to allocate memory " 5201 printk(KERN_ERR "STALLION: failed to allocate memory "
5216 "(size=%d)\n", STLI_TXBUFSIZE); 5202 "(size=%d)\n", STLI_TXBUFSIZE);
5217 stli_txcookbuf = stli_memalloc(STLI_TXBUFSIZE); 5203 stli_txcookbuf = kmalloc(STLI_TXBUFSIZE, GFP_KERNEL);
5218 if (stli_txcookbuf == (char *) NULL) 5204 if (!stli_txcookbuf)
5219 printk(KERN_ERR "STALLION: failed to allocate memory " 5205 printk(KERN_ERR "STALLION: failed to allocate memory "
5220 "(size=%d)\n", STLI_TXBUFSIZE); 5206 "(size=%d)\n", STLI_TXBUFSIZE);
5221 5207
diff --git a/drivers/char/stallion.c b/drivers/char/stallion.c
index 3f5d6077f39c..a9c5a7230f89 100644
--- a/drivers/char/stallion.c
+++ b/drivers/char/stallion.c
@@ -504,7 +504,6 @@ static int stl_echmcaintr(stlbrd_t *brdp);
504static int stl_echpciintr(stlbrd_t *brdp); 504static int stl_echpciintr(stlbrd_t *brdp);
505static int stl_echpci64intr(stlbrd_t *brdp); 505static int stl_echpci64intr(stlbrd_t *brdp);
506static void stl_offintr(void *private); 506static void stl_offintr(void *private);
507static void *stl_memalloc(int len);
508static stlbrd_t *stl_allocbrd(void); 507static stlbrd_t *stl_allocbrd(void);
509static stlport_t *stl_getport(int brdnr, int panelnr, int portnr); 508static stlport_t *stl_getport(int brdnr, int panelnr, int portnr);
510 509
@@ -940,17 +939,6 @@ static int stl_parsebrd(stlconf_t *confp, char **argp)
940/*****************************************************************************/ 939/*****************************************************************************/
941 940
942/* 941/*
943 * Local driver kernel memory allocation routine.
944 */
945
946static void *stl_memalloc(int len)
947{
948 return (void *) kmalloc(len, GFP_KERNEL);
949}
950
951/*****************************************************************************/
952
953/*
954 * Allocate a new board structure. Fill out the basic info in it. 942 * Allocate a new board structure. Fill out the basic info in it.
955 */ 943 */
956 944
@@ -958,14 +946,13 @@ static stlbrd_t *stl_allocbrd(void)
958{ 946{
959 stlbrd_t *brdp; 947 stlbrd_t *brdp;
960 948
961 brdp = (stlbrd_t *) stl_memalloc(sizeof(stlbrd_t)); 949 brdp = kzalloc(sizeof(stlbrd_t), GFP_KERNEL);
962 if (brdp == (stlbrd_t *) NULL) { 950 if (!brdp) {
963 printk("STALLION: failed to allocate memory (size=%d)\n", 951 printk("STALLION: failed to allocate memory (size=%d)\n",
964 sizeof(stlbrd_t)); 952 sizeof(stlbrd_t));
965 return (stlbrd_t *) NULL; 953 return NULL;
966 } 954 }
967 955
968 memset(brdp, 0, sizeof(stlbrd_t));
969 brdp->magic = STL_BOARDMAGIC; 956 brdp->magic = STL_BOARDMAGIC;
970 return brdp; 957 return brdp;
971} 958}
@@ -1017,9 +1004,9 @@ static int stl_open(struct tty_struct *tty, struct file *filp)
1017 portp->refcount++; 1004 portp->refcount++;
1018 1005
1019 if ((portp->flags & ASYNC_INITIALIZED) == 0) { 1006 if ((portp->flags & ASYNC_INITIALIZED) == 0) {
1020 if (portp->tx.buf == (char *) NULL) { 1007 if (!portp->tx.buf) {
1021 portp->tx.buf = (char *) stl_memalloc(STL_TXBUFSIZE); 1008 portp->tx.buf = kmalloc(STL_TXBUFSIZE, GFP_KERNEL);
1022 if (portp->tx.buf == (char *) NULL) 1009 if (!portp->tx.buf)
1023 return -ENOMEM; 1010 return -ENOMEM;
1024 portp->tx.head = portp->tx.buf; 1011 portp->tx.head = portp->tx.buf;
1025 portp->tx.tail = portp->tx.buf; 1012 portp->tx.tail = portp->tx.buf;
@@ -2178,13 +2165,12 @@ static int __init stl_initports(stlbrd_t *brdp, stlpanel_t *panelp)
2178 * each ports data structures. 2165 * each ports data structures.
2179 */ 2166 */
2180 for (i = 0; (i < panelp->nrports); i++) { 2167 for (i = 0; (i < panelp->nrports); i++) {
2181 portp = (stlport_t *) stl_memalloc(sizeof(stlport_t)); 2168 portp = kzalloc(sizeof(stlport_t), GFP_KERNEL);
2182 if (portp == (stlport_t *) NULL) { 2169 if (!portp) {
2183 printk("STALLION: failed to allocate memory " 2170 printk("STALLION: failed to allocate memory "
2184 "(size=%d)\n", sizeof(stlport_t)); 2171 "(size=%d)\n", sizeof(stlport_t));
2185 break; 2172 break;
2186 } 2173 }
2187 memset(portp, 0, sizeof(stlport_t));
2188 2174
2189 portp->magic = STL_PORTMAGIC; 2175 portp->magic = STL_PORTMAGIC;
2190 portp->portnr = i; 2176 portp->portnr = i;
@@ -2315,13 +2301,12 @@ static inline int stl_initeio(stlbrd_t *brdp)
2315 * can complete the setup. 2301 * can complete the setup.
2316 */ 2302 */
2317 2303
2318 panelp = (stlpanel_t *) stl_memalloc(sizeof(stlpanel_t)); 2304 panelp = kzalloc(sizeof(stlpanel_t), GFP_KERNEL);
2319 if (panelp == (stlpanel_t *) NULL) { 2305 if (!panelp) {
2320 printk(KERN_WARNING "STALLION: failed to allocate memory " 2306 printk(KERN_WARNING "STALLION: failed to allocate memory "
2321 "(size=%d)\n", sizeof(stlpanel_t)); 2307 "(size=%d)\n", sizeof(stlpanel_t));
2322 return(-ENOMEM); 2308 return -ENOMEM;
2323 } 2309 }
2324 memset(panelp, 0, sizeof(stlpanel_t));
2325 2310
2326 panelp->magic = STL_PANELMAGIC; 2311 panelp->magic = STL_PANELMAGIC;
2327 panelp->brdnr = brdp->brdnr; 2312 panelp->brdnr = brdp->brdnr;
@@ -2490,13 +2475,12 @@ static inline int stl_initech(stlbrd_t *brdp)
2490 status = inb(ioaddr + ECH_PNLSTATUS); 2475 status = inb(ioaddr + ECH_PNLSTATUS);
2491 if ((status & ECH_PNLIDMASK) != nxtid) 2476 if ((status & ECH_PNLIDMASK) != nxtid)
2492 break; 2477 break;
2493 panelp = (stlpanel_t *) stl_memalloc(sizeof(stlpanel_t)); 2478 panelp = kzalloc(sizeof(stlpanel_t), GFP_KERNEL);
2494 if (panelp == (stlpanel_t *) NULL) { 2479 if (!panelp) {
2495 printk("STALLION: failed to allocate memory " 2480 printk("STALLION: failed to allocate memory "
2496 "(size=%d)\n", sizeof(stlpanel_t)); 2481 "(size=%d)\n", sizeof(stlpanel_t));
2497 break; 2482 break;
2498 } 2483 }
2499 memset(panelp, 0, sizeof(stlpanel_t));
2500 panelp->magic = STL_PANELMAGIC; 2484 panelp->magic = STL_PANELMAGIC;
2501 panelp->brdnr = brdp->brdnr; 2485 panelp->brdnr = brdp->brdnr;
2502 panelp->panelnr = panelnr; 2486 panelp->panelnr = panelnr;
@@ -3074,8 +3058,8 @@ static int __init stl_init(void)
3074/* 3058/*
3075 * Allocate a temporary write buffer. 3059 * Allocate a temporary write buffer.
3076 */ 3060 */
3077 stl_tmpwritebuf = (char *) stl_memalloc(STL_TXBUFSIZE); 3061 stl_tmpwritebuf = kmalloc(STL_TXBUFSIZE, GFP_KERNEL);
3078 if (stl_tmpwritebuf == (char *) NULL) 3062 if (!stl_tmpwritebuf)
3079 printk("STALLION: failed to allocate memory (size=%d)\n", 3063 printk("STALLION: failed to allocate memory (size=%d)\n",
3080 STL_TXBUFSIZE); 3064 STL_TXBUFSIZE);
3081 3065
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c
index 0bfd1b63662e..98b126c2ded8 100644
--- a/drivers/char/tty_io.c
+++ b/drivers/char/tty_io.c
@@ -376,7 +376,7 @@ int tty_insert_flip_string(struct tty_struct *tty, const unsigned char *chars, s
376 return copied; 376 return copied;
377} 377}
378 378
379EXPORT_SYMBOL_GPL(tty_insert_flip_string); 379EXPORT_SYMBOL(tty_insert_flip_string);
380 380
381int tty_insert_flip_string_flags(struct tty_struct *tty, const unsigned char *chars, const char *flags, size_t size) 381int tty_insert_flip_string_flags(struct tty_struct *tty, const unsigned char *chars, const char *flags, size_t size)
382{ 382{
diff --git a/drivers/char/vt.c b/drivers/char/vt.c
index ca4844c527da..acc5d47844eb 100644
--- a/drivers/char/vt.c
+++ b/drivers/char/vt.c
@@ -2328,6 +2328,10 @@ int tioclinux(struct tty_struct *tty, unsigned long arg)
2328 case TIOCL_SETVESABLANK: 2328 case TIOCL_SETVESABLANK:
2329 set_vesa_blanking(p); 2329 set_vesa_blanking(p);
2330 break; 2330 break;
2331 case TIOCL_GETKMSGREDIRECT:
2332 data = kmsg_redirect;
2333 ret = __put_user(data, p);
2334 break;
2331 case TIOCL_SETKMSGREDIRECT: 2335 case TIOCL_SETKMSGREDIRECT:
2332 if (!capable(CAP_SYS_ADMIN)) { 2336 if (!capable(CAP_SYS_ADMIN)) {
2333 ret = -EPERM; 2337 ret = -EPERM;
diff --git a/drivers/edac/Kconfig b/drivers/edac/Kconfig
index b582d0cdc24f..4f0898400c6d 100644
--- a/drivers/edac/Kconfig
+++ b/drivers/edac/Kconfig
@@ -71,7 +71,7 @@ config EDAC_E7XXX
71 71
72config EDAC_E752X 72config EDAC_E752X
73 tristate "Intel e752x (e7520, e7525, e7320)" 73 tristate "Intel e752x (e7520, e7525, e7320)"
74 depends on EDAC_MM_EDAC && PCI && X86 74 depends on EDAC_MM_EDAC && PCI && X86 && HOTPLUG
75 help 75 help
76 Support for error detection and correction on the Intel 76 Support for error detection and correction on the Intel
77 E7520, E7525, E7320 server chipsets. 77 E7520, E7525, E7320 server chipsets.
diff --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c
index ccf528d733bf..a5017de72da5 100644
--- a/drivers/ide/ide-disk.c
+++ b/drivers/ide/ide-disk.c
@@ -61,6 +61,7 @@
61#include <linux/slab.h> 61#include <linux/slab.h>
62#include <linux/delay.h> 62#include <linux/delay.h>
63#include <linux/mutex.h> 63#include <linux/mutex.h>
64#include <linux/leds.h>
64 65
65#define _IDE_DISK 66#define _IDE_DISK
66 67
@@ -317,6 +318,8 @@ static ide_startstop_t ide_do_rw_disk (ide_drive_t *drive, struct request *rq, s
317 return ide_stopped; 318 return ide_stopped;
318 } 319 }
319 320
321 ledtrig_ide_activity();
322
320 pr_debug("%s: %sing: block=%llu, sectors=%lu, buffer=0x%08lx\n", 323 pr_debug("%s: %sing: block=%llu, sectors=%lu, buffer=0x%08lx\n",
321 drive->name, rq_data_dir(rq) == READ ? "read" : "writ", 324 drive->name, rq_data_dir(rq) == READ ? "read" : "writ",
322 (unsigned long long)block, rq->nr_sectors, 325 (unsigned long long)block, rq->nr_sectors,
diff --git a/drivers/ide/ide-taskfile.c b/drivers/ide/ide-taskfile.c
index 0606bd2f6020..9233b8109a0f 100644
--- a/drivers/ide/ide-taskfile.c
+++ b/drivers/ide/ide-taskfile.c
@@ -375,7 +375,13 @@ static void task_end_request(ide_drive_t *drive, struct request *rq, u8 stat)
375 } 375 }
376 } 376 }
377 377
378 ide_end_request(drive, 1, rq->hard_nr_sectors); 378 if (rq->rq_disk) {
379 ide_driver_t *drv;
380
381 drv = *(ide_driver_t **)rq->rq_disk->private_data;;
382 drv->end_request(drive, 1, rq->hard_nr_sectors);
383 } else
384 ide_end_request(drive, 1, rq->hard_nr_sectors);
379} 385}
380 386
381/* 387/*
diff --git a/drivers/ide/pci/via82cxxx.c b/drivers/ide/pci/via82cxxx.c
index c85b87cb59d1..3e677c4f8c28 100644
--- a/drivers/ide/pci/via82cxxx.c
+++ b/drivers/ide/pci/via82cxxx.c
@@ -440,7 +440,7 @@ static void __devinit init_hwif_via82cxxx(ide_hwif_t *hwif)
440 440
441 441
442#if defined(CONFIG_PPC_CHRP) && defined(CONFIG_PPC32) 442#if defined(CONFIG_PPC_CHRP) && defined(CONFIG_PPC32)
443 if(_machine == _MACH_chrp && _chrp_type == _CHRP_Pegasos) { 443 if(machine_is(chrp) && _chrp_type == _CHRP_Pegasos) {
444 hwif->irq = hwif->channel ? 15 : 14; 444 hwif->irq = hwif->channel ? 15 : 14;
445 } 445 }
446#endif 446#endif
diff --git a/drivers/ide/ppc/pmac.c b/drivers/ide/ppc/pmac.c
index 5013b1285e22..78e30f803671 100644
--- a/drivers/ide/ppc/pmac.c
+++ b/drivers/ide/ppc/pmac.c
@@ -1677,7 +1677,7 @@ MODULE_DEVICE_TABLE(pci, pmac_ide_pci_match);
1677void __init 1677void __init
1678pmac_ide_probe(void) 1678pmac_ide_probe(void)
1679{ 1679{
1680 if (_machine != _MACH_Pmac) 1680 if (!machine_is(powermac))
1681 return; 1681 return;
1682 1682
1683#ifdef CONFIG_BLK_DEV_IDE_PMAC_ATA100FIRST 1683#ifdef CONFIG_BLK_DEV_IDE_PMAC_ATA100FIRST
diff --git a/drivers/ieee1394/ohci1394.c b/drivers/ieee1394/ohci1394.c
index a86beeb6af5d..19222878aae9 100644
--- a/drivers/ieee1394/ohci1394.c
+++ b/drivers/ieee1394/ohci1394.c
@@ -3529,7 +3529,7 @@ static void ohci1394_pci_remove(struct pci_dev *pdev)
3529static int ohci1394_pci_resume (struct pci_dev *pdev) 3529static int ohci1394_pci_resume (struct pci_dev *pdev)
3530{ 3530{
3531#ifdef CONFIG_PPC_PMAC 3531#ifdef CONFIG_PPC_PMAC
3532 if (_machine == _MACH_Pmac) { 3532 if (machine_is(powermac)) {
3533 struct device_node *of_node; 3533 struct device_node *of_node;
3534 3534
3535 /* Re-enable 1394 */ 3535 /* Re-enable 1394 */
@@ -3548,7 +3548,7 @@ static int ohci1394_pci_resume (struct pci_dev *pdev)
3548static int ohci1394_pci_suspend (struct pci_dev *pdev, pm_message_t state) 3548static int ohci1394_pci_suspend (struct pci_dev *pdev, pm_message_t state)
3549{ 3549{
3550#ifdef CONFIG_PPC_PMAC 3550#ifdef CONFIG_PPC_PMAC
3551 if (_machine == _MACH_Pmac) { 3551 if (machine_is(powermac)) {
3552 struct device_node *of_node; 3552 struct device_node *of_node;
3553 3553
3554 /* Disable 1394 */ 3554 /* Disable 1394 */
diff --git a/drivers/infiniband/core/mad.c b/drivers/infiniband/core/mad.c
index f7854b65fd55..ba54c856b0e5 100644
--- a/drivers/infiniband/core/mad.c
+++ b/drivers/infiniband/core/mad.c
@@ -227,6 +227,14 @@ struct ib_mad_agent *ib_register_mad_agent(struct ib_device *device,
227 if (!is_vendor_oui(mad_reg_req->oui)) 227 if (!is_vendor_oui(mad_reg_req->oui))
228 goto error1; 228 goto error1;
229 } 229 }
230 /* Make sure class supplied is consistent with RMPP */
231 if (ib_is_mad_class_rmpp(mad_reg_req->mgmt_class)) {
232 if (!rmpp_version)
233 goto error1;
234 } else {
235 if (rmpp_version)
236 goto error1;
237 }
230 /* Make sure class supplied is consistent with QP type */ 238 /* Make sure class supplied is consistent with QP type */
231 if (qp_type == IB_QPT_SMI) { 239 if (qp_type == IB_QPT_SMI) {
232 if ((mad_reg_req->mgmt_class != 240 if ((mad_reg_req->mgmt_class !=
@@ -890,6 +898,35 @@ struct ib_mad_send_buf * ib_create_send_mad(struct ib_mad_agent *mad_agent,
890} 898}
891EXPORT_SYMBOL(ib_create_send_mad); 899EXPORT_SYMBOL(ib_create_send_mad);
892 900
901int ib_get_mad_data_offset(u8 mgmt_class)
902{
903 if (mgmt_class == IB_MGMT_CLASS_SUBN_ADM)
904 return IB_MGMT_SA_HDR;
905 else if ((mgmt_class == IB_MGMT_CLASS_DEVICE_MGMT) ||
906 (mgmt_class == IB_MGMT_CLASS_DEVICE_ADM) ||
907 (mgmt_class == IB_MGMT_CLASS_BIS))
908 return IB_MGMT_DEVICE_HDR;
909 else if ((mgmt_class >= IB_MGMT_CLASS_VENDOR_RANGE2_START) &&
910 (mgmt_class <= IB_MGMT_CLASS_VENDOR_RANGE2_END))
911 return IB_MGMT_VENDOR_HDR;
912 else
913 return IB_MGMT_MAD_HDR;
914}
915EXPORT_SYMBOL(ib_get_mad_data_offset);
916
917int ib_is_mad_class_rmpp(u8 mgmt_class)
918{
919 if ((mgmt_class == IB_MGMT_CLASS_SUBN_ADM) ||
920 (mgmt_class == IB_MGMT_CLASS_DEVICE_MGMT) ||
921 (mgmt_class == IB_MGMT_CLASS_DEVICE_ADM) ||
922 (mgmt_class == IB_MGMT_CLASS_BIS) ||
923 ((mgmt_class >= IB_MGMT_CLASS_VENDOR_RANGE2_START) &&
924 (mgmt_class <= IB_MGMT_CLASS_VENDOR_RANGE2_END)))
925 return 1;
926 return 0;
927}
928EXPORT_SYMBOL(ib_is_mad_class_rmpp);
929
893void *ib_get_rmpp_segment(struct ib_mad_send_buf *send_buf, int seg_num) 930void *ib_get_rmpp_segment(struct ib_mad_send_buf *send_buf, int seg_num)
894{ 931{
895 struct ib_mad_send_wr_private *mad_send_wr; 932 struct ib_mad_send_wr_private *mad_send_wr;
@@ -1022,6 +1059,13 @@ int ib_post_send_mad(struct ib_mad_send_buf *send_buf,
1022 goto error; 1059 goto error;
1023 } 1060 }
1024 1061
1062 if (!ib_is_mad_class_rmpp(((struct ib_mad_hdr *) send_buf->mad)->mgmt_class)) {
1063 if (mad_agent_priv->agent.rmpp_version) {
1064 ret = -EINVAL;
1065 goto error;
1066 }
1067 }
1068
1025 /* 1069 /*
1026 * Save pointer to next work request to post in case the 1070 * Save pointer to next work request to post in case the
1027 * current one completes, and the user modifies the work 1071 * current one completes, and the user modifies the work
@@ -1618,14 +1662,59 @@ static int is_data_mad(struct ib_mad_agent_private *mad_agent_priv,
1618 (rmpp_mad->rmpp_hdr.rmpp_type == IB_MGMT_RMPP_TYPE_DATA); 1662 (rmpp_mad->rmpp_hdr.rmpp_type == IB_MGMT_RMPP_TYPE_DATA);
1619} 1663}
1620 1664
1665static inline int rcv_has_same_class(struct ib_mad_send_wr_private *wr,
1666 struct ib_mad_recv_wc *rwc)
1667{
1668 return ((struct ib_mad *)(wr->send_buf.mad))->mad_hdr.mgmt_class ==
1669 rwc->recv_buf.mad->mad_hdr.mgmt_class;
1670}
1671
1672static inline int rcv_has_same_gid(struct ib_mad_send_wr_private *wr,
1673 struct ib_mad_recv_wc *rwc )
1674{
1675 struct ib_ah_attr attr;
1676 u8 send_resp, rcv_resp;
1677
1678 send_resp = ((struct ib_mad *)(wr->send_buf.mad))->
1679 mad_hdr.method & IB_MGMT_METHOD_RESP;
1680 rcv_resp = rwc->recv_buf.mad->mad_hdr.method & IB_MGMT_METHOD_RESP;
1681
1682 if (!send_resp && rcv_resp)
1683 /* is request/response. GID/LIDs are both local (same). */
1684 return 1;
1685
1686 if (send_resp == rcv_resp)
1687 /* both requests, or both responses. GIDs different */
1688 return 0;
1689
1690 if (ib_query_ah(wr->send_buf.ah, &attr))
1691 /* Assume not equal, to avoid false positives. */
1692 return 0;
1693
1694 if (!(attr.ah_flags & IB_AH_GRH) && !(rwc->wc->wc_flags & IB_WC_GRH))
1695 return attr.dlid == rwc->wc->slid;
1696 else if ((attr.ah_flags & IB_AH_GRH) &&
1697 (rwc->wc->wc_flags & IB_WC_GRH))
1698 return memcmp(attr.grh.dgid.raw,
1699 rwc->recv_buf.grh->sgid.raw, 16) == 0;
1700 else
1701 /* one has GID, other does not. Assume different */
1702 return 0;
1703}
1621struct ib_mad_send_wr_private* 1704struct ib_mad_send_wr_private*
1622ib_find_send_mad(struct ib_mad_agent_private *mad_agent_priv, __be64 tid) 1705ib_find_send_mad(struct ib_mad_agent_private *mad_agent_priv,
1706 struct ib_mad_recv_wc *mad_recv_wc)
1623{ 1707{
1624 struct ib_mad_send_wr_private *mad_send_wr; 1708 struct ib_mad_send_wr_private *mad_send_wr;
1709 struct ib_mad *mad;
1710
1711 mad = (struct ib_mad *)mad_recv_wc->recv_buf.mad;
1625 1712
1626 list_for_each_entry(mad_send_wr, &mad_agent_priv->wait_list, 1713 list_for_each_entry(mad_send_wr, &mad_agent_priv->wait_list,
1627 agent_list) { 1714 agent_list) {
1628 if (mad_send_wr->tid == tid) 1715 if ((mad_send_wr->tid == mad->mad_hdr.tid) &&
1716 rcv_has_same_class(mad_send_wr, mad_recv_wc) &&
1717 rcv_has_same_gid(mad_send_wr, mad_recv_wc))
1629 return mad_send_wr; 1718 return mad_send_wr;
1630 } 1719 }
1631 1720
@@ -1636,7 +1725,10 @@ ib_find_send_mad(struct ib_mad_agent_private *mad_agent_priv, __be64 tid)
1636 list_for_each_entry(mad_send_wr, &mad_agent_priv->send_list, 1725 list_for_each_entry(mad_send_wr, &mad_agent_priv->send_list,
1637 agent_list) { 1726 agent_list) {
1638 if (is_data_mad(mad_agent_priv, mad_send_wr->send_buf.mad) && 1727 if (is_data_mad(mad_agent_priv, mad_send_wr->send_buf.mad) &&
1639 mad_send_wr->tid == tid && mad_send_wr->timeout) { 1728 mad_send_wr->tid == mad->mad_hdr.tid &&
1729 mad_send_wr->timeout &&
1730 rcv_has_same_class(mad_send_wr, mad_recv_wc) &&
1731 rcv_has_same_gid(mad_send_wr, mad_recv_wc)) {
1640 /* Verify request has not been canceled */ 1732 /* Verify request has not been canceled */
1641 return (mad_send_wr->status == IB_WC_SUCCESS) ? 1733 return (mad_send_wr->status == IB_WC_SUCCESS) ?
1642 mad_send_wr : NULL; 1734 mad_send_wr : NULL;
@@ -1661,7 +1753,6 @@ static void ib_mad_complete_recv(struct ib_mad_agent_private *mad_agent_priv,
1661 struct ib_mad_send_wr_private *mad_send_wr; 1753 struct ib_mad_send_wr_private *mad_send_wr;
1662 struct ib_mad_send_wc mad_send_wc; 1754 struct ib_mad_send_wc mad_send_wc;
1663 unsigned long flags; 1755 unsigned long flags;
1664 __be64 tid;
1665 1756
1666 INIT_LIST_HEAD(&mad_recv_wc->rmpp_list); 1757 INIT_LIST_HEAD(&mad_recv_wc->rmpp_list);
1667 list_add(&mad_recv_wc->recv_buf.list, &mad_recv_wc->rmpp_list); 1758 list_add(&mad_recv_wc->recv_buf.list, &mad_recv_wc->rmpp_list);
@@ -1677,9 +1768,8 @@ static void ib_mad_complete_recv(struct ib_mad_agent_private *mad_agent_priv,
1677 1768
1678 /* Complete corresponding request */ 1769 /* Complete corresponding request */
1679 if (response_mad(mad_recv_wc->recv_buf.mad)) { 1770 if (response_mad(mad_recv_wc->recv_buf.mad)) {
1680 tid = mad_recv_wc->recv_buf.mad->mad_hdr.tid;
1681 spin_lock_irqsave(&mad_agent_priv->lock, flags); 1771 spin_lock_irqsave(&mad_agent_priv->lock, flags);
1682 mad_send_wr = ib_find_send_mad(mad_agent_priv, tid); 1772 mad_send_wr = ib_find_send_mad(mad_agent_priv, mad_recv_wc);
1683 if (!mad_send_wr) { 1773 if (!mad_send_wr) {
1684 spin_unlock_irqrestore(&mad_agent_priv->lock, flags); 1774 spin_unlock_irqrestore(&mad_agent_priv->lock, flags);
1685 ib_free_recv_mad(mad_recv_wc); 1775 ib_free_recv_mad(mad_recv_wc);
@@ -2408,11 +2498,11 @@ static int ib_mad_post_receive_mads(struct ib_mad_qp_info *qp_info,
2408 } 2498 }
2409 } 2499 }
2410 sg_list.addr = dma_map_single(qp_info->port_priv-> 2500 sg_list.addr = dma_map_single(qp_info->port_priv->
2411 device->dma_device, 2501 device->dma_device,
2412 &mad_priv->grh, 2502 &mad_priv->grh,
2413 sizeof *mad_priv - 2503 sizeof *mad_priv -
2414 sizeof mad_priv->header, 2504 sizeof mad_priv->header,
2415 DMA_FROM_DEVICE); 2505 DMA_FROM_DEVICE);
2416 pci_unmap_addr_set(&mad_priv->header, mapping, sg_list.addr); 2506 pci_unmap_addr_set(&mad_priv->header, mapping, sg_list.addr);
2417 recv_wr.wr_id = (unsigned long)&mad_priv->header.mad_list; 2507 recv_wr.wr_id = (unsigned long)&mad_priv->header.mad_list;
2418 mad_priv->header.mad_list.mad_queue = recv_queue; 2508 mad_priv->header.mad_list.mad_queue = recv_queue;
diff --git a/drivers/infiniband/core/mad_priv.h b/drivers/infiniband/core/mad_priv.h
index a7125d4b5ccf..6c9c133d71ef 100644
--- a/drivers/infiniband/core/mad_priv.h
+++ b/drivers/infiniband/core/mad_priv.h
@@ -216,7 +216,8 @@ extern kmem_cache_t *ib_mad_cache;
216int ib_send_mad(struct ib_mad_send_wr_private *mad_send_wr); 216int ib_send_mad(struct ib_mad_send_wr_private *mad_send_wr);
217 217
218struct ib_mad_send_wr_private * 218struct ib_mad_send_wr_private *
219ib_find_send_mad(struct ib_mad_agent_private *mad_agent_priv, __be64 tid); 219ib_find_send_mad(struct ib_mad_agent_private *mad_agent_priv,
220 struct ib_mad_recv_wc *mad_recv_wc);
220 221
221void ib_mad_complete_send_wr(struct ib_mad_send_wr_private *mad_send_wr, 222void ib_mad_complete_send_wr(struct ib_mad_send_wr_private *mad_send_wr,
222 struct ib_mad_send_wc *mad_send_wc); 223 struct ib_mad_send_wc *mad_send_wc);
diff --git a/drivers/infiniband/core/mad_rmpp.c b/drivers/infiniband/core/mad_rmpp.c
index bacfdd5bddad..dfd4e588ce03 100644
--- a/drivers/infiniband/core/mad_rmpp.c
+++ b/drivers/infiniband/core/mad_rmpp.c
@@ -1,6 +1,6 @@
1/* 1/*
2 * Copyright (c) 2005 Intel Inc. All rights reserved. 2 * Copyright (c) 2005 Intel Inc. All rights reserved.
3 * Copyright (c) 2005 Voltaire, Inc. All rights reserved. 3 * Copyright (c) 2005-2006 Voltaire, Inc. All rights reserved.
4 * 4 *
5 * This software is available to you under a choice of one of two 5 * This software is available to you under a choice of one of two
6 * licenses. You may choose to be licensed under the terms of the GNU 6 * licenses. You may choose to be licensed under the terms of the GNU
@@ -100,17 +100,6 @@ void ib_cancel_rmpp_recvs(struct ib_mad_agent_private *agent)
100 } 100 }
101} 101}
102 102
103static int data_offset(u8 mgmt_class)
104{
105 if (mgmt_class == IB_MGMT_CLASS_SUBN_ADM)
106 return IB_MGMT_SA_HDR;
107 else if ((mgmt_class >= IB_MGMT_CLASS_VENDOR_RANGE2_START) &&
108 (mgmt_class <= IB_MGMT_CLASS_VENDOR_RANGE2_END))
109 return IB_MGMT_VENDOR_HDR;
110 else
111 return IB_MGMT_RMPP_HDR;
112}
113
114static void format_ack(struct ib_mad_send_buf *msg, 103static void format_ack(struct ib_mad_send_buf *msg,
115 struct ib_rmpp_mad *data, 104 struct ib_rmpp_mad *data,
116 struct mad_rmpp_recv *rmpp_recv) 105 struct mad_rmpp_recv *rmpp_recv)
@@ -137,7 +126,7 @@ static void ack_recv(struct mad_rmpp_recv *rmpp_recv,
137 struct ib_mad_send_buf *msg; 126 struct ib_mad_send_buf *msg;
138 int ret, hdr_len; 127 int ret, hdr_len;
139 128
140 hdr_len = data_offset(recv_wc->recv_buf.mad->mad_hdr.mgmt_class); 129 hdr_len = ib_get_mad_data_offset(recv_wc->recv_buf.mad->mad_hdr.mgmt_class);
141 msg = ib_create_send_mad(&rmpp_recv->agent->agent, recv_wc->wc->src_qp, 130 msg = ib_create_send_mad(&rmpp_recv->agent->agent, recv_wc->wc->src_qp,
142 recv_wc->wc->pkey_index, 1, hdr_len, 131 recv_wc->wc->pkey_index, 1, hdr_len,
143 0, GFP_KERNEL); 132 0, GFP_KERNEL);
@@ -163,7 +152,7 @@ static struct ib_mad_send_buf *alloc_response_msg(struct ib_mad_agent *agent,
163 if (IS_ERR(ah)) 152 if (IS_ERR(ah))
164 return (void *) ah; 153 return (void *) ah;
165 154
166 hdr_len = data_offset(recv_wc->recv_buf.mad->mad_hdr.mgmt_class); 155 hdr_len = ib_get_mad_data_offset(recv_wc->recv_buf.mad->mad_hdr.mgmt_class);
167 msg = ib_create_send_mad(agent, recv_wc->wc->src_qp, 156 msg = ib_create_send_mad(agent, recv_wc->wc->src_qp,
168 recv_wc->wc->pkey_index, 1, 157 recv_wc->wc->pkey_index, 1,
169 hdr_len, 0, GFP_KERNEL); 158 hdr_len, 0, GFP_KERNEL);
@@ -408,7 +397,7 @@ static inline int get_mad_len(struct mad_rmpp_recv *rmpp_recv)
408 397
409 rmpp_mad = (struct ib_rmpp_mad *)rmpp_recv->cur_seg_buf->mad; 398 rmpp_mad = (struct ib_rmpp_mad *)rmpp_recv->cur_seg_buf->mad;
410 399
411 hdr_size = data_offset(rmpp_mad->mad_hdr.mgmt_class); 400 hdr_size = ib_get_mad_data_offset(rmpp_mad->mad_hdr.mgmt_class);
412 data_size = sizeof(struct ib_rmpp_mad) - hdr_size; 401 data_size = sizeof(struct ib_rmpp_mad) - hdr_size;
413 pad = IB_MGMT_RMPP_DATA - be32_to_cpu(rmpp_mad->rmpp_hdr.paylen_newwin); 402 pad = IB_MGMT_RMPP_DATA - be32_to_cpu(rmpp_mad->rmpp_hdr.paylen_newwin);
414 if (pad > IB_MGMT_RMPP_DATA || pad < 0) 403 if (pad > IB_MGMT_RMPP_DATA || pad < 0)
@@ -562,15 +551,15 @@ static int send_next_seg(struct ib_mad_send_wr_private *mad_send_wr)
562 return ib_send_mad(mad_send_wr); 551 return ib_send_mad(mad_send_wr);
563} 552}
564 553
565static void abort_send(struct ib_mad_agent_private *agent, __be64 tid, 554static void abort_send(struct ib_mad_agent_private *agent,
566 u8 rmpp_status) 555 struct ib_mad_recv_wc *mad_recv_wc, u8 rmpp_status)
567{ 556{
568 struct ib_mad_send_wr_private *mad_send_wr; 557 struct ib_mad_send_wr_private *mad_send_wr;
569 struct ib_mad_send_wc wc; 558 struct ib_mad_send_wc wc;
570 unsigned long flags; 559 unsigned long flags;
571 560
572 spin_lock_irqsave(&agent->lock, flags); 561 spin_lock_irqsave(&agent->lock, flags);
573 mad_send_wr = ib_find_send_mad(agent, tid); 562 mad_send_wr = ib_find_send_mad(agent, mad_recv_wc);
574 if (!mad_send_wr) 563 if (!mad_send_wr)
575 goto out; /* Unmatched send */ 564 goto out; /* Unmatched send */
576 565
@@ -612,8 +601,7 @@ static void process_rmpp_ack(struct ib_mad_agent_private *agent,
612 601
613 rmpp_mad = (struct ib_rmpp_mad *)mad_recv_wc->recv_buf.mad; 602 rmpp_mad = (struct ib_rmpp_mad *)mad_recv_wc->recv_buf.mad;
614 if (rmpp_mad->rmpp_hdr.rmpp_status) { 603 if (rmpp_mad->rmpp_hdr.rmpp_status) {
615 abort_send(agent, rmpp_mad->mad_hdr.tid, 604 abort_send(agent, mad_recv_wc, IB_MGMT_RMPP_STATUS_BAD_STATUS);
616 IB_MGMT_RMPP_STATUS_BAD_STATUS);
617 nack_recv(agent, mad_recv_wc, IB_MGMT_RMPP_STATUS_BAD_STATUS); 605 nack_recv(agent, mad_recv_wc, IB_MGMT_RMPP_STATUS_BAD_STATUS);
618 return; 606 return;
619 } 607 }
@@ -621,14 +609,13 @@ static void process_rmpp_ack(struct ib_mad_agent_private *agent,
621 seg_num = be32_to_cpu(rmpp_mad->rmpp_hdr.seg_num); 609 seg_num = be32_to_cpu(rmpp_mad->rmpp_hdr.seg_num);
622 newwin = be32_to_cpu(rmpp_mad->rmpp_hdr.paylen_newwin); 610 newwin = be32_to_cpu(rmpp_mad->rmpp_hdr.paylen_newwin);
623 if (newwin < seg_num) { 611 if (newwin < seg_num) {
624 abort_send(agent, rmpp_mad->mad_hdr.tid, 612 abort_send(agent, mad_recv_wc, IB_MGMT_RMPP_STATUS_W2S);
625 IB_MGMT_RMPP_STATUS_W2S);
626 nack_recv(agent, mad_recv_wc, IB_MGMT_RMPP_STATUS_W2S); 613 nack_recv(agent, mad_recv_wc, IB_MGMT_RMPP_STATUS_W2S);
627 return; 614 return;
628 } 615 }
629 616
630 spin_lock_irqsave(&agent->lock, flags); 617 spin_lock_irqsave(&agent->lock, flags);
631 mad_send_wr = ib_find_send_mad(agent, rmpp_mad->mad_hdr.tid); 618 mad_send_wr = ib_find_send_mad(agent, mad_recv_wc);
632 if (!mad_send_wr) 619 if (!mad_send_wr)
633 goto out; /* Unmatched ACK */ 620 goto out; /* Unmatched ACK */
634 621
@@ -639,8 +626,7 @@ static void process_rmpp_ack(struct ib_mad_agent_private *agent,
639 if (seg_num > mad_send_wr->send_buf.seg_count || 626 if (seg_num > mad_send_wr->send_buf.seg_count ||
640 seg_num > mad_send_wr->newwin) { 627 seg_num > mad_send_wr->newwin) {
641 spin_unlock_irqrestore(&agent->lock, flags); 628 spin_unlock_irqrestore(&agent->lock, flags);
642 abort_send(agent, rmpp_mad->mad_hdr.tid, 629 abort_send(agent, mad_recv_wc, IB_MGMT_RMPP_STATUS_S2B);
643 IB_MGMT_RMPP_STATUS_S2B);
644 nack_recv(agent, mad_recv_wc, IB_MGMT_RMPP_STATUS_S2B); 630 nack_recv(agent, mad_recv_wc, IB_MGMT_RMPP_STATUS_S2B);
645 return; 631 return;
646 } 632 }
@@ -728,12 +714,10 @@ static void process_rmpp_stop(struct ib_mad_agent_private *agent,
728 rmpp_mad = (struct ib_rmpp_mad *)mad_recv_wc->recv_buf.mad; 714 rmpp_mad = (struct ib_rmpp_mad *)mad_recv_wc->recv_buf.mad;
729 715
730 if (rmpp_mad->rmpp_hdr.rmpp_status != IB_MGMT_RMPP_STATUS_RESX) { 716 if (rmpp_mad->rmpp_hdr.rmpp_status != IB_MGMT_RMPP_STATUS_RESX) {
731 abort_send(agent, rmpp_mad->mad_hdr.tid, 717 abort_send(agent, mad_recv_wc, IB_MGMT_RMPP_STATUS_BAD_STATUS);
732 IB_MGMT_RMPP_STATUS_BAD_STATUS);
733 nack_recv(agent, mad_recv_wc, IB_MGMT_RMPP_STATUS_BAD_STATUS); 718 nack_recv(agent, mad_recv_wc, IB_MGMT_RMPP_STATUS_BAD_STATUS);
734 } else 719 } else
735 abort_send(agent, rmpp_mad->mad_hdr.tid, 720 abort_send(agent, mad_recv_wc, rmpp_mad->rmpp_hdr.rmpp_status);
736 rmpp_mad->rmpp_hdr.rmpp_status);
737} 721}
738 722
739static void process_rmpp_abort(struct ib_mad_agent_private *agent, 723static void process_rmpp_abort(struct ib_mad_agent_private *agent,
@@ -745,12 +729,10 @@ static void process_rmpp_abort(struct ib_mad_agent_private *agent,
745 729
746 if (rmpp_mad->rmpp_hdr.rmpp_status < IB_MGMT_RMPP_STATUS_ABORT_MIN || 730 if (rmpp_mad->rmpp_hdr.rmpp_status < IB_MGMT_RMPP_STATUS_ABORT_MIN ||
747 rmpp_mad->rmpp_hdr.rmpp_status > IB_MGMT_RMPP_STATUS_ABORT_MAX) { 731 rmpp_mad->rmpp_hdr.rmpp_status > IB_MGMT_RMPP_STATUS_ABORT_MAX) {
748 abort_send(agent, rmpp_mad->mad_hdr.tid, 732 abort_send(agent, mad_recv_wc, IB_MGMT_RMPP_STATUS_BAD_STATUS);
749 IB_MGMT_RMPP_STATUS_BAD_STATUS);
750 nack_recv(agent, mad_recv_wc, IB_MGMT_RMPP_STATUS_BAD_STATUS); 733 nack_recv(agent, mad_recv_wc, IB_MGMT_RMPP_STATUS_BAD_STATUS);
751 } else 734 } else
752 abort_send(agent, rmpp_mad->mad_hdr.tid, 735 abort_send(agent, mad_recv_wc, rmpp_mad->rmpp_hdr.rmpp_status);
753 rmpp_mad->rmpp_hdr.rmpp_status);
754} 736}
755 737
756struct ib_mad_recv_wc * 738struct ib_mad_recv_wc *
@@ -764,8 +746,7 @@ ib_process_rmpp_recv_wc(struct ib_mad_agent_private *agent,
764 return mad_recv_wc; 746 return mad_recv_wc;
765 747
766 if (rmpp_mad->rmpp_hdr.rmpp_version != IB_MGMT_RMPP_VERSION) { 748 if (rmpp_mad->rmpp_hdr.rmpp_version != IB_MGMT_RMPP_VERSION) {
767 abort_send(agent, rmpp_mad->mad_hdr.tid, 749 abort_send(agent, mad_recv_wc, IB_MGMT_RMPP_STATUS_UNV);
768 IB_MGMT_RMPP_STATUS_UNV);
769 nack_recv(agent, mad_recv_wc, IB_MGMT_RMPP_STATUS_UNV); 750 nack_recv(agent, mad_recv_wc, IB_MGMT_RMPP_STATUS_UNV);
770 goto out; 751 goto out;
771 } 752 }
@@ -783,8 +764,7 @@ ib_process_rmpp_recv_wc(struct ib_mad_agent_private *agent,
783 process_rmpp_abort(agent, mad_recv_wc); 764 process_rmpp_abort(agent, mad_recv_wc);
784 break; 765 break;
785 default: 766 default:
786 abort_send(agent, rmpp_mad->mad_hdr.tid, 767 abort_send(agent, mad_recv_wc, IB_MGMT_RMPP_STATUS_BADT);
787 IB_MGMT_RMPP_STATUS_BADT);
788 nack_recv(agent, mad_recv_wc, IB_MGMT_RMPP_STATUS_BADT); 768 nack_recv(agent, mad_recv_wc, IB_MGMT_RMPP_STATUS_BADT);
789 break; 769 break;
790 } 770 }
diff --git a/drivers/infiniband/core/user_mad.c b/drivers/infiniband/core/user_mad.c
index fb6cd42601f9..afe70a549c2f 100644
--- a/drivers/infiniband/core/user_mad.c
+++ b/drivers/infiniband/core/user_mad.c
@@ -177,17 +177,6 @@ static int queue_packet(struct ib_umad_file *file,
177 return ret; 177 return ret;
178} 178}
179 179
180static int data_offset(u8 mgmt_class)
181{
182 if (mgmt_class == IB_MGMT_CLASS_SUBN_ADM)
183 return IB_MGMT_SA_HDR;
184 else if ((mgmt_class >= IB_MGMT_CLASS_VENDOR_RANGE2_START) &&
185 (mgmt_class <= IB_MGMT_CLASS_VENDOR_RANGE2_END))
186 return IB_MGMT_VENDOR_HDR;
187 else
188 return IB_MGMT_RMPP_HDR;
189}
190
191static void send_handler(struct ib_mad_agent *agent, 180static void send_handler(struct ib_mad_agent *agent,
192 struct ib_mad_send_wc *send_wc) 181 struct ib_mad_send_wc *send_wc)
193{ 182{
@@ -283,7 +272,7 @@ static ssize_t copy_recv_mad(char __user *buf, struct ib_umad_packet *packet,
283 */ 272 */
284 return -ENOSPC; 273 return -ENOSPC;
285 } 274 }
286 offset = data_offset(recv_buf->mad->mad_hdr.mgmt_class); 275 offset = ib_get_mad_data_offset(recv_buf->mad->mad_hdr.mgmt_class);
287 max_seg_payload = sizeof (struct ib_mad) - offset; 276 max_seg_payload = sizeof (struct ib_mad) - offset;
288 277
289 for (left = packet->length - seg_payload, buf += seg_payload; 278 for (left = packet->length - seg_payload, buf += seg_payload;
@@ -441,21 +430,14 @@ static ssize_t ib_umad_write(struct file *filp, const char __user *buf,
441 } 430 }
442 431
443 rmpp_mad = (struct ib_rmpp_mad *) packet->mad.data; 432 rmpp_mad = (struct ib_rmpp_mad *) packet->mad.data;
444 if (rmpp_mad->mad_hdr.mgmt_class == IB_MGMT_CLASS_SUBN_ADM) { 433 hdr_len = ib_get_mad_data_offset(rmpp_mad->mad_hdr.mgmt_class);
445 hdr_len = IB_MGMT_SA_HDR; 434 if (!ib_is_mad_class_rmpp(rmpp_mad->mad_hdr.mgmt_class)) {
446 copy_offset = IB_MGMT_RMPP_HDR; 435 copy_offset = IB_MGMT_MAD_HDR;
447 rmpp_active = ib_get_rmpp_flags(&rmpp_mad->rmpp_hdr) & 436 rmpp_active = 0;
448 IB_MGMT_RMPP_FLAG_ACTIVE; 437 } else {
449 } else if (rmpp_mad->mad_hdr.mgmt_class >= IB_MGMT_CLASS_VENDOR_RANGE2_START &&
450 rmpp_mad->mad_hdr.mgmt_class <= IB_MGMT_CLASS_VENDOR_RANGE2_END) {
451 hdr_len = IB_MGMT_VENDOR_HDR;
452 copy_offset = IB_MGMT_RMPP_HDR; 438 copy_offset = IB_MGMT_RMPP_HDR;
453 rmpp_active = ib_get_rmpp_flags(&rmpp_mad->rmpp_hdr) & 439 rmpp_active = ib_get_rmpp_flags(&rmpp_mad->rmpp_hdr) &
454 IB_MGMT_RMPP_FLAG_ACTIVE; 440 IB_MGMT_RMPP_FLAG_ACTIVE;
455 } else {
456 hdr_len = IB_MGMT_MAD_HDR;
457 copy_offset = IB_MGMT_MAD_HDR;
458 rmpp_active = 0;
459 } 441 }
460 442
461 data_len = count - sizeof (struct ib_user_mad) - hdr_len; 443 data_len = count - sizeof (struct ib_user_mad) - hdr_len;
diff --git a/drivers/infiniband/hw/mthca/mthca_av.c b/drivers/infiniband/hw/mthca/mthca_av.c
index f023d3936518..bc5bdcbe51b5 100644
--- a/drivers/infiniband/hw/mthca/mthca_av.c
+++ b/drivers/infiniband/hw/mthca/mthca_av.c
@@ -265,7 +265,7 @@ int __devinit mthca_init_av_table(struct mthca_dev *dev)
265 return -ENOMEM; 265 return -ENOMEM;
266} 266}
267 267
268void __devexit mthca_cleanup_av_table(struct mthca_dev *dev) 268void mthca_cleanup_av_table(struct mthca_dev *dev)
269{ 269{
270 if (mthca_is_memfree(dev)) 270 if (mthca_is_memfree(dev))
271 return; 271 return;
diff --git a/drivers/infiniband/hw/mthca/mthca_cq.c b/drivers/infiniband/hw/mthca/mthca_cq.c
index 76aabc5bf371..312cf90731ea 100644
--- a/drivers/infiniband/hw/mthca/mthca_cq.c
+++ b/drivers/infiniband/hw/mthca/mthca_cq.c
@@ -973,7 +973,7 @@ int __devinit mthca_init_cq_table(struct mthca_dev *dev)
973 return err; 973 return err;
974} 974}
975 975
976void __devexit mthca_cleanup_cq_table(struct mthca_dev *dev) 976void mthca_cleanup_cq_table(struct mthca_dev *dev)
977{ 977{
978 mthca_array_cleanup(&dev->cq_table.cq, dev->limits.num_cqs); 978 mthca_array_cleanup(&dev->cq_table.cq, dev->limits.num_cqs);
979 mthca_alloc_cleanup(&dev->cq_table.alloc); 979 mthca_alloc_cleanup(&dev->cq_table.alloc);
diff --git a/drivers/infiniband/hw/mthca/mthca_eq.c b/drivers/infiniband/hw/mthca/mthca_eq.c
index cbdc348fb689..99f109c3815d 100644
--- a/drivers/infiniband/hw/mthca/mthca_eq.c
+++ b/drivers/infiniband/hw/mthca/mthca_eq.c
@@ -765,7 +765,7 @@ static int __devinit mthca_map_eq_regs(struct mthca_dev *dev)
765 765
766} 766}
767 767
768static void __devexit mthca_unmap_eq_regs(struct mthca_dev *dev) 768static void mthca_unmap_eq_regs(struct mthca_dev *dev)
769{ 769{
770 if (mthca_is_memfree(dev)) { 770 if (mthca_is_memfree(dev)) {
771 mthca_unmap_reg(dev, (pci_resource_len(dev->pdev, 0) - 1) & 771 mthca_unmap_reg(dev, (pci_resource_len(dev->pdev, 0) - 1) &
@@ -821,7 +821,7 @@ int __devinit mthca_map_eq_icm(struct mthca_dev *dev, u64 icm_virt)
821 return ret; 821 return ret;
822} 822}
823 823
824void __devexit mthca_unmap_eq_icm(struct mthca_dev *dev) 824void mthca_unmap_eq_icm(struct mthca_dev *dev)
825{ 825{
826 u8 status; 826 u8 status;
827 827
@@ -954,7 +954,7 @@ err_out_free:
954 return err; 954 return err;
955} 955}
956 956
957void __devexit mthca_cleanup_eq_table(struct mthca_dev *dev) 957void mthca_cleanup_eq_table(struct mthca_dev *dev)
958{ 958{
959 u8 status; 959 u8 status;
960 int i; 960 int i;
diff --git a/drivers/infiniband/hw/mthca/mthca_mad.c b/drivers/infiniband/hw/mthca/mthca_mad.c
index 4ace6a392f41..dfb482eac9a2 100644
--- a/drivers/infiniband/hw/mthca/mthca_mad.c
+++ b/drivers/infiniband/hw/mthca/mthca_mad.c
@@ -271,7 +271,7 @@ err:
271 return PTR_ERR(agent); 271 return PTR_ERR(agent);
272} 272}
273 273
274void mthca_free_agents(struct mthca_dev *dev) 274void __devexit mthca_free_agents(struct mthca_dev *dev)
275{ 275{
276 struct ib_mad_agent *agent; 276 struct ib_mad_agent *agent;
277 int p, q; 277 int p, q;
diff --git a/drivers/infiniband/hw/mthca/mthca_mcg.c b/drivers/infiniband/hw/mthca/mthca_mcg.c
index 9965bda9afed..47ca8a9b7247 100644
--- a/drivers/infiniband/hw/mthca/mthca_mcg.c
+++ b/drivers/infiniband/hw/mthca/mthca_mcg.c
@@ -388,7 +388,7 @@ int __devinit mthca_init_mcg_table(struct mthca_dev *dev)
388 return 0; 388 return 0;
389} 389}
390 390
391void __devexit mthca_cleanup_mcg_table(struct mthca_dev *dev) 391void mthca_cleanup_mcg_table(struct mthca_dev *dev)
392{ 392{
393 mthca_alloc_cleanup(&dev->mcg_table.alloc); 393 mthca_alloc_cleanup(&dev->mcg_table.alloc);
394} 394}
diff --git a/drivers/infiniband/hw/mthca/mthca_mr.c b/drivers/infiniband/hw/mthca/mthca_mr.c
index 698b62125765..25e1c1db9a40 100644
--- a/drivers/infiniband/hw/mthca/mthca_mr.c
+++ b/drivers/infiniband/hw/mthca/mthca_mr.c
@@ -170,7 +170,7 @@ err_out:
170 return -ENOMEM; 170 return -ENOMEM;
171} 171}
172 172
173static void __devexit mthca_buddy_cleanup(struct mthca_buddy *buddy) 173static void mthca_buddy_cleanup(struct mthca_buddy *buddy)
174{ 174{
175 int i; 175 int i;
176 176
@@ -866,7 +866,7 @@ err_mtt_buddy:
866 return err; 866 return err;
867} 867}
868 868
869void __devexit mthca_cleanup_mr_table(struct mthca_dev *dev) 869void mthca_cleanup_mr_table(struct mthca_dev *dev)
870{ 870{
871 /* XXX check if any MRs are still allocated? */ 871 /* XXX check if any MRs are still allocated? */
872 if (dev->limits.fmr_reserved_mtts) 872 if (dev->limits.fmr_reserved_mtts)
diff --git a/drivers/infiniband/hw/mthca/mthca_pd.c b/drivers/infiniband/hw/mthca/mthca_pd.c
index 105fc5faaddf..59df51614c85 100644
--- a/drivers/infiniband/hw/mthca/mthca_pd.c
+++ b/drivers/infiniband/hw/mthca/mthca_pd.c
@@ -77,7 +77,7 @@ int __devinit mthca_init_pd_table(struct mthca_dev *dev)
77 dev->limits.reserved_pds); 77 dev->limits.reserved_pds);
78} 78}
79 79
80void __devexit mthca_cleanup_pd_table(struct mthca_dev *dev) 80void mthca_cleanup_pd_table(struct mthca_dev *dev)
81{ 81{
82 /* XXX check if any PDs are still allocated? */ 82 /* XXX check if any PDs are still allocated? */
83 mthca_alloc_cleanup(&dev->pd_table.alloc); 83 mthca_alloc_cleanup(&dev->pd_table.alloc);
diff --git a/drivers/infiniband/hw/mthca/mthca_qp.c b/drivers/infiniband/hw/mthca/mthca_qp.c
index 1bc2678c2fae..057c8e6af87b 100644
--- a/drivers/infiniband/hw/mthca/mthca_qp.c
+++ b/drivers/infiniband/hw/mthca/mthca_qp.c
@@ -2204,7 +2204,7 @@ int __devinit mthca_init_qp_table(struct mthca_dev *dev)
2204 return err; 2204 return err;
2205} 2205}
2206 2206
2207void __devexit mthca_cleanup_qp_table(struct mthca_dev *dev) 2207void mthca_cleanup_qp_table(struct mthca_dev *dev)
2208{ 2208{
2209 int i; 2209 int i;
2210 u8 status; 2210 u8 status;
diff --git a/drivers/infiniband/hw/mthca/mthca_srq.c b/drivers/infiniband/hw/mthca/mthca_srq.c
index 0cfd15802217..2dd3aea05341 100644
--- a/drivers/infiniband/hw/mthca/mthca_srq.c
+++ b/drivers/infiniband/hw/mthca/mthca_srq.c
@@ -206,7 +206,7 @@ int mthca_alloc_srq(struct mthca_dev *dev, struct mthca_pd *pd,
206 roundup_pow_of_two(sizeof (struct mthca_next_seg) + 206 roundup_pow_of_two(sizeof (struct mthca_next_seg) +
207 srq->max_gs * sizeof (struct mthca_data_seg))); 207 srq->max_gs * sizeof (struct mthca_data_seg)));
208 208
209 if (ds > dev->limits.max_desc_sz) 209 if (!mthca_is_memfree(dev) && (ds > dev->limits.max_desc_sz))
210 return -EINVAL; 210 return -EINVAL;
211 211
212 srq->wqe_shift = long_log2(ds); 212 srq->wqe_shift = long_log2(ds);
@@ -684,7 +684,7 @@ int __devinit mthca_init_srq_table(struct mthca_dev *dev)
684 return err; 684 return err;
685} 685}
686 686
687void __devexit mthca_cleanup_srq_table(struct mthca_dev *dev) 687void mthca_cleanup_srq_table(struct mthca_dev *dev)
688{ 688{
689 if (!(dev->mthca_flags & MTHCA_FLAG_SRQ)) 689 if (!(dev->mthca_flags & MTHCA_FLAG_SRQ))
690 return; 690 return;
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c
index 53a32f65788d..9b0bd7c746ca 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_main.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c
@@ -723,7 +723,7 @@ static int ipoib_hard_header(struct sk_buff *skb,
723 * destination address onto the front of the skb so we can 723 * destination address onto the front of the skb so we can
724 * figure out where to send the packet later. 724 * figure out where to send the packet later.
725 */ 725 */
726 if (!skb->dst || !skb->dst->neighbour) { 726 if ((!skb->dst || !skb->dst->neighbour) && daddr) {
727 struct ipoib_pseudoheader *phdr = 727 struct ipoib_pseudoheader *phdr =
728 (struct ipoib_pseudoheader *) skb_push(skb, sizeof *phdr); 728 (struct ipoib_pseudoheader *) skb_push(skb, sizeof *phdr);
729 memcpy(phdr->hwaddr, daddr, INFINIBAND_ALEN); 729 memcpy(phdr->hwaddr, daddr, INFINIBAND_ALEN);
diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c
index 61924cc30e55..fd8a95a9c5d3 100644
--- a/drivers/infiniband/ulp/srp/ib_srp.c
+++ b/drivers/infiniband/ulp/srp/ib_srp.c
@@ -607,10 +607,10 @@ static void srp_unmap_data(struct scsi_cmnd *scmnd,
607 */ 607 */
608 if (likely(scmnd->use_sg)) { 608 if (likely(scmnd->use_sg)) {
609 nents = scmnd->use_sg; 609 nents = scmnd->use_sg;
610 scat = (struct scatterlist *) scmnd->request_buffer; 610 scat = scmnd->request_buffer;
611 } else { 611 } else {
612 nents = 1; 612 nents = 1;
613 scat = (struct scatterlist *) scmnd->request_buffer; 613 scat = &req->fake_sg;
614 } 614 }
615 615
616 dma_unmap_sg(target->srp_host->dev->dma_device, scat, nents, 616 dma_unmap_sg(target->srp_host->dev->dma_device, scat, nents,
diff --git a/drivers/input/keyboard/hil_kbd.c b/drivers/input/keyboard/hil_kbd.c
index 0a90962c38e7..63f387e4b783 100644
--- a/drivers/input/keyboard/hil_kbd.c
+++ b/drivers/input/keyboard/hil_kbd.c
@@ -66,7 +66,7 @@ static unsigned int hil_kbd_set3[HIL_KEYCODES_SET3_TBLSIZE] =
66static char hil_language[][16] = { HIL_LOCALE_MAP }; 66static char hil_language[][16] = { HIL_LOCALE_MAP };
67 67
68struct hil_kbd { 68struct hil_kbd {
69 struct input_dev dev; 69 struct input_dev *dev;
70 struct serio *serio; 70 struct serio *serio;
71 71
72 /* Input buffer and index for packets from HIL bus. */ 72 /* Input buffer and index for packets from HIL bus. */
@@ -86,7 +86,7 @@ struct hil_kbd {
86/* Process a complete packet after transfer from the HIL */ 86/* Process a complete packet after transfer from the HIL */
87static void hil_kbd_process_record(struct hil_kbd *kbd) 87static void hil_kbd_process_record(struct hil_kbd *kbd)
88{ 88{
89 struct input_dev *dev = &kbd->dev; 89 struct input_dev *dev = kbd->dev;
90 hil_packet *data = kbd->data; 90 hil_packet *data = kbd->data;
91 hil_packet p; 91 hil_packet p;
92 int idx, i, cnt; 92 int idx, i, cnt;
@@ -240,8 +240,8 @@ static void hil_kbd_disconnect(struct serio *serio)
240 return; 240 return;
241 } 241 }
242 242
243 input_unregister_device(&kbd->dev);
244 serio_close(serio); 243 serio_close(serio);
244 input_unregister_device(kbd->dev);
245 kfree(kbd); 245 kfree(kbd);
246} 246}
247 247
@@ -251,16 +251,18 @@ static int hil_kbd_connect(struct serio *serio, struct serio_driver *drv)
251 uint8_t did, *idd; 251 uint8_t did, *idd;
252 int i; 252 int i;
253 253
254 kbd = kmalloc(sizeof(*kbd), GFP_KERNEL); 254 kbd = kzalloc(sizeof(*kbd), GFP_KERNEL);
255 if (!kbd) 255 if (!kbd)
256 return -ENOMEM; 256 return -ENOMEM;
257 memset(kbd, 0, sizeof(struct hil_kbd)); 257
258 kbd->dev = input_allocate_device();
259 if (!kbd->dev) goto bail1;
260 kbd->dev->private = kbd;
258 261
259 if (serio_open(serio, drv)) goto bail0; 262 if (serio_open(serio, drv)) goto bail0;
260 263
261 serio_set_drvdata(serio, kbd); 264 serio_set_drvdata(serio, kbd);
262 kbd->serio = serio; 265 kbd->serio = serio;
263 kbd->dev.private = kbd;
264 266
265 init_MUTEX_LOCKED(&(kbd->sem)); 267 init_MUTEX_LOCKED(&(kbd->sem));
266 268
@@ -302,38 +304,38 @@ static int hil_kbd_connect(struct serio *serio, struct serio_driver *drv)
302 did, hil_language[did & HIL_IDD_DID_TYPE_KB_LANG_MASK]); 304 did, hil_language[did & HIL_IDD_DID_TYPE_KB_LANG_MASK]);
303 break; 305 break;
304 default: 306 default:
305 goto bail1; 307 goto bail2;
306 } 308 }
307 309
308 if(HIL_IDD_NUM_BUTTONS(idd) || HIL_IDD_NUM_AXES_PER_SET(*idd)) { 310 if(HIL_IDD_NUM_BUTTONS(idd) || HIL_IDD_NUM_AXES_PER_SET(*idd)) {
309 printk(KERN_INFO PREFIX "keyboards only, no combo devices supported.\n"); 311 printk(KERN_INFO PREFIX "keyboards only, no combo devices supported.\n");
310 goto bail1; 312 goto bail2;
311 } 313 }
312 314
313 315
314 kbd->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_REP); 316 kbd->dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
315 kbd->dev.ledbit[0] = BIT(LED_NUML) | BIT(LED_CAPSL) | BIT(LED_SCROLLL); 317 kbd->dev->ledbit[0] = BIT(LED_NUML) | BIT(LED_CAPSL) | BIT(LED_SCROLLL);
316 kbd->dev.keycodemax = HIL_KEYCODES_SET1_TBLSIZE; 318 kbd->dev->keycodemax = HIL_KEYCODES_SET1_TBLSIZE;
317 kbd->dev.keycodesize = sizeof(hil_kbd_set1[0]); 319 kbd->dev->keycodesize = sizeof(hil_kbd_set1[0]);
318 kbd->dev.keycode = hil_kbd_set1; 320 kbd->dev->keycode = hil_kbd_set1;
319 kbd->dev.name = strlen(kbd->rnm) ? kbd->rnm : HIL_GENERIC_NAME; 321 kbd->dev->name = strlen(kbd->rnm) ? kbd->rnm : HIL_GENERIC_NAME;
320 kbd->dev.phys = "hpkbd/input0"; /* XXX */ 322 kbd->dev->phys = "hpkbd/input0"; /* XXX */
321 323
322 kbd->dev.id.bustype = BUS_HIL; 324 kbd->dev->id.bustype = BUS_HIL;
323 kbd->dev.id.vendor = PCI_VENDOR_ID_HP; 325 kbd->dev->id.vendor = PCI_VENDOR_ID_HP;
324 kbd->dev.id.product = 0x0001; /* TODO: get from kbd->rsc */ 326 kbd->dev->id.product = 0x0001; /* TODO: get from kbd->rsc */
325 kbd->dev.id.version = 0x0100; /* TODO: get from kbd->rsc */ 327 kbd->dev->id.version = 0x0100; /* TODO: get from kbd->rsc */
326 kbd->dev.dev = &serio->dev; 328 kbd->dev->dev = &serio->dev;
327 329
328 for (i = 0; i < 128; i++) { 330 for (i = 0; i < 128; i++) {
329 set_bit(hil_kbd_set1[i], kbd->dev.keybit); 331 set_bit(hil_kbd_set1[i], kbd->dev->keybit);
330 set_bit(hil_kbd_set3[i], kbd->dev.keybit); 332 set_bit(hil_kbd_set3[i], kbd->dev->keybit);
331 } 333 }
332 clear_bit(0, kbd->dev.keybit); 334 clear_bit(0, kbd->dev->keybit);
333 335
334 input_register_device(&kbd->dev); 336 input_register_device(kbd->dev);
335 printk(KERN_INFO "input: %s, ID: %d\n", 337 printk(KERN_INFO "input: %s, ID: %d\n",
336 kbd->dev.name, did); 338 kbd->dev->name, did);
337 339
338 serio->write(serio, 0); 340 serio->write(serio, 0);
339 serio->write(serio, 0); 341 serio->write(serio, 0);
@@ -343,8 +345,10 @@ static int hil_kbd_connect(struct serio *serio, struct serio_driver *drv)
343 up(&(kbd->sem)); 345 up(&(kbd->sem));
344 346
345 return 0; 347 return 0;
346 bail1: 348 bail2:
347 serio_close(serio); 349 serio_close(serio);
350 bail1:
351 input_free_device(kbd->dev);
348 bail0: 352 bail0:
349 kfree(kbd); 353 kfree(kbd);
350 serio_set_drvdata(serio, NULL); 354 serio_set_drvdata(serio, NULL);
diff --git a/drivers/input/keyboard/hilkbd.c b/drivers/input/keyboard/hilkbd.c
index e95bc052e32a..33edd030aa75 100644
--- a/drivers/input/keyboard/hilkbd.c
+++ b/drivers/input/keyboard/hilkbd.c
@@ -3,7 +3,7 @@
3 * 3 *
4 * Copyright (C) 1998 Philip Blundell <philb@gnu.org> 4 * Copyright (C) 1998 Philip Blundell <philb@gnu.org>
5 * Copyright (C) 1999 Matthew Wilcox <willy@bofh.ai> 5 * Copyright (C) 1999 Matthew Wilcox <willy@bofh.ai>
6 * Copyright (C) 1999-2003 Helge Deller <deller@gmx.de> 6 * Copyright (C) 1999-2006 Helge Deller <deller@gmx.de>
7 * 7 *
8 * Very basic HP Human Interface Loop (HIL) driver. 8 * Very basic HP Human Interface Loop (HIL) driver.
9 * This driver handles the keyboard on HP300 (m68k) and on some 9 * This driver handles the keyboard on HP300 (m68k) and on some
@@ -90,7 +90,7 @@ static unsigned int hphilkeyb_keycode[HIL_KEYCODES_SET1_TBLSIZE] =
90 90
91/* HIL structure */ 91/* HIL structure */
92static struct { 92static struct {
93 struct input_dev dev; 93 struct input_dev *dev;
94 94
95 unsigned int curdev; 95 unsigned int curdev;
96 96
@@ -117,7 +117,7 @@ static void poll_finished(void)
117 down = (hil_dev.data[1] & 1) == 0; 117 down = (hil_dev.data[1] & 1) == 0;
118 scode = hil_dev.data[1] >> 1; 118 scode = hil_dev.data[1] >> 1;
119 key = hphilkeyb_keycode[scode]; 119 key = hphilkeyb_keycode[scode];
120 input_report_key(&hil_dev.dev, key, down); 120 input_report_key(hil_dev.dev, key, down);
121 break; 121 break;
122 } 122 }
123 hil_dev.curdev = 0; 123 hil_dev.curdev = 0;
@@ -207,9 +207,14 @@ hil_keyb_init(void)
207 unsigned int i, kbid; 207 unsigned int i, kbid;
208 wait_queue_head_t hil_wait; 208 wait_queue_head_t hil_wait;
209 209
210 if (hil_dev.dev.id.bustype) { 210 if (hil_dev.dev) {
211 return -ENODEV; /* already initialized */ 211 return -ENODEV; /* already initialized */
212 } 212 }
213
214 hil_dev.dev = input_allocate_device();
215 if (!hil_dev.dev)
216 return -ENOMEM;
217 hil_dev.dev->private = &hil_dev;
213 218
214#if defined(CONFIG_HP300) 219#if defined(CONFIG_HP300)
215 if (!hwreg_present((void *)(HILBASE + HIL_DATA))) 220 if (!hwreg_present((void *)(HILBASE + HIL_DATA)))
@@ -247,28 +252,26 @@ hil_keyb_init(void)
247 c = 0; 252 c = 0;
248 hil_do(HIL_WRITEKBDSADR, &c, 1); 253 hil_do(HIL_WRITEKBDSADR, &c, 1);
249 254
250 init_input_dev(&hil_dev.dev);
251
252 for (i = 0; i < HIL_KEYCODES_SET1_TBLSIZE; i++) 255 for (i = 0; i < HIL_KEYCODES_SET1_TBLSIZE; i++)
253 if (hphilkeyb_keycode[i] != KEY_RESERVED) 256 if (hphilkeyb_keycode[i] != KEY_RESERVED)
254 set_bit(hphilkeyb_keycode[i], hil_dev.dev.keybit); 257 set_bit(hphilkeyb_keycode[i], hil_dev.dev->keybit);
255 258
256 hil_dev.dev.evbit[0] = BIT(EV_KEY) | BIT(EV_REP); 259 hil_dev.dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
257 hil_dev.dev.ledbit[0] = BIT(LED_NUML) | BIT(LED_CAPSL) | BIT(LED_SCROLLL); 260 hil_dev.dev->ledbit[0] = BIT(LED_NUML) | BIT(LED_CAPSL) | BIT(LED_SCROLLL);
258 hil_dev.dev.keycodemax = HIL_KEYCODES_SET1_TBLSIZE; 261 hil_dev.dev->keycodemax = HIL_KEYCODES_SET1_TBLSIZE;
259 hil_dev.dev.keycodesize = sizeof(hphilkeyb_keycode[0]); 262 hil_dev.dev->keycodesize = sizeof(hphilkeyb_keycode[0]);
260 hil_dev.dev.keycode = hphilkeyb_keycode; 263 hil_dev.dev->keycode = hphilkeyb_keycode;
261 hil_dev.dev.name = "HIL keyboard"; 264 hil_dev.dev->name = "HIL keyboard";
262 hil_dev.dev.phys = "hpkbd/input0"; 265 hil_dev.dev->phys = "hpkbd/input0";
263 266
264 hil_dev.dev.id.bustype = BUS_HIL; 267 hil_dev.dev->id.bustype = BUS_HIL;
265 hil_dev.dev.id.vendor = PCI_VENDOR_ID_HP; 268 hil_dev.dev->id.vendor = PCI_VENDOR_ID_HP;
266 hil_dev.dev.id.product = 0x0001; 269 hil_dev.dev->id.product = 0x0001;
267 hil_dev.dev.id.version = 0x0010; 270 hil_dev.dev->id.version = 0x0010;
268 271
269 input_register_device(&hil_dev.dev); 272 input_register_device(hil_dev.dev);
270 printk(KERN_INFO "input: %s, ID %d at 0x%08lx (irq %d) found and attached\n", 273 printk(KERN_INFO "input: %s, ID %d at 0x%08lx (irq %d) found and attached\n",
271 hil_dev.dev.name, kbid, HILBASE, HIL_IRQ); 274 hil_dev.dev->name, kbid, HILBASE, HIL_IRQ);
272 275
273 return 0; 276 return 0;
274} 277}
@@ -329,7 +332,9 @@ static void __exit hil_exit(void)
329 /* Turn off interrupts */ 332 /* Turn off interrupts */
330 hil_do(HIL_INTOFF, NULL, 0); 333 hil_do(HIL_INTOFF, NULL, 0);
331 334
332 input_unregister_device(&hil_dev.dev); 335 input_unregister_device(hil_dev.dev);
336
337 hil_dev.dev = NULL;
333 338
334#if defined(CONFIG_PARISC) 339#if defined(CONFIG_PARISC)
335 unregister_parisc_driver(&hil_driver); 340 unregister_parisc_driver(&hil_driver);
diff --git a/drivers/input/mouse/hil_ptr.c b/drivers/input/mouse/hil_ptr.c
index c2bf2ed07dc6..bfb564fd8fe2 100644
--- a/drivers/input/mouse/hil_ptr.c
+++ b/drivers/input/mouse/hil_ptr.c
@@ -55,7 +55,7 @@ MODULE_LICENSE("Dual BSD/GPL");
55#define HIL_PTR_MAX_LENGTH 16 55#define HIL_PTR_MAX_LENGTH 16
56 56
57struct hil_ptr { 57struct hil_ptr {
58 struct input_dev dev; 58 struct input_dev *dev;
59 struct serio *serio; 59 struct serio *serio;
60 60
61 /* Input buffer and index for packets from HIL bus. */ 61 /* Input buffer and index for packets from HIL bus. */
@@ -79,7 +79,7 @@ struct hil_ptr {
79/* Process a complete packet after transfer from the HIL */ 79/* Process a complete packet after transfer from the HIL */
80static void hil_ptr_process_record(struct hil_ptr *ptr) 80static void hil_ptr_process_record(struct hil_ptr *ptr)
81{ 81{
82 struct input_dev *dev = &ptr->dev; 82 struct input_dev *dev = ptr->dev;
83 hil_packet *data = ptr->data; 83 hil_packet *data = ptr->data;
84 hil_packet p; 84 hil_packet p;
85 int idx, i, cnt, laxis; 85 int idx, i, cnt, laxis;
@@ -148,12 +148,12 @@ static void hil_ptr_process_record(struct hil_ptr *ptr)
148 if (absdev) { 148 if (absdev) {
149 val = lo + (hi<<8); 149 val = lo + (hi<<8);
150#ifdef TABLET_AUTOADJUST 150#ifdef TABLET_AUTOADJUST
151 if (val < ptr->dev.absmin[ABS_X + i]) 151 if (val < dev->absmin[ABS_X + i])
152 ptr->dev.absmin[ABS_X + i] = val; 152 dev->absmin[ABS_X + i] = val;
153 if (val > ptr->dev.absmax[ABS_X + i]) 153 if (val > dev->absmax[ABS_X + i])
154 ptr->dev.absmax[ABS_X + i] = val; 154 dev->absmax[ABS_X + i] = val;
155#endif 155#endif
156 if (i%3) val = ptr->dev.absmax[ABS_X + i] - val; 156 if (i%3) val = dev->absmax[ABS_X + i] - val;
157 input_report_abs(dev, ABS_X + i, val); 157 input_report_abs(dev, ABS_X + i, val);
158 } else { 158 } else {
159 val = (int) (((int8_t)lo) | ((int8_t)hi<<8)); 159 val = (int) (((int8_t)lo) | ((int8_t)hi<<8));
@@ -233,26 +233,29 @@ static void hil_ptr_disconnect(struct serio *serio)
233 return; 233 return;
234 } 234 }
235 235
236 input_unregister_device(&ptr->dev);
237 serio_close(serio); 236 serio_close(serio);
237 input_unregister_device(ptr->dev);
238 kfree(ptr); 238 kfree(ptr);
239} 239}
240 240
241static int hil_ptr_connect(struct serio *serio, struct serio_driver *driver) 241static int hil_ptr_connect(struct serio *serio, struct serio_driver *driver)
242{ 242{
243 struct hil_ptr *ptr; 243 struct hil_ptr *ptr;
244 char *txt; 244 char *txt;
245 unsigned int i, naxsets, btntype; 245 unsigned int i, naxsets, btntype;
246 uint8_t did, *idd; 246 uint8_t did, *idd;
247 247
248 if (!(ptr = kmalloc(sizeof(struct hil_ptr), GFP_KERNEL))) return -ENOMEM; 248 if (!(ptr = kzalloc(sizeof(struct hil_ptr), GFP_KERNEL)))
249 memset(ptr, 0, sizeof(struct hil_ptr)); 249 return -ENOMEM;
250 250
251 if (serio_open(serio, driver)) goto bail0; 251 ptr->dev = input_allocate_device();
252 if (!ptr->dev) goto bail0;
253 ptr->dev->private = ptr;
254
255 if (serio_open(serio, driver)) goto bail1;
252 256
253 serio_set_drvdata(serio, ptr); 257 serio_set_drvdata(serio, ptr);
254 ptr->serio = serio; 258 ptr->serio = serio;
255 ptr->dev.private = ptr;
256 259
257 init_MUTEX_LOCKED(&(ptr->sem)); 260 init_MUTEX_LOCKED(&(ptr->sem));
258 261
@@ -283,25 +286,24 @@ static int hil_ptr_connect(struct serio *serio, struct serio_driver *driver)
283 286
284 up(&(ptr->sem)); 287 up(&(ptr->sem));
285 288
286 init_input_dev(&ptr->dev);
287 did = ptr->idd[0]; 289 did = ptr->idd[0];
288 idd = ptr->idd + 1; 290 idd = ptr->idd + 1;
289 txt = "unknown"; 291 txt = "unknown";
290 if ((did & HIL_IDD_DID_TYPE_MASK) == HIL_IDD_DID_TYPE_REL) { 292 if ((did & HIL_IDD_DID_TYPE_MASK) == HIL_IDD_DID_TYPE_REL) {
291 ptr->dev.evbit[0] = BIT(EV_REL); 293 ptr->dev->evbit[0] = BIT(EV_REL);
292 txt = "relative"; 294 txt = "relative";
293 } 295 }
294 296
295 if ((did & HIL_IDD_DID_TYPE_MASK) == HIL_IDD_DID_TYPE_ABS) { 297 if ((did & HIL_IDD_DID_TYPE_MASK) == HIL_IDD_DID_TYPE_ABS) {
296 ptr->dev.evbit[0] = BIT(EV_ABS); 298 ptr->dev->evbit[0] = BIT(EV_ABS);
297 txt = "absolute"; 299 txt = "absolute";
298 } 300 }
299 if (!ptr->dev.evbit[0]) { 301 if (!ptr->dev->evbit[0]) {
300 goto bail1; 302 goto bail2;
301 } 303 }
302 304
303 ptr->nbtn = HIL_IDD_NUM_BUTTONS(idd); 305 ptr->nbtn = HIL_IDD_NUM_BUTTONS(idd);
304 if (ptr->nbtn) ptr->dev.evbit[0] |= BIT(EV_KEY); 306 if (ptr->nbtn) ptr->dev->evbit[0] |= BIT(EV_KEY);
305 307
306 naxsets = HIL_IDD_NUM_AXSETS(*idd); 308 naxsets = HIL_IDD_NUM_AXSETS(*idd);
307 ptr->naxes = HIL_IDD_NUM_AXES_PER_SET(*idd); 309 ptr->naxes = HIL_IDD_NUM_AXES_PER_SET(*idd);
@@ -325,7 +327,7 @@ static int hil_ptr_connect(struct serio *serio, struct serio_driver *driver)
325 btntype = BTN_MOUSE; 327 btntype = BTN_MOUSE;
326 328
327 for (i = 0; i < ptr->nbtn; i++) { 329 for (i = 0; i < ptr->nbtn; i++) {
328 set_bit(btntype | i, ptr->dev.keybit); 330 set_bit(btntype | i, ptr->dev->keybit);
329 ptr->btnmap[i] = btntype | i; 331 ptr->btnmap[i] = btntype | i;
330 } 332 }
331 333
@@ -337,50 +339,52 @@ static int hil_ptr_connect(struct serio *serio, struct serio_driver *driver)
337 339
338 if ((did & HIL_IDD_DID_TYPE_MASK) == HIL_IDD_DID_TYPE_REL) { 340 if ((did & HIL_IDD_DID_TYPE_MASK) == HIL_IDD_DID_TYPE_REL) {
339 for (i = 0; i < ptr->naxes; i++) { 341 for (i = 0; i < ptr->naxes; i++) {
340 set_bit(REL_X + i, ptr->dev.relbit); 342 set_bit(REL_X + i, ptr->dev->relbit);
341 } 343 }
342 for (i = 3; (i < ptr->naxes + 3) && (naxsets > 1); i++) { 344 for (i = 3; (i < ptr->naxes + 3) && (naxsets > 1); i++) {
343 set_bit(REL_X + i, ptr->dev.relbit); 345 set_bit(REL_X + i, ptr->dev->relbit);
344 } 346 }
345 } else { 347 } else {
346 for (i = 0; i < ptr->naxes; i++) { 348 for (i = 0; i < ptr->naxes; i++) {
347 set_bit(ABS_X + i, ptr->dev.absbit); 349 set_bit(ABS_X + i, ptr->dev->absbit);
348 ptr->dev.absmin[ABS_X + i] = 0; 350 ptr->dev->absmin[ABS_X + i] = 0;
349 ptr->dev.absmax[ABS_X + i] = 351 ptr->dev->absmax[ABS_X + i] =
350 HIL_IDD_AXIS_MAX((ptr->idd + 1), i); 352 HIL_IDD_AXIS_MAX((ptr->idd + 1), i);
351 } 353 }
352 for (i = 3; (i < ptr->naxes + 3) && (naxsets > 1); i++) { 354 for (i = 3; (i < ptr->naxes + 3) && (naxsets > 1); i++) {
353 set_bit(ABS_X + i, ptr->dev.absbit); 355 set_bit(ABS_X + i, ptr->dev->absbit);
354 ptr->dev.absmin[ABS_X + i] = 0; 356 ptr->dev->absmin[ABS_X + i] = 0;
355 ptr->dev.absmax[ABS_X + i] = 357 ptr->dev->absmax[ABS_X + i] =
356 HIL_IDD_AXIS_MAX((ptr->idd + 1), (i - 3)); 358 HIL_IDD_AXIS_MAX((ptr->idd + 1), (i - 3));
357 } 359 }
358#ifdef TABLET_AUTOADJUST 360#ifdef TABLET_AUTOADJUST
359 for (i = 0; i < ABS_MAX; i++) { 361 for (i = 0; i < ABS_MAX; i++) {
360 int diff = ptr->dev.absmax[ABS_X + i] / 10; 362 int diff = ptr->dev->absmax[ABS_X + i] / 10;
361 ptr->dev.absmin[ABS_X + i] += diff; 363 ptr->dev->absmin[ABS_X + i] += diff;
362 ptr->dev.absmax[ABS_X + i] -= diff; 364 ptr->dev->absmax[ABS_X + i] -= diff;
363 } 365 }
364#endif 366#endif
365 } 367 }
366 368
367 ptr->dev.name = strlen(ptr->rnm) ? ptr->rnm : HIL_GENERIC_NAME; 369 ptr->dev->name = strlen(ptr->rnm) ? ptr->rnm : HIL_GENERIC_NAME;
368 370
369 ptr->dev.id.bustype = BUS_HIL; 371 ptr->dev->id.bustype = BUS_HIL;
370 ptr->dev.id.vendor = PCI_VENDOR_ID_HP; 372 ptr->dev->id.vendor = PCI_VENDOR_ID_HP;
371 ptr->dev.id.product = 0x0001; /* TODO: get from ptr->rsc */ 373 ptr->dev->id.product = 0x0001; /* TODO: get from ptr->rsc */
372 ptr->dev.id.version = 0x0100; /* TODO: get from ptr->rsc */ 374 ptr->dev->id.version = 0x0100; /* TODO: get from ptr->rsc */
373 ptr->dev.dev = &serio->dev; 375 ptr->dev->dev = &serio->dev;
374 376
375 input_register_device(&ptr->dev); 377 input_register_device(ptr->dev);
376 printk(KERN_INFO "input: %s (%s), ID: %d\n", 378 printk(KERN_INFO "input: %s (%s), ID: %d\n",
377 ptr->dev.name, 379 ptr->dev->name,
378 (btntype == BTN_MOUSE) ? "HIL mouse":"HIL tablet or touchpad", 380 (btntype == BTN_MOUSE) ? "HIL mouse":"HIL tablet or touchpad",
379 did); 381 did);
380 382
381 return 0; 383 return 0;
382 bail1: 384 bail2:
383 serio_close(serio); 385 serio_close(serio);
386 bail1:
387 input_free_device(ptr->dev);
384 bail0: 388 bail0:
385 kfree(ptr); 389 kfree(ptr);
386 serio_set_drvdata(serio, NULL); 390 serio_set_drvdata(serio, NULL);
diff --git a/drivers/input/serio/gscps2.c b/drivers/input/serio/gscps2.c
index a7b0de0f92b2..c0b1e4becad3 100644
--- a/drivers/input/serio/gscps2.c
+++ b/drivers/input/serio/gscps2.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * drivers/input/serio/gscps2.c 2 * drivers/input/serio/gscps2.c
3 * 3 *
4 * Copyright (c) 2004 Helge Deller <deller@gmx.de> 4 * Copyright (c) 2004-2006 Helge Deller <deller@gmx.de>
5 * Copyright (c) 2002 Laurent Canet <canetl@esiee.fr> 5 * Copyright (c) 2002 Laurent Canet <canetl@esiee.fr>
6 * Copyright (c) 2002 Thibaut Varene <varenet@parisc-linux.org> 6 * Copyright (c) 2002 Thibaut Varene <varenet@parisc-linux.org>
7 * 7 *
@@ -354,7 +354,7 @@ static int __init gscps2_probe(struct parisc_device *dev)
354 memset(serio, 0, sizeof(struct serio)); 354 memset(serio, 0, sizeof(struct serio));
355 ps2port->port = serio; 355 ps2port->port = serio;
356 ps2port->padev = dev; 356 ps2port->padev = dev;
357 ps2port->addr = ioremap(hpa, GSC_STATUS + 4); 357 ps2port->addr = ioremap_nocache(hpa, GSC_STATUS + 4);
358 spin_lock_init(&ps2port->lock); 358 spin_lock_init(&ps2port->lock);
359 359
360 gscps2_reset(ps2port); 360 gscps2_reset(ps2port);
diff --git a/drivers/isdn/sc/ioctl.c b/drivers/isdn/sc/ioctl.c
index 94c9afb7017c..f4f71226a078 100644
--- a/drivers/isdn/sc/ioctl.c
+++ b/drivers/isdn/sc/ioctl.c
@@ -46,7 +46,8 @@ int sc_ioctl(int card, scs_ioctl *data)
46 pr_debug("%s: SCIOCRESET: ioctl received\n", 46 pr_debug("%s: SCIOCRESET: ioctl received\n",
47 sc_adapter[card]->devicename); 47 sc_adapter[card]->devicename);
48 sc_adapter[card]->StartOnReset = 0; 48 sc_adapter[card]->StartOnReset = 0;
49 return (reset(card)); 49 kfree(rcvmsg);
50 return reset(card);
50 } 51 }
51 52
52 case SCIOCLOAD: 53 case SCIOCLOAD:
@@ -183,7 +184,7 @@ int sc_ioctl(int card, scs_ioctl *data)
183 sc_adapter[card]->devicename); 184 sc_adapter[card]->devicename);
184 185
185 spid = kmalloc(SCIOC_SPIDSIZE, GFP_KERNEL); 186 spid = kmalloc(SCIOC_SPIDSIZE, GFP_KERNEL);
186 if(!spid) { 187 if (!spid) {
187 kfree(rcvmsg); 188 kfree(rcvmsg);
188 return -ENOMEM; 189 return -ENOMEM;
189 } 190 }
@@ -195,10 +196,10 @@ int sc_ioctl(int card, scs_ioctl *data)
195 if (!status) { 196 if (!status) {
196 pr_debug("%s: SCIOCGETSPID: command successful\n", 197 pr_debug("%s: SCIOCGETSPID: command successful\n",
197 sc_adapter[card]->devicename); 198 sc_adapter[card]->devicename);
198 } 199 } else {
199 else {
200 pr_debug("%s: SCIOCGETSPID: command failed (status = %d)\n", 200 pr_debug("%s: SCIOCGETSPID: command failed (status = %d)\n",
201 sc_adapter[card]->devicename, status); 201 sc_adapter[card]->devicename, status);
202 kfree(spid);
202 kfree(rcvmsg); 203 kfree(rcvmsg);
203 return status; 204 return status;
204 } 205 }
diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
new file mode 100644
index 000000000000..2c4f20b7f021
--- /dev/null
+++ b/drivers/leds/Kconfig
@@ -0,0 +1,77 @@
1
2menu "LED devices"
3
4config NEW_LEDS
5 bool "LED Support"
6 help
7 Say Y to enable Linux LED support. This is not related to standard
8 keyboard LEDs which are controlled via the input system.
9
10config LEDS_CLASS
11 tristate "LED Class Support"
12 depends NEW_LEDS
13 help
14 This option enables the led sysfs class in /sys/class/leds. You'll
15 need this to do anything useful with LEDs. If unsure, say N.
16
17config LEDS_TRIGGERS
18 bool "LED Trigger support"
19 depends NEW_LEDS
20 help
21 This option enables trigger support for the leds class.
22 These triggers allow kernel events to drive the LEDs and can
23 be configured via sysfs. If unsure, say Y.
24
25config LEDS_CORGI
26 tristate "LED Support for the Sharp SL-C7x0 series"
27 depends LEDS_CLASS && PXA_SHARP_C7xx
28 help
29 This option enables support for the LEDs on Sharp Zaurus
30 SL-C7x0 series (C700, C750, C760, C860).
31
32config LEDS_LOCOMO
33 tristate "LED Support for Locomo device"
34 depends LEDS_CLASS && SHARP_LOCOMO
35 help
36 This option enables support for the LEDs on Sharp Locomo.
37 Zaurus models SL-5500 and SL-5600.
38
39config LEDS_SPITZ
40 tristate "LED Support for the Sharp SL-Cxx00 series"
41 depends LEDS_CLASS && PXA_SHARP_Cxx00
42 help
43 This option enables support for the LEDs on Sharp Zaurus
44 SL-Cxx00 series (C1000, C3000, C3100).
45
46config LEDS_IXP4XX
47 tristate "LED Support for GPIO connected LEDs on IXP4XX processors"
48 depends LEDS_CLASS && ARCH_IXP4XX
49 help
50 This option enables support for the LEDs connected to GPIO
51 outputs of the Intel IXP4XX processors. To be useful the
52 particular board must have LEDs and they must be connected
53 to the GPIO lines. If unsure, say Y.
54
55config LEDS_TOSA
56 tristate "LED Support for the Sharp SL-6000 series"
57 depends LEDS_CLASS && PXA_SHARPSL
58 help
59 This option enables support for the LEDs on Sharp Zaurus
60 SL-6000 series.
61
62config LEDS_TRIGGER_TIMER
63 tristate "LED Timer Trigger"
64 depends LEDS_TRIGGERS
65 help
66 This allows LEDs to be controlled by a programmable timer
67 via sysfs. If unsure, say Y.
68
69config LEDS_TRIGGER_IDE_DISK
70 bool "LED Timer Trigger"
71 depends LEDS_TRIGGERS && BLK_DEV_IDEDISK
72 help
73 This allows LEDs to be controlled by IDE disk activity.
74 If unsure, say Y.
75
76endmenu
77
diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile
new file mode 100644
index 000000000000..40699d3cabbf
--- /dev/null
+++ b/drivers/leds/Makefile
@@ -0,0 +1,16 @@
1
2# LED Core
3obj-$(CONFIG_NEW_LEDS) += led-core.o
4obj-$(CONFIG_LEDS_CLASS) += led-class.o
5obj-$(CONFIG_LEDS_TRIGGERS) += led-triggers.o
6
7# LED Platform Drivers
8obj-$(CONFIG_LEDS_CORGI) += leds-corgi.o
9obj-$(CONFIG_LEDS_LOCOMO) += leds-locomo.o
10obj-$(CONFIG_LEDS_SPITZ) += leds-spitz.o
11obj-$(CONFIG_LEDS_IXP4XX) += leds-ixp4xx-gpio.o
12obj-$(CONFIG_LEDS_TOSA) += leds-tosa.o
13
14# LED Triggers
15obj-$(CONFIG_LEDS_TRIGGER_TIMER) += ledtrig-timer.o
16obj-$(CONFIG_LEDS_TRIGGER_IDE_DISK) += ledtrig-ide-disk.o
diff --git a/drivers/leds/led-class.c b/drivers/leds/led-class.c
new file mode 100644
index 000000000000..b0b5d05fadd6
--- /dev/null
+++ b/drivers/leds/led-class.c
@@ -0,0 +1,167 @@
1/*
2 * LED Class Core
3 *
4 * Copyright (C) 2005 John Lenz <lenz@cs.wisc.edu>
5 * Copyright (C) 2005-2006 Richard Purdie <rpurdie@openedhand.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#include <linux/config.h>
13#include <linux/module.h>
14#include <linux/kernel.h>
15#include <linux/init.h>
16#include <linux/list.h>
17#include <linux/spinlock.h>
18#include <linux/device.h>
19#include <linux/sysdev.h>
20#include <linux/timer.h>
21#include <linux/err.h>
22#include <linux/leds.h>
23#include "leds.h"
24
25static struct class *leds_class;
26
27static ssize_t led_brightness_show(struct class_device *dev, char *buf)
28{
29 struct led_classdev *led_cdev = class_get_devdata(dev);
30 ssize_t ret = 0;
31
32 /* no lock needed for this */
33 sprintf(buf, "%u\n", led_cdev->brightness);
34 ret = strlen(buf) + 1;
35
36 return ret;
37}
38
39static ssize_t led_brightness_store(struct class_device *dev,
40 const char *buf, size_t size)
41{
42 struct led_classdev *led_cdev = class_get_devdata(dev);
43 ssize_t ret = -EINVAL;
44 char *after;
45 unsigned long state = simple_strtoul(buf, &after, 10);
46
47 if (after - buf > 0) {
48 ret = after - buf;
49 led_set_brightness(led_cdev, state);
50 }
51
52 return ret;
53}
54
55static CLASS_DEVICE_ATTR(brightness, 0644, led_brightness_show,
56 led_brightness_store);
57#ifdef CONFIG_LEDS_TRIGGERS
58static CLASS_DEVICE_ATTR(trigger, 0644, led_trigger_show, led_trigger_store);
59#endif
60
61/**
62 * led_classdev_suspend - suspend an led_classdev.
63 * @led_cdev: the led_classdev to suspend.
64 */
65void led_classdev_suspend(struct led_classdev *led_cdev)
66{
67 led_cdev->flags |= LED_SUSPENDED;
68 led_cdev->brightness_set(led_cdev, 0);
69}
70EXPORT_SYMBOL_GPL(led_classdev_suspend);
71
72/**
73 * led_classdev_resume - resume an led_classdev.
74 * @led_cdev: the led_classdev to resume.
75 */
76void led_classdev_resume(struct led_classdev *led_cdev)
77{
78 led_cdev->brightness_set(led_cdev, led_cdev->brightness);
79 led_cdev->flags &= ~LED_SUSPENDED;
80}
81EXPORT_SYMBOL_GPL(led_classdev_resume);
82
83/**
84 * led_classdev_register - register a new object of led_classdev class.
85 * @dev: The device to register.
86 * @led_cdev: the led_classdev structure for this device.
87 */
88int led_classdev_register(struct device *parent, struct led_classdev *led_cdev)
89{
90 led_cdev->class_dev = class_device_create(leds_class, NULL, 0,
91 parent, "%s", led_cdev->name);
92 if (unlikely(IS_ERR(led_cdev->class_dev)))
93 return PTR_ERR(led_cdev->class_dev);
94
95 class_set_devdata(led_cdev->class_dev, led_cdev);
96
97 /* register the attributes */
98 class_device_create_file(led_cdev->class_dev,
99 &class_device_attr_brightness);
100
101 /* add to the list of leds */
102 write_lock(&leds_list_lock);
103 list_add_tail(&led_cdev->node, &leds_list);
104 write_unlock(&leds_list_lock);
105
106#ifdef CONFIG_LEDS_TRIGGERS
107 rwlock_init(&led_cdev->trigger_lock);
108
109 led_trigger_set_default(led_cdev);
110
111 class_device_create_file(led_cdev->class_dev,
112 &class_device_attr_trigger);
113#endif
114
115 printk(KERN_INFO "Registered led device: %s\n",
116 led_cdev->class_dev->class_id);
117
118 return 0;
119}
120EXPORT_SYMBOL_GPL(led_classdev_register);
121
122/**
123 * led_classdev_unregister - unregisters a object of led_properties class.
124 * @led_cdev: the led device to unreigister
125 *
126 * Unregisters a previously registered via led_classdev_register object.
127 */
128void led_classdev_unregister(struct led_classdev *led_cdev)
129{
130 class_device_remove_file(led_cdev->class_dev,
131 &class_device_attr_brightness);
132#ifdef CONFIG_LEDS_TRIGGERS
133 class_device_remove_file(led_cdev->class_dev,
134 &class_device_attr_trigger);
135 write_lock(&led_cdev->trigger_lock);
136 if (led_cdev->trigger)
137 led_trigger_set(led_cdev, NULL);
138 write_unlock(&led_cdev->trigger_lock);
139#endif
140
141 class_device_unregister(led_cdev->class_dev);
142
143 write_lock(&leds_list_lock);
144 list_del(&led_cdev->node);
145 write_unlock(&leds_list_lock);
146}
147EXPORT_SYMBOL_GPL(led_classdev_unregister);
148
149static int __init leds_init(void)
150{
151 leds_class = class_create(THIS_MODULE, "leds");
152 if (IS_ERR(leds_class))
153 return PTR_ERR(leds_class);
154 return 0;
155}
156
157static void __exit leds_exit(void)
158{
159 class_destroy(leds_class);
160}
161
162subsys_initcall(leds_init);
163module_exit(leds_exit);
164
165MODULE_AUTHOR("John Lenz, Richard Purdie");
166MODULE_LICENSE("GPL");
167MODULE_DESCRIPTION("LED Class Interface");
diff --git a/drivers/leds/led-core.c b/drivers/leds/led-core.c
new file mode 100644
index 000000000000..fe6541326c71
--- /dev/null
+++ b/drivers/leds/led-core.c
@@ -0,0 +1,25 @@
1/*
2 * LED Class Core
3 *
4 * Copyright 2005-2006 Openedhand Ltd.
5 *
6 * Author: Richard Purdie <rpurdie@openedhand.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 *
12 */
13
14#include <linux/kernel.h>
15#include <linux/list.h>
16#include <linux/module.h>
17#include <linux/spinlock.h>
18#include <linux/leds.h>
19#include "leds.h"
20
21rwlock_t leds_list_lock = RW_LOCK_UNLOCKED;
22LIST_HEAD(leds_list);
23
24EXPORT_SYMBOL_GPL(leds_list);
25EXPORT_SYMBOL_GPL(leds_list_lock);
diff --git a/drivers/leds/led-triggers.c b/drivers/leds/led-triggers.c
new file mode 100644
index 000000000000..5e2cd8be1191
--- /dev/null
+++ b/drivers/leds/led-triggers.c
@@ -0,0 +1,239 @@
1/*
2 * LED Triggers Core
3 *
4 * Copyright 2005-2006 Openedhand Ltd.
5 *
6 * Author: Richard Purdie <rpurdie@openedhand.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 *
12 */
13
14#include <linux/config.h>
15#include <linux/module.h>
16#include <linux/kernel.h>
17#include <linux/init.h>
18#include <linux/list.h>
19#include <linux/spinlock.h>
20#include <linux/device.h>
21#include <linux/sysdev.h>
22#include <linux/timer.h>
23#include <linux/leds.h>
24#include "leds.h"
25
26/*
27 * Nests outside led_cdev->trigger_lock
28 */
29static rwlock_t triggers_list_lock = RW_LOCK_UNLOCKED;
30static LIST_HEAD(trigger_list);
31
32ssize_t led_trigger_store(struct class_device *dev, const char *buf,
33 size_t count)
34{
35 struct led_classdev *led_cdev = class_get_devdata(dev);
36 char trigger_name[TRIG_NAME_MAX];
37 struct led_trigger *trig;
38 size_t len;
39
40 trigger_name[sizeof(trigger_name) - 1] = '\0';
41 strncpy(trigger_name, buf, sizeof(trigger_name) - 1);
42 len = strlen(trigger_name);
43
44 if (len && trigger_name[len - 1] == '\n')
45 trigger_name[len - 1] = '\0';
46
47 if (!strcmp(trigger_name, "none")) {
48 write_lock(&led_cdev->trigger_lock);
49 led_trigger_set(led_cdev, NULL);
50 write_unlock(&led_cdev->trigger_lock);
51 return count;
52 }
53
54 read_lock(&triggers_list_lock);
55 list_for_each_entry(trig, &trigger_list, next_trig) {
56 if (!strcmp(trigger_name, trig->name)) {
57 write_lock(&led_cdev->trigger_lock);
58 led_trigger_set(led_cdev, trig);
59 write_unlock(&led_cdev->trigger_lock);
60
61 read_unlock(&triggers_list_lock);
62 return count;
63 }
64 }
65 read_unlock(&triggers_list_lock);
66
67 return -EINVAL;
68}
69
70
71ssize_t led_trigger_show(struct class_device *dev, char *buf)
72{
73 struct led_classdev *led_cdev = class_get_devdata(dev);
74 struct led_trigger *trig;
75 int len = 0;
76
77 read_lock(&triggers_list_lock);
78 read_lock(&led_cdev->trigger_lock);
79
80 if (!led_cdev->trigger)
81 len += sprintf(buf+len, "[none] ");
82 else
83 len += sprintf(buf+len, "none ");
84
85 list_for_each_entry(trig, &trigger_list, next_trig) {
86 if (led_cdev->trigger && !strcmp(led_cdev->trigger->name,
87 trig->name))
88 len += sprintf(buf+len, "[%s] ", trig->name);
89 else
90 len += sprintf(buf+len, "%s ", trig->name);
91 }
92 read_unlock(&led_cdev->trigger_lock);
93 read_unlock(&triggers_list_lock);
94
95 len += sprintf(len+buf, "\n");
96 return len;
97}
98
99void led_trigger_event(struct led_trigger *trigger,
100 enum led_brightness brightness)
101{
102 struct list_head *entry;
103
104 if (!trigger)
105 return;
106
107 read_lock(&trigger->leddev_list_lock);
108 list_for_each(entry, &trigger->led_cdevs) {
109 struct led_classdev *led_cdev;
110
111 led_cdev = list_entry(entry, struct led_classdev, trig_list);
112 led_set_brightness(led_cdev, brightness);
113 }
114 read_unlock(&trigger->leddev_list_lock);
115}
116
117/* Caller must ensure led_cdev->trigger_lock held */
118void led_trigger_set(struct led_classdev *led_cdev, struct led_trigger *trigger)
119{
120 unsigned long flags;
121
122 /* Remove any existing trigger */
123 if (led_cdev->trigger) {
124 write_lock_irqsave(&led_cdev->trigger->leddev_list_lock, flags);
125 list_del(&led_cdev->trig_list);
126 write_unlock_irqrestore(&led_cdev->trigger->leddev_list_lock, flags);
127 if (led_cdev->trigger->deactivate)
128 led_cdev->trigger->deactivate(led_cdev);
129 }
130 if (trigger) {
131 write_lock_irqsave(&trigger->leddev_list_lock, flags);
132 list_add_tail(&led_cdev->trig_list, &trigger->led_cdevs);
133 write_unlock_irqrestore(&trigger->leddev_list_lock, flags);
134 if (trigger->activate)
135 trigger->activate(led_cdev);
136 }
137 led_cdev->trigger = trigger;
138}
139
140void led_trigger_set_default(struct led_classdev *led_cdev)
141{
142 struct led_trigger *trig;
143
144 if (!led_cdev->default_trigger)
145 return;
146
147 read_lock(&triggers_list_lock);
148 write_lock(&led_cdev->trigger_lock);
149 list_for_each_entry(trig, &trigger_list, next_trig) {
150 if (!strcmp(led_cdev->default_trigger, trig->name))
151 led_trigger_set(led_cdev, trig);
152 }
153 write_unlock(&led_cdev->trigger_lock);
154 read_unlock(&triggers_list_lock);
155}
156
157int led_trigger_register(struct led_trigger *trigger)
158{
159 struct led_classdev *led_cdev;
160
161 rwlock_init(&trigger->leddev_list_lock);
162 INIT_LIST_HEAD(&trigger->led_cdevs);
163
164 /* Add to the list of led triggers */
165 write_lock(&triggers_list_lock);
166 list_add_tail(&trigger->next_trig, &trigger_list);
167 write_unlock(&triggers_list_lock);
168
169 /* Register with any LEDs that have this as a default trigger */
170 read_lock(&leds_list_lock);
171 list_for_each_entry(led_cdev, &leds_list, node) {
172 write_lock(&led_cdev->trigger_lock);
173 if (!led_cdev->trigger && led_cdev->default_trigger &&
174 !strcmp(led_cdev->default_trigger, trigger->name))
175 led_trigger_set(led_cdev, trigger);
176 write_unlock(&led_cdev->trigger_lock);
177 }
178 read_unlock(&leds_list_lock);
179
180 return 0;
181}
182
183void led_trigger_register_simple(const char *name, struct led_trigger **tp)
184{
185 struct led_trigger *trigger;
186
187 trigger = kzalloc(sizeof(struct led_trigger), GFP_KERNEL);
188
189 if (trigger) {
190 trigger->name = name;
191 led_trigger_register(trigger);
192 }
193 *tp = trigger;
194}
195
196void led_trigger_unregister(struct led_trigger *trigger)
197{
198 struct led_classdev *led_cdev;
199
200 /* Remove from the list of led triggers */
201 write_lock(&triggers_list_lock);
202 list_del(&trigger->next_trig);
203 write_unlock(&triggers_list_lock);
204
205 /* Remove anyone actively using this trigger */
206 read_lock(&leds_list_lock);
207 list_for_each_entry(led_cdev, &leds_list, node) {
208 write_lock(&led_cdev->trigger_lock);
209 if (led_cdev->trigger == trigger)
210 led_trigger_set(led_cdev, NULL);
211 write_unlock(&led_cdev->trigger_lock);
212 }
213 read_unlock(&leds_list_lock);
214}
215
216void led_trigger_unregister_simple(struct led_trigger *trigger)
217{
218 led_trigger_unregister(trigger);
219 kfree(trigger);
220}
221
222/* Used by LED Class */
223EXPORT_SYMBOL_GPL(led_trigger_set);
224EXPORT_SYMBOL_GPL(led_trigger_set_default);
225EXPORT_SYMBOL_GPL(led_trigger_show);
226EXPORT_SYMBOL_GPL(led_trigger_store);
227
228/* LED Trigger Interface */
229EXPORT_SYMBOL_GPL(led_trigger_register);
230EXPORT_SYMBOL_GPL(led_trigger_unregister);
231
232/* Simple LED Tigger Interface */
233EXPORT_SYMBOL_GPL(led_trigger_register_simple);
234EXPORT_SYMBOL_GPL(led_trigger_unregister_simple);
235EXPORT_SYMBOL_GPL(led_trigger_event);
236
237MODULE_AUTHOR("Richard Purdie");
238MODULE_LICENSE("GPL");
239MODULE_DESCRIPTION("LED Triggers Core");
diff --git a/drivers/leds/leds-corgi.c b/drivers/leds/leds-corgi.c
new file mode 100644
index 000000000000..bb7d84df0121
--- /dev/null
+++ b/drivers/leds/leds-corgi.c
@@ -0,0 +1,121 @@
1/*
2 * LED Triggers Core
3 *
4 * Copyright 2005-2006 Openedhand Ltd.
5 *
6 * Author: Richard Purdie <rpurdie@openedhand.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 *
12 */
13
14#include <linux/config.h>
15#include <linux/kernel.h>
16#include <linux/init.h>
17#include <linux/platform_device.h>
18#include <linux/leds.h>
19#include <asm/mach-types.h>
20#include <asm/arch/corgi.h>
21#include <asm/arch/hardware.h>
22#include <asm/arch/pxa-regs.h>
23#include <asm/hardware/scoop.h>
24
25static void corgiled_amber_set(struct led_classdev *led_cdev, enum led_brightness value)
26{
27 if (value)
28 GPSR0 = GPIO_bit(CORGI_GPIO_LED_ORANGE);
29 else
30 GPCR0 = GPIO_bit(CORGI_GPIO_LED_ORANGE);
31}
32
33static void corgiled_green_set(struct led_classdev *led_cdev, enum led_brightness value)
34{
35 if (value)
36 set_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_LED_GREEN);
37 else
38 reset_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_LED_GREEN);
39}
40
41static struct led_classdev corgi_amber_led = {
42 .name = "corgi:amber",
43 .default_trigger = "sharpsl-charge",
44 .brightness_set = corgiled_amber_set,
45};
46
47static struct led_classdev corgi_green_led = {
48 .name = "corgi:green",
49 .default_trigger = "nand-disk",
50 .brightness_set = corgiled_green_set,
51};
52
53#ifdef CONFIG_PM
54static int corgiled_suspend(struct platform_device *dev, pm_message_t state)
55{
56#ifdef CONFIG_LEDS_TRIGGERS
57 if (corgi_amber_led.trigger && strcmp(corgi_amber_led.trigger->name, "sharpsl-charge"))
58#endif
59 led_classdev_suspend(&corgi_amber_led);
60 led_classdev_suspend(&corgi_green_led);
61 return 0;
62}
63
64static int corgiled_resume(struct platform_device *dev)
65{
66 led_classdev_resume(&corgi_amber_led);
67 led_classdev_resume(&corgi_green_led);
68 return 0;
69}
70#endif
71
72static int corgiled_probe(struct platform_device *pdev)
73{
74 int ret;
75
76 ret = led_classdev_register(&pdev->dev, &corgi_amber_led);
77 if (ret < 0)
78 return ret;
79
80 ret = led_classdev_register(&pdev->dev, &corgi_green_led);
81 if (ret < 0)
82 led_classdev_unregister(&corgi_amber_led);
83
84 return ret;
85}
86
87static int corgiled_remove(struct platform_device *pdev)
88{
89 led_classdev_unregister(&corgi_amber_led);
90 led_classdev_unregister(&corgi_green_led);
91 return 0;
92}
93
94static struct platform_driver corgiled_driver = {
95 .probe = corgiled_probe,
96 .remove = corgiled_remove,
97#ifdef CONFIG_PM
98 .suspend = corgiled_suspend,
99 .resume = corgiled_resume,
100#endif
101 .driver = {
102 .name = "corgi-led",
103 },
104};
105
106static int __init corgiled_init(void)
107{
108 return platform_driver_register(&corgiled_driver);
109}
110
111static void __exit corgiled_exit(void)
112{
113 platform_driver_unregister(&corgiled_driver);
114}
115
116module_init(corgiled_init);
117module_exit(corgiled_exit);
118
119MODULE_AUTHOR("Richard Purdie <rpurdie@openedhand.com>");
120MODULE_DESCRIPTION("Corgi LED driver");
121MODULE_LICENSE("GPL");
diff --git a/drivers/leds/leds-ixp4xx-gpio.c b/drivers/leds/leds-ixp4xx-gpio.c
new file mode 100644
index 000000000000..30ced150e4cf
--- /dev/null
+++ b/drivers/leds/leds-ixp4xx-gpio.c
@@ -0,0 +1,215 @@
1/*
2 * IXP4XX GPIO driver LED driver
3 *
4 * Author: John Bowler <jbowler@acm.org>
5 *
6 * Copyright (c) 2006 John Bowler
7 *
8 * Permission is hereby granted, free of charge, to any
9 * person obtaining a copy of this software and associated
10 * documentation files (the "Software"), to deal in the
11 * Software without restriction, including without
12 * limitation the rights to use, copy, modify, merge,
13 * publish, distribute, sublicense, and/or sell copies of
14 * the Software, and to permit persons to whom the
15 * Software is furnished to do so, subject to the
16 * following conditions:
17 *
18 * The above copyright notice and this permission notice
19 * shall be included in all copies or substantial portions
20 * of the Software.
21 *
22 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
23 * ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
24 * TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
25 * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
26 * SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
27 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
28 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
29 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
30 * OTHER DEALINGS IN THE SOFTWARE.
31 *
32 */
33
34#include <linux/config.h>
35#include <linux/kernel.h>
36#include <linux/init.h>
37#include <linux/platform_device.h>
38#include <linux/spinlock.h>
39#include <linux/leds.h>
40#include <asm/arch/hardware.h>
41
42extern spinlock_t gpio_lock;
43
44/* Up to 16 gpio lines are possible. */
45#define GPIO_MAX 16
46static struct ixp4xxgpioled_device {
47 struct led_classdev ancestor;
48 int flags;
49} ixp4xxgpioled_devices[GPIO_MAX];
50
51void ixp4xxgpioled_brightness_set(struct led_classdev *pled,
52 enum led_brightness value)
53{
54 const struct ixp4xxgpioled_device *const ixp4xx_dev =
55 container_of(pled, struct ixp4xxgpioled_device, ancestor);
56 const u32 gpio_pin = ixp4xx_dev - ixp4xxgpioled_devices;
57
58 if (gpio_pin < GPIO_MAX && ixp4xx_dev->ancestor.name != 0) {
59 /* Set or clear the 'gpio_pin' bit according to the style
60 * and the required setting (value > 0 == on)
61 */
62 const int gpio_value =
63 (value > 0) == (ixp4xx_dev->flags != IXP4XX_GPIO_LOW) ?
64 IXP4XX_GPIO_HIGH : IXP4XX_GPIO_LOW;
65
66 {
67 unsigned long flags;
68 spin_lock_irqsave(&gpio_lock, flags);
69 gpio_line_set(gpio_pin, gpio_value);
70 spin_unlock_irqrestore(&gpio_lock, flags);
71 }
72 }
73}
74
75/* LEDs are described in resources, the following iterates over the valid
76 * LED resources.
77 */
78#define for_all_leds(i, pdev) \
79 for (i=0; i<pdev->num_resources; ++i) \
80 if (pdev->resource[i].start < GPIO_MAX && \
81 pdev->resource[i].name != 0)
82
83/* The following applies 'operation' to each LED from the given platform,
84 * the function always returns 0 to allow tail call elimination.
85 */
86static int apply_to_all_leds(struct platform_device *pdev,
87 void (*operation)(struct led_classdev *pled))
88{
89 int i;
90
91 for_all_leds(i, pdev)
92 operation(&ixp4xxgpioled_devices[pdev->resource[i].start].ancestor);
93 return 0;
94}
95
96#ifdef CONFIG_PM
97static int ixp4xxgpioled_suspend(struct platform_device *pdev,
98 pm_message_t state)
99{
100 return apply_to_all_leds(pdev, led_classdev_suspend);
101}
102
103static int ixp4xxgpioled_resume(struct platform_device *pdev)
104{
105 return apply_to_all_leds(pdev, led_classdev_resume);
106}
107#endif
108
109static void ixp4xxgpioled_remove_one_led(struct led_classdev *pled)
110{
111 led_classdev_unregister(pled);
112 pled->name = 0;
113}
114
115static int ixp4xxgpioled_remove(struct platform_device *pdev)
116{
117 return apply_to_all_leds(pdev, ixp4xxgpioled_remove_one_led);
118}
119
120static int ixp4xxgpioled_probe(struct platform_device *pdev)
121{
122 /* The board level has to tell the driver where the
123 * LEDs are connected - there is no way to find out
124 * electrically. It must also say whether the GPIO
125 * lines are active high or active low.
126 *
127 * To do this read the num_resources (the number of
128 * LEDs) and the struct resource (the data for each
129 * LED). The name comes from the resource, and it
130 * isn't copied.
131 */
132 int i;
133
134 for_all_leds(i, pdev) {
135 const u8 gpio_pin = pdev->resource[i].start;
136 int rc;
137
138 if (ixp4xxgpioled_devices[gpio_pin].ancestor.name == 0) {
139 unsigned long flags;
140
141 spin_lock_irqsave(&gpio_lock, flags);
142 gpio_line_config(gpio_pin, IXP4XX_GPIO_OUT);
143 /* The config can, apparently, reset the state,
144 * I suspect the gpio line may be an input and
145 * the config may cause the line to be latched,
146 * so the setting depends on how the LED is
147 * connected to the line (which affects how it
148 * floats if not driven).
149 */
150 gpio_line_set(gpio_pin, IXP4XX_GPIO_HIGH);
151 spin_unlock_irqrestore(&gpio_lock, flags);
152
153 ixp4xxgpioled_devices[gpio_pin].flags =
154 pdev->resource[i].flags & IORESOURCE_BITS;
155
156 ixp4xxgpioled_devices[gpio_pin].ancestor.name =
157 pdev->resource[i].name;
158
159 /* This is how a board manufacturer makes the LED
160 * come on on reset - the GPIO line will be high, so
161 * make the LED light when the line is low...
162 */
163 if (ixp4xxgpioled_devices[gpio_pin].flags != IXP4XX_GPIO_LOW)
164 ixp4xxgpioled_devices[gpio_pin].ancestor.brightness = 100;
165 else
166 ixp4xxgpioled_devices[gpio_pin].ancestor.brightness = 0;
167
168 ixp4xxgpioled_devices[gpio_pin].ancestor.flags = 0;
169
170 ixp4xxgpioled_devices[gpio_pin].ancestor.brightness_set =
171 ixp4xxgpioled_brightness_set;
172
173 ixp4xxgpioled_devices[gpio_pin].ancestor.default_trigger = 0;
174 }
175
176 rc = led_classdev_register(&pdev->dev,
177 &ixp4xxgpioled_devices[gpio_pin].ancestor);
178 if (rc < 0) {
179 ixp4xxgpioled_devices[gpio_pin].ancestor.name = 0;
180 ixp4xxgpioled_remove(pdev);
181 return rc;
182 }
183 }
184
185 return 0;
186}
187
188static struct platform_driver ixp4xxgpioled_driver = {
189 .probe = ixp4xxgpioled_probe,
190 .remove = ixp4xxgpioled_remove,
191#ifdef CONFIG_PM
192 .suspend = ixp4xxgpioled_suspend,
193 .resume = ixp4xxgpioled_resume,
194#endif
195 .driver = {
196 .name = "IXP4XX-GPIO-LED",
197 },
198};
199
200static int __init ixp4xxgpioled_init(void)
201{
202 return platform_driver_register(&ixp4xxgpioled_driver);
203}
204
205static void __exit ixp4xxgpioled_exit(void)
206{
207 platform_driver_unregister(&ixp4xxgpioled_driver);
208}
209
210module_init(ixp4xxgpioled_init);
211module_exit(ixp4xxgpioled_exit);
212
213MODULE_AUTHOR("John Bowler <jbowler@acm.org>");
214MODULE_DESCRIPTION("IXP4XX GPIO LED driver");
215MODULE_LICENSE("Dual MIT/GPL");
diff --git a/drivers/leds/leds-locomo.c b/drivers/leds/leds-locomo.c
new file mode 100644
index 000000000000..749a86c2adb6
--- /dev/null
+++ b/drivers/leds/leds-locomo.c
@@ -0,0 +1,95 @@
1/*
2 * linux/drivers/leds/locomo.c
3 *
4 * Copyright (C) 2005 John Lenz <lenz@cs.wisc.edu>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10
11#include <linux/config.h>
12#include <linux/kernel.h>
13#include <linux/init.h>
14#include <linux/device.h>
15#include <linux/leds.h>
16
17#include <asm/hardware.h>
18#include <asm/hardware/locomo.h>
19
20static void locomoled_brightness_set(struct led_classdev *led_cdev,
21 enum led_brightness value, int offset)
22{
23 struct locomo_dev *locomo_dev = LOCOMO_DEV(led_cdev->class_dev->dev);
24 unsigned long flags;
25
26 local_irq_save(flags);
27 if (value)
28 locomo_writel(LOCOMO_LPT_TOFH, locomo_dev->mapbase + offset);
29 else
30 locomo_writel(LOCOMO_LPT_TOFL, locomo_dev->mapbase + offset);
31 local_irq_restore(flags);
32}
33
34static void locomoled_brightness_set0(struct led_classdev *led_cdev,
35 enum led_brightness value)
36{
37 locomoled_brightness_set(led_cdev, value, LOCOMO_LPT0);
38}
39
40static void locomoled_brightness_set1(struct led_classdev *led_cdev,
41 enum led_brightness value)
42{
43 locomoled_brightness_set(led_cdev, value, LOCOMO_LPT1);
44}
45
46static struct led_classdev locomo_led0 = {
47 .name = "locomo:amber",
48 .brightness_set = locomoled_brightness_set0,
49};
50
51static struct led_classdev locomo_led1 = {
52 .name = "locomo:green",
53 .brightness_set = locomoled_brightness_set1,
54};
55
56static int locomoled_probe(struct locomo_dev *ldev)
57{
58 int ret;
59
60 ret = led_classdev_register(&ldev->dev, &locomo_led0);
61 if (ret < 0)
62 return ret;
63
64 ret = led_classdev_register(&ldev->dev, &locomo_led1);
65 if (ret < 0)
66 led_classdev_unregister(&locomo_led0);
67
68 return ret;
69}
70
71static int locomoled_remove(struct locomo_dev *dev)
72{
73 led_classdev_unregister(&locomo_led0);
74 led_classdev_unregister(&locomo_led1);
75 return 0;
76}
77
78static struct locomo_driver locomoled_driver = {
79 .drv = {
80 .name = "locomoled"
81 },
82 .devid = LOCOMO_DEVID_LED,
83 .probe = locomoled_probe,
84 .remove = locomoled_remove,
85};
86
87static int __init locomoled_init(void)
88{
89 return locomo_driver_register(&locomoled_driver);
90}
91module_init(locomoled_init);
92
93MODULE_AUTHOR("John Lenz <lenz@cs.wisc.edu>");
94MODULE_DESCRIPTION("Locomo LED driver");
95MODULE_LICENSE("GPL");
diff --git a/drivers/leds/leds-spitz.c b/drivers/leds/leds-spitz.c
new file mode 100644
index 000000000000..65bbef4a5e09
--- /dev/null
+++ b/drivers/leds/leds-spitz.c
@@ -0,0 +1,125 @@
1/*
2 * LED Triggers Core
3 *
4 * Copyright 2005-2006 Openedhand Ltd.
5 *
6 * Author: Richard Purdie <rpurdie@openedhand.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 *
12 */
13
14#include <linux/config.h>
15#include <linux/kernel.h>
16#include <linux/init.h>
17#include <linux/platform_device.h>
18#include <linux/leds.h>
19#include <asm/hardware/scoop.h>
20#include <asm/mach-types.h>
21#include <asm/arch/hardware.h>
22#include <asm/arch/pxa-regs.h>
23#include <asm/arch/spitz.h>
24
25static void spitzled_amber_set(struct led_classdev *led_cdev, enum led_brightness value)
26{
27 if (value)
28 set_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_LED_ORANGE);
29 else
30 reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_LED_ORANGE);
31}
32
33static void spitzled_green_set(struct led_classdev *led_cdev, enum led_brightness value)
34{
35 if (value)
36 set_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_LED_GREEN);
37 else
38 reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_LED_GREEN);
39}
40
41static struct led_classdev spitz_amber_led = {
42 .name = "spitz:amber",
43 .default_trigger = "sharpsl-charge",
44 .brightness_set = spitzled_amber_set,
45};
46
47static struct led_classdev spitz_green_led = {
48 .name = "spitz:green",
49 .default_trigger = "ide-disk",
50 .brightness_set = spitzled_green_set,
51};
52
53#ifdef CONFIG_PM
54static int spitzled_suspend(struct platform_device *dev, pm_message_t state)
55{
56#ifdef CONFIG_LEDS_TRIGGERS
57 if (spitz_amber_led.trigger && strcmp(spitz_amber_led.trigger->name, "sharpsl-charge"))
58#endif
59 led_classdev_suspend(&spitz_amber_led);
60 led_classdev_suspend(&spitz_green_led);
61 return 0;
62}
63
64static int spitzled_resume(struct platform_device *dev)
65{
66 led_classdev_resume(&spitz_amber_led);
67 led_classdev_resume(&spitz_green_led);
68 return 0;
69}
70#endif
71
72static int spitzled_probe(struct platform_device *pdev)
73{
74 int ret;
75
76 if (machine_is_akita())
77 spitz_green_led.default_trigger = "nand-disk";
78
79 ret = led_classdev_register(&pdev->dev, &spitz_amber_led);
80 if (ret < 0)
81 return ret;
82
83 ret = led_classdev_register(&pdev->dev, &spitz_green_led);
84 if (ret < 0)
85 led_classdev_unregister(&spitz_amber_led);
86
87 return ret;
88}
89
90static int spitzled_remove(struct platform_device *pdev)
91{
92 led_classdev_unregister(&spitz_amber_led);
93 led_classdev_unregister(&spitz_green_led);
94
95 return 0;
96}
97
98static struct platform_driver spitzled_driver = {
99 .probe = spitzled_probe,
100 .remove = spitzled_remove,
101#ifdef CONFIG_PM
102 .suspend = spitzled_suspend,
103 .resume = spitzled_resume,
104#endif
105 .driver = {
106 .name = "spitz-led",
107 },
108};
109
110static int __init spitzled_init(void)
111{
112 return platform_driver_register(&spitzled_driver);
113}
114
115static void __exit spitzled_exit(void)
116{
117 platform_driver_unregister(&spitzled_driver);
118}
119
120module_init(spitzled_init);
121module_exit(spitzled_exit);
122
123MODULE_AUTHOR("Richard Purdie <rpurdie@openedhand.com>");
124MODULE_DESCRIPTION("Spitz LED driver");
125MODULE_LICENSE("GPL");
diff --git a/drivers/leds/leds-tosa.c b/drivers/leds/leds-tosa.c
new file mode 100644
index 000000000000..c9e8cc1ec481
--- /dev/null
+++ b/drivers/leds/leds-tosa.c
@@ -0,0 +1,131 @@
1/*
2 * LED Triggers Core
3 *
4 * Copyright 2005 Dirk Opfer
5 *
6 * Author: Dirk Opfer <Dirk@Opfer-Online.de>
7 * based on spitz.c
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 *
13 */
14
15#include <linux/config.h>
16#include <linux/kernel.h>
17#include <linux/init.h>
18#include <linux/platform_device.h>
19#include <linux/leds.h>
20#include <asm/hardware/scoop.h>
21#include <asm/mach-types.h>
22#include <asm/arch/hardware.h>
23#include <asm/arch/pxa-regs.h>
24#include <asm/arch/tosa.h>
25
26static void tosaled_amber_set(struct led_classdev *led_cdev,
27 enum led_brightness value)
28{
29 if (value)
30 set_scoop_gpio(&tosascoop_jc_device.dev,
31 TOSA_SCOOP_JC_CHRG_ERR_LED);
32 else
33 reset_scoop_gpio(&tosascoop_jc_device.dev,
34 TOSA_SCOOP_JC_CHRG_ERR_LED);
35}
36
37static void tosaled_green_set(struct led_classdev *led_cdev,
38 enum led_brightness value)
39{
40 if (value)
41 set_scoop_gpio(&tosascoop_jc_device.dev,
42 TOSA_SCOOP_JC_NOTE_LED);
43 else
44 reset_scoop_gpio(&tosascoop_jc_device.dev,
45 TOSA_SCOOP_JC_NOTE_LED);
46}
47
48static struct led_classdev tosa_amber_led = {
49 .name = "tosa:amber",
50 .default_trigger = "sharpsl-charge",
51 .brightness_set = tosaled_amber_set,
52};
53
54static struct led_classdev tosa_green_led = {
55 .name = "tosa:green",
56 .default_trigger = "nand-disk",
57 .brightness_set = tosaled_green_set,
58};
59
60#ifdef CONFIG_PM
61static int tosaled_suspend(struct platform_device *dev, pm_message_t state)
62{
63#ifdef CONFIG_LEDS_TRIGGERS
64 if (tosa_amber_led.trigger && strcmp(tosa_amber_led.trigger->name,
65 "sharpsl-charge"))
66#endif
67 led_classdev_suspend(&tosa_amber_led);
68 led_classdev_suspend(&tosa_green_led);
69 return 0;
70}
71
72static int tosaled_resume(struct platform_device *dev)
73{
74 led_classdev_resume(&tosa_amber_led);
75 led_classdev_resume(&tosa_green_led);
76 return 0;
77}
78#else
79#define tosaled_suspend NULL
80#define tosaled_resume NULL
81#endif
82
83static int tosaled_probe(struct platform_device *pdev)
84{
85 int ret;
86
87 ret = led_classdev_register(&pdev->dev, &tosa_amber_led);
88 if (ret < 0)
89 return ret;
90
91 ret = led_classdev_register(&pdev->dev, &tosa_green_led);
92 if (ret < 0)
93 led_classdev_unregister(&tosa_amber_led);
94
95 return ret;
96}
97
98static int tosaled_remove(struct platform_device *pdev)
99{
100 led_classdev_unregister(&tosa_amber_led);
101 led_classdev_unregister(&tosa_green_led);
102
103 return 0;
104}
105
106static struct platform_driver tosaled_driver = {
107 .probe = tosaled_probe,
108 .remove = tosaled_remove,
109 .suspend = tosaled_suspend,
110 .resume = tosaled_resume,
111 .driver = {
112 .name = "tosa-led",
113 },
114};
115
116static int __init tosaled_init(void)
117{
118 return platform_driver_register(&tosaled_driver);
119}
120
121static void __exit tosaled_exit(void)
122{
123 platform_driver_unregister(&tosaled_driver);
124}
125
126module_init(tosaled_init);
127module_exit(tosaled_exit);
128
129MODULE_AUTHOR("Dirk Opfer <Dirk@Opfer-Online.de>");
130MODULE_DESCRIPTION("Tosa LED driver");
131MODULE_LICENSE("GPL");
diff --git a/drivers/leds/leds.h b/drivers/leds/leds.h
new file mode 100644
index 000000000000..a715c4ed93ff
--- /dev/null
+++ b/drivers/leds/leds.h
@@ -0,0 +1,44 @@
1/*
2 * LED Core
3 *
4 * Copyright 2005 Openedhand Ltd.
5 *
6 * Author: Richard Purdie <rpurdie@openedhand.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 *
12 */
13#ifndef __LEDS_H_INCLUDED
14#define __LEDS_H_INCLUDED
15
16#include <linux/leds.h>
17
18static inline void led_set_brightness(struct led_classdev *led_cdev,
19 enum led_brightness value)
20{
21 if (value > LED_FULL)
22 value = LED_FULL;
23 led_cdev->brightness = value;
24 if (!(led_cdev->flags & LED_SUSPENDED))
25 led_cdev->brightness_set(led_cdev, value);
26}
27
28extern rwlock_t leds_list_lock;
29extern struct list_head leds_list;
30
31#ifdef CONFIG_LEDS_TRIGGERS
32void led_trigger_set_default(struct led_classdev *led_cdev);
33void led_trigger_set(struct led_classdev *led_cdev,
34 struct led_trigger *trigger);
35#else
36#define led_trigger_set_default(x) do {} while(0)
37#define led_trigger_set(x, y) do {} while(0)
38#endif
39
40ssize_t led_trigger_store(struct class_device *dev, const char *buf,
41 size_t count);
42ssize_t led_trigger_show(struct class_device *dev, char *buf);
43
44#endif /* __LEDS_H_INCLUDED */
diff --git a/drivers/leds/ledtrig-ide-disk.c b/drivers/leds/ledtrig-ide-disk.c
new file mode 100644
index 000000000000..fa651886ab4f
--- /dev/null
+++ b/drivers/leds/ledtrig-ide-disk.c
@@ -0,0 +1,62 @@
1/*
2 * LED IDE-Disk Activity Trigger
3 *
4 * Copyright 2006 Openedhand Ltd.
5 *
6 * Author: Richard Purdie <rpurdie@openedhand.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 *
12 */
13
14#include <linux/module.h>
15#include <linux/kernel.h>
16#include <linux/init.h>
17#include <linux/timer.h>
18#include <linux/leds.h>
19
20static void ledtrig_ide_timerfunc(unsigned long data);
21
22DEFINE_LED_TRIGGER(ledtrig_ide);
23static DEFINE_TIMER(ledtrig_ide_timer, ledtrig_ide_timerfunc, 0, 0);
24static int ide_activity;
25static int ide_lastactivity;
26
27void ledtrig_ide_activity(void)
28{
29 ide_activity++;
30 if (!timer_pending(&ledtrig_ide_timer))
31 mod_timer(&ledtrig_ide_timer, jiffies + msecs_to_jiffies(10));
32}
33EXPORT_SYMBOL(ledtrig_ide_activity);
34
35static void ledtrig_ide_timerfunc(unsigned long data)
36{
37 if (ide_lastactivity != ide_activity) {
38 ide_lastactivity = ide_activity;
39 led_trigger_event(ledtrig_ide, LED_FULL);
40 mod_timer(&ledtrig_ide_timer, jiffies + msecs_to_jiffies(10));
41 } else {
42 led_trigger_event(ledtrig_ide, LED_OFF);
43 }
44}
45
46static int __init ledtrig_ide_init(void)
47{
48 led_trigger_register_simple("ide-disk", &ledtrig_ide);
49 return 0;
50}
51
52static void __exit ledtrig_ide_exit(void)
53{
54 led_trigger_unregister_simple(ledtrig_ide);
55}
56
57module_init(ledtrig_ide_init);
58module_exit(ledtrig_ide_exit);
59
60MODULE_AUTHOR("Richard Purdie <rpurdie@openedhand.com>");
61MODULE_DESCRIPTION("LED IDE Disk Activity Trigger");
62MODULE_LICENSE("GPL");
diff --git a/drivers/leds/ledtrig-timer.c b/drivers/leds/ledtrig-timer.c
new file mode 100644
index 000000000000..f484b5d6dbf8
--- /dev/null
+++ b/drivers/leds/ledtrig-timer.c
@@ -0,0 +1,170 @@
1/*
2 * LED Kernel Timer Trigger
3 *
4 * Copyright 2005-2006 Openedhand Ltd.
5 *
6 * Author: Richard Purdie <rpurdie@openedhand.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 *
12 */
13
14#include <linux/config.h>
15#include <linux/module.h>
16#include <linux/kernel.h>
17#include <linux/init.h>
18#include <linux/list.h>
19#include <linux/spinlock.h>
20#include <linux/device.h>
21#include <linux/sysdev.h>
22#include <linux/timer.h>
23#include <linux/leds.h>
24#include "leds.h"
25
26struct timer_trig_data {
27 unsigned long delay_on; /* milliseconds on */
28 unsigned long delay_off; /* milliseconds off */
29 struct timer_list timer;
30};
31
32static void led_timer_function(unsigned long data)
33{
34 struct led_classdev *led_cdev = (struct led_classdev *) data;
35 struct timer_trig_data *timer_data = led_cdev->trigger_data;
36 unsigned long brightness = LED_OFF;
37 unsigned long delay = timer_data->delay_off;
38
39 if (!timer_data->delay_on || !timer_data->delay_off) {
40 led_set_brightness(led_cdev, LED_OFF);
41 return;
42 }
43
44 if (!led_cdev->brightness) {
45 brightness = LED_FULL;
46 delay = timer_data->delay_on;
47 }
48
49 led_set_brightness(led_cdev, brightness);
50
51 mod_timer(&timer_data->timer, jiffies + msecs_to_jiffies(delay));
52}
53
54static ssize_t led_delay_on_show(struct class_device *dev, char *buf)
55{
56 struct led_classdev *led_cdev = class_get_devdata(dev);
57 struct timer_trig_data *timer_data = led_cdev->trigger_data;
58
59 sprintf(buf, "%lu\n", timer_data->delay_on);
60
61 return strlen(buf) + 1;
62}
63
64static ssize_t led_delay_on_store(struct class_device *dev, const char *buf,
65 size_t size)
66{
67 struct led_classdev *led_cdev = class_get_devdata(dev);
68 struct timer_trig_data *timer_data = led_cdev->trigger_data;
69 int ret = -EINVAL;
70 char *after;
71 unsigned long state = simple_strtoul(buf, &after, 10);
72
73 if (after - buf > 0) {
74 timer_data->delay_on = state;
75 mod_timer(&timer_data->timer, jiffies + 1);
76 ret = after - buf;
77 }
78
79 return ret;
80}
81
82static ssize_t led_delay_off_show(struct class_device *dev, char *buf)
83{
84 struct led_classdev *led_cdev = class_get_devdata(dev);
85 struct timer_trig_data *timer_data = led_cdev->trigger_data;
86
87 sprintf(buf, "%lu\n", timer_data->delay_off);
88
89 return strlen(buf) + 1;
90}
91
92static ssize_t led_delay_off_store(struct class_device *dev, const char *buf,
93 size_t size)
94{
95 struct led_classdev *led_cdev = class_get_devdata(dev);
96 struct timer_trig_data *timer_data = led_cdev->trigger_data;
97 int ret = -EINVAL;
98 char *after;
99 unsigned long state = simple_strtoul(buf, &after, 10);
100
101 if (after - buf > 0) {
102 timer_data->delay_off = state;
103 mod_timer(&timer_data->timer, jiffies + 1);
104 ret = after - buf;
105 }
106
107 return ret;
108}
109
110static CLASS_DEVICE_ATTR(delay_on, 0644, led_delay_on_show,
111 led_delay_on_store);
112static CLASS_DEVICE_ATTR(delay_off, 0644, led_delay_off_show,
113 led_delay_off_store);
114
115static void timer_trig_activate(struct led_classdev *led_cdev)
116{
117 struct timer_trig_data *timer_data;
118
119 timer_data = kzalloc(sizeof(struct timer_trig_data), GFP_KERNEL);
120 if (!timer_data)
121 return;
122
123 led_cdev->trigger_data = timer_data;
124
125 init_timer(&timer_data->timer);
126 timer_data->timer.function = led_timer_function;
127 timer_data->timer.data = (unsigned long) led_cdev;
128
129 class_device_create_file(led_cdev->class_dev,
130 &class_device_attr_delay_on);
131 class_device_create_file(led_cdev->class_dev,
132 &class_device_attr_delay_off);
133}
134
135static void timer_trig_deactivate(struct led_classdev *led_cdev)
136{
137 struct timer_trig_data *timer_data = led_cdev->trigger_data;
138
139 if (timer_data) {
140 class_device_remove_file(led_cdev->class_dev,
141 &class_device_attr_delay_on);
142 class_device_remove_file(led_cdev->class_dev,
143 &class_device_attr_delay_off);
144 del_timer_sync(&timer_data->timer);
145 kfree(timer_data);
146 }
147}
148
149static struct led_trigger timer_led_trigger = {
150 .name = "timer",
151 .activate = timer_trig_activate,
152 .deactivate = timer_trig_deactivate,
153};
154
155static int __init timer_trig_init(void)
156{
157 return led_trigger_register(&timer_led_trigger);
158}
159
160static void __exit timer_trig_exit(void)
161{
162 led_trigger_unregister(&timer_led_trigger);
163}
164
165module_init(timer_trig_init);
166module_exit(timer_trig_exit);
167
168MODULE_AUTHOR("Richard Purdie <rpurdie@openedhand.com>");
169MODULE_DESCRIPTION("Timer LED trigger");
170MODULE_LICENSE("GPL");
diff --git a/drivers/macintosh/adb.c b/drivers/macintosh/adb.c
index 34fcabac5fdb..259fd8973ce9 100644
--- a/drivers/macintosh/adb.c
+++ b/drivers/macintosh/adb.c
@@ -42,6 +42,7 @@
42#include <asm/semaphore.h> 42#include <asm/semaphore.h>
43#ifdef CONFIG_PPC 43#ifdef CONFIG_PPC
44#include <asm/prom.h> 44#include <asm/prom.h>
45#include <asm/machdep.h>
45#endif 46#endif
46 47
47 48
@@ -294,7 +295,7 @@ int __init adb_init(void)
294 int i; 295 int i;
295 296
296#ifdef CONFIG_PPC32 297#ifdef CONFIG_PPC32
297 if ( (_machine != _MACH_chrp) && (_machine != _MACH_Pmac) ) 298 if (!machine_is(chrp) && !machine_is(powermac))
298 return 0; 299 return 0;
299#endif 300#endif
300#ifdef CONFIG_MAC 301#ifdef CONFIG_MAC
diff --git a/drivers/macintosh/adbhid.c b/drivers/macintosh/adbhid.c
index f5779a73184d..394334ec5765 100644
--- a/drivers/macintosh/adbhid.c
+++ b/drivers/macintosh/adbhid.c
@@ -1206,8 +1206,8 @@ init_ms_a3(int id)
1206static int __init adbhid_init(void) 1206static int __init adbhid_init(void)
1207{ 1207{
1208#ifndef CONFIG_MAC 1208#ifndef CONFIG_MAC
1209 if ( (_machine != _MACH_chrp) && (_machine != _MACH_Pmac) ) 1209 if (!machine_is(chrp) && !machine_is(powermac))
1210 return 0; 1210 return 0;
1211#endif 1211#endif
1212 1212
1213 led_request.complete = 1; 1213 led_request.complete = 1;
diff --git a/drivers/macintosh/mediabay.c b/drivers/macintosh/mediabay.c
index 8dbf2852bae0..53c1c7909413 100644
--- a/drivers/macintosh/mediabay.c
+++ b/drivers/macintosh/mediabay.c
@@ -839,8 +839,8 @@ static int __init media_bay_init(void)
839 media_bays[i].cd_index = -1; 839 media_bays[i].cd_index = -1;
840#endif 840#endif
841 } 841 }
842 if (_machine != _MACH_Pmac) 842 if (!machine_is(powermac))
843 return -ENODEV; 843 return 0;
844 844
845 macio_register_driver(&media_bay_driver); 845 macio_register_driver(&media_bay_driver);
846 846
diff --git a/drivers/md/md.c b/drivers/md/md.c
index 039e071c1007..1ed5152db450 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -215,13 +215,11 @@ static void mddev_put(mddev_t *mddev)
215 return; 215 return;
216 if (!mddev->raid_disks && list_empty(&mddev->disks)) { 216 if (!mddev->raid_disks && list_empty(&mddev->disks)) {
217 list_del(&mddev->all_mddevs); 217 list_del(&mddev->all_mddevs);
218 /* that blocks */ 218 spin_unlock(&all_mddevs_lock);
219 blk_cleanup_queue(mddev->queue); 219 blk_cleanup_queue(mddev->queue);
220 /* that also blocks */
221 kobject_unregister(&mddev->kobj); 220 kobject_unregister(&mddev->kobj);
222 /* result blows... */ 221 } else
223 } 222 spin_unlock(&all_mddevs_lock);
224 spin_unlock(&all_mddevs_lock);
225} 223}
226 224
227static mddev_t * mddev_find(dev_t unit) 225static mddev_t * mddev_find(dev_t unit)
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
index 3cb0872a845d..9b374c91db66 100644
--- a/drivers/md/raid1.c
+++ b/drivers/md/raid1.c
@@ -1135,8 +1135,19 @@ static int end_sync_write(struct bio *bio, unsigned int bytes_done, int error)
1135 mirror = i; 1135 mirror = i;
1136 break; 1136 break;
1137 } 1137 }
1138 if (!uptodate) 1138 if (!uptodate) {
1139 int sync_blocks = 0;
1140 sector_t s = r1_bio->sector;
1141 long sectors_to_go = r1_bio->sectors;
1142 /* make sure these bits doesn't get cleared. */
1143 do {
1144 bitmap_end_sync(mddev->bitmap, r1_bio->sector,
1145 &sync_blocks, 1);
1146 s += sync_blocks;
1147 sectors_to_go -= sync_blocks;
1148 } while (sectors_to_go > 0);
1139 md_error(mddev, conf->mirrors[mirror].rdev); 1149 md_error(mddev, conf->mirrors[mirror].rdev);
1150 }
1140 1151
1141 update_head_pos(mirror, r1_bio); 1152 update_head_pos(mirror, r1_bio);
1142 1153
diff --git a/drivers/md/raid6main.c b/drivers/md/raid6main.c
index 6df4930fddec..ab64b37e4996 100644
--- a/drivers/md/raid6main.c
+++ b/drivers/md/raid6main.c
@@ -2151,6 +2151,8 @@ static int run(mddev_t *mddev)
2151 } 2151 }
2152 2152
2153 /* Ok, everything is just fine now */ 2153 /* Ok, everything is just fine now */
2154 sysfs_create_group(&mddev->kobj, &raid6_attrs_group);
2155
2154 mddev->array_size = mddev->size * (mddev->raid_disks - 2); 2156 mddev->array_size = mddev->size * (mddev->raid_disks - 2);
2155 2157
2156 mddev->queue->unplug_fn = raid6_unplug_device; 2158 mddev->queue->unplug_fn = raid6_unplug_device;
diff --git a/drivers/media/video/cpia_pp.c b/drivers/media/video/cpia_pp.c
index 3021f21aae36..0b00e6027dfb 100644
--- a/drivers/media/video/cpia_pp.c
+++ b/drivers/media/video/cpia_pp.c
@@ -873,7 +873,7 @@ static int __init cpia_pp_setup(char *str)
873 parport_nr[parport_ptr++] = PPCPIA_PARPORT_NONE; 873 parport_nr[parport_ptr++] = PPCPIA_PARPORT_NONE;
874 } 874 }
875 875
876 return 0; 876 return 1;
877} 877}
878 878
879__setup("cpia_pp=", cpia_pp_setup); 879__setup("cpia_pp=", cpia_pp_setup);
diff --git a/drivers/media/video/planb.c b/drivers/media/video/planb.c
index 522e9ddeb089..d9e3cada52f4 100644
--- a/drivers/media/video/planb.c
+++ b/drivers/media/video/planb.c
@@ -2156,7 +2156,7 @@ static int find_planb(void)
2156 struct pci_dev *pdev; 2156 struct pci_dev *pdev;
2157 int rc; 2157 int rc;
2158 2158
2159 if (_machine != _MACH_Pmac) 2159 if (!machine_is(powermac))
2160 return 0; 2160 return 0;
2161 2161
2162 planb_devices = find_devices("planb"); 2162 planb_devices = find_devices("planb");
diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig
index 3f5d77f633fa..7cc162e8978b 100644
--- a/drivers/mmc/Kconfig
+++ b/drivers/mmc/Kconfig
@@ -60,6 +60,17 @@ config MMC_SDHCI
60 60
61 If unsure, say N. 61 If unsure, say N.
62 62
63config MMC_OMAP
64 tristate "TI OMAP Multimedia Card Interface support"
65 depends on ARCH_OMAP && MMC
66 select TPS65010 if MACH_OMAP_H2
67 help
68 This selects the TI OMAP Multimedia card Interface.
69 If you have an OMAP board with a Multimedia Card slot,
70 say Y or M here.
71
72 If unsure, say N.
73
63config MMC_WBSD 74config MMC_WBSD
64 tristate "Winbond W83L51xD SD/MMC Card Interface support" 75 tristate "Winbond W83L51xD SD/MMC Card Interface support"
65 depends on MMC && ISA_DMA_API 76 depends on MMC && ISA_DMA_API
diff --git a/drivers/mmc/Makefile b/drivers/mmc/Makefile
index 769d545284a4..c7c34aadfc92 100644
--- a/drivers/mmc/Makefile
+++ b/drivers/mmc/Makefile
@@ -20,5 +20,10 @@ obj-$(CONFIG_MMC_PXA) += pxamci.o
20obj-$(CONFIG_MMC_SDHCI) += sdhci.o 20obj-$(CONFIG_MMC_SDHCI) += sdhci.o
21obj-$(CONFIG_MMC_WBSD) += wbsd.o 21obj-$(CONFIG_MMC_WBSD) += wbsd.o
22obj-$(CONFIG_MMC_AU1X) += au1xmmc.o 22obj-$(CONFIG_MMC_AU1X) += au1xmmc.o
23obj-$(CONFIG_MMC_OMAP) += omap.o
23 24
24mmc_core-y := mmc.o mmc_queue.o mmc_sysfs.o 25mmc_core-y := mmc.o mmc_queue.o mmc_sysfs.o
26
27ifeq ($(CONFIG_MMC_DEBUG),y)
28EXTRA_CFLAGS += -DDEBUG
29endif
diff --git a/drivers/mmc/au1xmmc.c b/drivers/mmc/au1xmmc.c
index 85e89c77bdea..c0326bbc5f28 100644
--- a/drivers/mmc/au1xmmc.c
+++ b/drivers/mmc/au1xmmc.c
@@ -56,12 +56,11 @@
56#define DRIVER_NAME "au1xxx-mmc" 56#define DRIVER_NAME "au1xxx-mmc"
57 57
58/* Set this to enable special debugging macros */ 58/* Set this to enable special debugging macros */
59/* #define MMC_DEBUG */
60 59
61#ifdef MMC_DEBUG 60#ifdef DEBUG
62#define DEBUG(fmt, idx, args...) printk("au1xx(%d): DEBUG: " fmt, idx, ##args) 61#define DBG(fmt, idx, args...) printk("au1xx(%d): DEBUG: " fmt, idx, ##args)
63#else 62#else
64#define DEBUG(fmt, idx, args...) 63#define DBG(fmt, idx, args...)
65#endif 64#endif
66 65
67const struct { 66const struct {
@@ -424,18 +423,18 @@ static void au1xmmc_receive_pio(struct au1xmmc_host *host)
424 break; 423 break;
425 424
426 if (status & SD_STATUS_RC) { 425 if (status & SD_STATUS_RC) {
427 DEBUG("RX CRC Error [%d + %d].\n", host->id, 426 DBG("RX CRC Error [%d + %d].\n", host->id,
428 host->pio.len, count); 427 host->pio.len, count);
429 break; 428 break;
430 } 429 }
431 430
432 if (status & SD_STATUS_RO) { 431 if (status & SD_STATUS_RO) {
433 DEBUG("RX Overrun [%d + %d]\n", host->id, 432 DBG("RX Overrun [%d + %d]\n", host->id,
434 host->pio.len, count); 433 host->pio.len, count);
435 break; 434 break;
436 } 435 }
437 else if (status & SD_STATUS_RU) { 436 else if (status & SD_STATUS_RU) {
438 DEBUG("RX Underrun [%d + %d]\n", host->id, 437 DBG("RX Underrun [%d + %d]\n", host->id,
439 host->pio.len, count); 438 host->pio.len, count);
440 break; 439 break;
441 } 440 }
@@ -721,7 +720,7 @@ static void au1xmmc_set_ios(struct mmc_host* mmc, struct mmc_ios* ios)
721{ 720{
722 struct au1xmmc_host *host = mmc_priv(mmc); 721 struct au1xmmc_host *host = mmc_priv(mmc);
723 722
724 DEBUG("set_ios (power=%u, clock=%uHz, vdd=%u, mode=%u)\n", 723 DBG("set_ios (power=%u, clock=%uHz, vdd=%u, mode=%u)\n",
725 host->id, ios->power_mode, ios->clock, ios->vdd, 724 host->id, ios->power_mode, ios->clock, ios->vdd,
726 ios->bus_mode); 725 ios->bus_mode);
727 726
@@ -810,7 +809,7 @@ static irqreturn_t au1xmmc_irq(int irq, void *dev_id, struct pt_regs *regs)
810 au1xmmc_receive_pio(host); 809 au1xmmc_receive_pio(host);
811 } 810 }
812 else if (status & 0x203FBC70) { 811 else if (status & 0x203FBC70) {
813 DEBUG("Unhandled status %8.8x\n", host->id, status); 812 DBG("Unhandled status %8.8x\n", host->id, status);
814 handled = 0; 813 handled = 0;
815 } 814 }
816 815
@@ -839,7 +838,7 @@ static void au1xmmc_poll_event(unsigned long arg)
839 838
840 if (host->mrq != NULL) { 839 if (host->mrq != NULL) {
841 u32 status = au_readl(HOST_STATUS(host)); 840 u32 status = au_readl(HOST_STATUS(host));
842 DEBUG("PENDING - %8.8x\n", host->id, status); 841 DBG("PENDING - %8.8x\n", host->id, status);
843 } 842 }
844 843
845 mod_timer(&host->timer, jiffies + AU1XMMC_DETECT_TIMEOUT); 844 mod_timer(&host->timer, jiffies + AU1XMMC_DETECT_TIMEOUT);
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index 1888060c5e0c..da6ddd910fc5 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -27,12 +27,6 @@
27 27
28#include "mmc.h" 28#include "mmc.h"
29 29
30#ifdef CONFIG_MMC_DEBUG
31#define DBG(x...) printk(KERN_DEBUG x)
32#else
33#define DBG(x...) do { } while (0)
34#endif
35
36#define CMD_RETRIES 3 30#define CMD_RETRIES 3
37 31
38/* 32/*
@@ -77,8 +71,9 @@ void mmc_request_done(struct mmc_host *host, struct mmc_request *mrq)
77{ 71{
78 struct mmc_command *cmd = mrq->cmd; 72 struct mmc_command *cmd = mrq->cmd;
79 int err = mrq->cmd->error; 73 int err = mrq->cmd->error;
80 DBG("MMC: req done (%02x): %d: %08x %08x %08x %08x\n", cmd->opcode, 74 pr_debug("MMC: req done (%02x): %d: %08x %08x %08x %08x\n",
81 err, cmd->resp[0], cmd->resp[1], cmd->resp[2], cmd->resp[3]); 75 cmd->opcode, err, cmd->resp[0], cmd->resp[1],
76 cmd->resp[2], cmd->resp[3]);
82 77
83 if (err && cmd->retries) { 78 if (err && cmd->retries) {
84 cmd->retries--; 79 cmd->retries--;
@@ -102,8 +97,8 @@ EXPORT_SYMBOL(mmc_request_done);
102void 97void
103mmc_start_request(struct mmc_host *host, struct mmc_request *mrq) 98mmc_start_request(struct mmc_host *host, struct mmc_request *mrq)
104{ 99{
105 DBG("MMC: starting cmd %02x arg %08x flags %08x\n", 100 pr_debug("MMC: starting cmd %02x arg %08x flags %08x\n",
106 mrq->cmd->opcode, mrq->cmd->arg, mrq->cmd->flags); 101 mrq->cmd->opcode, mrq->cmd->arg, mrq->cmd->flags);
107 102
108 WARN_ON(host->card_busy == NULL); 103 WARN_ON(host->card_busy == NULL);
109 104
@@ -976,8 +971,8 @@ static unsigned int mmc_calculate_clock(struct mmc_host *host)
976 if (!mmc_card_dead(card) && max_dtr > card->csd.max_dtr) 971 if (!mmc_card_dead(card) && max_dtr > card->csd.max_dtr)
977 max_dtr = card->csd.max_dtr; 972 max_dtr = card->csd.max_dtr;
978 973
979 DBG("MMC: selected %d.%03dMHz transfer rate\n", 974 pr_debug("MMC: selected %d.%03dMHz transfer rate\n",
980 max_dtr / 1000000, (max_dtr / 1000) % 1000); 975 max_dtr / 1000000, (max_dtr / 1000) % 1000);
981 976
982 return max_dtr; 977 return max_dtr;
983} 978}
diff --git a/drivers/mmc/mmci.c b/drivers/mmc/mmci.c
index 9fef29d978b5..df7e861e2fc7 100644
--- a/drivers/mmc/mmci.c
+++ b/drivers/mmc/mmci.c
@@ -33,12 +33,8 @@
33 33
34#define DRIVER_NAME "mmci-pl18x" 34#define DRIVER_NAME "mmci-pl18x"
35 35
36#ifdef CONFIG_MMC_DEBUG
37#define DBG(host,fmt,args...) \ 36#define DBG(host,fmt,args...) \
38 pr_debug("%s: %s: " fmt, mmc_hostname(host->mmc), __func__ , args) 37 pr_debug("%s: %s: " fmt, mmc_hostname(host->mmc), __func__ , args)
39#else
40#define DBG(host,fmt,args...) do { } while (0)
41#endif
42 38
43static unsigned int fmax = 515633; 39static unsigned int fmax = 515633;
44 40
diff --git a/drivers/mmc/omap.c b/drivers/mmc/omap.c
new file mode 100644
index 000000000000..becb3c68c34d
--- /dev/null
+++ b/drivers/mmc/omap.c
@@ -0,0 +1,1226 @@
1/*
2 * linux/drivers/media/mmc/omap.c
3 *
4 * Copyright (C) 2004 Nokia Corporation
5 * Written by Tuukka Tikkanen and Juha Yrjölä<juha.yrjola@nokia.com>
6 * Misc hacks here and there by Tony Lindgren <tony@atomide.com>
7 * Other hacks (DMA, SD, etc) by David Brownell
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 */
13
14#include <linux/config.h>
15#include <linux/module.h>
16#include <linux/moduleparam.h>
17#include <linux/init.h>
18#include <linux/ioport.h>
19#include <linux/platform_device.h>
20#include <linux/interrupt.h>
21#include <linux/dma-mapping.h>
22#include <linux/delay.h>
23#include <linux/spinlock.h>
24#include <linux/timer.h>
25#include <linux/mmc/host.h>
26#include <linux/mmc/protocol.h>
27#include <linux/mmc/card.h>
28#include <linux/clk.h>
29
30#include <asm/io.h>
31#include <asm/irq.h>
32#include <asm/scatterlist.h>
33#include <asm/mach-types.h>
34
35#include <asm/arch/board.h>
36#include <asm/arch/gpio.h>
37#include <asm/arch/dma.h>
38#include <asm/arch/mux.h>
39#include <asm/arch/fpga.h>
40#include <asm/arch/tps65010.h>
41
42#include "omap.h"
43
44#define DRIVER_NAME "mmci-omap"
45#define RSP_TYPE(x) ((x) & ~(MMC_RSP_BUSY|MMC_RSP_OPCODE))
46
47/* Specifies how often in millisecs to poll for card status changes
48 * when the cover switch is open */
49#define OMAP_MMC_SWITCH_POLL_DELAY 500
50
51static int mmc_omap_enable_poll = 1;
52
53struct mmc_omap_host {
54 int initialized;
55 int suspended;
56 struct mmc_request * mrq;
57 struct mmc_command * cmd;
58 struct mmc_data * data;
59 struct mmc_host * mmc;
60 struct device * dev;
61 unsigned char id; /* 16xx chips have 2 MMC blocks */
62 struct clk * iclk;
63 struct clk * fclk;
64 void __iomem *base;
65 int irq;
66 unsigned char bus_mode;
67 unsigned char hw_bus_mode;
68
69 unsigned int sg_len;
70 int sg_idx;
71 u16 * buffer;
72 u32 buffer_bytes_left;
73 u32 total_bytes_left;
74
75 unsigned use_dma:1;
76 unsigned brs_received:1, dma_done:1;
77 unsigned dma_is_read:1;
78 unsigned dma_in_use:1;
79 int dma_ch;
80 spinlock_t dma_lock;
81 struct timer_list dma_timer;
82 unsigned dma_len;
83
84 short power_pin;
85 short wp_pin;
86
87 int switch_pin;
88 struct work_struct switch_work;
89 struct timer_list switch_timer;
90 int switch_last_state;
91};
92
93static inline int
94mmc_omap_cover_is_open(struct mmc_omap_host *host)
95{
96 if (host->switch_pin < 0)
97 return 0;
98 return omap_get_gpio_datain(host->switch_pin);
99}
100
101static ssize_t
102mmc_omap_show_cover_switch(struct device *dev,
103 struct device_attribute *attr, char *buf)
104{
105 struct mmc_omap_host *host = dev_get_drvdata(dev);
106
107 return sprintf(buf, "%s\n", mmc_omap_cover_is_open(host) ? "open" :
108 "closed");
109}
110
111static DEVICE_ATTR(cover_switch, S_IRUGO, mmc_omap_show_cover_switch, NULL);
112
113static ssize_t
114mmc_omap_show_enable_poll(struct device *dev,
115 struct device_attribute *attr, char *buf)
116{
117 return snprintf(buf, PAGE_SIZE, "%d\n", mmc_omap_enable_poll);
118}
119
120static ssize_t
121mmc_omap_store_enable_poll(struct device *dev,
122 struct device_attribute *attr, const char *buf,
123 size_t size)
124{
125 int enable_poll;
126
127 if (sscanf(buf, "%10d", &enable_poll) != 1)
128 return -EINVAL;
129
130 if (enable_poll != mmc_omap_enable_poll) {
131 struct mmc_omap_host *host = dev_get_drvdata(dev);
132
133 mmc_omap_enable_poll = enable_poll;
134 if (enable_poll && host->switch_pin >= 0)
135 schedule_work(&host->switch_work);
136 }
137 return size;
138}
139
140static DEVICE_ATTR(enable_poll, 0664,
141 mmc_omap_show_enable_poll, mmc_omap_store_enable_poll);
142
143static void
144mmc_omap_start_command(struct mmc_omap_host *host, struct mmc_command *cmd)
145{
146 u32 cmdreg;
147 u32 resptype;
148 u32 cmdtype;
149
150 host->cmd = cmd;
151
152 resptype = 0;
153 cmdtype = 0;
154
155 /* Our hardware needs to know exact type */
156 switch (RSP_TYPE(mmc_resp_type(cmd))) {
157 case RSP_TYPE(MMC_RSP_R1):
158 /* resp 1, resp 1b */
159 resptype = 1;
160 break;
161 case RSP_TYPE(MMC_RSP_R2):
162 resptype = 2;
163 break;
164 case RSP_TYPE(MMC_RSP_R3):
165 resptype = 3;
166 break;
167 default:
168 break;
169 }
170
171 if (mmc_cmd_type(cmd) == MMC_CMD_ADTC) {
172 cmdtype = OMAP_MMC_CMDTYPE_ADTC;
173 } else if (mmc_cmd_type(cmd) == MMC_CMD_BC) {
174 cmdtype = OMAP_MMC_CMDTYPE_BC;
175 } else if (mmc_cmd_type(cmd) == MMC_CMD_BCR) {
176 cmdtype = OMAP_MMC_CMDTYPE_BCR;
177 } else {
178 cmdtype = OMAP_MMC_CMDTYPE_AC;
179 }
180
181 cmdreg = cmd->opcode | (resptype << 8) | (cmdtype << 12);
182
183 if (host->bus_mode == MMC_BUSMODE_OPENDRAIN)
184 cmdreg |= 1 << 6;
185
186 if (cmd->flags & MMC_RSP_BUSY)
187 cmdreg |= 1 << 11;
188
189 if (host->data && !(host->data->flags & MMC_DATA_WRITE))
190 cmdreg |= 1 << 15;
191
192 clk_enable(host->fclk);
193
194 OMAP_MMC_WRITE(host->base, CTO, 200);
195 OMAP_MMC_WRITE(host->base, ARGL, cmd->arg & 0xffff);
196 OMAP_MMC_WRITE(host->base, ARGH, cmd->arg >> 16);
197 OMAP_MMC_WRITE(host->base, IE,
198 OMAP_MMC_STAT_A_EMPTY | OMAP_MMC_STAT_A_FULL |
199 OMAP_MMC_STAT_CMD_CRC | OMAP_MMC_STAT_CMD_TOUT |
200 OMAP_MMC_STAT_DATA_CRC | OMAP_MMC_STAT_DATA_TOUT |
201 OMAP_MMC_STAT_END_OF_CMD | OMAP_MMC_STAT_CARD_ERR |
202 OMAP_MMC_STAT_END_OF_DATA);
203 OMAP_MMC_WRITE(host->base, CMD, cmdreg);
204}
205
206static void
207mmc_omap_xfer_done(struct mmc_omap_host *host, struct mmc_data *data)
208{
209 if (host->dma_in_use) {
210 enum dma_data_direction dma_data_dir;
211
212 BUG_ON(host->dma_ch < 0);
213 if (data->error != MMC_ERR_NONE)
214 omap_stop_dma(host->dma_ch);
215 /* Release DMA channel lazily */
216 mod_timer(&host->dma_timer, jiffies + HZ);
217 if (data->flags & MMC_DATA_WRITE)
218 dma_data_dir = DMA_TO_DEVICE;
219 else
220 dma_data_dir = DMA_FROM_DEVICE;
221 dma_unmap_sg(mmc_dev(host->mmc), data->sg, host->sg_len,
222 dma_data_dir);
223 }
224 host->data = NULL;
225 host->sg_len = 0;
226 clk_disable(host->fclk);
227
228 /* NOTE: MMC layer will sometimes poll-wait CMD13 next, issuing
229 * dozens of requests until the card finishes writing data.
230 * It'd be cheaper to just wait till an EOFB interrupt arrives...
231 */
232
233 if (!data->stop) {
234 host->mrq = NULL;
235 mmc_request_done(host->mmc, data->mrq);
236 return;
237 }
238
239 mmc_omap_start_command(host, data->stop);
240}
241
242static void
243mmc_omap_end_of_data(struct mmc_omap_host *host, struct mmc_data *data)
244{
245 unsigned long flags;
246 int done;
247
248 if (!host->dma_in_use) {
249 mmc_omap_xfer_done(host, data);
250 return;
251 }
252 done = 0;
253 spin_lock_irqsave(&host->dma_lock, flags);
254 if (host->dma_done)
255 done = 1;
256 else
257 host->brs_received = 1;
258 spin_unlock_irqrestore(&host->dma_lock, flags);
259 if (done)
260 mmc_omap_xfer_done(host, data);
261}
262
263static void
264mmc_omap_dma_timer(unsigned long data)
265{
266 struct mmc_omap_host *host = (struct mmc_omap_host *) data;
267
268 BUG_ON(host->dma_ch < 0);
269 omap_free_dma(host->dma_ch);
270 host->dma_ch = -1;
271}
272
273static void
274mmc_omap_dma_done(struct mmc_omap_host *host, struct mmc_data *data)
275{
276 unsigned long flags;
277 int done;
278
279 done = 0;
280 spin_lock_irqsave(&host->dma_lock, flags);
281 if (host->brs_received)
282 done = 1;
283 else
284 host->dma_done = 1;
285 spin_unlock_irqrestore(&host->dma_lock, flags);
286 if (done)
287 mmc_omap_xfer_done(host, data);
288}
289
290static void
291mmc_omap_cmd_done(struct mmc_omap_host *host, struct mmc_command *cmd)
292{
293 host->cmd = NULL;
294
295 if (cmd->flags & MMC_RSP_PRESENT) {
296 if (cmd->flags & MMC_RSP_136) {
297 /* response type 2 */
298 cmd->resp[3] =
299 OMAP_MMC_READ(host->base, RSP0) |
300 (OMAP_MMC_READ(host->base, RSP1) << 16);
301 cmd->resp[2] =
302 OMAP_MMC_READ(host->base, RSP2) |
303 (OMAP_MMC_READ(host->base, RSP3) << 16);
304 cmd->resp[1] =
305 OMAP_MMC_READ(host->base, RSP4) |
306 (OMAP_MMC_READ(host->base, RSP5) << 16);
307 cmd->resp[0] =
308 OMAP_MMC_READ(host->base, RSP6) |
309 (OMAP_MMC_READ(host->base, RSP7) << 16);
310 } else {
311 /* response types 1, 1b, 3, 4, 5, 6 */
312 cmd->resp[0] =
313 OMAP_MMC_READ(host->base, RSP6) |
314 (OMAP_MMC_READ(host->base, RSP7) << 16);
315 }
316 }
317
318 if (host->data == NULL || cmd->error != MMC_ERR_NONE) {
319 host->mrq = NULL;
320 clk_disable(host->fclk);
321 mmc_request_done(host->mmc, cmd->mrq);
322 }
323}
324
325/* PIO only */
326static void
327mmc_omap_sg_to_buf(struct mmc_omap_host *host)
328{
329 struct scatterlist *sg;
330
331 sg = host->data->sg + host->sg_idx;
332 host->buffer_bytes_left = sg->length;
333 host->buffer = page_address(sg->page) + sg->offset;
334 if (host->buffer_bytes_left > host->total_bytes_left)
335 host->buffer_bytes_left = host->total_bytes_left;
336}
337
338/* PIO only */
339static void
340mmc_omap_xfer_data(struct mmc_omap_host *host, int write)
341{
342 int n;
343 void __iomem *reg;
344 u16 *p;
345
346 if (host->buffer_bytes_left == 0) {
347 host->sg_idx++;
348 BUG_ON(host->sg_idx == host->sg_len);
349 mmc_omap_sg_to_buf(host);
350 }
351 n = 64;
352 if (n > host->buffer_bytes_left)
353 n = host->buffer_bytes_left;
354 host->buffer_bytes_left -= n;
355 host->total_bytes_left -= n;
356 host->data->bytes_xfered += n;
357
358 if (write) {
359 __raw_writesw(host->base + OMAP_MMC_REG_DATA, host->buffer, n);
360 } else {
361 __raw_readsw(host->base + OMAP_MMC_REG_DATA, host->buffer, n);
362 }
363}
364
365static inline void mmc_omap_report_irq(u16 status)
366{
367 static const char *mmc_omap_status_bits[] = {
368 "EOC", "CD", "CB", "BRS", "EOFB", "DTO", "DCRC", "CTO",
369 "CCRC", "CRW", "AF", "AE", "OCRB", "CIRQ", "CERR"
370 };
371 int i, c = 0;
372
373 for (i = 0; i < ARRAY_SIZE(mmc_omap_status_bits); i++)
374 if (status & (1 << i)) {
375 if (c)
376 printk(" ");
377 printk("%s", mmc_omap_status_bits[i]);
378 c++;
379 }
380}
381
382static irqreturn_t mmc_omap_irq(int irq, void *dev_id, struct pt_regs *regs)
383{
384 struct mmc_omap_host * host = (struct mmc_omap_host *)dev_id;
385 u16 status;
386 int end_command;
387 int end_transfer;
388 int transfer_error;
389
390 if (host->cmd == NULL && host->data == NULL) {
391 status = OMAP_MMC_READ(host->base, STAT);
392 dev_info(mmc_dev(host->mmc),"spurious irq 0x%04x\n", status);
393 if (status != 0) {
394 OMAP_MMC_WRITE(host->base, STAT, status);
395 OMAP_MMC_WRITE(host->base, IE, 0);
396 }
397 return IRQ_HANDLED;
398 }
399
400 end_command = 0;
401 end_transfer = 0;
402 transfer_error = 0;
403
404 while ((status = OMAP_MMC_READ(host->base, STAT)) != 0) {
405 OMAP_MMC_WRITE(host->base, STAT, status);
406#ifdef CONFIG_MMC_DEBUG
407 dev_dbg(mmc_dev(host->mmc), "MMC IRQ %04x (CMD %d): ",
408 status, host->cmd != NULL ? host->cmd->opcode : -1);
409 mmc_omap_report_irq(status);
410 printk("\n");
411#endif
412 if (host->total_bytes_left) {
413 if ((status & OMAP_MMC_STAT_A_FULL) ||
414 (status & OMAP_MMC_STAT_END_OF_DATA))
415 mmc_omap_xfer_data(host, 0);
416 if (status & OMAP_MMC_STAT_A_EMPTY)
417 mmc_omap_xfer_data(host, 1);
418 }
419
420 if (status & OMAP_MMC_STAT_END_OF_DATA) {
421 end_transfer = 1;
422 }
423
424 if (status & OMAP_MMC_STAT_DATA_TOUT) {
425 dev_dbg(mmc_dev(host->mmc), "data timeout\n");
426 if (host->data) {
427 host->data->error |= MMC_ERR_TIMEOUT;
428 transfer_error = 1;
429 }
430 }
431
432 if (status & OMAP_MMC_STAT_DATA_CRC) {
433 if (host->data) {
434 host->data->error |= MMC_ERR_BADCRC;
435 dev_dbg(mmc_dev(host->mmc),
436 "data CRC error, bytes left %d\n",
437 host->total_bytes_left);
438 transfer_error = 1;
439 } else {
440 dev_dbg(mmc_dev(host->mmc), "data CRC error\n");
441 }
442 }
443
444 if (status & OMAP_MMC_STAT_CMD_TOUT) {
445 /* Timeouts are routine with some commands */
446 if (host->cmd) {
447 if (host->cmd->opcode != MMC_ALL_SEND_CID &&
448 host->cmd->opcode !=
449 MMC_SEND_OP_COND &&
450 host->cmd->opcode !=
451 MMC_APP_CMD &&
452 !mmc_omap_cover_is_open(host))
453 dev_err(mmc_dev(host->mmc),
454 "command timeout, CMD %d\n",
455 host->cmd->opcode);
456 host->cmd->error = MMC_ERR_TIMEOUT;
457 end_command = 1;
458 }
459 }
460
461 if (status & OMAP_MMC_STAT_CMD_CRC) {
462 if (host->cmd) {
463 dev_err(mmc_dev(host->mmc),
464 "command CRC error (CMD%d, arg 0x%08x)\n",
465 host->cmd->opcode, host->cmd->arg);
466 host->cmd->error = MMC_ERR_BADCRC;
467 end_command = 1;
468 } else
469 dev_err(mmc_dev(host->mmc),
470 "command CRC error without cmd?\n");
471 }
472
473 if (status & OMAP_MMC_STAT_CARD_ERR) {
474 if (host->cmd && host->cmd->opcode == MMC_STOP_TRANSMISSION) {
475 u32 response = OMAP_MMC_READ(host->base, RSP6)
476 | (OMAP_MMC_READ(host->base, RSP7) << 16);
477 /* STOP sometimes sets must-ignore bits */
478 if (!(response & (R1_CC_ERROR
479 | R1_ILLEGAL_COMMAND
480 | R1_COM_CRC_ERROR))) {
481 end_command = 1;
482 continue;
483 }
484 }
485
486 dev_dbg(mmc_dev(host->mmc), "card status error (CMD%d)\n",
487 host->cmd->opcode);
488 if (host->cmd) {
489 host->cmd->error = MMC_ERR_FAILED;
490 end_command = 1;
491 }
492 if (host->data) {
493 host->data->error = MMC_ERR_FAILED;
494 transfer_error = 1;
495 }
496 }
497
498 /*
499 * NOTE: On 1610 the END_OF_CMD may come too early when
500 * starting a write
501 */
502 if ((status & OMAP_MMC_STAT_END_OF_CMD) &&
503 (!(status & OMAP_MMC_STAT_A_EMPTY))) {
504 end_command = 1;
505 }
506 }
507
508 if (end_command) {
509 mmc_omap_cmd_done(host, host->cmd);
510 }
511 if (transfer_error)
512 mmc_omap_xfer_done(host, host->data);
513 else if (end_transfer)
514 mmc_omap_end_of_data(host, host->data);
515
516 return IRQ_HANDLED;
517}
518
519static irqreturn_t mmc_omap_switch_irq(int irq, void *dev_id, struct pt_regs *regs)
520{
521 struct mmc_omap_host *host = (struct mmc_omap_host *) dev_id;
522
523 schedule_work(&host->switch_work);
524
525 return IRQ_HANDLED;
526}
527
528static void mmc_omap_switch_timer(unsigned long arg)
529{
530 struct mmc_omap_host *host = (struct mmc_omap_host *) arg;
531
532 schedule_work(&host->switch_work);
533}
534
535/* FIXME: Handle card insertion and removal properly. Maybe use a mask
536 * for MMC state? */
537static void mmc_omap_switch_callback(unsigned long data, u8 mmc_mask)
538{
539}
540
541static void mmc_omap_switch_handler(void *data)
542{
543 struct mmc_omap_host *host = (struct mmc_omap_host *) data;
544 struct mmc_card *card;
545 static int complained = 0;
546 int cards = 0, cover_open;
547
548 if (host->switch_pin == -1)
549 return;
550 cover_open = mmc_omap_cover_is_open(host);
551 if (cover_open != host->switch_last_state) {
552 kobject_uevent(&host->dev->kobj, KOBJ_CHANGE);
553 host->switch_last_state = cover_open;
554 }
555 mmc_detect_change(host->mmc, 0);
556 list_for_each_entry(card, &host->mmc->cards, node) {
557 if (mmc_card_present(card))
558 cards++;
559 }
560 if (mmc_omap_cover_is_open(host)) {
561 if (!complained) {
562 dev_info(mmc_dev(host->mmc), "cover is open");
563 complained = 1;
564 }
565 if (mmc_omap_enable_poll)
566 mod_timer(&host->switch_timer, jiffies +
567 msecs_to_jiffies(OMAP_MMC_SWITCH_POLL_DELAY));
568 } else {
569 complained = 0;
570 }
571}
572
573/* Prepare to transfer the next segment of a scatterlist */
574static void
575mmc_omap_prepare_dma(struct mmc_omap_host *host, struct mmc_data *data)
576{
577 int dma_ch = host->dma_ch;
578 unsigned long data_addr;
579 u16 buf, frame;
580 u32 count;
581 struct scatterlist *sg = &data->sg[host->sg_idx];
582 int src_port = 0;
583 int dst_port = 0;
584 int sync_dev = 0;
585
586 data_addr = io_v2p((u32) host->base) + OMAP_MMC_REG_DATA;
587 frame = 1 << data->blksz_bits;
588 count = sg_dma_len(sg);
589
590 if ((data->blocks == 1) && (count > (1 << data->blksz_bits)))
591 count = frame;
592
593 host->dma_len = count;
594
595 /* FIFO is 16x2 bytes on 15xx, and 32x2 bytes on 16xx and 24xx.
596 * Use 16 or 32 word frames when the blocksize is at least that large.
597 * Blocksize is usually 512 bytes; but not for some SD reads.
598 */
599 if (cpu_is_omap15xx() && frame > 32)
600 frame = 32;
601 else if (frame > 64)
602 frame = 64;
603 count /= frame;
604 frame >>= 1;
605
606 if (!(data->flags & MMC_DATA_WRITE)) {
607 buf = 0x800f | ((frame - 1) << 8);
608
609 if (cpu_class_is_omap1()) {
610 src_port = OMAP_DMA_PORT_TIPB;
611 dst_port = OMAP_DMA_PORT_EMIFF;
612 }
613 if (cpu_is_omap24xx())
614 sync_dev = OMAP24XX_DMA_MMC1_RX;
615
616 omap_set_dma_src_params(dma_ch, src_port,
617 OMAP_DMA_AMODE_CONSTANT,
618 data_addr, 0, 0);
619 omap_set_dma_dest_params(dma_ch, dst_port,
620 OMAP_DMA_AMODE_POST_INC,
621 sg_dma_address(sg), 0, 0);
622 omap_set_dma_dest_data_pack(dma_ch, 1);
623 omap_set_dma_dest_burst_mode(dma_ch, OMAP_DMA_DATA_BURST_4);
624 } else {
625 buf = 0x0f80 | ((frame - 1) << 0);
626
627 if (cpu_class_is_omap1()) {
628 src_port = OMAP_DMA_PORT_EMIFF;
629 dst_port = OMAP_DMA_PORT_TIPB;
630 }
631 if (cpu_is_omap24xx())
632 sync_dev = OMAP24XX_DMA_MMC1_TX;
633
634 omap_set_dma_dest_params(dma_ch, dst_port,
635 OMAP_DMA_AMODE_CONSTANT,
636 data_addr, 0, 0);
637 omap_set_dma_src_params(dma_ch, src_port,
638 OMAP_DMA_AMODE_POST_INC,
639 sg_dma_address(sg), 0, 0);
640 omap_set_dma_src_data_pack(dma_ch, 1);
641 omap_set_dma_src_burst_mode(dma_ch, OMAP_DMA_DATA_BURST_4);
642 }
643
644 /* Max limit for DMA frame count is 0xffff */
645 if (unlikely(count > 0xffff))
646 BUG();
647
648 OMAP_MMC_WRITE(host->base, BUF, buf);
649 omap_set_dma_transfer_params(dma_ch, OMAP_DMA_DATA_TYPE_S16,
650 frame, count, OMAP_DMA_SYNC_FRAME,
651 sync_dev, 0);
652}
653
654/* A scatterlist segment completed */
655static void mmc_omap_dma_cb(int lch, u16 ch_status, void *data)
656{
657 struct mmc_omap_host *host = (struct mmc_omap_host *) data;
658 struct mmc_data *mmcdat = host->data;
659
660 if (unlikely(host->dma_ch < 0)) {
661 dev_err(mmc_dev(host->mmc), "DMA callback while DMA not
662 enabled\n");
663 return;
664 }
665 /* FIXME: We really should do something to _handle_ the errors */
666 if (ch_status & OMAP_DMA_TOUT_IRQ) {
667 dev_err(mmc_dev(host->mmc),"DMA timeout\n");
668 return;
669 }
670 if (ch_status & OMAP_DMA_DROP_IRQ) {
671 dev_err(mmc_dev(host->mmc), "DMA sync error\n");
672 return;
673 }
674 if (!(ch_status & OMAP_DMA_BLOCK_IRQ)) {
675 return;
676 }
677 mmcdat->bytes_xfered += host->dma_len;
678 host->sg_idx++;
679 if (host->sg_idx < host->sg_len) {
680 mmc_omap_prepare_dma(host, host->data);
681 omap_start_dma(host->dma_ch);
682 } else
683 mmc_omap_dma_done(host, host->data);
684}
685
686static int mmc_omap_get_dma_channel(struct mmc_omap_host *host, struct mmc_data *data)
687{
688 const char *dev_name;
689 int sync_dev, dma_ch, is_read, r;
690
691 is_read = !(data->flags & MMC_DATA_WRITE);
692 del_timer_sync(&host->dma_timer);
693 if (host->dma_ch >= 0) {
694 if (is_read == host->dma_is_read)
695 return 0;
696 omap_free_dma(host->dma_ch);
697 host->dma_ch = -1;
698 }
699
700 if (is_read) {
701 if (host->id == 1) {
702 sync_dev = OMAP_DMA_MMC_RX;
703 dev_name = "MMC1 read";
704 } else {
705 sync_dev = OMAP_DMA_MMC2_RX;
706 dev_name = "MMC2 read";
707 }
708 } else {
709 if (host->id == 1) {
710 sync_dev = OMAP_DMA_MMC_TX;
711 dev_name = "MMC1 write";
712 } else {
713 sync_dev = OMAP_DMA_MMC2_TX;
714 dev_name = "MMC2 write";
715 }
716 }
717 r = omap_request_dma(sync_dev, dev_name, mmc_omap_dma_cb,
718 host, &dma_ch);
719 if (r != 0) {
720 dev_dbg(mmc_dev(host->mmc), "omap_request_dma() failed with %d\n", r);
721 return r;
722 }
723 host->dma_ch = dma_ch;
724 host->dma_is_read = is_read;
725
726 return 0;
727}
728
729static inline void set_cmd_timeout(struct mmc_omap_host *host, struct mmc_request *req)
730{
731 u16 reg;
732
733 reg = OMAP_MMC_READ(host->base, SDIO);
734 reg &= ~(1 << 5);
735 OMAP_MMC_WRITE(host->base, SDIO, reg);
736 /* Set maximum timeout */
737 OMAP_MMC_WRITE(host->base, CTO, 0xff);
738}
739
740static inline void set_data_timeout(struct mmc_omap_host *host, struct mmc_request *req)
741{
742 int timeout;
743 u16 reg;
744
745 /* Convert ns to clock cycles by assuming 20MHz frequency
746 * 1 cycle at 20MHz = 500 ns
747 */
748 timeout = req->data->timeout_clks + req->data->timeout_ns / 500;
749
750 /* Check if we need to use timeout multiplier register */
751 reg = OMAP_MMC_READ(host->base, SDIO);
752 if (timeout > 0xffff) {
753 reg |= (1 << 5);
754 timeout /= 1024;
755 } else
756 reg &= ~(1 << 5);
757 OMAP_MMC_WRITE(host->base, SDIO, reg);
758 OMAP_MMC_WRITE(host->base, DTO, timeout);
759}
760
761static void
762mmc_omap_prepare_data(struct mmc_omap_host *host, struct mmc_request *req)
763{
764 struct mmc_data *data = req->data;
765 int i, use_dma, block_size;
766 unsigned sg_len;
767
768 host->data = data;
769 if (data == NULL) {
770 OMAP_MMC_WRITE(host->base, BLEN, 0);
771 OMAP_MMC_WRITE(host->base, NBLK, 0);
772 OMAP_MMC_WRITE(host->base, BUF, 0);
773 host->dma_in_use = 0;
774 set_cmd_timeout(host, req);
775 return;
776 }
777
778
779 block_size = 1 << data->blksz_bits;
780
781 OMAP_MMC_WRITE(host->base, NBLK, data->blocks - 1);
782 OMAP_MMC_WRITE(host->base, BLEN, block_size - 1);
783 set_data_timeout(host, req);
784
785 /* cope with calling layer confusion; it issues "single
786 * block" writes using multi-block scatterlists.
787 */
788 sg_len = (data->blocks == 1) ? 1 : data->sg_len;
789
790 /* Only do DMA for entire blocks */
791 use_dma = host->use_dma;
792 if (use_dma) {
793 for (i = 0; i < sg_len; i++) {
794 if ((data->sg[i].length % block_size) != 0) {
795 use_dma = 0;
796 break;
797 }
798 }
799 }
800
801 host->sg_idx = 0;
802 if (use_dma) {
803 if (mmc_omap_get_dma_channel(host, data) == 0) {
804 enum dma_data_direction dma_data_dir;
805
806 if (data->flags & MMC_DATA_WRITE)
807 dma_data_dir = DMA_TO_DEVICE;
808 else
809 dma_data_dir = DMA_FROM_DEVICE;
810
811 host->sg_len = dma_map_sg(mmc_dev(host->mmc), data->sg,
812 sg_len, dma_data_dir);
813 host->total_bytes_left = 0;
814 mmc_omap_prepare_dma(host, req->data);
815 host->brs_received = 0;
816 host->dma_done = 0;
817 host->dma_in_use = 1;
818 } else
819 use_dma = 0;
820 }
821
822 /* Revert to PIO? */
823 if (!use_dma) {
824 OMAP_MMC_WRITE(host->base, BUF, 0x1f1f);
825 host->total_bytes_left = data->blocks * block_size;
826 host->sg_len = sg_len;
827 mmc_omap_sg_to_buf(host);
828 host->dma_in_use = 0;
829 }
830}
831
832static void mmc_omap_request(struct mmc_host *mmc, struct mmc_request *req)
833{
834 struct mmc_omap_host *host = mmc_priv(mmc);
835
836 WARN_ON(host->mrq != NULL);
837
838 host->mrq = req;
839
840 /* only touch fifo AFTER the controller readies it */
841 mmc_omap_prepare_data(host, req);
842 mmc_omap_start_command(host, req->cmd);
843 if (host->dma_in_use)
844 omap_start_dma(host->dma_ch);
845}
846
847static void innovator_fpga_socket_power(int on)
848{
849#if defined(CONFIG_MACH_OMAP_INNOVATOR) && defined(CONFIG_ARCH_OMAP15XX)
850
851 if (on) {
852 fpga_write(fpga_read(OMAP1510_FPGA_POWER) | (1 << 3),
853 OMAP1510_FPGA_POWER);
854 } else {
855 fpga_write(fpga_read(OMAP1510_FPGA_POWER) & ~(1 << 3),
856 OMAP1510_FPGA_POWER);
857 }
858#endif
859}
860
861/*
862 * Turn the socket power on/off. Innovator uses FPGA, most boards
863 * probably use GPIO.
864 */
865static void mmc_omap_power(struct mmc_omap_host *host, int on)
866{
867 if (on) {
868 if (machine_is_omap_innovator())
869 innovator_fpga_socket_power(1);
870 else if (machine_is_omap_h2())
871 tps65010_set_gpio_out_value(GPIO3, HIGH);
872 else if (machine_is_omap_h3())
873 /* GPIO 4 of TPS65010 sends SD_EN signal */
874 tps65010_set_gpio_out_value(GPIO4, HIGH);
875 else if (cpu_is_omap24xx()) {
876 u16 reg = OMAP_MMC_READ(host->base, CON);
877 OMAP_MMC_WRITE(host->base, CON, reg | (1 << 11));
878 } else
879 if (host->power_pin >= 0)
880 omap_set_gpio_dataout(host->power_pin, 1);
881 } else {
882 if (machine_is_omap_innovator())
883 innovator_fpga_socket_power(0);
884 else if (machine_is_omap_h2())
885 tps65010_set_gpio_out_value(GPIO3, LOW);
886 else if (machine_is_omap_h3())
887 tps65010_set_gpio_out_value(GPIO4, LOW);
888 else if (cpu_is_omap24xx()) {
889 u16 reg = OMAP_MMC_READ(host->base, CON);
890 OMAP_MMC_WRITE(host->base, CON, reg & ~(1 << 11));
891 } else
892 if (host->power_pin >= 0)
893 omap_set_gpio_dataout(host->power_pin, 0);
894 }
895}
896
897static void mmc_omap_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
898{
899 struct mmc_omap_host *host = mmc_priv(mmc);
900 int dsor;
901 int realclock, i;
902
903 realclock = ios->clock;
904
905 if (ios->clock == 0)
906 dsor = 0;
907 else {
908 int func_clk_rate = clk_get_rate(host->fclk);
909
910 dsor = func_clk_rate / realclock;
911 if (dsor < 1)
912 dsor = 1;
913
914 if (func_clk_rate / dsor > realclock)
915 dsor++;
916
917 if (dsor > 250)
918 dsor = 250;
919 dsor++;
920
921 if (ios->bus_width == MMC_BUS_WIDTH_4)
922 dsor |= 1 << 15;
923 }
924
925 switch (ios->power_mode) {
926 case MMC_POWER_OFF:
927 mmc_omap_power(host, 0);
928 break;
929 case MMC_POWER_UP:
930 case MMC_POWER_ON:
931 mmc_omap_power(host, 1);
932 dsor |= 1<<11;
933 break;
934 }
935
936 host->bus_mode = ios->bus_mode;
937 host->hw_bus_mode = host->bus_mode;
938
939 clk_enable(host->fclk);
940
941 /* On insanely high arm_per frequencies something sometimes
942 * goes somehow out of sync, and the POW bit is not being set,
943 * which results in the while loop below getting stuck.
944 * Writing to the CON register twice seems to do the trick. */
945 for (i = 0; i < 2; i++)
946 OMAP_MMC_WRITE(host->base, CON, dsor);
947 if (ios->power_mode == MMC_POWER_UP) {
948 /* Send clock cycles, poll completion */
949 OMAP_MMC_WRITE(host->base, IE, 0);
950 OMAP_MMC_WRITE(host->base, STAT, 0xffff);
951 OMAP_MMC_WRITE(host->base, CMD, 1<<7);
952 while (0 == (OMAP_MMC_READ(host->base, STAT) & 1));
953 OMAP_MMC_WRITE(host->base, STAT, 1);
954 }
955 clk_disable(host->fclk);
956}
957
958static int mmc_omap_get_ro(struct mmc_host *mmc)
959{
960 struct mmc_omap_host *host = mmc_priv(mmc);
961
962 return host->wp_pin && omap_get_gpio_datain(host->wp_pin);
963}
964
965static struct mmc_host_ops mmc_omap_ops = {
966 .request = mmc_omap_request,
967 .set_ios = mmc_omap_set_ios,
968 .get_ro = mmc_omap_get_ro,
969};
970
971static int __init mmc_omap_probe(struct platform_device *pdev)
972{
973 struct omap_mmc_conf *minfo = pdev->dev.platform_data;
974 struct mmc_host *mmc;
975 struct mmc_omap_host *host = NULL;
976 int ret = 0;
977
978 if (platform_get_resource(pdev, IORESOURCE_MEM, 0) ||
979 platform_get_irq(pdev, IORESOURCE_IRQ, 0)) {
980 dev_err(&pdev->dev, "mmc_omap_probe: invalid resource type\n");
981 return -ENODEV;
982 }
983
984 if (!request_mem_region(pdev->resource[0].start,
985 pdev->resource[0].end - pdev->resource[0].start + 1,
986 pdev->name)) {
987 dev_dbg(&pdev->dev, "request_mem_region failed\n");
988 return -EBUSY;
989 }
990
991 mmc = mmc_alloc_host(sizeof(struct mmc_omap_host), &pdev->dev);
992 if (!mmc) {
993 ret = -ENOMEM;
994 goto out;
995 }
996
997 host = mmc_priv(mmc);
998 host->mmc = mmc;
999
1000 spin_lock_init(&host->dma_lock);
1001 init_timer(&host->dma_timer);
1002 host->dma_timer.function = mmc_omap_dma_timer;
1003 host->dma_timer.data = (unsigned long) host;
1004
1005 host->id = pdev->id;
1006
1007 if (cpu_is_omap24xx()) {
1008 host->iclk = clk_get(&pdev->dev, "mmc_ick");
1009 if (IS_ERR(host->iclk))
1010 goto out;
1011 clk_enable(host->iclk);
1012 }
1013
1014 if (!cpu_is_omap24xx())
1015 host->fclk = clk_get(&pdev->dev, "mmc_ck");
1016 else
1017 host->fclk = clk_get(&pdev->dev, "mmc_fck");
1018
1019 if (IS_ERR(host->fclk)) {
1020 ret = PTR_ERR(host->fclk);
1021 goto out;
1022 }
1023
1024 /* REVISIT:
1025 * Also, use minfo->cover to decide how to manage
1026 * the card detect sensing.
1027 */
1028 host->power_pin = minfo->power_pin;
1029 host->switch_pin = minfo->switch_pin;
1030 host->wp_pin = minfo->wp_pin;
1031 host->use_dma = 1;
1032 host->dma_ch = -1;
1033
1034 host->irq = pdev->resource[1].start;
1035 host->base = ioremap(pdev->res.start, SZ_4K);
1036 if (!host->base) {
1037 ret = -ENOMEM;
1038 goto out;
1039 }
1040
1041 if (minfo->wire4)
1042 mmc->caps |= MMC_CAP_4_BIT_DATA;
1043
1044 mmc->ops = &mmc_omap_ops;
1045 mmc->f_min = 400000;
1046 mmc->f_max = 24000000;
1047 mmc->ocr_avail = MMC_VDD_32_33|MMC_VDD_33_34;
1048
1049 /* Use scatterlist DMA to reduce per-transfer costs.
1050 * NOTE max_seg_size assumption that small blocks aren't
1051 * normally used (except e.g. for reading SD registers).
1052 */
1053 mmc->max_phys_segs = 32;
1054 mmc->max_hw_segs = 32;
1055 mmc->max_sectors = 256; /* NBLK max 11-bits, OMAP also limited by DMA */
1056 mmc->max_seg_size = mmc->max_sectors * 512;
1057
1058 if (host->power_pin >= 0) {
1059 if ((ret = omap_request_gpio(host->power_pin)) != 0) {
1060 dev_err(mmc_dev(host->mmc), "Unable to get GPIO
1061 pin for MMC power\n");
1062 goto out;
1063 }
1064 omap_set_gpio_direction(host->power_pin, 0);
1065 }
1066
1067 ret = request_irq(host->irq, mmc_omap_irq, 0, DRIVER_NAME, host);
1068 if (ret)
1069 goto out;
1070
1071 host->dev = &pdev->dev;
1072 platform_set_drvdata(pdev, host);
1073
1074 mmc_add_host(mmc);
1075
1076 if (host->switch_pin >= 0) {
1077 INIT_WORK(&host->switch_work, mmc_omap_switch_handler, host);
1078 init_timer(&host->switch_timer);
1079 host->switch_timer.function = mmc_omap_switch_timer;
1080 host->switch_timer.data = (unsigned long) host;
1081 if (omap_request_gpio(host->switch_pin) != 0) {
1082 dev_warn(mmc_dev(host->mmc), "Unable to get GPIO pin for MMC cover switch\n");
1083 host->switch_pin = -1;
1084 goto no_switch;
1085 }
1086
1087 omap_set_gpio_direction(host->switch_pin, 1);
1088 ret = request_irq(OMAP_GPIO_IRQ(host->switch_pin),
1089 mmc_omap_switch_irq, SA_TRIGGER_RISING, DRIVER_NAME, host);
1090 if (ret) {
1091 dev_warn(mmc_dev(host->mmc), "Unable to get IRQ for MMC cover switch\n");
1092 omap_free_gpio(host->switch_pin);
1093 host->switch_pin = -1;
1094 goto no_switch;
1095 }
1096 ret = device_create_file(&pdev->dev, &dev_attr_cover_switch);
1097 if (ret == 0) {
1098 ret = device_create_file(&pdev->dev, &dev_attr_enable_poll);
1099 if (ret != 0)
1100 device_remove_file(&pdev->dev, &dev_attr_cover_switch);
1101 }
1102 if (ret) {
1103 dev_wan(mmc_dev(host->mmc), "Unable to create sysfs attributes\n");
1104 free_irq(OMAP_GPIO_IRQ(host->switch_pin), host);
1105 omap_free_gpio(host->switch_pin);
1106 host->switch_pin = -1;
1107 goto no_switch;
1108 }
1109 if (mmc_omap_enable_poll && mmc_omap_cover_is_open(host))
1110 schedule_work(&host->switch_work);
1111 }
1112
1113no_switch:
1114 return 0;
1115
1116out:
1117 /* FIXME: Free other resources too. */
1118 if (host) {
1119 if (host->iclk && !IS_ERR(host->iclk))
1120 clk_put(host->iclk);
1121 if (host->fclk && !IS_ERR(host->fclk))
1122 clk_put(host->fclk);
1123 mmc_free_host(host->mmc);
1124 }
1125 return ret;
1126}
1127
1128static int mmc_omap_remove(struct platform_device *pdev)
1129{
1130 struct mmc_omap_host *host = platform_get_drvdata(pdev);
1131
1132 platform_set_drvdata(pdev, NULL);
1133
1134 if (host) {
1135 mmc_remove_host(host->mmc);
1136 free_irq(host->irq, host);
1137
1138 if (host->power_pin >= 0)
1139 omap_free_gpio(host->power_pin);
1140 if (host->switch_pin >= 0) {
1141 device_remove_file(&pdev->dev, &dev_attr_enable_poll);
1142 device_remove_file(&pdev->dev, &dev_attr_cover_switch);
1143 free_irq(OMAP_GPIO_IRQ(host->switch_pin), host);
1144 omap_free_gpio(host->switch_pin);
1145 host->switch_pin = -1;
1146 del_timer_sync(&host->switch_timer);
1147 flush_scheduled_work();
1148 }
1149 if (host->iclk && !IS_ERR(host->iclk))
1150 clk_put(host->iclk);
1151 if (host->fclk && !IS_ERR(host->fclk))
1152 clk_put(host->fclk);
1153 mmc_free_host(host->mmc);
1154 }
1155
1156 release_mem_region(pdev->resource[0].start,
1157 pdev->resource[0].end - pdev->resource[0].start + 1);
1158
1159 return 0;
1160}
1161
1162#ifdef CONFIG_PM
1163static int mmc_omap_suspend(struct platform_device *pdev, pm_message_t mesg)
1164{
1165 int ret = 0;
1166 struct mmc_omap_host *host = platform_get_drvdata(pdev);
1167
1168 if (host && host->suspended)
1169 return 0;
1170
1171 if (host) {
1172 ret = mmc_suspend_host(host->mmc, mesg);
1173 if (ret == 0)
1174 host->suspended = 1;
1175 }
1176 return ret;
1177}
1178
1179static int mmc_omap_resume(struct platform_device *pdev)
1180{
1181 int ret = 0;
1182 struct mmc_omap_host *host = platform_get_drvdata(pdev);
1183
1184 if (host && !host->suspended)
1185 return 0;
1186
1187 if (host) {
1188 ret = mmc_resume_host(host->mmc);
1189 if (ret == 0)
1190 host->suspended = 0;
1191 }
1192
1193 return ret;
1194}
1195#else
1196#define mmc_omap_suspend NULL
1197#define mmc_omap_resume NULL
1198#endif
1199
1200static struct platform_driver mmc_omap_driver = {
1201 .probe = mmc_omap_probe,
1202 .remove = mmc_omap_remove,
1203 .suspend = mmc_omap_suspend,
1204 .resume = mmc_omap_resume,
1205 .driver = {
1206 .name = DRIVER_NAME,
1207 },
1208};
1209
1210static int __init mmc_omap_init(void)
1211{
1212 return platform_driver_register(&mmc_omap_driver);
1213}
1214
1215static void __exit mmc_omap_exit(void)
1216{
1217 platform_driver_unregister(&mmc_omap_driver);
1218}
1219
1220module_init(mmc_omap_init);
1221module_exit(mmc_omap_exit);
1222
1223MODULE_DESCRIPTION("OMAP Multimedia Card driver");
1224MODULE_LICENSE("GPL");
1225MODULE_ALIAS(DRIVER_NAME);
1226MODULE_AUTHOR("Juha Yrjölä");
diff --git a/drivers/mmc/omap.h b/drivers/mmc/omap.h
new file mode 100644
index 000000000000..c954d355a5e3
--- /dev/null
+++ b/drivers/mmc/omap.h
@@ -0,0 +1,55 @@
1#ifndef DRIVERS_MEDIA_MMC_OMAP_H
2#define DRIVERS_MEDIA_MMC_OMAP_H
3
4#define OMAP_MMC_REG_CMD 0x00
5#define OMAP_MMC_REG_ARGL 0x04
6#define OMAP_MMC_REG_ARGH 0x08
7#define OMAP_MMC_REG_CON 0x0c
8#define OMAP_MMC_REG_STAT 0x10
9#define OMAP_MMC_REG_IE 0x14
10#define OMAP_MMC_REG_CTO 0x18
11#define OMAP_MMC_REG_DTO 0x1c
12#define OMAP_MMC_REG_DATA 0x20
13#define OMAP_MMC_REG_BLEN 0x24
14#define OMAP_MMC_REG_NBLK 0x28
15#define OMAP_MMC_REG_BUF 0x2c
16#define OMAP_MMC_REG_SDIO 0x34
17#define OMAP_MMC_REG_REV 0x3c
18#define OMAP_MMC_REG_RSP0 0x40
19#define OMAP_MMC_REG_RSP1 0x44
20#define OMAP_MMC_REG_RSP2 0x48
21#define OMAP_MMC_REG_RSP3 0x4c
22#define OMAP_MMC_REG_RSP4 0x50
23#define OMAP_MMC_REG_RSP5 0x54
24#define OMAP_MMC_REG_RSP6 0x58
25#define OMAP_MMC_REG_RSP7 0x5c
26#define OMAP_MMC_REG_IOSR 0x60
27#define OMAP_MMC_REG_SYSC 0x64
28#define OMAP_MMC_REG_SYSS 0x68
29
30#define OMAP_MMC_STAT_CARD_ERR (1 << 14)
31#define OMAP_MMC_STAT_CARD_IRQ (1 << 13)
32#define OMAP_MMC_STAT_OCR_BUSY (1 << 12)
33#define OMAP_MMC_STAT_A_EMPTY (1 << 11)
34#define OMAP_MMC_STAT_A_FULL (1 << 10)
35#define OMAP_MMC_STAT_CMD_CRC (1 << 8)
36#define OMAP_MMC_STAT_CMD_TOUT (1 << 7)
37#define OMAP_MMC_STAT_DATA_CRC (1 << 6)
38#define OMAP_MMC_STAT_DATA_TOUT (1 << 5)
39#define OMAP_MMC_STAT_END_BUSY (1 << 4)
40#define OMAP_MMC_STAT_END_OF_DATA (1 << 3)
41#define OMAP_MMC_STAT_CARD_BUSY (1 << 2)
42#define OMAP_MMC_STAT_END_OF_CMD (1 << 0)
43
44#define OMAP_MMC_READ(base, reg) __raw_readw((base) + OMAP_MMC_REG_##reg)
45#define OMAP_MMC_WRITE(base, reg, val) __raw_writew((val), (base) + OMAP_MMC_REG_##reg)
46
47/*
48 * Command types
49 */
50#define OMAP_MMC_CMDTYPE_BC 0
51#define OMAP_MMC_CMDTYPE_BCR 1
52#define OMAP_MMC_CMDTYPE_AC 2
53#define OMAP_MMC_CMDTYPE_ADTC 3
54
55#endif
diff --git a/drivers/mmc/pxamci.c b/drivers/mmc/pxamci.c
index c32fad1ce51c..eb9a8826e9b5 100644
--- a/drivers/mmc/pxamci.c
+++ b/drivers/mmc/pxamci.c
@@ -37,12 +37,6 @@
37 37
38#include "pxamci.h" 38#include "pxamci.h"
39 39
40#ifdef CONFIG_MMC_DEBUG
41#define DBG(x...) printk(KERN_DEBUG x)
42#else
43#define DBG(x...) do { } while (0)
44#endif
45
46#define DRIVER_NAME "pxa2xx-mci" 40#define DRIVER_NAME "pxa2xx-mci"
47 41
48#define NR_SG 1 42#define NR_SG 1
@@ -206,7 +200,7 @@ static void pxamci_start_cmd(struct pxamci_host *host, struct mmc_command *cmd,
206 200
207static void pxamci_finish_request(struct pxamci_host *host, struct mmc_request *mrq) 201static void pxamci_finish_request(struct pxamci_host *host, struct mmc_request *mrq)
208{ 202{
209 DBG("PXAMCI: request done\n"); 203 pr_debug("PXAMCI: request done\n");
210 host->mrq = NULL; 204 host->mrq = NULL;
211 host->cmd = NULL; 205 host->cmd = NULL;
212 host->data = NULL; 206 host->data = NULL;
@@ -252,7 +246,7 @@ static int pxamci_cmd_done(struct pxamci_host *host, unsigned int stat)
252 if ((cmd->resp[0] & 0x80000000) == 0) 246 if ((cmd->resp[0] & 0x80000000) == 0)
253 cmd->error = MMC_ERR_BADCRC; 247 cmd->error = MMC_ERR_BADCRC;
254 } else { 248 } else {
255 DBG("ignoring CRC from command %d - *risky*\n",cmd->opcode); 249 pr_debug("ignoring CRC from command %d - *risky*\n",cmd->opcode);
256 } 250 }
257#else 251#else
258 cmd->error = MMC_ERR_BADCRC; 252 cmd->error = MMC_ERR_BADCRC;
@@ -317,12 +311,12 @@ static irqreturn_t pxamci_irq(int irq, void *devid, struct pt_regs *regs)
317 311
318 ireg = readl(host->base + MMC_I_REG); 312 ireg = readl(host->base + MMC_I_REG);
319 313
320 DBG("PXAMCI: irq %08x\n", ireg); 314 pr_debug("PXAMCI: irq %08x\n", ireg);
321 315
322 if (ireg) { 316 if (ireg) {
323 unsigned stat = readl(host->base + MMC_STAT); 317 unsigned stat = readl(host->base + MMC_STAT);
324 318
325 DBG("PXAMCI: stat %08x\n", stat); 319 pr_debug("PXAMCI: stat %08x\n", stat);
326 320
327 if (ireg & END_CMD_RES) 321 if (ireg & END_CMD_RES)
328 handled |= pxamci_cmd_done(host, stat); 322 handled |= pxamci_cmd_done(host, stat);
@@ -376,9 +370,9 @@ static void pxamci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
376{ 370{
377 struct pxamci_host *host = mmc_priv(mmc); 371 struct pxamci_host *host = mmc_priv(mmc);
378 372
379 DBG("pxamci_set_ios: clock %u power %u vdd %u.%02u\n", 373 pr_debug("pxamci_set_ios: clock %u power %u vdd %u.%02u\n",
380 ios->clock, ios->power_mode, ios->vdd / 100, 374 ios->clock, ios->power_mode, ios->vdd / 100,
381 ios->vdd % 100); 375 ios->vdd % 100);
382 376
383 if (ios->clock) { 377 if (ios->clock) {
384 unsigned int clk = CLOCKRATE / ios->clock; 378 unsigned int clk = CLOCKRATE / ios->clock;
@@ -405,8 +399,8 @@ static void pxamci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
405 host->cmdat |= CMDAT_INIT; 399 host->cmdat |= CMDAT_INIT;
406 } 400 }
407 401
408 DBG("pxamci_set_ios: clkrt = %x cmdat = %x\n", 402 pr_debug("pxamci_set_ios: clkrt = %x cmdat = %x\n",
409 host->clkrt, host->cmdat); 403 host->clkrt, host->cmdat);
410} 404}
411 405
412static struct mmc_host_ops pxamci_ops = { 406static struct mmc_host_ops pxamci_ops = {
diff --git a/drivers/mmc/sdhci.c b/drivers/mmc/sdhci.c
index 8b811d94371c..bdbfca050029 100644
--- a/drivers/mmc/sdhci.c
+++ b/drivers/mmc/sdhci.c
@@ -31,12 +31,8 @@
31 31
32#define BUGMAIL "<sdhci-devel@list.drzeus.cx>" 32#define BUGMAIL "<sdhci-devel@list.drzeus.cx>"
33 33
34#ifdef CONFIG_MMC_DEBUG
35#define DBG(f, x...) \ 34#define DBG(f, x...) \
36 printk(KERN_DEBUG DRIVER_NAME " [%s()]: " f, __func__,## x) 35 pr_debug(DRIVER_NAME " [%s()]: " f, __func__,## x)
37#else
38#define DBG(f, x...) do { } while (0)
39#endif
40 36
41static const struct pci_device_id pci_ids[] __devinitdata = { 37static const struct pci_device_id pci_ids[] __devinitdata = {
42 /* handle any SD host controller */ 38 /* handle any SD host controller */
diff --git a/drivers/mmc/wbsd.c b/drivers/mmc/wbsd.c
index 3be397d436fa..511f7b0b31d2 100644
--- a/drivers/mmc/wbsd.c
+++ b/drivers/mmc/wbsd.c
@@ -44,15 +44,10 @@
44#define DRIVER_NAME "wbsd" 44#define DRIVER_NAME "wbsd"
45#define DRIVER_VERSION "1.5" 45#define DRIVER_VERSION "1.5"
46 46
47#ifdef CONFIG_MMC_DEBUG
48#define DBG(x...) \ 47#define DBG(x...) \
49 printk(KERN_DEBUG DRIVER_NAME ": " x) 48 pr_debug(DRIVER_NAME ": " x)
50#define DBGF(f, x...) \ 49#define DBGF(f, x...) \
51 printk(KERN_DEBUG DRIVER_NAME " [%s()]: " f, __func__ , ##x) 50 pr_debug(DRIVER_NAME " [%s()]: " f, __func__ , ##x)
52#else
53#define DBG(x...) do { } while (0)
54#define DBGF(x...) do { } while (0)
55#endif
56 51
57/* 52/*
58 * Device resources 53 * Device resources
diff --git a/drivers/mtd/chips/amd_flash.c b/drivers/mtd/chips/amd_flash.c
index fdb91b6f1d97..57115618c496 100644
--- a/drivers/mtd/chips/amd_flash.c
+++ b/drivers/mtd/chips/amd_flash.c
@@ -664,7 +664,7 @@ static struct mtd_info *amd_flash_probe(struct map_info *map)
664 printk("%s: Probing for AMD compatible flash...\n", map->name); 664 printk("%s: Probing for AMD compatible flash...\n", map->name);
665 665
666 if ((table_pos[0] = probe_new_chip(mtd, 0, NULL, &temp, table, 666 if ((table_pos[0] = probe_new_chip(mtd, 0, NULL, &temp, table,
667 sizeof(table)/sizeof(table[0]))) 667 ARRAY_SIZE(table)))
668 == -1) { 668 == -1) {
669 printk(KERN_WARNING 669 printk(KERN_WARNING
670 "%s: Found no AMD compatible device at location zero\n", 670 "%s: Found no AMD compatible device at location zero\n",
@@ -696,7 +696,7 @@ static struct mtd_info *amd_flash_probe(struct map_info *map)
696 base += (1 << temp.chipshift)) { 696 base += (1 << temp.chipshift)) {
697 int numchips = temp.numchips; 697 int numchips = temp.numchips;
698 table_pos[numchips] = probe_new_chip(mtd, base, chips, 698 table_pos[numchips] = probe_new_chip(mtd, base, chips,
699 &temp, table, sizeof(table)/sizeof(table[0])); 699 &temp, table, ARRAY_SIZE(table));
700 } 700 }
701 701
702 mtd->eraseregions = kmalloc(sizeof(struct mtd_erase_region_info) * 702 mtd->eraseregions = kmalloc(sizeof(struct mtd_erase_region_info) *
diff --git a/drivers/mtd/chips/jedec_probe.c b/drivers/mtd/chips/jedec_probe.c
index edb306c03c0a..517ea33e7260 100644
--- a/drivers/mtd/chips/jedec_probe.c
+++ b/drivers/mtd/chips/jedec_probe.c
@@ -34,6 +34,7 @@
34#define MANUFACTURER_MACRONIX 0x00C2 34#define MANUFACTURER_MACRONIX 0x00C2
35#define MANUFACTURER_NEC 0x0010 35#define MANUFACTURER_NEC 0x0010
36#define MANUFACTURER_PMC 0x009D 36#define MANUFACTURER_PMC 0x009D
37#define MANUFACTURER_SHARP 0x00b0
37#define MANUFACTURER_SST 0x00BF 38#define MANUFACTURER_SST 0x00BF
38#define MANUFACTURER_ST 0x0020 39#define MANUFACTURER_ST 0x0020
39#define MANUFACTURER_TOSHIBA 0x0098 40#define MANUFACTURER_TOSHIBA 0x0098
@@ -124,6 +125,9 @@
124#define PM49FL004 0x006E 125#define PM49FL004 0x006E
125#define PM49FL008 0x006A 126#define PM49FL008 0x006A
126 127
128/* Sharp */
129#define LH28F640BF 0x00b0
130
127/* ST - www.st.com */ 131/* ST - www.st.com */
128#define M29W800DT 0x00D7 132#define M29W800DT 0x00D7
129#define M29W800DB 0x005B 133#define M29W800DB 0x005B
@@ -1267,6 +1271,19 @@ static const struct amd_flash_info jedec_table[] = {
1267 .regions = { 1271 .regions = {
1268 ERASEINFO( 0x01000, 256 ) 1272 ERASEINFO( 0x01000, 256 )
1269 } 1273 }
1274 }, {
1275 .mfr_id = MANUFACTURER_SHARP,
1276 .dev_id = LH28F640BF,
1277 .name = "LH28F640BF",
1278 .uaddr = {
1279 [0] = MTD_UADDR_UNNECESSARY, /* x8 */
1280 },
1281 .DevSize = SIZE_4MiB,
1282 .CmdSet = P_ID_INTEL_STD,
1283 .NumEraseRegions= 1,
1284 .regions = {
1285 ERASEINFO(0x40000,16),
1286 }
1270 }, { 1287 }, {
1271 .mfr_id = MANUFACTURER_SST, 1288 .mfr_id = MANUFACTURER_SST,
1272 .dev_id = SST39LF512, 1289 .dev_id = SST39LF512,
@@ -2035,7 +2052,7 @@ static int jedec_probe_chip(struct map_info *map, __u32 base,
2035 DEBUG(MTD_DEBUG_LEVEL3, 2052 DEBUG(MTD_DEBUG_LEVEL3,
2036 "Search for id:(%02x %02x) interleave(%d) type(%d)\n", 2053 "Search for id:(%02x %02x) interleave(%d) type(%d)\n",
2037 cfi->mfr, cfi->id, cfi_interleave(cfi), cfi->device_type); 2054 cfi->mfr, cfi->id, cfi_interleave(cfi), cfi->device_type);
2038 for (i=0; i<sizeof(jedec_table)/sizeof(jedec_table[0]); i++) { 2055 for (i = 0; i < ARRAY_SIZE(jedec_table); i++) {
2039 if ( jedec_match( base, map, cfi, &jedec_table[i] ) ) { 2056 if ( jedec_match( base, map, cfi, &jedec_table[i] ) ) {
2040 DEBUG( MTD_DEBUG_LEVEL3, 2057 DEBUG( MTD_DEBUG_LEVEL3,
2041 "MTD %s(): matched device 0x%x,0x%x unlock_addrs: 0x%.4x 0x%.4x\n", 2058 "MTD %s(): matched device 0x%x,0x%x unlock_addrs: 0x%.4x 0x%.4x\n",
diff --git a/drivers/mtd/chips/sharp.c b/drivers/mtd/chips/sharp.c
index 36f61a6a766e..3cc0b23c5865 100644
--- a/drivers/mtd/chips/sharp.c
+++ b/drivers/mtd/chips/sharp.c
@@ -64,7 +64,7 @@
64 64
65#undef AUTOUNLOCK /* automatically unlocks blocks before erasing */ 65#undef AUTOUNLOCK /* automatically unlocks blocks before erasing */
66 66
67struct mtd_info *sharp_probe(struct map_info *); 67static struct mtd_info *sharp_probe(struct map_info *);
68 68
69static int sharp_probe_map(struct map_info *map,struct mtd_info *mtd); 69static int sharp_probe_map(struct map_info *map,struct mtd_info *mtd);
70 70
@@ -96,7 +96,6 @@ struct sharp_info{
96 struct flchip chips[1]; 96 struct flchip chips[1];
97}; 97};
98 98
99struct mtd_info *sharp_probe(struct map_info *map);
100static void sharp_destroy(struct mtd_info *mtd); 99static void sharp_destroy(struct mtd_info *mtd);
101 100
102static struct mtd_chip_driver sharp_chipdrv = { 101static struct mtd_chip_driver sharp_chipdrv = {
@@ -107,7 +106,7 @@ static struct mtd_chip_driver sharp_chipdrv = {
107}; 106};
108 107
109 108
110struct mtd_info *sharp_probe(struct map_info *map) 109static struct mtd_info *sharp_probe(struct map_info *map)
111{ 110{
112 struct mtd_info *mtd = NULL; 111 struct mtd_info *mtd = NULL;
113 struct sharp_info *sharp = NULL; 112 struct sharp_info *sharp = NULL;
@@ -581,7 +580,7 @@ static void sharp_destroy(struct mtd_info *mtd)
581 580
582} 581}
583 582
584int __init sharp_probe_init(void) 583static int __init sharp_probe_init(void)
585{ 584{
586 printk("MTD Sharp chip driver <ds@lineo.com>\n"); 585 printk("MTD Sharp chip driver <ds@lineo.com>\n");
587 586
diff --git a/drivers/mtd/cmdlinepart.c b/drivers/mtd/cmdlinepart.c
index 6b8bb2e4dcfd..a7a7bfe33879 100644
--- a/drivers/mtd/cmdlinepart.c
+++ b/drivers/mtd/cmdlinepart.c
@@ -42,7 +42,8 @@
42 42
43 43
44/* special size referring to all the remaining space in a partition */ 44/* special size referring to all the remaining space in a partition */
45#define SIZE_REMAINING 0xffffffff 45#define SIZE_REMAINING UINT_MAX
46#define OFFSET_CONTINUOUS UINT_MAX
46 47
47struct cmdline_mtd_partition { 48struct cmdline_mtd_partition {
48 struct cmdline_mtd_partition *next; 49 struct cmdline_mtd_partition *next;
@@ -75,7 +76,7 @@ static struct mtd_partition * newpart(char *s,
75{ 76{
76 struct mtd_partition *parts; 77 struct mtd_partition *parts;
77 unsigned long size; 78 unsigned long size;
78 unsigned long offset = 0; 79 unsigned long offset = OFFSET_CONTINUOUS;
79 char *name; 80 char *name;
80 int name_len; 81 int name_len;
81 unsigned char *extra_mem; 82 unsigned char *extra_mem;
@@ -314,7 +315,7 @@ static int parse_cmdline_partitions(struct mtd_info *master,
314 { 315 {
315 for(i = 0, offset = 0; i < part->num_parts; i++) 316 for(i = 0, offset = 0; i < part->num_parts; i++)
316 { 317 {
317 if (!part->parts[i].offset) 318 if (part->parts[i].offset == OFFSET_CONTINUOUS)
318 part->parts[i].offset = offset; 319 part->parts[i].offset = offset;
319 else 320 else
320 offset = part->parts[i].offset; 321 offset = part->parts[i].offset;
diff --git a/drivers/mtd/devices/blkmtd.c b/drivers/mtd/devices/blkmtd.c
index 04f864d238db..79f2e1f23ebd 100644
--- a/drivers/mtd/devices/blkmtd.c
+++ b/drivers/mtd/devices/blkmtd.c
@@ -28,8 +28,9 @@
28#include <linux/pagemap.h> 28#include <linux/pagemap.h>
29#include <linux/list.h> 29#include <linux/list.h>
30#include <linux/init.h> 30#include <linux/init.h>
31#include <linux/mount.h>
31#include <linux/mtd/mtd.h> 32#include <linux/mtd/mtd.h>
32 33#include <linux/mutex.h>
33 34
34#define err(format, arg...) printk(KERN_ERR "blkmtd: " format "\n" , ## arg) 35#define err(format, arg...) printk(KERN_ERR "blkmtd: " format "\n" , ## arg)
35#define info(format, arg...) printk(KERN_INFO "blkmtd: " format "\n" , ## arg) 36#define info(format, arg...) printk(KERN_INFO "blkmtd: " format "\n" , ## arg)
@@ -46,7 +47,7 @@ struct blkmtd_dev {
46 struct list_head list; 47 struct list_head list;
47 struct block_device *blkdev; 48 struct block_device *blkdev;
48 struct mtd_info mtd_info; 49 struct mtd_info mtd_info;
49 struct semaphore wrbuf_mutex; 50 struct mutex wrbuf_mutex;
50}; 51};
51 52
52 53
@@ -268,7 +269,7 @@ static int write_pages(struct blkmtd_dev *dev, const u_char *buf, loff_t to,
268 if(end_len) 269 if(end_len)
269 pagecnt++; 270 pagecnt++;
270 271
271 down(&dev->wrbuf_mutex); 272 mutex_lock(&dev->wrbuf_mutex);
272 273
273 DEBUG(3, "blkmtd: write: start_len = %zd len = %zd end_len = %zd pagecnt = %d\n", 274 DEBUG(3, "blkmtd: write: start_len = %zd len = %zd end_len = %zd pagecnt = %d\n",
274 start_len, len, end_len, pagecnt); 275 start_len, len, end_len, pagecnt);
@@ -376,7 +377,7 @@ static int write_pages(struct blkmtd_dev *dev, const u_char *buf, loff_t to,
376 blkmtd_write_out(bio); 377 blkmtd_write_out(bio);
377 378
378 DEBUG(2, "blkmtd: write: end, retlen = %zd, err = %d\n", *retlen, err); 379 DEBUG(2, "blkmtd: write: end, retlen = %zd, err = %d\n", *retlen, err);
379 up(&dev->wrbuf_mutex); 380 mutex_unlock(&dev->wrbuf_mutex);
380 381
381 if(retlen) 382 if(retlen)
382 *retlen = thislen; 383 *retlen = thislen;
@@ -614,8 +615,6 @@ static struct mtd_erase_region_info *calc_erase_regions(
614} 615}
615 616
616 617
617extern dev_t __init name_to_dev_t(const char *line);
618
619static struct blkmtd_dev *add_device(char *devname, int readonly, int erase_size) 618static struct blkmtd_dev *add_device(char *devname, int readonly, int erase_size)
620{ 619{
621 struct block_device *bdev; 620 struct block_device *bdev;
@@ -659,7 +658,7 @@ static struct blkmtd_dev *add_device(char *devname, int readonly, int erase_size
659 memset(dev, 0, sizeof(struct blkmtd_dev)); 658 memset(dev, 0, sizeof(struct blkmtd_dev));
660 dev->blkdev = bdev; 659 dev->blkdev = bdev;
661 if(!readonly) { 660 if(!readonly) {
662 init_MUTEX(&dev->wrbuf_mutex); 661 mutex_init(&dev->wrbuf_mutex);
663 } 662 }
664 663
665 dev->mtd_info.size = dev->blkdev->bd_inode->i_size & PAGE_MASK; 664 dev->mtd_info.size = dev->blkdev->bd_inode->i_size & PAGE_MASK;
diff --git a/drivers/mtd/devices/block2mtd.c b/drivers/mtd/devices/block2mtd.c
index 7ff403b2a0a0..4160b8334c53 100644
--- a/drivers/mtd/devices/block2mtd.c
+++ b/drivers/mtd/devices/block2mtd.c
@@ -18,6 +18,7 @@
18#include <linux/init.h> 18#include <linux/init.h>
19#include <linux/mtd/mtd.h> 19#include <linux/mtd/mtd.h>
20#include <linux/buffer_head.h> 20#include <linux/buffer_head.h>
21#include <linux/mutex.h>
21 22
22#define VERSION "$Revision: 1.30 $" 23#define VERSION "$Revision: 1.30 $"
23 24
@@ -31,7 +32,7 @@ struct block2mtd_dev {
31 struct list_head list; 32 struct list_head list;
32 struct block_device *blkdev; 33 struct block_device *blkdev;
33 struct mtd_info mtd; 34 struct mtd_info mtd;
34 struct semaphore write_mutex; 35 struct mutex write_mutex;
35}; 36};
36 37
37 38
@@ -134,9 +135,9 @@ static int block2mtd_erase(struct mtd_info *mtd, struct erase_info *instr)
134 int err; 135 int err;
135 136
136 instr->state = MTD_ERASING; 137 instr->state = MTD_ERASING;
137 down(&dev->write_mutex); 138 mutex_lock(&dev->write_mutex);
138 err = _block2mtd_erase(dev, from, len); 139 err = _block2mtd_erase(dev, from, len);
139 up(&dev->write_mutex); 140 mutex_unlock(&dev->write_mutex);
140 if (err) { 141 if (err) {
141 ERROR("erase failed err = %d", err); 142 ERROR("erase failed err = %d", err);
142 instr->state = MTD_ERASE_FAILED; 143 instr->state = MTD_ERASE_FAILED;
@@ -249,9 +250,9 @@ static int block2mtd_write(struct mtd_info *mtd, loff_t to, size_t len,
249 if (to + len > mtd->size) 250 if (to + len > mtd->size)
250 len = mtd->size - to; 251 len = mtd->size - to;
251 252
252 down(&dev->write_mutex); 253 mutex_lock(&dev->write_mutex);
253 err = _block2mtd_write(dev, buf, to, len, retlen); 254 err = _block2mtd_write(dev, buf, to, len, retlen);
254 up(&dev->write_mutex); 255 mutex_unlock(&dev->write_mutex);
255 if (err > 0) 256 if (err > 0)
256 err = 0; 257 err = 0;
257 return err; 258 return err;
@@ -310,7 +311,7 @@ static struct block2mtd_dev *add_device(char *devname, int erase_size)
310 goto devinit_err; 311 goto devinit_err;
311 } 312 }
312 313
313 init_MUTEX(&dev->write_mutex); 314 mutex_init(&dev->write_mutex);
314 315
315 /* Setup the MTD structure */ 316 /* Setup the MTD structure */
316 /* make the name contain the block device in */ 317 /* make the name contain the block device in */
diff --git a/drivers/mtd/devices/doc2000.c b/drivers/mtd/devices/doc2000.c
index e4345cf744a2..23e7a5c7d2c1 100644
--- a/drivers/mtd/devices/doc2000.c
+++ b/drivers/mtd/devices/doc2000.c
@@ -20,6 +20,7 @@
20#include <linux/init.h> 20#include <linux/init.h>
21#include <linux/types.h> 21#include <linux/types.h>
22#include <linux/bitops.h> 22#include <linux/bitops.h>
23#include <linux/mutex.h>
23 24
24#include <linux/mtd/mtd.h> 25#include <linux/mtd/mtd.h>
25#include <linux/mtd/nand.h> 26#include <linux/mtd/nand.h>
@@ -605,7 +606,7 @@ static void DoC2k_init(struct mtd_info *mtd)
605 606
606 this->curfloor = -1; 607 this->curfloor = -1;
607 this->curchip = -1; 608 this->curchip = -1;
608 init_MUTEX(&this->lock); 609 mutex_init(&this->lock);
609 610
610 /* Ident all the chips present. */ 611 /* Ident all the chips present. */
611 DoC_ScanChips(this, maxchips); 612 DoC_ScanChips(this, maxchips);
@@ -645,7 +646,7 @@ static int doc_read_ecc(struct mtd_info *mtd, loff_t from, size_t len,
645 if (from >= this->totlen) 646 if (from >= this->totlen)
646 return -EINVAL; 647 return -EINVAL;
647 648
648 down(&this->lock); 649 mutex_lock(&this->lock);
649 650
650 *retlen = 0; 651 *retlen = 0;
651 while (left) { 652 while (left) {
@@ -774,7 +775,7 @@ static int doc_read_ecc(struct mtd_info *mtd, loff_t from, size_t len,
774 buf += len; 775 buf += len;
775 } 776 }
776 777
777 up(&this->lock); 778 mutex_unlock(&this->lock);
778 779
779 return ret; 780 return ret;
780} 781}
@@ -803,7 +804,7 @@ static int doc_write_ecc(struct mtd_info *mtd, loff_t to, size_t len,
803 if (to >= this->totlen) 804 if (to >= this->totlen)
804 return -EINVAL; 805 return -EINVAL;
805 806
806 down(&this->lock); 807 mutex_lock(&this->lock);
807 808
808 *retlen = 0; 809 *retlen = 0;
809 while (left) { 810 while (left) {
@@ -873,7 +874,7 @@ static int doc_write_ecc(struct mtd_info *mtd, loff_t to, size_t len,
873 printk(KERN_ERR "Error programming flash\n"); 874 printk(KERN_ERR "Error programming flash\n");
874 /* Error in programming */ 875 /* Error in programming */
875 *retlen = 0; 876 *retlen = 0;
876 up(&this->lock); 877 mutex_unlock(&this->lock);
877 return -EIO; 878 return -EIO;
878 } 879 }
879 880
@@ -935,7 +936,7 @@ static int doc_write_ecc(struct mtd_info *mtd, loff_t to, size_t len,
935 printk(KERN_ERR "Error programming flash\n"); 936 printk(KERN_ERR "Error programming flash\n");
936 /* Error in programming */ 937 /* Error in programming */
937 *retlen = 0; 938 *retlen = 0;
938 up(&this->lock); 939 mutex_unlock(&this->lock);
939 return -EIO; 940 return -EIO;
940 } 941 }
941 942
@@ -956,7 +957,7 @@ static int doc_write_ecc(struct mtd_info *mtd, loff_t to, size_t len,
956 957
957 ret = doc_write_oob_nolock(mtd, to, 8, &dummy, x); 958 ret = doc_write_oob_nolock(mtd, to, 8, &dummy, x);
958 if (ret) { 959 if (ret) {
959 up(&this->lock); 960 mutex_unlock(&this->lock);
960 return ret; 961 return ret;
961 } 962 }
962 } 963 }
@@ -966,7 +967,7 @@ static int doc_write_ecc(struct mtd_info *mtd, loff_t to, size_t len,
966 buf += len; 967 buf += len;
967 } 968 }
968 969
969 up(&this->lock); 970 mutex_unlock(&this->lock);
970 return 0; 971 return 0;
971} 972}
972 973
@@ -975,13 +976,13 @@ static int doc_writev_ecc(struct mtd_info *mtd, const struct kvec *vecs,
975 u_char *eccbuf, struct nand_oobinfo *oobsel) 976 u_char *eccbuf, struct nand_oobinfo *oobsel)
976{ 977{
977 static char static_buf[512]; 978 static char static_buf[512];
978 static DECLARE_MUTEX(writev_buf_sem); 979 static DEFINE_MUTEX(writev_buf_mutex);
979 980
980 size_t totretlen = 0; 981 size_t totretlen = 0;
981 size_t thisvecofs = 0; 982 size_t thisvecofs = 0;
982 int ret= 0; 983 int ret= 0;
983 984
984 down(&writev_buf_sem); 985 mutex_lock(&writev_buf_mutex);
985 986
986 while(count) { 987 while(count) {
987 size_t thislen, thisretlen; 988 size_t thislen, thisretlen;
@@ -1024,7 +1025,7 @@ static int doc_writev_ecc(struct mtd_info *mtd, const struct kvec *vecs,
1024 to += thislen; 1025 to += thislen;
1025 } 1026 }
1026 1027
1027 up(&writev_buf_sem); 1028 mutex_unlock(&writev_buf_mutex);
1028 *retlen = totretlen; 1029 *retlen = totretlen;
1029 return ret; 1030 return ret;
1030} 1031}
@@ -1037,7 +1038,7 @@ static int doc_read_oob(struct mtd_info *mtd, loff_t ofs, size_t len,
1037 int len256 = 0, ret; 1038 int len256 = 0, ret;
1038 struct Nand *mychip; 1039 struct Nand *mychip;
1039 1040
1040 down(&this->lock); 1041 mutex_lock(&this->lock);
1041 1042
1042 mychip = &this->chips[ofs >> this->chipshift]; 1043 mychip = &this->chips[ofs >> this->chipshift];
1043 1044
@@ -1083,7 +1084,7 @@ static int doc_read_oob(struct mtd_info *mtd, loff_t ofs, size_t len,
1083 1084
1084 ret = DoC_WaitReady(this); 1085 ret = DoC_WaitReady(this);
1085 1086
1086 up(&this->lock); 1087 mutex_unlock(&this->lock);
1087 return ret; 1088 return ret;
1088 1089
1089} 1090}
@@ -1197,10 +1198,10 @@ static int doc_write_oob(struct mtd_info *mtd, loff_t ofs, size_t len,
1197 struct DiskOnChip *this = mtd->priv; 1198 struct DiskOnChip *this = mtd->priv;
1198 int ret; 1199 int ret;
1199 1200
1200 down(&this->lock); 1201 mutex_lock(&this->lock);
1201 ret = doc_write_oob_nolock(mtd, ofs, len, retlen, buf); 1202 ret = doc_write_oob_nolock(mtd, ofs, len, retlen, buf);
1202 1203
1203 up(&this->lock); 1204 mutex_unlock(&this->lock);
1204 return ret; 1205 return ret;
1205} 1206}
1206 1207
@@ -1214,10 +1215,10 @@ static int doc_erase(struct mtd_info *mtd, struct erase_info *instr)
1214 struct Nand *mychip; 1215 struct Nand *mychip;
1215 int status; 1216 int status;
1216 1217
1217 down(&this->lock); 1218 mutex_lock(&this->lock);
1218 1219
1219 if (ofs & (mtd->erasesize-1) || len & (mtd->erasesize-1)) { 1220 if (ofs & (mtd->erasesize-1) || len & (mtd->erasesize-1)) {
1220 up(&this->lock); 1221 mutex_unlock(&this->lock);
1221 return -EINVAL; 1222 return -EINVAL;
1222 } 1223 }
1223 1224
@@ -1265,7 +1266,7 @@ static int doc_erase(struct mtd_info *mtd, struct erase_info *instr)
1265 callback: 1266 callback:
1266 mtd_erase_callback(instr); 1267 mtd_erase_callback(instr);
1267 1268
1268 up(&this->lock); 1269 mutex_unlock(&this->lock);
1269 return 0; 1270 return 0;
1270} 1271}
1271 1272
diff --git a/drivers/mtd/devices/lart.c b/drivers/mtd/devices/lart.c
index 1e876fcb0408..29b0ddaa324e 100644
--- a/drivers/mtd/devices/lart.c
+++ b/drivers/mtd/devices/lart.c
@@ -581,8 +581,6 @@ static int flash_write (struct mtd_info *mtd,loff_t to,size_t len,size_t *retlen
581 581
582/***************************************************************************************************/ 582/***************************************************************************************************/
583 583
584#define NB_OF(x) (sizeof (x) / sizeof (x[0]))
585
586static struct mtd_info mtd; 584static struct mtd_info mtd;
587 585
588static struct mtd_erase_region_info erase_regions[] = { 586static struct mtd_erase_region_info erase_regions[] = {
@@ -640,7 +638,7 @@ int __init lart_flash_init (void)
640 mtd.flags = MTD_CAP_NORFLASH; 638 mtd.flags = MTD_CAP_NORFLASH;
641 mtd.size = FLASH_BLOCKSIZE_PARAM * FLASH_NUMBLOCKS_16m_PARAM + FLASH_BLOCKSIZE_MAIN * FLASH_NUMBLOCKS_16m_MAIN; 639 mtd.size = FLASH_BLOCKSIZE_PARAM * FLASH_NUMBLOCKS_16m_PARAM + FLASH_BLOCKSIZE_MAIN * FLASH_NUMBLOCKS_16m_MAIN;
642 mtd.erasesize = FLASH_BLOCKSIZE_MAIN; 640 mtd.erasesize = FLASH_BLOCKSIZE_MAIN;
643 mtd.numeraseregions = NB_OF (erase_regions); 641 mtd.numeraseregions = ARRAY_SIZE(erase_regions);
644 mtd.eraseregions = erase_regions; 642 mtd.eraseregions = erase_regions;
645 mtd.erase = flash_erase; 643 mtd.erase = flash_erase;
646 mtd.read = flash_read; 644 mtd.read = flash_read;
@@ -670,9 +668,9 @@ int __init lart_flash_init (void)
670 result,mtd.eraseregions[result].numblocks); 668 result,mtd.eraseregions[result].numblocks);
671 669
672#ifdef HAVE_PARTITIONS 670#ifdef HAVE_PARTITIONS
673 printk ("\npartitions = %d\n",NB_OF (lart_partitions)); 671 printk ("\npartitions = %d\n", ARRAY_SIZE(lart_partitions));
674 672
675 for (result = 0; result < NB_OF (lart_partitions); result++) 673 for (result = 0; result < ARRAY_SIZE(lart_partitions); result++)
676 printk (KERN_DEBUG 674 printk (KERN_DEBUG
677 "\n\n" 675 "\n\n"
678 "lart_partitions[%d].name = %s\n" 676 "lart_partitions[%d].name = %s\n"
@@ -687,7 +685,7 @@ int __init lart_flash_init (void)
687#ifndef HAVE_PARTITIONS 685#ifndef HAVE_PARTITIONS
688 result = add_mtd_device (&mtd); 686 result = add_mtd_device (&mtd);
689#else 687#else
690 result = add_mtd_partitions (&mtd,lart_partitions,NB_OF (lart_partitions)); 688 result = add_mtd_partitions (&mtd,lart_partitions, ARRAY_SIZE(lart_partitions));
691#endif 689#endif
692 690
693 return (result); 691 return (result);
diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c
index d5f24089be71..04e65d5dae00 100644
--- a/drivers/mtd/devices/m25p80.c
+++ b/drivers/mtd/devices/m25p80.c
@@ -186,7 +186,7 @@ static int m25p80_erase(struct mtd_info *mtd, struct erase_info *instr)
186 struct m25p *flash = mtd_to_m25p(mtd); 186 struct m25p *flash = mtd_to_m25p(mtd);
187 u32 addr,len; 187 u32 addr,len;
188 188
189 DEBUG(MTD_DEBUG_LEVEL2, "%s: %s %s 0x%08x, len %zd\n", 189 DEBUG(MTD_DEBUG_LEVEL2, "%s: %s %s 0x%08x, len %d\n",
190 flash->spi->dev.bus_id, __FUNCTION__, "at", 190 flash->spi->dev.bus_id, __FUNCTION__, "at",
191 (u32)instr->addr, instr->len); 191 (u32)instr->addr, instr->len);
192 192
diff --git a/drivers/mtd/devices/ms02-nv.c b/drivers/mtd/devices/ms02-nv.c
index 0ff2e4378244..485f663493d2 100644
--- a/drivers/mtd/devices/ms02-nv.c
+++ b/drivers/mtd/devices/ms02-nv.c
@@ -308,7 +308,7 @@ static int __init ms02nv_init(void)
308 break; 308 break;
309 } 309 }
310 310
311 for (i = 0; i < (sizeof(ms02nv_addrs) / sizeof(*ms02nv_addrs)); i++) 311 for (i = 0; i < ARRAY_SIZE(ms02nv_addrs); i++)
312 if (!ms02nv_init_one(ms02nv_addrs[i] << stride)) 312 if (!ms02nv_init_one(ms02nv_addrs[i] << stride))
313 count++; 313 count++;
314 314
diff --git a/drivers/mtd/inftlcore.c b/drivers/mtd/inftlcore.c
index 8a544890173d..a3b92479719d 100644
--- a/drivers/mtd/inftlcore.c
+++ b/drivers/mtd/inftlcore.c
@@ -47,9 +47,6 @@
47 */ 47 */
48#define MAX_LOOPS 10000 48#define MAX_LOOPS 10000
49 49
50extern void INFTL_dumptables(struct INFTLrecord *inftl);
51extern void INFTL_dumpVUchains(struct INFTLrecord *inftl);
52
53static void inftl_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd) 50static void inftl_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd)
54{ 51{
55 struct INFTLrecord *inftl; 52 struct INFTLrecord *inftl;
@@ -132,7 +129,7 @@ static void inftl_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd)
132 return; 129 return;
133 } 130 }
134#ifdef PSYCHO_DEBUG 131#ifdef PSYCHO_DEBUG
135 printk(KERN_INFO "INFTL: Found new nftl%c\n", nftl->mbd.devnum + 'a'); 132 printk(KERN_INFO "INFTL: Found new inftl%c\n", inftl->mbd.devnum + 'a');
136#endif 133#endif
137 return; 134 return;
138} 135}
@@ -885,8 +882,6 @@ static struct mtd_blktrans_ops inftl_tr = {
885 .owner = THIS_MODULE, 882 .owner = THIS_MODULE,
886}; 883};
887 884
888extern char inftlmountrev[];
889
890static int __init init_inftl(void) 885static int __init init_inftl(void)
891{ 886{
892 printk(KERN_INFO "INFTL: inftlcore.c $Revision: 1.19 $, " 887 printk(KERN_INFO "INFTL: inftlcore.c $Revision: 1.19 $, "
diff --git a/drivers/mtd/maps/alchemy-flash.c b/drivers/mtd/maps/alchemy-flash.c
index a57791a6ce40..b933a2a27b18 100644
--- a/drivers/mtd/maps/alchemy-flash.c
+++ b/drivers/mtd/maps/alchemy-flash.c
@@ -126,8 +126,6 @@ static struct mtd_partition alchemy_partitions[] = {
126 } 126 }
127}; 127};
128 128
129#define NB_OF(x) (sizeof(x)/sizeof(x[0]))
130
131static struct mtd_info *mymtd; 129static struct mtd_info *mymtd;
132 130
133int __init alchemy_mtd_init(void) 131int __init alchemy_mtd_init(void)
@@ -154,7 +152,7 @@ int __init alchemy_mtd_init(void)
154 * Static partition definition selection 152 * Static partition definition selection
155 */ 153 */
156 parts = alchemy_partitions; 154 parts = alchemy_partitions;
157 nb_parts = NB_OF(alchemy_partitions); 155 nb_parts = ARRAY_SIZE(alchemy_partitions);
158 alchemy_map.size = window_size; 156 alchemy_map.size = window_size;
159 157
160 /* 158 /*
diff --git a/drivers/mtd/maps/cfi_flagadm.c b/drivers/mtd/maps/cfi_flagadm.c
index 6a8c0415bde8..fd0f0d3187de 100644
--- a/drivers/mtd/maps/cfi_flagadm.c
+++ b/drivers/mtd/maps/cfi_flagadm.c
@@ -86,7 +86,7 @@ struct mtd_partition flagadm_parts[] = {
86 } 86 }
87}; 87};
88 88
89#define PARTITION_COUNT (sizeof(flagadm_parts)/sizeof(struct mtd_partition)) 89#define PARTITION_COUNT ARRAY_SIZE(flagadm_parts)
90 90
91static struct mtd_info *mymtd; 91static struct mtd_info *mymtd;
92 92
diff --git a/drivers/mtd/maps/dbox2-flash.c b/drivers/mtd/maps/dbox2-flash.c
index 49d90542fc75..652813cd6c2d 100644
--- a/drivers/mtd/maps/dbox2-flash.c
+++ b/drivers/mtd/maps/dbox2-flash.c
@@ -57,7 +57,7 @@ static struct mtd_partition partition_info[]= {
57 } 57 }
58}; 58};
59 59
60#define NUM_PARTITIONS (sizeof(partition_info) / sizeof(partition_info[0])) 60#define NUM_PARTITIONS ARRAY_SIZE(partition_info)
61 61
62#define WINDOW_ADDR 0x10000000 62#define WINDOW_ADDR 0x10000000
63#define WINDOW_SIZE 0x800000 63#define WINDOW_SIZE 0x800000
diff --git a/drivers/mtd/maps/dilnetpc.c b/drivers/mtd/maps/dilnetpc.c
index efb221692641..c299d10b33e6 100644
--- a/drivers/mtd/maps/dilnetpc.c
+++ b/drivers/mtd/maps/dilnetpc.c
@@ -300,7 +300,7 @@ static struct mtd_partition partition_info[]=
300 }, 300 },
301}; 301};
302 302
303#define NUM_PARTITIONS (sizeof(partition_info)/sizeof(partition_info[0])) 303#define NUM_PARTITIONS ARRAY_SIZE(partition_info)
304 304
305static struct mtd_info *mymtd; 305static struct mtd_info *mymtd;
306static struct mtd_info *lowlvl_parts[NUM_PARTITIONS]; 306static struct mtd_info *lowlvl_parts[NUM_PARTITIONS];
@@ -345,7 +345,7 @@ static struct mtd_partition higlvl_partition_info[]=
345 }, 345 },
346}; 346};
347 347
348#define NUM_HIGHLVL_PARTITIONS (sizeof(higlvl_partition_info)/sizeof(partition_info[0])) 348#define NUM_HIGHLVL_PARTITIONS ARRAY_SIZE(higlvl_partition_info)
349 349
350 350
351static int dnp_adnp_probe(void) 351static int dnp_adnp_probe(void)
diff --git a/drivers/mtd/maps/dmv182.c b/drivers/mtd/maps/dmv182.c
index b993ac01a9a5..2bb3c0f0f970 100644
--- a/drivers/mtd/maps/dmv182.c
+++ b/drivers/mtd/maps/dmv182.c
@@ -99,7 +99,7 @@ static struct mtd_info *this_mtd;
99static int __init init_svme182(void) 99static int __init init_svme182(void)
100{ 100{
101 struct mtd_partition *partitions; 101 struct mtd_partition *partitions;
102 int num_parts = sizeof(svme182_partitions) / sizeof(struct mtd_partition); 102 int num_parts = ARRAY_SIZE(svme182_partitions);
103 103
104 partitions = svme182_partitions; 104 partitions = svme182_partitions;
105 105
diff --git a/drivers/mtd/maps/h720x-flash.c b/drivers/mtd/maps/h720x-flash.c
index 319094821101..0667101ccbe1 100644
--- a/drivers/mtd/maps/h720x-flash.c
+++ b/drivers/mtd/maps/h720x-flash.c
@@ -59,7 +59,7 @@ static struct mtd_partition h720x_partitions[] = {
59 } 59 }
60}; 60};
61 61
62#define NUM_PARTITIONS (sizeof(h720x_partitions)/sizeof(h720x_partitions[0])) 62#define NUM_PARTITIONS ARRAY_SIZE(h720x_partitions)
63 63
64static int nr_mtd_parts; 64static int nr_mtd_parts;
65static struct mtd_partition *mtd_parts; 65static struct mtd_partition *mtd_parts;
diff --git a/drivers/mtd/maps/netsc520.c b/drivers/mtd/maps/netsc520.c
index 33060a315722..ed215470158b 100644
--- a/drivers/mtd/maps/netsc520.c
+++ b/drivers/mtd/maps/netsc520.c
@@ -76,7 +76,7 @@ static struct mtd_partition partition_info[]={
76 .size = 0x80000 76 .size = 0x80000
77 }, 77 },
78}; 78};
79#define NUM_PARTITIONS (sizeof(partition_info)/sizeof(partition_info[0])) 79#define NUM_PARTITIONS ARRAY_SIZE(partition_info)
80 80
81#define WINDOW_SIZE 0x00100000 81#define WINDOW_SIZE 0x00100000
82#define WINDOW_ADDR 0x00200000 82#define WINDOW_ADDR 0x00200000
@@ -88,7 +88,7 @@ static struct map_info netsc520_map = {
88 .phys = WINDOW_ADDR, 88 .phys = WINDOW_ADDR,
89}; 89};
90 90
91#define NUM_FLASH_BANKS (sizeof(netsc520_map)/sizeof(struct map_info)) 91#define NUM_FLASH_BANKS ARRAY_SIZE(netsc520_map)
92 92
93static struct mtd_info *mymtd; 93static struct mtd_info *mymtd;
94 94
diff --git a/drivers/mtd/maps/nettel.c b/drivers/mtd/maps/nettel.c
index 632eb2aa968f..54a3102ab19a 100644
--- a/drivers/mtd/maps/nettel.c
+++ b/drivers/mtd/maps/nettel.c
@@ -128,8 +128,7 @@ static struct mtd_partition nettel_amd_partitions[] = {
128 } 128 }
129}; 129};
130 130
131#define NUM_AMD_PARTITIONS \ 131#define NUM_AMD_PARTITIONS ARRAY_SIZE(nettel_amd_partitions)
132 (sizeof(nettel_amd_partitions)/sizeof(nettel_amd_partitions[0]))
133 132
134/****************************************************************************/ 133/****************************************************************************/
135 134
diff --git a/drivers/mtd/maps/ocotea.c b/drivers/mtd/maps/ocotea.c
index c223514ca2eb..a21fcd195ab4 100644
--- a/drivers/mtd/maps/ocotea.c
+++ b/drivers/mtd/maps/ocotea.c
@@ -58,8 +58,6 @@ static struct mtd_partition ocotea_large_partitions[] = {
58 } 58 }
59}; 59};
60 60
61#define NB_OF(x) (sizeof(x)/sizeof(x[0]))
62
63int __init init_ocotea(void) 61int __init init_ocotea(void)
64{ 62{
65 u8 fpga0_reg; 63 u8 fpga0_reg;
@@ -97,7 +95,7 @@ int __init init_ocotea(void)
97 if (flash) { 95 if (flash) {
98 flash->owner = THIS_MODULE; 96 flash->owner = THIS_MODULE;
99 add_mtd_partitions(flash, ocotea_small_partitions, 97 add_mtd_partitions(flash, ocotea_small_partitions,
100 NB_OF(ocotea_small_partitions)); 98 ARRAY_SIZE(ocotea_small_partitions));
101 } else { 99 } else {
102 printk("map probe failed for flash\n"); 100 printk("map probe failed for flash\n");
103 return -ENXIO; 101 return -ENXIO;
@@ -118,7 +116,7 @@ int __init init_ocotea(void)
118 if (flash) { 116 if (flash) {
119 flash->owner = THIS_MODULE; 117 flash->owner = THIS_MODULE;
120 add_mtd_partitions(flash, ocotea_large_partitions, 118 add_mtd_partitions(flash, ocotea_large_partitions,
121 NB_OF(ocotea_large_partitions)); 119 ARRAY_SIZE(ocotea_large_partitions));
122 } else { 120 } else {
123 printk("map probe failed for flash\n"); 121 printk("map probe failed for flash\n");
124 return -ENXIO; 122 return -ENXIO;
diff --git a/drivers/mtd/maps/pci.c b/drivers/mtd/maps/pci.c
index 21822c2edbe4..d2ab1bae9c34 100644
--- a/drivers/mtd/maps/pci.c
+++ b/drivers/mtd/maps/pci.c
@@ -334,9 +334,6 @@ mtd_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
334 return 0; 334 return 0;
335 335
336release: 336release:
337 if (mtd)
338 map_destroy(mtd);
339
340 if (map) { 337 if (map) {
341 map->exit(dev, map); 338 map->exit(dev, map);
342 kfree(map); 339 kfree(map);
diff --git a/drivers/mtd/maps/pcmciamtd.c b/drivers/mtd/maps/pcmciamtd.c
index f988c817e196..8bbc751a6021 100644
--- a/drivers/mtd/maps/pcmciamtd.c
+++ b/drivers/mtd/maps/pcmciamtd.c
@@ -616,7 +616,7 @@ static void pcmciamtd_config(dev_link_t *link)
616 } else if(mem_type == 2) { 616 } else if(mem_type == 2) {
617 mtd = do_map_probe("map_rom", &dev->pcmcia_map); 617 mtd = do_map_probe("map_rom", &dev->pcmcia_map);
618 } else { 618 } else {
619 for(i = 0; i < sizeof(probes) / sizeof(char *); i++) { 619 for(i = 0; i < ARRAY_SIZE(probes); i++) {
620 DEBUG(1, "Trying %s", probes[i]); 620 DEBUG(1, "Trying %s", probes[i]);
621 mtd = do_map_probe(probes[i], &dev->pcmcia_map); 621 mtd = do_map_probe(probes[i], &dev->pcmcia_map);
622 if(mtd) 622 if(mtd)
diff --git a/drivers/mtd/maps/redwood.c b/drivers/mtd/maps/redwood.c
index 5b76ed886185..50b14033613f 100644
--- a/drivers/mtd/maps/redwood.c
+++ b/drivers/mtd/maps/redwood.c
@@ -121,8 +121,7 @@ struct map_info redwood_flash_map = {
121}; 121};
122 122
123 123
124#define NUM_REDWOOD_FLASH_PARTITIONS \ 124#define NUM_REDWOOD_FLASH_PARTITIONS ARRAY_SIZE(redwood_flash_partitions)
125 (sizeof(redwood_flash_partitions)/sizeof(redwood_flash_partitions[0]))
126 125
127static struct mtd_info *redwood_mtd; 126static struct mtd_info *redwood_mtd;
128 127
diff --git a/drivers/mtd/maps/sbc8240.c b/drivers/mtd/maps/sbc8240.c
index 225cdd9ba5b2..350286dc1d2e 100644
--- a/drivers/mtd/maps/sbc8240.c
+++ b/drivers/mtd/maps/sbc8240.c
@@ -66,7 +66,7 @@ static struct map_info sbc8240_map[2] = {
66 } 66 }
67}; 67};
68 68
69#define NUM_FLASH_BANKS (sizeof(sbc8240_map) / sizeof(struct map_info)) 69#define NUM_FLASH_BANKS ARRAY_SIZE(sbc8240_map)
70 70
71/* 71/*
72 * The following defines the partition layout of SBC8240 boards. 72 * The following defines the partition layout of SBC8240 boards.
@@ -125,8 +125,6 @@ static struct mtd_partition sbc8240_fs_partitions [] = {
125 } 125 }
126}; 126};
127 127
128#define NB_OF(x) (sizeof (x) / sizeof (x[0]))
129
130/* trivial struct to describe partition information */ 128/* trivial struct to describe partition information */
131struct mtd_part_def 129struct mtd_part_def
132{ 130{
@@ -190,10 +188,10 @@ int __init init_sbc8240_mtd (void)
190#ifdef CONFIG_MTD_PARTITIONS 188#ifdef CONFIG_MTD_PARTITIONS
191 sbc8240_part_banks[0].mtd_part = sbc8240_uboot_partitions; 189 sbc8240_part_banks[0].mtd_part = sbc8240_uboot_partitions;
192 sbc8240_part_banks[0].type = "static image"; 190 sbc8240_part_banks[0].type = "static image";
193 sbc8240_part_banks[0].nums = NB_OF(sbc8240_uboot_partitions); 191 sbc8240_part_banks[0].nums = ARRAY_SIZE(sbc8240_uboot_partitions);
194 sbc8240_part_banks[1].mtd_part = sbc8240_fs_partitions; 192 sbc8240_part_banks[1].mtd_part = sbc8240_fs_partitions;
195 sbc8240_part_banks[1].type = "static file system"; 193 sbc8240_part_banks[1].type = "static file system";
196 sbc8240_part_banks[1].nums = NB_OF(sbc8240_fs_partitions); 194 sbc8240_part_banks[1].nums = ARRAY_SIZE(sbc8240_fs_partitions);
197 195
198 for (i = 0; i < NUM_FLASH_BANKS; i++) { 196 for (i = 0; i < NUM_FLASH_BANKS; i++) {
199 197
diff --git a/drivers/mtd/maps/sc520cdp.c b/drivers/mtd/maps/sc520cdp.c
index ed92afadd8a9..e8c130e1efd3 100644
--- a/drivers/mtd/maps/sc520cdp.c
+++ b/drivers/mtd/maps/sc520cdp.c
@@ -107,7 +107,7 @@ static struct map_info sc520cdp_map[] = {
107 }, 107 },
108}; 108};
109 109
110#define NUM_FLASH_BANKS (sizeof(sc520cdp_map)/sizeof(struct map_info)) 110#define NUM_FLASH_BANKS ARRAY_SIZE(sc520cdp_map)
111 111
112static struct mtd_info *mymtd[NUM_FLASH_BANKS]; 112static struct mtd_info *mymtd[NUM_FLASH_BANKS];
113static struct mtd_info *merged_mtd; 113static struct mtd_info *merged_mtd;
diff --git a/drivers/mtd/maps/scx200_docflash.c b/drivers/mtd/maps/scx200_docflash.c
index 2c91dff8bb60..28b8a571a91a 100644
--- a/drivers/mtd/maps/scx200_docflash.c
+++ b/drivers/mtd/maps/scx200_docflash.c
@@ -70,7 +70,7 @@ static struct mtd_partition partition_info[] = {
70 .size = 0x80000 70 .size = 0x80000
71 }, 71 },
72}; 72};
73#define NUM_PARTITIONS (sizeof(partition_info)/sizeof(partition_info[0])) 73#define NUM_PARTITIONS ARRAY_SIZE(partition_info)
74#endif 74#endif
75 75
76 76
diff --git a/drivers/mtd/maps/sharpsl-flash.c b/drivers/mtd/maps/sharpsl-flash.c
index 999f4bb3d845..12fe53c0d2fc 100644
--- a/drivers/mtd/maps/sharpsl-flash.c
+++ b/drivers/mtd/maps/sharpsl-flash.c
@@ -49,8 +49,6 @@ static struct mtd_partition sharpsl_partitions[1] = {
49 } 49 }
50}; 50};
51 51
52#define NB_OF(x) (sizeof(x)/sizeof(x[0]))
53
54int __init init_sharpsl(void) 52int __init init_sharpsl(void)
55{ 53{
56 struct mtd_partition *parts; 54 struct mtd_partition *parts;
@@ -92,7 +90,7 @@ int __init init_sharpsl(void)
92 } 90 }
93 91
94 parts = sharpsl_partitions; 92 parts = sharpsl_partitions;
95 nb_parts = NB_OF(sharpsl_partitions); 93 nb_parts = ARRAY_SIZE(sharpsl_partitions);
96 94
97 printk(KERN_NOTICE "Using %s partision definition\n", part_type); 95 printk(KERN_NOTICE "Using %s partision definition\n", part_type);
98 add_mtd_partitions(mymtd, parts, nb_parts); 96 add_mtd_partitions(mymtd, parts, nb_parts);
diff --git a/drivers/mtd/maps/ts5500_flash.c b/drivers/mtd/maps/ts5500_flash.c
index 4b372bcb17f1..a7422c200567 100644
--- a/drivers/mtd/maps/ts5500_flash.c
+++ b/drivers/mtd/maps/ts5500_flash.c
@@ -64,7 +64,7 @@ static struct mtd_partition ts5500_partitions[] = {
64 } 64 }
65}; 65};
66 66
67#define NUM_PARTITIONS (sizeof(ts5500_partitions)/sizeof(struct mtd_partition)) 67#define NUM_PARTITIONS ARRAY_SIZE(ts5500_partitions)
68 68
69static struct mtd_info *mymtd; 69static struct mtd_info *mymtd;
70 70
diff --git a/drivers/mtd/maps/uclinux.c b/drivers/mtd/maps/uclinux.c
index 79d92808b766..f7264dc2ac9b 100644
--- a/drivers/mtd/maps/uclinux.c
+++ b/drivers/mtd/maps/uclinux.c
@@ -37,7 +37,7 @@ struct mtd_partition uclinux_romfs[] = {
37 { .name = "ROMfs" } 37 { .name = "ROMfs" }
38}; 38};
39 39
40#define NUM_PARTITIONS (sizeof(uclinux_romfs) / sizeof(uclinux_romfs[0])) 40#define NUM_PARTITIONS ARRAY_SIZE(uclinux_romfs)
41 41
42/****************************************************************************/ 42/****************************************************************************/
43 43
diff --git a/drivers/mtd/maps/vmax301.c b/drivers/mtd/maps/vmax301.c
index e0063941c0df..b3e487395435 100644
--- a/drivers/mtd/maps/vmax301.c
+++ b/drivers/mtd/maps/vmax301.c
@@ -182,7 +182,7 @@ int __init init_vmax301(void)
182 } 182 }
183 } 183 }
184 184
185 if (!vmax_mtd[1] && !vmax_mtd[2]) { 185 if (!vmax_mtd[0] && !vmax_mtd[1]) {
186 iounmap((void *)iomapadr); 186 iounmap((void *)iomapadr);
187 return -ENXIO; 187 return -ENXIO;
188 } 188 }
diff --git a/drivers/mtd/mtd_blkdevs.c b/drivers/mtd/mtd_blkdevs.c
index 840dd66ce2dc..458d3c8ae1ee 100644
--- a/drivers/mtd/mtd_blkdevs.c
+++ b/drivers/mtd/mtd_blkdevs.c
@@ -19,12 +19,12 @@
19#include <linux/spinlock.h> 19#include <linux/spinlock.h>
20#include <linux/hdreg.h> 20#include <linux/hdreg.h>
21#include <linux/init.h> 21#include <linux/init.h>
22#include <asm/semaphore.h> 22#include <linux/mutex.h>
23#include <asm/uaccess.h> 23#include <asm/uaccess.h>
24 24
25static LIST_HEAD(blktrans_majors); 25static LIST_HEAD(blktrans_majors);
26 26
27extern struct semaphore mtd_table_mutex; 27extern struct mutex mtd_table_mutex;
28extern struct mtd_info *mtd_table[]; 28extern struct mtd_info *mtd_table[];
29 29
30struct mtd_blkcore_priv { 30struct mtd_blkcore_priv {
@@ -122,9 +122,9 @@ static int mtd_blktrans_thread(void *arg)
122 122
123 spin_unlock_irq(rq->queue_lock); 123 spin_unlock_irq(rq->queue_lock);
124 124
125 down(&dev->sem); 125 mutex_lock(&dev->lock);
126 res = do_blktrans_request(tr, dev, req); 126 res = do_blktrans_request(tr, dev, req);
127 up(&dev->sem); 127 mutex_unlock(&dev->lock);
128 128
129 spin_lock_irq(rq->queue_lock); 129 spin_lock_irq(rq->queue_lock);
130 130
@@ -235,8 +235,8 @@ int add_mtd_blktrans_dev(struct mtd_blktrans_dev *new)
235 int last_devnum = -1; 235 int last_devnum = -1;
236 struct gendisk *gd; 236 struct gendisk *gd;
237 237
238 if (!down_trylock(&mtd_table_mutex)) { 238 if (!!mutex_trylock(&mtd_table_mutex)) {
239 up(&mtd_table_mutex); 239 mutex_unlock(&mtd_table_mutex);
240 BUG(); 240 BUG();
241 } 241 }
242 242
@@ -267,7 +267,7 @@ int add_mtd_blktrans_dev(struct mtd_blktrans_dev *new)
267 return -EBUSY; 267 return -EBUSY;
268 } 268 }
269 269
270 init_MUTEX(&new->sem); 270 mutex_init(&new->lock);
271 list_add_tail(&new->list, &tr->devs); 271 list_add_tail(&new->list, &tr->devs);
272 added: 272 added:
273 if (!tr->writesect) 273 if (!tr->writesect)
@@ -313,8 +313,8 @@ int add_mtd_blktrans_dev(struct mtd_blktrans_dev *new)
313 313
314int del_mtd_blktrans_dev(struct mtd_blktrans_dev *old) 314int del_mtd_blktrans_dev(struct mtd_blktrans_dev *old)
315{ 315{
316 if (!down_trylock(&mtd_table_mutex)) { 316 if (!!mutex_trylock(&mtd_table_mutex)) {
317 up(&mtd_table_mutex); 317 mutex_unlock(&mtd_table_mutex);
318 BUG(); 318 BUG();
319 } 319 }
320 320
@@ -378,14 +378,14 @@ int register_mtd_blktrans(struct mtd_blktrans_ops *tr)
378 378
379 memset(tr->blkcore_priv, 0, sizeof(*tr->blkcore_priv)); 379 memset(tr->blkcore_priv, 0, sizeof(*tr->blkcore_priv));
380 380
381 down(&mtd_table_mutex); 381 mutex_lock(&mtd_table_mutex);
382 382
383 ret = register_blkdev(tr->major, tr->name); 383 ret = register_blkdev(tr->major, tr->name);
384 if (ret) { 384 if (ret) {
385 printk(KERN_WARNING "Unable to register %s block device on major %d: %d\n", 385 printk(KERN_WARNING "Unable to register %s block device on major %d: %d\n",
386 tr->name, tr->major, ret); 386 tr->name, tr->major, ret);
387 kfree(tr->blkcore_priv); 387 kfree(tr->blkcore_priv);
388 up(&mtd_table_mutex); 388 mutex_unlock(&mtd_table_mutex);
389 return ret; 389 return ret;
390 } 390 }
391 spin_lock_init(&tr->blkcore_priv->queue_lock); 391 spin_lock_init(&tr->blkcore_priv->queue_lock);
@@ -396,7 +396,7 @@ int register_mtd_blktrans(struct mtd_blktrans_ops *tr)
396 if (!tr->blkcore_priv->rq) { 396 if (!tr->blkcore_priv->rq) {
397 unregister_blkdev(tr->major, tr->name); 397 unregister_blkdev(tr->major, tr->name);
398 kfree(tr->blkcore_priv); 398 kfree(tr->blkcore_priv);
399 up(&mtd_table_mutex); 399 mutex_unlock(&mtd_table_mutex);
400 return -ENOMEM; 400 return -ENOMEM;
401 } 401 }
402 402
@@ -407,7 +407,7 @@ int register_mtd_blktrans(struct mtd_blktrans_ops *tr)
407 blk_cleanup_queue(tr->blkcore_priv->rq); 407 blk_cleanup_queue(tr->blkcore_priv->rq);
408 unregister_blkdev(tr->major, tr->name); 408 unregister_blkdev(tr->major, tr->name);
409 kfree(tr->blkcore_priv); 409 kfree(tr->blkcore_priv);
410 up(&mtd_table_mutex); 410 mutex_unlock(&mtd_table_mutex);
411 return ret; 411 return ret;
412 } 412 }
413 413
@@ -419,7 +419,7 @@ int register_mtd_blktrans(struct mtd_blktrans_ops *tr)
419 tr->add_mtd(tr, mtd_table[i]); 419 tr->add_mtd(tr, mtd_table[i]);
420 } 420 }
421 421
422 up(&mtd_table_mutex); 422 mutex_unlock(&mtd_table_mutex);
423 423
424 return 0; 424 return 0;
425} 425}
@@ -428,7 +428,7 @@ int deregister_mtd_blktrans(struct mtd_blktrans_ops *tr)
428{ 428{
429 struct list_head *this, *next; 429 struct list_head *this, *next;
430 430
431 down(&mtd_table_mutex); 431 mutex_lock(&mtd_table_mutex);
432 432
433 /* Clean up the kernel thread */ 433 /* Clean up the kernel thread */
434 tr->blkcore_priv->exiting = 1; 434 tr->blkcore_priv->exiting = 1;
@@ -446,7 +446,7 @@ int deregister_mtd_blktrans(struct mtd_blktrans_ops *tr)
446 blk_cleanup_queue(tr->blkcore_priv->rq); 446 blk_cleanup_queue(tr->blkcore_priv->rq);
447 unregister_blkdev(tr->major, tr->name); 447 unregister_blkdev(tr->major, tr->name);
448 448
449 up(&mtd_table_mutex); 449 mutex_unlock(&mtd_table_mutex);
450 450
451 kfree(tr->blkcore_priv); 451 kfree(tr->blkcore_priv);
452 452
diff --git a/drivers/mtd/mtdblock.c b/drivers/mtd/mtdblock.c
index e84756644fd1..2cef280e388c 100644
--- a/drivers/mtd/mtdblock.c
+++ b/drivers/mtd/mtdblock.c
@@ -19,11 +19,13 @@
19 19
20#include <linux/mtd/mtd.h> 20#include <linux/mtd/mtd.h>
21#include <linux/mtd/blktrans.h> 21#include <linux/mtd/blktrans.h>
22#include <linux/mutex.h>
23
22 24
23static struct mtdblk_dev { 25static struct mtdblk_dev {
24 struct mtd_info *mtd; 26 struct mtd_info *mtd;
25 int count; 27 int count;
26 struct semaphore cache_sem; 28 struct mutex cache_mutex;
27 unsigned char *cache_data; 29 unsigned char *cache_data;
28 unsigned long cache_offset; 30 unsigned long cache_offset;
29 unsigned int cache_size; 31 unsigned int cache_size;
@@ -284,7 +286,7 @@ static int mtdblock_open(struct mtd_blktrans_dev *mbd)
284 mtdblk->count = 1; 286 mtdblk->count = 1;
285 mtdblk->mtd = mtd; 287 mtdblk->mtd = mtd;
286 288
287 init_MUTEX (&mtdblk->cache_sem); 289 mutex_init(&mtdblk->cache_mutex);
288 mtdblk->cache_state = STATE_EMPTY; 290 mtdblk->cache_state = STATE_EMPTY;
289 if ((mtdblk->mtd->flags & MTD_CAP_RAM) != MTD_CAP_RAM && 291 if ((mtdblk->mtd->flags & MTD_CAP_RAM) != MTD_CAP_RAM &&
290 mtdblk->mtd->erasesize) { 292 mtdblk->mtd->erasesize) {
@@ -306,9 +308,9 @@ static int mtdblock_release(struct mtd_blktrans_dev *mbd)
306 308
307 DEBUG(MTD_DEBUG_LEVEL1, "mtdblock_release\n"); 309 DEBUG(MTD_DEBUG_LEVEL1, "mtdblock_release\n");
308 310
309 down(&mtdblk->cache_sem); 311 mutex_lock(&mtdblk->cache_mutex);
310 write_cached_data(mtdblk); 312 write_cached_data(mtdblk);
311 up(&mtdblk->cache_sem); 313 mutex_unlock(&mtdblk->cache_mutex);
312 314
313 if (!--mtdblk->count) { 315 if (!--mtdblk->count) {
314 /* It was the last usage. Free the device */ 316 /* It was the last usage. Free the device */
@@ -327,9 +329,9 @@ static int mtdblock_flush(struct mtd_blktrans_dev *dev)
327{ 329{
328 struct mtdblk_dev *mtdblk = mtdblks[dev->devnum]; 330 struct mtdblk_dev *mtdblk = mtdblks[dev->devnum];
329 331
330 down(&mtdblk->cache_sem); 332 mutex_lock(&mtdblk->cache_mutex);
331 write_cached_data(mtdblk); 333 write_cached_data(mtdblk);
332 up(&mtdblk->cache_sem); 334 mutex_unlock(&mtdblk->cache_mutex);
333 335
334 if (mtdblk->mtd->sync) 336 if (mtdblk->mtd->sync)
335 mtdblk->mtd->sync(mtdblk->mtd); 337 mtdblk->mtd->sync(mtdblk->mtd);
diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c
index dade02ab0687..9905870f56e5 100644
--- a/drivers/mtd/mtdcore.c
+++ b/drivers/mtd/mtdcore.c
@@ -19,15 +19,13 @@
19#include <linux/ioctl.h> 19#include <linux/ioctl.h>
20#include <linux/init.h> 20#include <linux/init.h>
21#include <linux/mtd/compatmac.h> 21#include <linux/mtd/compatmac.h>
22#ifdef CONFIG_PROC_FS
23#include <linux/proc_fs.h> 22#include <linux/proc_fs.h>
24#endif
25 23
26#include <linux/mtd/mtd.h> 24#include <linux/mtd/mtd.h>
27 25
28/* These are exported solely for the purpose of mtd_blkdevs.c. You 26/* These are exported solely for the purpose of mtd_blkdevs.c. You
29 should not use them for _anything_ else */ 27 should not use them for _anything_ else */
30DECLARE_MUTEX(mtd_table_mutex); 28DEFINE_MUTEX(mtd_table_mutex);
31struct mtd_info *mtd_table[MAX_MTD_DEVICES]; 29struct mtd_info *mtd_table[MAX_MTD_DEVICES];
32 30
33EXPORT_SYMBOL_GPL(mtd_table_mutex); 31EXPORT_SYMBOL_GPL(mtd_table_mutex);
@@ -49,7 +47,7 @@ int add_mtd_device(struct mtd_info *mtd)
49{ 47{
50 int i; 48 int i;
51 49
52 down(&mtd_table_mutex); 50 mutex_lock(&mtd_table_mutex);
53 51
54 for (i=0; i < MAX_MTD_DEVICES; i++) 52 for (i=0; i < MAX_MTD_DEVICES; i++)
55 if (!mtd_table[i]) { 53 if (!mtd_table[i]) {
@@ -67,7 +65,7 @@ int add_mtd_device(struct mtd_info *mtd)
67 not->add(mtd); 65 not->add(mtd);
68 } 66 }
69 67
70 up(&mtd_table_mutex); 68 mutex_unlock(&mtd_table_mutex);
71 /* We _know_ we aren't being removed, because 69 /* We _know_ we aren't being removed, because
72 our caller is still holding us here. So none 70 our caller is still holding us here. So none
73 of this try_ nonsense, and no bitching about it 71 of this try_ nonsense, and no bitching about it
@@ -76,7 +74,7 @@ int add_mtd_device(struct mtd_info *mtd)
76 return 0; 74 return 0;
77 } 75 }
78 76
79 up(&mtd_table_mutex); 77 mutex_unlock(&mtd_table_mutex);
80 return 1; 78 return 1;
81} 79}
82 80
@@ -94,7 +92,7 @@ int del_mtd_device (struct mtd_info *mtd)
94{ 92{
95 int ret; 93 int ret;
96 94
97 down(&mtd_table_mutex); 95 mutex_lock(&mtd_table_mutex);
98 96
99 if (mtd_table[mtd->index] != mtd) { 97 if (mtd_table[mtd->index] != mtd) {
100 ret = -ENODEV; 98 ret = -ENODEV;
@@ -118,7 +116,7 @@ int del_mtd_device (struct mtd_info *mtd)
118 ret = 0; 116 ret = 0;
119 } 117 }
120 118
121 up(&mtd_table_mutex); 119 mutex_unlock(&mtd_table_mutex);
122 return ret; 120 return ret;
123} 121}
124 122
@@ -135,7 +133,7 @@ void register_mtd_user (struct mtd_notifier *new)
135{ 133{
136 int i; 134 int i;
137 135
138 down(&mtd_table_mutex); 136 mutex_lock(&mtd_table_mutex);
139 137
140 list_add(&new->list, &mtd_notifiers); 138 list_add(&new->list, &mtd_notifiers);
141 139
@@ -145,7 +143,7 @@ void register_mtd_user (struct mtd_notifier *new)
145 if (mtd_table[i]) 143 if (mtd_table[i])
146 new->add(mtd_table[i]); 144 new->add(mtd_table[i]);
147 145
148 up(&mtd_table_mutex); 146 mutex_unlock(&mtd_table_mutex);
149} 147}
150 148
151/** 149/**
@@ -162,7 +160,7 @@ int unregister_mtd_user (struct mtd_notifier *old)
162{ 160{
163 int i; 161 int i;
164 162
165 down(&mtd_table_mutex); 163 mutex_lock(&mtd_table_mutex);
166 164
167 module_put(THIS_MODULE); 165 module_put(THIS_MODULE);
168 166
@@ -171,7 +169,7 @@ int unregister_mtd_user (struct mtd_notifier *old)
171 old->remove(mtd_table[i]); 169 old->remove(mtd_table[i]);
172 170
173 list_del(&old->list); 171 list_del(&old->list);
174 up(&mtd_table_mutex); 172 mutex_unlock(&mtd_table_mutex);
175 return 0; 173 return 0;
176} 174}
177 175
@@ -193,7 +191,7 @@ struct mtd_info *get_mtd_device(struct mtd_info *mtd, int num)
193 struct mtd_info *ret = NULL; 191 struct mtd_info *ret = NULL;
194 int i; 192 int i;
195 193
196 down(&mtd_table_mutex); 194 mutex_lock(&mtd_table_mutex);
197 195
198 if (num == -1) { 196 if (num == -1) {
199 for (i=0; i< MAX_MTD_DEVICES; i++) 197 for (i=0; i< MAX_MTD_DEVICES; i++)
@@ -211,7 +209,7 @@ struct mtd_info *get_mtd_device(struct mtd_info *mtd, int num)
211 if (ret) 209 if (ret)
212 ret->usecount++; 210 ret->usecount++;
213 211
214 up(&mtd_table_mutex); 212 mutex_unlock(&mtd_table_mutex);
215 return ret; 213 return ret;
216} 214}
217 215
@@ -219,9 +217,9 @@ void put_mtd_device(struct mtd_info *mtd)
219{ 217{
220 int c; 218 int c;
221 219
222 down(&mtd_table_mutex); 220 mutex_lock(&mtd_table_mutex);
223 c = --mtd->usecount; 221 c = --mtd->usecount;
224 up(&mtd_table_mutex); 222 mutex_unlock(&mtd_table_mutex);
225 BUG_ON(c < 0); 223 BUG_ON(c < 0);
226 224
227 module_put(mtd->owner); 225 module_put(mtd->owner);
@@ -296,10 +294,11 @@ EXPORT_SYMBOL(unregister_mtd_user);
296EXPORT_SYMBOL(default_mtd_writev); 294EXPORT_SYMBOL(default_mtd_writev);
297EXPORT_SYMBOL(default_mtd_readv); 295EXPORT_SYMBOL(default_mtd_readv);
298 296
297#ifdef CONFIG_PROC_FS
298
299/*====================================================================*/ 299/*====================================================================*/
300/* Support for /proc/mtd */ 300/* Support for /proc/mtd */
301 301
302#ifdef CONFIG_PROC_FS
303static struct proc_dir_entry *proc_mtd; 302static struct proc_dir_entry *proc_mtd;
304 303
305static inline int mtd_proc_info (char *buf, int i) 304static inline int mtd_proc_info (char *buf, int i)
@@ -319,7 +318,7 @@ static int mtd_read_proc (char *page, char **start, off_t off, int count,
319 int len, l, i; 318 int len, l, i;
320 off_t begin = 0; 319 off_t begin = 0;
321 320
322 down(&mtd_table_mutex); 321 mutex_lock(&mtd_table_mutex);
323 322
324 len = sprintf(page, "dev: size erasesize name\n"); 323 len = sprintf(page, "dev: size erasesize name\n");
325 for (i=0; i< MAX_MTD_DEVICES; i++) { 324 for (i=0; i< MAX_MTD_DEVICES; i++) {
@@ -337,38 +336,34 @@ static int mtd_read_proc (char *page, char **start, off_t off, int count,
337 *eof = 1; 336 *eof = 1;
338 337
339done: 338done:
340 up(&mtd_table_mutex); 339 mutex_unlock(&mtd_table_mutex);
341 if (off >= len+begin) 340 if (off >= len+begin)
342 return 0; 341 return 0;
343 *start = page + (off-begin); 342 *start = page + (off-begin);
344 return ((count < begin+len-off) ? count : begin+len-off); 343 return ((count < begin+len-off) ? count : begin+len-off);
345} 344}
346 345
347#endif /* CONFIG_PROC_FS */
348
349/*====================================================================*/ 346/*====================================================================*/
350/* Init code */ 347/* Init code */
351 348
352static int __init init_mtd(void) 349static int __init init_mtd(void)
353{ 350{
354#ifdef CONFIG_PROC_FS
355 if ((proc_mtd = create_proc_entry( "mtd", 0, NULL ))) 351 if ((proc_mtd = create_proc_entry( "mtd", 0, NULL )))
356 proc_mtd->read_proc = mtd_read_proc; 352 proc_mtd->read_proc = mtd_read_proc;
357#endif
358 return 0; 353 return 0;
359} 354}
360 355
361static void __exit cleanup_mtd(void) 356static void __exit cleanup_mtd(void)
362{ 357{
363#ifdef CONFIG_PROC_FS
364 if (proc_mtd) 358 if (proc_mtd)
365 remove_proc_entry( "mtd", NULL); 359 remove_proc_entry( "mtd", NULL);
366#endif
367} 360}
368 361
369module_init(init_mtd); 362module_init(init_mtd);
370module_exit(cleanup_mtd); 363module_exit(cleanup_mtd);
371 364
365#endif /* CONFIG_PROC_FS */
366
372 367
373MODULE_LICENSE("GPL"); 368MODULE_LICENSE("GPL");
374MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org>"); 369MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org>");
diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig
index 1fc4c134d939..cfe288a6e853 100644
--- a/drivers/mtd/nand/Kconfig
+++ b/drivers/mtd/nand/Kconfig
@@ -178,17 +178,16 @@ config MTD_NAND_DISKONCHIP_BBTWRITE
178 Even if you leave this disabled, you can enable BBT writes at module 178 Even if you leave this disabled, you can enable BBT writes at module
179 load time (assuming you build diskonchip as a module) with the module 179 load time (assuming you build diskonchip as a module) with the module
180 parameter "inftl_bbt_write=1". 180 parameter "inftl_bbt_write=1".
181
182 config MTD_NAND_SHARPSL
183 bool "Support for NAND Flash on Sharp SL Series (C7xx + others)"
184 depends on MTD_NAND && ARCH_PXA
185
186 config MTD_NAND_NANDSIM
187 bool "Support for NAND Flash Simulator"
188 depends on MTD_NAND && MTD_PARTITIONS
189 181
182config MTD_NAND_SHARPSL
183 tristate "Support for NAND Flash on Sharp SL Series (C7xx + others)"
184 depends on MTD_NAND && ARCH_PXA
185
186config MTD_NAND_NANDSIM
187 tristate "Support for NAND Flash Simulator"
188 depends on MTD_NAND && MTD_PARTITIONS
190 help 189 help
191 The simulator may simulate verious NAND flash chips for the 190 The simulator may simulate verious NAND flash chips for the
192 MTD nand layer. 191 MTD nand layer.
193 192
194endmenu 193endmenu
diff --git a/drivers/mtd/nand/au1550nd.c b/drivers/mtd/nand/au1550nd.c
index 201e1362da14..bde3550910a2 100644
--- a/drivers/mtd/nand/au1550nd.c
+++ b/drivers/mtd/nand/au1550nd.c
@@ -55,8 +55,6 @@ static const struct mtd_partition partition_info[] = {
55 .size = MTDPART_SIZ_FULL 55 .size = MTDPART_SIZ_FULL
56 } 56 }
57}; 57};
58#define NB_OF(x) (sizeof(x)/sizeof(x[0]))
59
60 58
61/** 59/**
62 * au_read_byte - read one byte from the chip 60 * au_read_byte - read one byte from the chip
@@ -462,7 +460,7 @@ int __init au1xxx_nand_init (void)
462 } 460 }
463 461
464 /* Register the partitions */ 462 /* Register the partitions */
465 add_mtd_partitions(au1550_mtd, partition_info, NB_OF(partition_info)); 463 add_mtd_partitions(au1550_mtd, partition_info, ARRAY_SIZE(partition_info));
466 464
467 return 0; 465 return 0;
468 466
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index 5d222460b42a..95e96fa1fceb 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -80,6 +80,7 @@
80#include <linux/mtd/compatmac.h> 80#include <linux/mtd/compatmac.h>
81#include <linux/interrupt.h> 81#include <linux/interrupt.h>
82#include <linux/bitops.h> 82#include <linux/bitops.h>
83#include <linux/leds.h>
83#include <asm/io.h> 84#include <asm/io.h>
84 85
85#ifdef CONFIG_MTD_PARTITIONS 86#ifdef CONFIG_MTD_PARTITIONS
@@ -515,6 +516,8 @@ static int nand_block_checkbad (struct mtd_info *mtd, loff_t ofs, int getchip, i
515 return nand_isbad_bbt (mtd, ofs, allowbbt); 516 return nand_isbad_bbt (mtd, ofs, allowbbt);
516} 517}
517 518
519DEFINE_LED_TRIGGER(nand_led_trigger);
520
518/* 521/*
519 * Wait for the ready pin, after a command 522 * Wait for the ready pin, after a command
520 * The timeout is catched later. 523 * The timeout is catched later.
@@ -524,12 +527,14 @@ static void nand_wait_ready(struct mtd_info *mtd)
524 struct nand_chip *this = mtd->priv; 527 struct nand_chip *this = mtd->priv;
525 unsigned long timeo = jiffies + 2; 528 unsigned long timeo = jiffies + 2;
526 529
530 led_trigger_event(nand_led_trigger, LED_FULL);
527 /* wait until command is processed or timeout occures */ 531 /* wait until command is processed or timeout occures */
528 do { 532 do {
529 if (this->dev_ready(mtd)) 533 if (this->dev_ready(mtd))
530 return; 534 break;
531 touch_softlockup_watchdog(); 535 touch_softlockup_watchdog();
532 } while (time_before(jiffies, timeo)); 536 } while (time_before(jiffies, timeo));
537 led_trigger_event(nand_led_trigger, LED_OFF);
533} 538}
534 539
535/** 540/**
@@ -817,6 +822,8 @@ static int nand_wait(struct mtd_info *mtd, struct nand_chip *this, int state)
817 else 822 else
818 timeo += (HZ * 20) / 1000; 823 timeo += (HZ * 20) / 1000;
819 824
825 led_trigger_event(nand_led_trigger, LED_FULL);
826
820 /* Apply this short delay always to ensure that we do wait tWB in 827 /* Apply this short delay always to ensure that we do wait tWB in
821 * any case on any machine. */ 828 * any case on any machine. */
822 ndelay (100); 829 ndelay (100);
@@ -840,6 +847,8 @@ static int nand_wait(struct mtd_info *mtd, struct nand_chip *this, int state)
840 } 847 }
841 cond_resched(); 848 cond_resched();
842 } 849 }
850 led_trigger_event(nand_led_trigger, LED_OFF);
851
843 status = (int) this->read_byte(mtd); 852 status = (int) this->read_byte(mtd);
844 return status; 853 return status;
845} 854}
@@ -2724,6 +2733,21 @@ void nand_release (struct mtd_info *mtd)
2724EXPORT_SYMBOL_GPL (nand_scan); 2733EXPORT_SYMBOL_GPL (nand_scan);
2725EXPORT_SYMBOL_GPL (nand_release); 2734EXPORT_SYMBOL_GPL (nand_release);
2726 2735
2736
2737static int __init nand_base_init(void)
2738{
2739 led_trigger_register_simple("nand-disk", &nand_led_trigger);
2740 return 0;
2741}
2742
2743static void __exit nand_base_exit(void)
2744{
2745 led_trigger_unregister_simple(nand_led_trigger);
2746}
2747
2748module_init(nand_base_init);
2749module_exit(nand_base_exit);
2750
2727MODULE_LICENSE ("GPL"); 2751MODULE_LICENSE ("GPL");
2728MODULE_AUTHOR ("Steven J. Hill <sjhill@realitydiluted.com>, Thomas Gleixner <tglx@linutronix.de>"); 2752MODULE_AUTHOR ("Steven J. Hill <sjhill@realitydiluted.com>, Thomas Gleixner <tglx@linutronix.de>");
2729MODULE_DESCRIPTION ("Generic NAND flash driver code"); 2753MODULE_DESCRIPTION ("Generic NAND flash driver code");
diff --git a/drivers/mtd/redboot.c b/drivers/mtd/redboot.c
index 8815c8dbef2d..c077d2ec9cdd 100644
--- a/drivers/mtd/redboot.c
+++ b/drivers/mtd/redboot.c
@@ -85,10 +85,6 @@ static int parse_redboot_partitions(struct mtd_info *master,
85 85
86 numslots = (master->erasesize / sizeof(struct fis_image_desc)); 86 numslots = (master->erasesize / sizeof(struct fis_image_desc));
87 for (i = 0; i < numslots; i++) { 87 for (i = 0; i < numslots; i++) {
88 if (buf[i].name[0] == 0xff) {
89 i = numslots;
90 break;
91 }
92 if (!memcmp(buf[i].name, "FIS directory", 14)) { 88 if (!memcmp(buf[i].name, "FIS directory", 14)) {
93 /* This is apparently the FIS directory entry for the 89 /* This is apparently the FIS directory entry for the
94 * FIS directory itself. The FIS directory size is 90 * FIS directory itself. The FIS directory size is
@@ -128,7 +124,7 @@ static int parse_redboot_partitions(struct mtd_info *master,
128 struct fis_list *new_fl, **prev; 124 struct fis_list *new_fl, **prev;
129 125
130 if (buf[i].name[0] == 0xff) 126 if (buf[i].name[0] == 0xff)
131 break; 127 continue;
132 if (!redboot_checksum(&buf[i])) 128 if (!redboot_checksum(&buf[i]))
133 break; 129 break;
134 130
diff --git a/drivers/net/3c59x.c b/drivers/net/3c59x.c
index 70f63891b19c..274b0138d442 100644
--- a/drivers/net/3c59x.c
+++ b/drivers/net/3c59x.c
@@ -788,7 +788,7 @@ struct vortex_private {
788 int options; /* User-settable misc. driver options. */ 788 int options; /* User-settable misc. driver options. */
789 unsigned int media_override:4, /* Passed-in media type. */ 789 unsigned int media_override:4, /* Passed-in media type. */
790 default_media:4, /* Read from the EEPROM/Wn3_Config. */ 790 default_media:4, /* Read from the EEPROM/Wn3_Config. */
791 full_duplex:1, force_fd:1, autoselect:1, 791 full_duplex:1, autoselect:1,
792 bus_master:1, /* Vortex can only do a fragment bus-m. */ 792 bus_master:1, /* Vortex can only do a fragment bus-m. */
793 full_bus_master_tx:1, full_bus_master_rx:2, /* Boomerang */ 793 full_bus_master_tx:1, full_bus_master_rx:2, /* Boomerang */
794 flow_ctrl:1, /* Use 802.3x flow control (PAUSE only) */ 794 flow_ctrl:1, /* Use 802.3x flow control (PAUSE only) */
@@ -1633,12 +1633,6 @@ vortex_set_duplex(struct net_device *dev)
1633 ((vp->full_duplex && vp->flow_ctrl && vp->partner_flow_ctrl) ? 1633 ((vp->full_duplex && vp->flow_ctrl && vp->partner_flow_ctrl) ?
1634 0x100 : 0), 1634 0x100 : 0),
1635 ioaddr + Wn3_MAC_Ctrl); 1635 ioaddr + Wn3_MAC_Ctrl);
1636
1637 issue_and_wait(dev, TxReset);
1638 /*
1639 * Don't reset the PHY - that upsets autonegotiation during DHCP operations.
1640 */
1641 issue_and_wait(dev, RxReset|0x04);
1642} 1636}
1643 1637
1644static void vortex_check_media(struct net_device *dev, unsigned int init) 1638static void vortex_check_media(struct net_device *dev, unsigned int init)
@@ -1663,7 +1657,7 @@ vortex_up(struct net_device *dev)
1663 struct vortex_private *vp = netdev_priv(dev); 1657 struct vortex_private *vp = netdev_priv(dev);
1664 void __iomem *ioaddr = vp->ioaddr; 1658 void __iomem *ioaddr = vp->ioaddr;
1665 unsigned int config; 1659 unsigned int config;
1666 int i; 1660 int i, mii_reg1, mii_reg5;
1667 1661
1668 if (VORTEX_PCI(vp)) { 1662 if (VORTEX_PCI(vp)) {
1669 pci_set_power_state(VORTEX_PCI(vp), PCI_D0); /* Go active */ 1663 pci_set_power_state(VORTEX_PCI(vp), PCI_D0); /* Go active */
@@ -1723,14 +1717,23 @@ vortex_up(struct net_device *dev)
1723 printk(KERN_DEBUG "vortex_up(): writing 0x%x to InternalConfig\n", config); 1717 printk(KERN_DEBUG "vortex_up(): writing 0x%x to InternalConfig\n", config);
1724 iowrite32(config, ioaddr + Wn3_Config); 1718 iowrite32(config, ioaddr + Wn3_Config);
1725 1719
1726 netif_carrier_off(dev);
1727 if (dev->if_port == XCVR_MII || dev->if_port == XCVR_NWAY) { 1720 if (dev->if_port == XCVR_MII || dev->if_port == XCVR_NWAY) {
1728 EL3WINDOW(4); 1721 EL3WINDOW(4);
1722 mii_reg1 = mdio_read(dev, vp->phys[0], MII_BMSR);
1723 mii_reg5 = mdio_read(dev, vp->phys[0], MII_LPA);
1724 vp->partner_flow_ctrl = ((mii_reg5 & 0x0400) != 0);
1725
1729 vortex_check_media(dev, 1); 1726 vortex_check_media(dev, 1);
1730 } 1727 }
1731 else 1728 else
1732 vortex_set_duplex(dev); 1729 vortex_set_duplex(dev);
1733 1730
1731 issue_and_wait(dev, TxReset);
1732 /*
1733 * Don't reset the PHY - that upsets autonegotiation during DHCP operations.
1734 */
1735 issue_and_wait(dev, RxReset|0x04);
1736
1734 1737
1735 iowrite16(SetStatusEnb | 0x00, ioaddr + EL3_CMD); 1738 iowrite16(SetStatusEnb | 0x00, ioaddr + EL3_CMD);
1736 1739
@@ -2083,16 +2086,14 @@ vortex_error(struct net_device *dev, int status)
2083 } 2086 }
2084 if (tx_status & 0x14) vp->stats.tx_fifo_errors++; 2087 if (tx_status & 0x14) vp->stats.tx_fifo_errors++;
2085 if (tx_status & 0x38) vp->stats.tx_aborted_errors++; 2088 if (tx_status & 0x38) vp->stats.tx_aborted_errors++;
2089 if (tx_status & 0x08) vp->xstats.tx_max_collisions++;
2086 iowrite8(0, ioaddr + TxStatus); 2090 iowrite8(0, ioaddr + TxStatus);
2087 if (tx_status & 0x30) { /* txJabber or txUnderrun */ 2091 if (tx_status & 0x30) { /* txJabber or txUnderrun */
2088 do_tx_reset = 1; 2092 do_tx_reset = 1;
2089 } else if (tx_status & 0x08) { /* maxCollisions */ 2093 } else if ((tx_status & 0x08) && (vp->drv_flags & MAX_COLLISION_RESET)) { /* maxCollisions */
2090 vp->xstats.tx_max_collisions++; 2094 do_tx_reset = 1;
2091 if (vp->drv_flags & MAX_COLLISION_RESET) { 2095 reset_mask = 0x0108; /* Reset interface logic, but not download logic */
2092 do_tx_reset = 1; 2096 } else { /* Merely re-enable the transmitter. */
2093 reset_mask = 0x0108; /* Reset interface logic, but not download logic */
2094 }
2095 } else { /* Merely re-enable the transmitter. */
2096 iowrite16(TxEnable, ioaddr + EL3_CMD); 2097 iowrite16(TxEnable, ioaddr + EL3_CMD);
2097 } 2098 }
2098 } 2099 }
diff --git a/drivers/net/8390.h b/drivers/net/8390.h
index 599b68d8c45f..51e39dcd0603 100644
--- a/drivers/net/8390.h
+++ b/drivers/net/8390.h
@@ -134,7 +134,7 @@ struct ei_device {
134#define inb_p(_p) inb(_p) 134#define inb_p(_p) inb(_p)
135#define outb_p(_v,_p) outb(_v,_p) 135#define outb_p(_v,_p) outb(_v,_p)
136 136
137#elif defined(CONFIG_NET_CBUS) || defined(CONFIG_NE_H8300) || defined(CONFIG_NE_H8300_MODULE) 137#elif defined(CONFIG_NE_H8300) || defined(CONFIG_NE_H8300_MODULE)
138#define EI_SHIFT(x) (ei_local->reg_offset[x]) 138#define EI_SHIFT(x) (ei_local->reg_offset[x])
139#else 139#else
140#define EI_SHIFT(x) (x) 140#define EI_SHIFT(x) (x)
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index e20b849a22e8..bdaaad8f2123 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -2313,13 +2313,11 @@ config S2IO_NAPI
2313 2313
2314endmenu 2314endmenu
2315 2315
2316if !UML
2317source "drivers/net/tokenring/Kconfig" 2316source "drivers/net/tokenring/Kconfig"
2318 2317
2319source "drivers/net/wireless/Kconfig" 2318source "drivers/net/wireless/Kconfig"
2320 2319
2321source "drivers/net/pcmcia/Kconfig" 2320source "drivers/net/pcmcia/Kconfig"
2322endif
2323 2321
2324source "drivers/net/wan/Kconfig" 2322source "drivers/net/wan/Kconfig"
2325 2323
diff --git a/drivers/net/acenic_firmware.h b/drivers/net/acenic_firmware.h
index 6d625d595622..d7882dd783c8 100644
--- a/drivers/net/acenic_firmware.h
+++ b/drivers/net/acenic_firmware.h
@@ -4397,7 +4397,7 @@ static u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __devinitdata = {
43970x3c010001, 0x220821, 0xac317e30, 0x8fbf0024, 43970x3c010001, 0x220821, 0xac317e30, 0x8fbf0024,
43980x8fb40020, 0x8fb3001c, 0x8fb20018, 0x8fb10014, 43980x8fb40020, 0x8fb3001c, 0x8fb20018, 0x8fb10014,
43990x8fb00010, 0x3e00008, 0x27bd0028, 0x0 }; 43990x8fb00010, 0x3e00008, 0x27bd0028, 0x0 };
4400static u32 tigonFwRodata[(MAX_RODATA_LEN/4) + 1] __initdata = { 4400static u32 tigonFwRodata[(MAX_RODATA_LEN/4) + 1] __devinitdata = {
44010x24486561, 0x6465723a, 0x202f7072, 44010x24486561, 0x6465723a, 0x202f7072,
44020x6f6a6563, 0x74732f72, 0x63732f73, 0x772f6765, 44020x6f6a6563, 0x74732f72, 0x63732f73, 0x772f6765,
44030x2f2e2f6e, 0x69632f66, 0x772f636f, 0x6d6d6f6e, 44030x2f2e2f6e, 0x69632f66, 0x772f636f, 0x6d6d6f6e,
@@ -4571,7 +4571,7 @@ static u32 tigonFwRodata[(MAX_RODATA_LEN/4) + 1] __initdata = {
45710x0, 0x14c38, 0x14c38, 0x14b80, 45710x0, 0x14c38, 0x14c38, 0x14b80,
45720x14bc4, 0x14c38, 0x14c38, 0x0, 45720x14bc4, 0x14c38, 0x14c38, 0x0,
45730x0, 0x0 }; 45730x0, 0x0 };
4574static u32 tigonFwData[(MAX_DATA_LEN/4) + 1] __initdata = { 4574static u32 tigonFwData[(MAX_DATA_LEN/4) + 1] __devinitdata = {
45750x416c7465, 45750x416c7465,
45760x6f6e2041, 0x63654e49, 0x43205600, 0x416c7465, 45760x6f6e2041, 0x63654e49, 0x43205600, 0x416c7465,
45770x6f6e2041, 0x63654e49, 0x43205600, 0x42424242, 45770x6f6e2041, 0x63654e49, 0x43205600, 0x42424242,
@@ -4612,7 +4612,7 @@ static u32 tigonFwData[(MAX_DATA_LEN/4) + 1] __initdata = {
4612#define tigon2FwSbssLen 0xcc 4612#define tigon2FwSbssLen 0xcc
4613#define tigon2FwBssAddr 0x00016f50 4613#define tigon2FwBssAddr 0x00016f50
4614#define tigon2FwBssLen 0x20c0 4614#define tigon2FwBssLen 0x20c0
4615static u32 tigon2FwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 4615static u32 tigon2FwText[(MAX_TEXT_LEN/4) + 1] __devinitdata = {
46160x0, 46160x0,
46170x10000003, 0x0, 0xd, 0xd, 46170x10000003, 0x0, 0xd, 0xd,
46180x3c1d0001, 0x8fbd6d20, 0x3a0f021, 0x3c100000, 46180x3c1d0001, 0x8fbd6d20, 0x3a0f021, 0x3c100000,
@@ -9154,7 +9154,7 @@ static u32 tigon2FwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
91540x24020001, 0x8f430328, 0x1021, 0x24630001, 91540x24020001, 0x8f430328, 0x1021, 0x24630001,
91550x3e00008, 0xaf430328, 0x3e00008, 0x0, 91550x3e00008, 0xaf430328, 0x3e00008, 0x0,
91560x0, 0x0, 0x0, 0x0 }; 91560x0, 0x0, 0x0, 0x0 };
9157static u32 tigon2FwRodata[(MAX_RODATA_LEN/4) + 1] __initdata = { 9157static u32 tigon2FwRodata[(MAX_RODATA_LEN/4) + 1] __devinitdata = {
91580x24486561, 0x6465723a, 0x202f7072, 91580x24486561, 0x6465723a, 0x202f7072,
91590x6f6a6563, 0x74732f72, 0x63732f73, 0x772f6765, 91590x6f6a6563, 0x74732f72, 0x63732f73, 0x772f6765,
91600x2f2e2f6e, 0x69632f66, 0x77322f63, 0x6f6d6d6f, 91600x2f2e2f6e, 0x69632f66, 0x77322f63, 0x6f6d6d6f,
@@ -9425,7 +9425,7 @@ static u32 tigon2FwRodata[(MAX_RODATA_LEN/4) + 1] __initdata = {
94250x14ed8, 0x14b8c, 0x14bd8, 0x14c24, 94250x14ed8, 0x14b8c, 0x14bd8, 0x14c24,
94260x14ed8, 0x7365746d, 0x61636163, 0x74000000, 94260x14ed8, 0x7365746d, 0x61636163, 0x74000000,
94270x0, 0x0 }; 94270x0, 0x0 };
9428static u32 tigon2FwData[(MAX_DATA_LEN/4) + 1] __initdata = { 9428static u32 tigon2FwData[(MAX_DATA_LEN/4) + 1] __devinitdata = {
94290x1, 94290x1,
94300x1, 0x1, 0xc001fc, 0x3ffc, 94300x1, 0x1, 0xc001fc, 0x3ffc,
94310xc00000, 0x416c7465, 0x6f6e2041, 0x63654e49, 94310xc00000, 0x416c7465, 0x6f6e2041, 0x63654e49,
diff --git a/drivers/net/b44.c b/drivers/net/b44.c
index c3267e4e1bb0..15032f2c7817 100644
--- a/drivers/net/b44.c
+++ b/drivers/net/b44.c
@@ -1339,6 +1339,9 @@ static int b44_set_mac_addr(struct net_device *dev, void *p)
1339 if (netif_running(dev)) 1339 if (netif_running(dev))
1340 return -EBUSY; 1340 return -EBUSY;
1341 1341
1342 if (!is_valid_ether_addr(addr->sa_data))
1343 return -EINVAL;
1344
1342 memcpy(dev->dev_addr, addr->sa_data, dev->addr_len); 1345 memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
1343 1346
1344 spin_lock_irq(&bp->lock); 1347 spin_lock_irq(&bp->lock);
@@ -1876,6 +1879,12 @@ static int __devinit b44_get_invariants(struct b44 *bp)
1876 bp->dev->dev_addr[3] = eeprom[80]; 1879 bp->dev->dev_addr[3] = eeprom[80];
1877 bp->dev->dev_addr[4] = eeprom[83]; 1880 bp->dev->dev_addr[4] = eeprom[83];
1878 bp->dev->dev_addr[5] = eeprom[82]; 1881 bp->dev->dev_addr[5] = eeprom[82];
1882
1883 if (!is_valid_ether_addr(&bp->dev->dev_addr[0])){
1884 printk(KERN_ERR PFX "Invalid MAC address found in EEPROM\n");
1885 return -EINVAL;
1886 }
1887
1879 memcpy(bp->dev->perm_addr, bp->dev->dev_addr, bp->dev->addr_len); 1888 memcpy(bp->dev->perm_addr, bp->dev->dev_addr, bp->dev->addr_len);
1880 1889
1881 bp->phy_addr = eeprom[90] & 0x1f; 1890 bp->phy_addr = eeprom[90] & 0x1f;
@@ -2033,6 +2042,11 @@ static int __devinit b44_init_one(struct pci_dev *pdev,
2033 2042
2034 pci_save_state(bp->pdev); 2043 pci_save_state(bp->pdev);
2035 2044
2045 /* Chip reset provides power to the b44 MAC & PCI cores, which
2046 * is necessary for MAC register access.
2047 */
2048 b44_chip_reset(bp);
2049
2036 printk(KERN_INFO "%s: Broadcom 4400 10/100BaseT Ethernet ", dev->name); 2050 printk(KERN_INFO "%s: Broadcom 4400 10/100BaseT Ethernet ", dev->name);
2037 for (i = 0; i < 6; i++) 2051 for (i = 0; i < 6; i++)
2038 printk("%2.2x%c", dev->dev_addr[i], 2052 printk("%2.2x%c", dev->dev_addr[i],
diff --git a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c
index f3f5825469d6..6a407070c2e8 100644
--- a/drivers/net/bonding/bond_3ad.c
+++ b/drivers/net/bonding/bond_3ad.c
@@ -2294,6 +2294,34 @@ void bond_3ad_handle_link_change(struct slave *slave, char link)
2294 port->sm_vars |= AD_PORT_BEGIN; 2294 port->sm_vars |= AD_PORT_BEGIN;
2295} 2295}
2296 2296
2297/*
2298 * set link state for bonding master: if we have an active partnered
2299 * aggregator, we're up, if not, we're down. Presumes that we cannot
2300 * have an active aggregator if there are no slaves with link up.
2301 *
2302 * Called by bond_set_carrier(). Return zero if carrier state does not
2303 * change, nonzero if it does.
2304 */
2305int bond_3ad_set_carrier(struct bonding *bond)
2306{
2307 struct aggregator *agg;
2308
2309 agg = __get_active_agg(&(SLAVE_AD_INFO(bond->first_slave).aggregator));
2310 if (agg && MAC_ADDRESS_COMPARE(&agg->partner_system, &null_mac_addr)) {
2311 if (!netif_carrier_ok(bond->dev)) {
2312 netif_carrier_on(bond->dev);
2313 return 1;
2314 }
2315 return 0;
2316 }
2317
2318 if (netif_carrier_ok(bond->dev)) {
2319 netif_carrier_off(bond->dev);
2320 return 1;
2321 }
2322 return 0;
2323}
2324
2297/** 2325/**
2298 * bond_3ad_get_active_agg_info - get information of the active aggregator 2326 * bond_3ad_get_active_agg_info - get information of the active aggregator
2299 * @bond: bonding struct to work on 2327 * @bond: bonding struct to work on
diff --git a/drivers/net/bonding/bond_3ad.h b/drivers/net/bonding/bond_3ad.h
index 5ee2cef5b037..6ad5ad6e65d5 100644
--- a/drivers/net/bonding/bond_3ad.h
+++ b/drivers/net/bonding/bond_3ad.h
@@ -283,5 +283,6 @@ void bond_3ad_handle_link_change(struct slave *slave, char link);
283int bond_3ad_get_active_agg_info(struct bonding *bond, struct ad_info *ad_info); 283int bond_3ad_get_active_agg_info(struct bonding *bond, struct ad_info *ad_info);
284int bond_3ad_xmit_xor(struct sk_buff *skb, struct net_device *dev); 284int bond_3ad_xmit_xor(struct sk_buff *skb, struct net_device *dev);
285int bond_3ad_lacpdu_recv(struct sk_buff *skb, struct net_device *dev, struct packet_type* ptype, struct net_device *orig_dev); 285int bond_3ad_lacpdu_recv(struct sk_buff *skb, struct net_device *dev, struct packet_type* ptype, struct net_device *orig_dev);
286int bond_3ad_set_carrier(struct bonding *bond);
286#endif //__BOND_3AD_H__ 287#endif //__BOND_3AD_H__
287 288
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index f13a539dc169..55d236726d11 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -559,6 +559,42 @@ out:
559/*------------------------------- Link status -------------------------------*/ 559/*------------------------------- Link status -------------------------------*/
560 560
561/* 561/*
562 * Set the carrier state for the master according to the state of its
563 * slaves. If any slaves are up, the master is up. In 802.3ad mode,
564 * do special 802.3ad magic.
565 *
566 * Returns zero if carrier state does not change, nonzero if it does.
567 */
568static int bond_set_carrier(struct bonding *bond)
569{
570 struct slave *slave;
571 int i;
572
573 if (bond->slave_cnt == 0)
574 goto down;
575
576 if (bond->params.mode == BOND_MODE_8023AD)
577 return bond_3ad_set_carrier(bond);
578
579 bond_for_each_slave(bond, slave, i) {
580 if (slave->link == BOND_LINK_UP) {
581 if (!netif_carrier_ok(bond->dev)) {
582 netif_carrier_on(bond->dev);
583 return 1;
584 }
585 return 0;
586 }
587 }
588
589down:
590 if (netif_carrier_ok(bond->dev)) {
591 netif_carrier_off(bond->dev);
592 return 1;
593 }
594 return 0;
595}
596
597/*
562 * Get link speed and duplex from the slave's base driver 598 * Get link speed and duplex from the slave's base driver
563 * using ethtool. If for some reason the call fails or the 599 * using ethtool. If for some reason the call fails or the
564 * values are invalid, fake speed and duplex to 100/Full 600 * values are invalid, fake speed and duplex to 100/Full
@@ -1074,10 +1110,24 @@ void bond_change_active_slave(struct bonding *bond, struct slave *new_active)
1074void bond_select_active_slave(struct bonding *bond) 1110void bond_select_active_slave(struct bonding *bond)
1075{ 1111{
1076 struct slave *best_slave; 1112 struct slave *best_slave;
1113 int rv;
1077 1114
1078 best_slave = bond_find_best_slave(bond); 1115 best_slave = bond_find_best_slave(bond);
1079 if (best_slave != bond->curr_active_slave) { 1116 if (best_slave != bond->curr_active_slave) {
1080 bond_change_active_slave(bond, best_slave); 1117 bond_change_active_slave(bond, best_slave);
1118 rv = bond_set_carrier(bond);
1119 if (!rv)
1120 return;
1121
1122 if (netif_carrier_ok(bond->dev)) {
1123 printk(KERN_INFO DRV_NAME
1124 ": %s: first active interface up!\n",
1125 bond->dev->name);
1126 } else {
1127 printk(KERN_INFO DRV_NAME ": %s: "
1128 "now running without any active interface !\n",
1129 bond->dev->name);
1130 }
1081 } 1131 }
1082} 1132}
1083 1133
@@ -1458,10 +1508,14 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
1458 if (((!bond->curr_active_slave) || 1508 if (((!bond->curr_active_slave) ||
1459 (bond->curr_active_slave->dev->priv_flags & IFF_SLAVE_INACTIVE)) && 1509 (bond->curr_active_slave->dev->priv_flags & IFF_SLAVE_INACTIVE)) &&
1460 (new_slave->link != BOND_LINK_DOWN)) { 1510 (new_slave->link != BOND_LINK_DOWN)) {
1461 dprintk("This is the first active slave\n");
1462 /* first slave or no active slave yet, and this link 1511 /* first slave or no active slave yet, and this link
1463 is OK, so make this interface the active one */ 1512 is OK, so make this interface the active one */
1464 bond_change_active_slave(bond, new_slave); 1513 bond_change_active_slave(bond, new_slave);
1514 printk(KERN_INFO DRV_NAME
1515 ": %s: first active interface up!\n",
1516 bond->dev->name);
1517 netif_carrier_on(bond->dev);
1518
1465 } else { 1519 } else {
1466 dprintk("This is just a backup slave\n"); 1520 dprintk("This is just a backup slave\n");
1467 bond_set_slave_inactive_flags(new_slave); 1521 bond_set_slave_inactive_flags(new_slave);
@@ -1517,6 +1571,8 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
1517 break; 1571 break;
1518 } /* switch(bond_mode) */ 1572 } /* switch(bond_mode) */
1519 1573
1574 bond_set_carrier(bond);
1575
1520 write_unlock_bh(&bond->lock); 1576 write_unlock_bh(&bond->lock);
1521 1577
1522 res = bond_create_slave_symlinks(bond_dev, slave_dev); 1578 res = bond_create_slave_symlinks(bond_dev, slave_dev);
@@ -1656,18 +1712,12 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev)
1656 bond_alb_deinit_slave(bond, slave); 1712 bond_alb_deinit_slave(bond, slave);
1657 } 1713 }
1658 1714
1659 if (oldcurrent == slave) { 1715 if (oldcurrent == slave)
1660 bond_select_active_slave(bond); 1716 bond_select_active_slave(bond);
1661 1717
1662 if (!bond->curr_active_slave) {
1663 printk(KERN_INFO DRV_NAME
1664 ": %s: now running without any active "
1665 "interface !\n",
1666 bond_dev->name);
1667 }
1668 }
1669
1670 if (bond->slave_cnt == 0) { 1718 if (bond->slave_cnt == 0) {
1719 bond_set_carrier(bond);
1720
1671 /* if the last slave was removed, zero the mac address 1721 /* if the last slave was removed, zero the mac address
1672 * of the master so it will be set by the application 1722 * of the master so it will be set by the application
1673 * to the mac address of the first slave 1723 * to the mac address of the first slave
@@ -1751,6 +1801,8 @@ static int bond_release_all(struct net_device *bond_dev)
1751 1801
1752 write_lock_bh(&bond->lock); 1802 write_lock_bh(&bond->lock);
1753 1803
1804 netif_carrier_off(bond_dev);
1805
1754 if (bond->slave_cnt == 0) { 1806 if (bond->slave_cnt == 0) {
1755 goto out; 1807 goto out;
1756 } 1808 }
@@ -2187,15 +2239,9 @@ void bond_mii_monitor(struct net_device *bond_dev)
2187 2239
2188 bond_select_active_slave(bond); 2240 bond_select_active_slave(bond);
2189 2241
2190 if (oldcurrent && !bond->curr_active_slave) {
2191 printk(KERN_INFO DRV_NAME
2192 ": %s: now running without any active "
2193 "interface !\n",
2194 bond_dev->name);
2195 }
2196
2197 write_unlock(&bond->curr_slave_lock); 2242 write_unlock(&bond->curr_slave_lock);
2198 } 2243 } else
2244 bond_set_carrier(bond);
2199 2245
2200re_arm: 2246re_arm:
2201 if (bond->params.miimon) { 2247 if (bond->params.miimon) {
@@ -2499,13 +2545,6 @@ void bond_loadbalance_arp_mon(struct net_device *bond_dev)
2499 2545
2500 bond_select_active_slave(bond); 2546 bond_select_active_slave(bond);
2501 2547
2502 if (oldcurrent && !bond->curr_active_slave) {
2503 printk(KERN_INFO DRV_NAME
2504 ": %s: now running without any active "
2505 "interface !\n",
2506 bond_dev->name);
2507 }
2508
2509 write_unlock(&bond->curr_slave_lock); 2548 write_unlock(&bond->curr_slave_lock);
2510 } 2549 }
2511 2550
@@ -2579,12 +2618,15 @@ void bond_activebackup_arp_mon(struct net_device *bond_dev)
2579 bond->current_arp_slave = NULL; 2618 bond->current_arp_slave = NULL;
2580 } 2619 }
2581 2620
2621 bond_set_carrier(bond);
2622
2582 if (slave == bond->curr_active_slave) { 2623 if (slave == bond->curr_active_slave) {
2583 printk(KERN_INFO DRV_NAME 2624 printk(KERN_INFO DRV_NAME
2584 ": %s: %s is up and now the " 2625 ": %s: %s is up and now the "
2585 "active interface\n", 2626 "active interface\n",
2586 bond_dev->name, 2627 bond_dev->name,
2587 slave->dev->name); 2628 slave->dev->name);
2629 netif_carrier_on(bond->dev);
2588 } else { 2630 } else {
2589 printk(KERN_INFO DRV_NAME 2631 printk(KERN_INFO DRV_NAME
2590 ": %s: backup interface %s is " 2632 ": %s: backup interface %s is "
@@ -2844,7 +2886,8 @@ static void bond_info_show_master(struct seq_file *seq)
2844 (curr) ? curr->dev->name : "None"); 2886 (curr) ? curr->dev->name : "None");
2845 } 2887 }
2846 2888
2847 seq_printf(seq, "MII Status: %s\n", (curr) ? "up" : "down"); 2889 seq_printf(seq, "MII Status: %s\n", netif_carrier_ok(bond->dev) ?
2890 "up" : "down");
2848 seq_printf(seq, "MII Polling Interval (ms): %d\n", bond->params.miimon); 2891 seq_printf(seq, "MII Polling Interval (ms): %d\n", bond->params.miimon);
2849 seq_printf(seq, "Up Delay (ms): %d\n", 2892 seq_printf(seq, "Up Delay (ms): %d\n",
2850 bond->params.updelay * bond->params.miimon); 2893 bond->params.updelay * bond->params.miimon);
@@ -4531,6 +4574,8 @@ int bond_create(char *name, struct bond_params *params, struct bonding **newbond
4531 if (newbond) 4574 if (newbond)
4532 *newbond = bond_dev->priv; 4575 *newbond = bond_dev->priv;
4533 4576
4577 netif_carrier_off(bond_dev);
4578
4534 rtnl_unlock(); /* allows sysfs registration of net device */ 4579 rtnl_unlock(); /* allows sysfs registration of net device */
4535 res = bond_create_sysfs_entry(bond_dev->priv); 4580 res = bond_create_sysfs_entry(bond_dev->priv);
4536 goto done; 4581 goto done;
diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h
index ce9dc9b4e2dc..0bdfe2c71453 100644
--- a/drivers/net/bonding/bonding.h
+++ b/drivers/net/bonding/bonding.h
@@ -22,8 +22,8 @@
22#include "bond_3ad.h" 22#include "bond_3ad.h"
23#include "bond_alb.h" 23#include "bond_alb.h"
24 24
25#define DRV_VERSION "3.0.2" 25#define DRV_VERSION "3.0.3"
26#define DRV_RELDATE "February 21, 2006" 26#define DRV_RELDATE "March 23, 2006"
27#define DRV_NAME "bonding" 27#define DRV_NAME "bonding"
28#define DRV_DESCRIPTION "Ethernet Channel Bonding Driver" 28#define DRV_DESCRIPTION "Ethernet Channel Bonding Driver"
29 29
diff --git a/drivers/net/ixp2000/ixpdev.c b/drivers/net/ixp2000/ixpdev.c
index 77f104a005f3..fbc2d21020f4 100644
--- a/drivers/net/ixp2000/ixpdev.c
+++ b/drivers/net/ixp2000/ixpdev.c
@@ -299,10 +299,7 @@ int ixpdev_init(int __nds_count, struct net_device **__nds,
299 int i; 299 int i;
300 int err; 300 int err;
301 301
302 if (RX_BUF_COUNT > 192 || TX_BUF_COUNT > 192) { 302 BUILD_BUG_ON(RX_BUF_COUNT > 192 || TX_BUF_COUNT > 192);
303 static void __too_many_rx_or_tx_buffers(void);
304 __too_many_rx_or_tx_buffers();
305 }
306 303
307 printk(KERN_INFO "IXP2000 MSF ethernet driver %s\n", DRV_MODULE_VERSION); 304 printk(KERN_INFO "IXP2000 MSF ethernet driver %s\n", DRV_MODULE_VERSION);
308 305
diff --git a/drivers/net/natsemi.c b/drivers/net/natsemi.c
index 8d4999837b65..7826afbb9db9 100644
--- a/drivers/net/natsemi.c
+++ b/drivers/net/natsemi.c
@@ -226,7 +226,7 @@ static int full_duplex[MAX_UNITS];
226 NATSEMI_PG1_NREGS) 226 NATSEMI_PG1_NREGS)
227#define NATSEMI_REGS_VER 1 /* v1 added RFDR registers */ 227#define NATSEMI_REGS_VER 1 /* v1 added RFDR registers */
228#define NATSEMI_REGS_SIZE (NATSEMI_NREGS * sizeof(u32)) 228#define NATSEMI_REGS_SIZE (NATSEMI_NREGS * sizeof(u32))
229#define NATSEMI_EEPROM_SIZE 24 /* 12 16-bit values */ 229#define NATSEMI_DEF_EEPROM_SIZE 24 /* 12 16-bit values */
230 230
231/* Buffer sizes: 231/* Buffer sizes:
232 * The nic writes 32-bit values, even if the upper bytes of 232 * The nic writes 32-bit values, even if the upper bytes of
@@ -714,6 +714,8 @@ struct netdev_private {
714 unsigned int iosize; 714 unsigned int iosize;
715 spinlock_t lock; 715 spinlock_t lock;
716 u32 msg_enable; 716 u32 msg_enable;
717 /* EEPROM data */
718 int eeprom_size;
717}; 719};
718 720
719static void move_int_phy(struct net_device *dev, int addr); 721static void move_int_phy(struct net_device *dev, int addr);
@@ -890,6 +892,7 @@ static int __devinit natsemi_probe1 (struct pci_dev *pdev,
890 np->msg_enable = (debug >= 0) ? (1<<debug)-1 : NATSEMI_DEF_MSG; 892 np->msg_enable = (debug >= 0) ? (1<<debug)-1 : NATSEMI_DEF_MSG;
891 np->hands_off = 0; 893 np->hands_off = 0;
892 np->intr_status = 0; 894 np->intr_status = 0;
895 np->eeprom_size = NATSEMI_DEF_EEPROM_SIZE;
893 896
894 /* Initial port: 897 /* Initial port:
895 * - If the nic was configured to use an external phy and if find_mii 898 * - If the nic was configured to use an external phy and if find_mii
@@ -2582,7 +2585,8 @@ static int get_regs_len(struct net_device *dev)
2582 2585
2583static int get_eeprom_len(struct net_device *dev) 2586static int get_eeprom_len(struct net_device *dev)
2584{ 2587{
2585 return NATSEMI_EEPROM_SIZE; 2588 struct netdev_private *np = netdev_priv(dev);
2589 return np->eeprom_size;
2586} 2590}
2587 2591
2588static int get_settings(struct net_device *dev, struct ethtool_cmd *ecmd) 2592static int get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
@@ -2669,15 +2673,20 @@ static u32 get_link(struct net_device *dev)
2669static int get_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom, u8 *data) 2673static int get_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom, u8 *data)
2670{ 2674{
2671 struct netdev_private *np = netdev_priv(dev); 2675 struct netdev_private *np = netdev_priv(dev);
2672 u8 eebuf[NATSEMI_EEPROM_SIZE]; 2676 u8 *eebuf;
2673 int res; 2677 int res;
2674 2678
2679 eebuf = kmalloc(np->eeprom_size, GFP_KERNEL);
2680 if (!eebuf)
2681 return -ENOMEM;
2682
2675 eeprom->magic = PCI_VENDOR_ID_NS | (PCI_DEVICE_ID_NS_83815<<16); 2683 eeprom->magic = PCI_VENDOR_ID_NS | (PCI_DEVICE_ID_NS_83815<<16);
2676 spin_lock_irq(&np->lock); 2684 spin_lock_irq(&np->lock);
2677 res = netdev_get_eeprom(dev, eebuf); 2685 res = netdev_get_eeprom(dev, eebuf);
2678 spin_unlock_irq(&np->lock); 2686 spin_unlock_irq(&np->lock);
2679 if (!res) 2687 if (!res)
2680 memcpy(data, eebuf+eeprom->offset, eeprom->len); 2688 memcpy(data, eebuf+eeprom->offset, eeprom->len);
2689 kfree(eebuf);
2681 return res; 2690 return res;
2682} 2691}
2683 2692
@@ -3033,9 +3042,10 @@ static int netdev_get_eeprom(struct net_device *dev, u8 *buf)
3033 int i; 3042 int i;
3034 u16 *ebuf = (u16 *)buf; 3043 u16 *ebuf = (u16 *)buf;
3035 void __iomem * ioaddr = ns_ioaddr(dev); 3044 void __iomem * ioaddr = ns_ioaddr(dev);
3045 struct netdev_private *np = netdev_priv(dev);
3036 3046
3037 /* eeprom_read reads 16 bits, and indexes by 16 bits */ 3047 /* eeprom_read reads 16 bits, and indexes by 16 bits */
3038 for (i = 0; i < NATSEMI_EEPROM_SIZE/2; i++) { 3048 for (i = 0; i < np->eeprom_size/2; i++) {
3039 ebuf[i] = eeprom_read(ioaddr, i); 3049 ebuf[i] = eeprom_read(ioaddr, i);
3040 /* The EEPROM itself stores data bit-swapped, but eeprom_read 3050 /* The EEPROM itself stores data bit-swapped, but eeprom_read
3041 * reads it back "sanely". So we swap it back here in order to 3051 * reads it back "sanely". So we swap it back here in order to
diff --git a/drivers/net/netconsole.c b/drivers/net/netconsole.c
index edd1b5306b16..75b35ad760de 100644
--- a/drivers/net/netconsole.c
+++ b/drivers/net/netconsole.c
@@ -94,7 +94,7 @@ static struct console netconsole = {
94static int option_setup(char *opt) 94static int option_setup(char *opt)
95{ 95{
96 configured = !netpoll_parse_options(&np, opt); 96 configured = !netpoll_parse_options(&np, opt);
97 return 0; 97 return 1;
98} 98}
99 99
100__setup("netconsole=", option_setup); 100__setup("netconsole=", option_setup);
diff --git a/drivers/net/pcmcia/axnet_cs.c b/drivers/net/pcmcia/axnet_cs.c
index aa5581369399..1cc94b2d76c1 100644
--- a/drivers/net/pcmcia/axnet_cs.c
+++ b/drivers/net/pcmcia/axnet_cs.c
@@ -35,6 +35,7 @@
35#include <linux/spinlock.h> 35#include <linux/spinlock.h>
36#include <linux/ethtool.h> 36#include <linux/ethtool.h>
37#include <linux/netdevice.h> 37#include <linux/netdevice.h>
38#include <linux/crc32.h>
38#include "../8390.h" 39#include "../8390.h"
39 40
40#include <pcmcia/cs_types.h> 41#include <pcmcia/cs_types.h>
@@ -1682,17 +1683,67 @@ static struct net_device_stats *get_stats(struct net_device *dev)
1682 return &ei_local->stat; 1683 return &ei_local->stat;
1683} 1684}
1684 1685
1686/*
1687 * Form the 64 bit 8390 multicast table from the linked list of addresses
1688 * associated with this dev structure.
1689 */
1690
1691static inline void make_mc_bits(u8 *bits, struct net_device *dev)
1692{
1693 struct dev_mc_list *dmi;
1694 u32 crc;
1695
1696 for (dmi=dev->mc_list; dmi; dmi=dmi->next) {
1697
1698 crc = ether_crc(ETH_ALEN, dmi->dmi_addr);
1699 /*
1700 * The 8390 uses the 6 most significant bits of the
1701 * CRC to index the multicast table.
1702 */
1703 bits[crc>>29] |= (1<<((crc>>26)&7));
1704 }
1705}
1706
1685/** 1707/**
1686 * do_set_multicast_list - set/clear multicast filter 1708 * do_set_multicast_list - set/clear multicast filter
1687 * @dev: net device for which multicast filter is adjusted 1709 * @dev: net device for which multicast filter is adjusted
1688 * 1710 *
1689 * Set or clear the multicast filter for this adaptor. May be called 1711 * Set or clear the multicast filter for this adaptor.
1690 * from a BH in 2.1.x. Must be called with lock held. 1712 * Must be called with lock held.
1691 */ 1713 */
1692 1714
1693static void do_set_multicast_list(struct net_device *dev) 1715static void do_set_multicast_list(struct net_device *dev)
1694{ 1716{
1695 long e8390_base = dev->base_addr; 1717 long e8390_base = dev->base_addr;
1718 int i;
1719 struct ei_device *ei_local = (struct ei_device*)netdev_priv(dev);
1720
1721 if (!(dev->flags&(IFF_PROMISC|IFF_ALLMULTI))) {
1722 memset(ei_local->mcfilter, 0, 8);
1723 if (dev->mc_list)
1724 make_mc_bits(ei_local->mcfilter, dev);
1725 } else {
1726 /* set to accept-all */
1727 memset(ei_local->mcfilter, 0xFF, 8);
1728 }
1729
1730 /*
1731 * DP8390 manuals don't specify any magic sequence for altering
1732 * the multicast regs on an already running card. To be safe, we
1733 * ensure multicast mode is off prior to loading up the new hash
1734 * table. If this proves to be not enough, we can always resort
1735 * to stopping the NIC, loading the table and then restarting.
1736 */
1737
1738 if (netif_running(dev))
1739 outb_p(E8390_RXCONFIG, e8390_base + EN0_RXCR);
1740
1741 outb_p(E8390_NODMA + E8390_PAGE1, e8390_base + E8390_CMD);
1742 for(i = 0; i < 8; i++)
1743 {
1744 outb_p(ei_local->mcfilter[i], e8390_base + EN1_MULT_SHIFT(i));
1745 }
1746 outb_p(E8390_NODMA + E8390_PAGE0, e8390_base + E8390_CMD);
1696 1747
1697 if(dev->flags&IFF_PROMISC) 1748 if(dev->flags&IFF_PROMISC)
1698 outb_p(E8390_RXCONFIG | 0x58, e8390_base + EN0_RXCR); 1749 outb_p(E8390_RXCONFIG | 0x58, e8390_base + EN0_RXCR);
@@ -1794,12 +1845,6 @@ static void AX88190_init(struct net_device *dev, int startp)
1794 if(inb_p(e8390_base + EN1_PHYS_SHIFT(i))!=dev->dev_addr[i]) 1845 if(inb_p(e8390_base + EN1_PHYS_SHIFT(i))!=dev->dev_addr[i])
1795 printk(KERN_ERR "Hw. address read/write mismap %d\n",i); 1846 printk(KERN_ERR "Hw. address read/write mismap %d\n",i);
1796 } 1847 }
1797 /*
1798 * Initialize the multicast list to accept-all. If we enable multicast
1799 * the higher levels can do the filtering.
1800 */
1801 for (i = 0; i < 8; i++)
1802 outb_p(0xff, e8390_base + EN1_MULT + i);
1803 1848
1804 outb_p(ei_local->rx_start_page, e8390_base + EN1_CURPAG); 1849 outb_p(ei_local->rx_start_page, e8390_base + EN1_CURPAG);
1805 outb_p(E8390_NODMA+E8390_PAGE0+E8390_STOP, e8390_base+E8390_CMD); 1850 outb_p(E8390_NODMA+E8390_PAGE0+E8390_STOP, e8390_base+E8390_CMD);
diff --git a/drivers/net/pcmcia/xirc2ps_cs.c b/drivers/net/pcmcia/xirc2ps_cs.c
index eed496803fe4..e8f849e12976 100644
--- a/drivers/net/pcmcia/xirc2ps_cs.c
+++ b/drivers/net/pcmcia/xirc2ps_cs.c
@@ -1973,7 +1973,7 @@ static int __init setup_xirc2ps_cs(char *str)
1973 MAYBE_SET(lockup_hack, 6); 1973 MAYBE_SET(lockup_hack, 6);
1974#undef MAYBE_SET 1974#undef MAYBE_SET
1975 1975
1976 return 0; 1976 return 1;
1977} 1977}
1978 1978
1979__setup("xirc2ps_cs=", setup_xirc2ps_cs); 1979__setup("xirc2ps_cs=", setup_xirc2ps_cs);
diff --git a/drivers/net/pcnet32.c b/drivers/net/pcnet32.c
index 9595f74da93f..07c31f19c6ba 100644
--- a/drivers/net/pcnet32.c
+++ b/drivers/net/pcnet32.c
@@ -1167,8 +1167,8 @@ pcnet32_probe1(unsigned long ioaddr, int shared, struct pci_dev *pdev)
1167 * station address PROM at the base address and programmed into the 1167 * station address PROM at the base address and programmed into the
1168 * "Physical Address Registers" CSR12-14. 1168 * "Physical Address Registers" CSR12-14.
1169 * As a precautionary measure, we read the PROM values and complain if 1169 * As a precautionary measure, we read the PROM values and complain if
1170 * they disagree with the CSRs. Either way, we use the CSR values, and 1170 * they disagree with the CSRs. If they miscompare, and the PROM addr
1171 * double check that they are valid. 1171 * is valid, then the PROM addr is used.
1172 */ 1172 */
1173 for (i = 0; i < 3; i++) { 1173 for (i = 0; i < 3; i++) {
1174 unsigned int val; 1174 unsigned int val;
diff --git a/drivers/net/spider_net.c b/drivers/net/spider_net.c
index 1f5975a61e1f..43f5e86fc559 100644
--- a/drivers/net/spider_net.c
+++ b/drivers/net/spider_net.c
@@ -1442,7 +1442,7 @@ spider_net_handle_error_irq(struct spider_net_card *card, u32 status_reg)
1442 case SPIDER_NET_GRFAFLLINT: /* fallthrough */ 1442 case SPIDER_NET_GRFAFLLINT: /* fallthrough */
1443 case SPIDER_NET_GRMFLLINT: 1443 case SPIDER_NET_GRMFLLINT:
1444 if (netif_msg_intr(card) && net_ratelimit()) 1444 if (netif_msg_intr(card) && net_ratelimit())
1445 pr_err("Spider RX RAM full, incoming packets " 1445 pr_debug("Spider RX RAM full, incoming packets "
1446 "might be discarded!\n"); 1446 "might be discarded!\n");
1447 spider_net_rx_irq_off(card); 1447 spider_net_rx_irq_off(card);
1448 tasklet_schedule(&card->rxram_full_tl); 1448 tasklet_schedule(&card->rxram_full_tl);
@@ -2086,7 +2086,7 @@ spider_net_setup_netdev(struct spider_net_card *card)
2086 2086
2087 spider_net_setup_netdev_ops(netdev); 2087 spider_net_setup_netdev_ops(netdev);
2088 2088
2089 netdev->features = 0; 2089 netdev->features = NETIF_F_HW_CSUM;
2090 /* some time: NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX | 2090 /* some time: NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX |
2091 * NETIF_F_HW_VLAN_FILTER */ 2091 * NETIF_F_HW_VLAN_FILTER */
2092 2092
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index b5473325bff4..964c09644832 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -69,8 +69,8 @@
69 69
70#define DRV_MODULE_NAME "tg3" 70#define DRV_MODULE_NAME "tg3"
71#define PFX DRV_MODULE_NAME ": " 71#define PFX DRV_MODULE_NAME ": "
72#define DRV_MODULE_VERSION "3.54" 72#define DRV_MODULE_VERSION "3.55"
73#define DRV_MODULE_RELDATE "Mar 23, 2006" 73#define DRV_MODULE_RELDATE "Mar 27, 2006"
74 74
75#define TG3_DEF_MAC_MODE 0 75#define TG3_DEF_MAC_MODE 0
76#define TG3_DEF_RX_MODE 0 76#define TG3_DEF_RX_MODE 0
@@ -497,21 +497,20 @@ static void tg3_write_mem(struct tg3 *tp, u32 off, u32 val)
497 unsigned long flags; 497 unsigned long flags;
498 498
499 spin_lock_irqsave(&tp->indirect_lock, flags); 499 spin_lock_irqsave(&tp->indirect_lock, flags);
500 pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, off); 500 if (tp->write32 != tg3_write_indirect_reg32) {
501 pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_DATA, val); 501 tw32_f(TG3PCI_MEM_WIN_BASE_ADDR, off);
502 tw32_f(TG3PCI_MEM_WIN_DATA, val);
502 503
503 /* Always leave this as zero. */ 504 /* Always leave this as zero. */
504 pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, 0); 505 tw32_f(TG3PCI_MEM_WIN_BASE_ADDR, 0);
505 spin_unlock_irqrestore(&tp->indirect_lock, flags); 506 } else {
506} 507 pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, off);
508 pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_DATA, val);
507 509
508static void tg3_write_mem_fast(struct tg3 *tp, u32 off, u32 val) 510 /* Always leave this as zero. */
509{ 511 pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, 0);
510 /* If no workaround is needed, write to mem space directly */ 512 }
511 if (tp->write32 != tg3_write_indirect_reg32) 513 spin_unlock_irqrestore(&tp->indirect_lock, flags);
512 tw32(NIC_SRAM_WIN_BASE + off, val);
513 else
514 tg3_write_mem(tp, off, val);
515} 514}
516 515
517static void tg3_read_mem(struct tg3 *tp, u32 off, u32 *val) 516static void tg3_read_mem(struct tg3 *tp, u32 off, u32 *val)
@@ -519,11 +518,19 @@ static void tg3_read_mem(struct tg3 *tp, u32 off, u32 *val)
519 unsigned long flags; 518 unsigned long flags;
520 519
521 spin_lock_irqsave(&tp->indirect_lock, flags); 520 spin_lock_irqsave(&tp->indirect_lock, flags);
522 pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, off); 521 if (tp->write32 != tg3_write_indirect_reg32) {
523 pci_read_config_dword(tp->pdev, TG3PCI_MEM_WIN_DATA, val); 522 tw32_f(TG3PCI_MEM_WIN_BASE_ADDR, off);
523 *val = tr32(TG3PCI_MEM_WIN_DATA);
524 524
525 /* Always leave this as zero. */ 525 /* Always leave this as zero. */
526 pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, 0); 526 tw32_f(TG3PCI_MEM_WIN_BASE_ADDR, 0);
527 } else {
528 pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, off);
529 pci_read_config_dword(tp->pdev, TG3PCI_MEM_WIN_DATA, val);
530
531 /* Always leave this as zero. */
532 pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, 0);
533 }
527 spin_unlock_irqrestore(&tp->indirect_lock, flags); 534 spin_unlock_irqrestore(&tp->indirect_lock, flags);
528} 535}
529 536
@@ -1367,12 +1374,12 @@ static int tg3_set_power_state(struct tg3 *tp, pci_power_t state)
1367 } 1374 }
1368 } 1375 }
1369 1376
1377 tg3_write_sig_post_reset(tp, RESET_KIND_SHUTDOWN);
1378
1370 /* Finally, set the new power state. */ 1379 /* Finally, set the new power state. */
1371 pci_write_config_word(tp->pdev, pm + PCI_PM_CTRL, power_control); 1380 pci_write_config_word(tp->pdev, pm + PCI_PM_CTRL, power_control);
1372 udelay(100); /* Delay after power state change */ 1381 udelay(100); /* Delay after power state change */
1373 1382
1374 tg3_write_sig_post_reset(tp, RESET_KIND_SHUTDOWN);
1375
1376 return 0; 1383 return 0;
1377} 1384}
1378 1385
@@ -3600,7 +3607,7 @@ static inline int tg3_40bit_overflow_test(struct tg3 *tp, dma_addr_t mapping,
3600 int len) 3607 int len)
3601{ 3608{
3602#if defined(CONFIG_HIGHMEM) && (BITS_PER_LONG == 64) 3609#if defined(CONFIG_HIGHMEM) && (BITS_PER_LONG == 64)
3603 if (tp->tg3_flags2 & TG3_FLG2_5780_CLASS) 3610 if (tp->tg3_flags & TG3_FLAG_40BIT_DMA_BUG)
3604 return (((u64) mapping + len) > DMA_40BIT_MASK); 3611 return (((u64) mapping + len) > DMA_40BIT_MASK);
3605 return 0; 3612 return 0;
3606#else 3613#else
@@ -6461,6 +6468,9 @@ static void tg3_timer(unsigned long __opaque)
6461{ 6468{
6462 struct tg3 *tp = (struct tg3 *) __opaque; 6469 struct tg3 *tp = (struct tg3 *) __opaque;
6463 6470
6471 if (tp->irq_sync)
6472 goto restart_timer;
6473
6464 spin_lock(&tp->lock); 6474 spin_lock(&tp->lock);
6465 6475
6466 if (!(tp->tg3_flags & TG3_FLAG_TAGGED_STATUS)) { 6476 if (!(tp->tg3_flags & TG3_FLAG_TAGGED_STATUS)) {
@@ -6537,11 +6547,11 @@ static void tg3_timer(unsigned long __opaque)
6537 if (tp->tg3_flags & TG3_FLAG_ENABLE_ASF) { 6547 if (tp->tg3_flags & TG3_FLAG_ENABLE_ASF) {
6538 u32 val; 6548 u32 val;
6539 6549
6540 tg3_write_mem_fast(tp, NIC_SRAM_FW_CMD_MBOX, 6550 tg3_write_mem(tp, NIC_SRAM_FW_CMD_MBOX,
6541 FWCMD_NICDRV_ALIVE2); 6551 FWCMD_NICDRV_ALIVE2);
6542 tg3_write_mem_fast(tp, NIC_SRAM_FW_CMD_LEN_MBOX, 4); 6552 tg3_write_mem(tp, NIC_SRAM_FW_CMD_LEN_MBOX, 4);
6543 /* 5 seconds timeout */ 6553 /* 5 seconds timeout */
6544 tg3_write_mem_fast(tp, NIC_SRAM_FW_CMD_DATA_MBOX, 5); 6554 tg3_write_mem(tp, NIC_SRAM_FW_CMD_DATA_MBOX, 5);
6545 val = tr32(GRC_RX_CPU_EVENT); 6555 val = tr32(GRC_RX_CPU_EVENT);
6546 val |= (1 << 14); 6556 val |= (1 << 14);
6547 tw32(GRC_RX_CPU_EVENT, val); 6557 tw32(GRC_RX_CPU_EVENT, val);
@@ -6551,6 +6561,7 @@ static void tg3_timer(unsigned long __opaque)
6551 6561
6552 spin_unlock(&tp->lock); 6562 spin_unlock(&tp->lock);
6553 6563
6564restart_timer:
6554 tp->timer.expires = jiffies + tp->timer_offset; 6565 tp->timer.expires = jiffies + tp->timer_offset;
6555 add_timer(&tp->timer); 6566 add_timer(&tp->timer);
6556} 6567}
@@ -8399,8 +8410,11 @@ static int tg3_run_loopback(struct tg3 *tp, int loopback_mode)
8399 } 8410 }
8400 mac_mode = (tp->mac_mode & ~MAC_MODE_PORT_MODE_MASK) | 8411 mac_mode = (tp->mac_mode & ~MAC_MODE_PORT_MODE_MASK) |
8401 MAC_MODE_LINK_POLARITY | MAC_MODE_PORT_MODE_GMII; 8412 MAC_MODE_LINK_POLARITY | MAC_MODE_PORT_MODE_GMII;
8402 if ((tp->phy_id & PHY_ID_MASK) == PHY_ID_BCM5401) 8413 if ((tp->phy_id & PHY_ID_MASK) == PHY_ID_BCM5401) {
8403 mac_mode &= ~MAC_MODE_LINK_POLARITY; 8414 mac_mode &= ~MAC_MODE_LINK_POLARITY;
8415 tg3_writephy(tp, MII_TG3_EXT_CTRL,
8416 MII_TG3_EXT_CTRL_LNK3_LED_MODE);
8417 }
8404 tw32(MAC_MODE, mac_mode); 8418 tw32(MAC_MODE, mac_mode);
8405 } 8419 }
8406 else 8420 else
@@ -10531,6 +10545,7 @@ static int __devinit tg3_get_device_address(struct tg3 *tp)
10531{ 10545{
10532 struct net_device *dev = tp->dev; 10546 struct net_device *dev = tp->dev;
10533 u32 hi, lo, mac_offset; 10547 u32 hi, lo, mac_offset;
10548 int addr_ok = 0;
10534 10549
10535#ifdef CONFIG_SPARC64 10550#ifdef CONFIG_SPARC64
10536 if (!tg3_get_macaddr_sparc(tp)) 10551 if (!tg3_get_macaddr_sparc(tp))
@@ -10560,29 +10575,34 @@ static int __devinit tg3_get_device_address(struct tg3 *tp)
10560 dev->dev_addr[3] = (lo >> 16) & 0xff; 10575 dev->dev_addr[3] = (lo >> 16) & 0xff;
10561 dev->dev_addr[4] = (lo >> 8) & 0xff; 10576 dev->dev_addr[4] = (lo >> 8) & 0xff;
10562 dev->dev_addr[5] = (lo >> 0) & 0xff; 10577 dev->dev_addr[5] = (lo >> 0) & 0xff;
10563 }
10564 /* Next, try NVRAM. */
10565 else if (!(tp->tg3_flags & TG3_FLG2_SUN_570X) &&
10566 !tg3_nvram_read(tp, mac_offset + 0, &hi) &&
10567 !tg3_nvram_read(tp, mac_offset + 4, &lo)) {
10568 dev->dev_addr[0] = ((hi >> 16) & 0xff);
10569 dev->dev_addr[1] = ((hi >> 24) & 0xff);
10570 dev->dev_addr[2] = ((lo >> 0) & 0xff);
10571 dev->dev_addr[3] = ((lo >> 8) & 0xff);
10572 dev->dev_addr[4] = ((lo >> 16) & 0xff);
10573 dev->dev_addr[5] = ((lo >> 24) & 0xff);
10574 }
10575 /* Finally just fetch it out of the MAC control regs. */
10576 else {
10577 hi = tr32(MAC_ADDR_0_HIGH);
10578 lo = tr32(MAC_ADDR_0_LOW);
10579 10578
10580 dev->dev_addr[5] = lo & 0xff; 10579 /* Some old bootcode may report a 0 MAC address in SRAM */
10581 dev->dev_addr[4] = (lo >> 8) & 0xff; 10580 addr_ok = is_valid_ether_addr(&dev->dev_addr[0]);
10582 dev->dev_addr[3] = (lo >> 16) & 0xff; 10581 }
10583 dev->dev_addr[2] = (lo >> 24) & 0xff; 10582 if (!addr_ok) {
10584 dev->dev_addr[1] = hi & 0xff; 10583 /* Next, try NVRAM. */
10585 dev->dev_addr[0] = (hi >> 8) & 0xff; 10584 if (!(tp->tg3_flags & TG3_FLG2_SUN_570X) &&
10585 !tg3_nvram_read(tp, mac_offset + 0, &hi) &&
10586 !tg3_nvram_read(tp, mac_offset + 4, &lo)) {
10587 dev->dev_addr[0] = ((hi >> 16) & 0xff);
10588 dev->dev_addr[1] = ((hi >> 24) & 0xff);
10589 dev->dev_addr[2] = ((lo >> 0) & 0xff);
10590 dev->dev_addr[3] = ((lo >> 8) & 0xff);
10591 dev->dev_addr[4] = ((lo >> 16) & 0xff);
10592 dev->dev_addr[5] = ((lo >> 24) & 0xff);
10593 }
10594 /* Finally just fetch it out of the MAC control regs. */
10595 else {
10596 hi = tr32(MAC_ADDR_0_HIGH);
10597 lo = tr32(MAC_ADDR_0_LOW);
10598
10599 dev->dev_addr[5] = lo & 0xff;
10600 dev->dev_addr[4] = (lo >> 8) & 0xff;
10601 dev->dev_addr[3] = (lo >> 16) & 0xff;
10602 dev->dev_addr[2] = (lo >> 24) & 0xff;
10603 dev->dev_addr[1] = hi & 0xff;
10604 dev->dev_addr[0] = (hi >> 8) & 0xff;
10605 }
10586 } 10606 }
10587 10607
10588 if (!is_valid_ether_addr(&dev->dev_addr[0])) { 10608 if (!is_valid_ether_addr(&dev->dev_addr[0])) {
diff --git a/drivers/net/tokenring/Kconfig b/drivers/net/tokenring/Kconfig
index e4cfc80b283b..99c4c1922f19 100644
--- a/drivers/net/tokenring/Kconfig
+++ b/drivers/net/tokenring/Kconfig
@@ -3,7 +3,7 @@
3# 3#
4 4
5menu "Token Ring devices" 5menu "Token Ring devices"
6 depends on NETDEVICES 6 depends on NETDEVICES && !UML
7 7
8# So far, we only have PCI, ISA, and MCA token ring devices 8# So far, we only have PCI, ISA, and MCA token ring devices
9config TR 9config TR
diff --git a/drivers/net/tulip/de4x5.c b/drivers/net/tulip/de4x5.c
index d1a86a080a65..f56094102042 100644
--- a/drivers/net/tulip/de4x5.c
+++ b/drivers/net/tulip/de4x5.c
@@ -4160,7 +4160,7 @@ get_hw_addr(struct net_device *dev)
4160 ** If the address starts with 00 a0, we have to bit-reverse 4160 ** If the address starts with 00 a0, we have to bit-reverse
4161 ** each byte of the address. 4161 ** each byte of the address.
4162 */ 4162 */
4163 if ( (_machine & _MACH_Pmac) && 4163 if ( machine_is(powermac) &&
4164 (dev->dev_addr[0] == 0) && 4164 (dev->dev_addr[0] == 0) &&
4165 (dev->dev_addr[1] == 0xa0) ) 4165 (dev->dev_addr[1] == 0xa0) )
4166 { 4166 {
diff --git a/drivers/net/via-rhine.c b/drivers/net/via-rhine.c
index 241871589283..a9b2150909d6 100644
--- a/drivers/net/via-rhine.c
+++ b/drivers/net/via-rhine.c
@@ -1085,6 +1085,25 @@ static void rhine_check_media(struct net_device *dev, unsigned int init_media)
1085 else 1085 else
1086 iowrite8(ioread8(ioaddr + ChipCmd1) & ~Cmd1FDuplex, 1086 iowrite8(ioread8(ioaddr + ChipCmd1) & ~Cmd1FDuplex,
1087 ioaddr + ChipCmd1); 1087 ioaddr + ChipCmd1);
1088 if (debug > 1)
1089 printk(KERN_INFO "%s: force_media %d, carrier %d\n", dev->name,
1090 rp->mii_if.force_media, netif_carrier_ok(dev));
1091}
1092
1093/* Called after status of force_media possibly changed */
1094void rhine_set_carrier(struct mii_if_info *mii)
1095{
1096 if (mii->force_media) {
1097 /* autoneg is off: Link is always assumed to be up */
1098 if (!netif_carrier_ok(mii->dev))
1099 netif_carrier_on(mii->dev);
1100 }
1101 else /* Let MMI library update carrier status */
1102 rhine_check_media(mii->dev, 0);
1103 if (debug > 1)
1104 printk(KERN_INFO "%s: force_media %d, carrier %d\n",
1105 mii->dev->name, mii->force_media,
1106 netif_carrier_ok(mii->dev));
1088} 1107}
1089 1108
1090static void rhine_check_media_task(struct net_device *dev) 1109static void rhine_check_media_task(struct net_device *dev)
@@ -1782,6 +1801,7 @@ static int netdev_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
1782 spin_lock_irq(&rp->lock); 1801 spin_lock_irq(&rp->lock);
1783 rc = mii_ethtool_sset(&rp->mii_if, cmd); 1802 rc = mii_ethtool_sset(&rp->mii_if, cmd);
1784 spin_unlock_irq(&rp->lock); 1803 spin_unlock_irq(&rp->lock);
1804 rhine_set_carrier(&rp->mii_if);
1785 1805
1786 return rc; 1806 return rc;
1787} 1807}
@@ -1869,6 +1889,7 @@ static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
1869 spin_lock_irq(&rp->lock); 1889 spin_lock_irq(&rp->lock);
1870 rc = generic_mii_ioctl(&rp->mii_if, if_mii(rq), cmd, NULL); 1890 rc = generic_mii_ioctl(&rp->mii_if, if_mii(rq), cmd, NULL);
1871 spin_unlock_irq(&rp->lock); 1891 spin_unlock_irq(&rp->lock);
1892 rhine_set_carrier(&rp->mii_if);
1872 1893
1873 return rc; 1894 return rc;
1874} 1895}
diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig
index fd17aa8491b6..bad09ebdb50b 100644
--- a/drivers/net/wireless/Kconfig
+++ b/drivers/net/wireless/Kconfig
@@ -309,7 +309,10 @@ config APPLE_AIRPORT
309 Say Y here to support the Airport 802.11b wireless Ethernet hardware 309 Say Y here to support the Airport 802.11b wireless Ethernet hardware
310 built into the Macintosh iBook and other recent PowerPC-based 310 built into the Macintosh iBook and other recent PowerPC-based
311 Macintosh machines. This is essentially a Lucent Orinoco card with 311 Macintosh machines. This is essentially a Lucent Orinoco card with
312 a non-standard interface 312 a non-standard interface.
313
314 This driver does not support the Airport Extreme (802.11b/g). Use
315 the BCM43xx driver for Airport Extreme cards.
313 316
314config PLX_HERMES 317config PLX_HERMES
315 tristate "Hermes in PLX9052 based PCI adaptor support (Netgear MA301 etc.)" 318 tristate "Hermes in PLX9052 based PCI adaptor support (Netgear MA301 etc.)"
@@ -353,7 +356,7 @@ config PCI_HERMES
353 356
354config ATMEL 357config ATMEL
355 tristate "Atmel at76c50x chipset 802.11b support" 358 tristate "Atmel at76c50x chipset 802.11b support"
356 depends on NET_RADIO 359 depends on NET_RADIO && (PCI || PCMCIA)
357 select FW_LOADER 360 select FW_LOADER
358 select CRC32 361 select CRC32
359 ---help--- 362 ---help---
@@ -401,6 +404,7 @@ config PCMCIA_HERMES
401config PCMCIA_SPECTRUM 404config PCMCIA_SPECTRUM
402 tristate "Symbol Spectrum24 Trilogy PCMCIA card support" 405 tristate "Symbol Spectrum24 Trilogy PCMCIA card support"
403 depends on NET_RADIO && PCMCIA && HERMES 406 depends on NET_RADIO && PCMCIA && HERMES
407 select FW_LOADER
404 ---help--- 408 ---help---
405 409
406 This is a driver for 802.11b cards using RAM-loadable Symbol 410 This is a driver for 802.11b cards using RAM-loadable Symbol
@@ -500,6 +504,7 @@ config PRISM54
500 will be called prism54.ko. 504 will be called prism54.ko.
501 505
502source "drivers/net/wireless/hostap/Kconfig" 506source "drivers/net/wireless/hostap/Kconfig"
507source "drivers/net/wireless/bcm43xx/Kconfig"
503 508
504# yes, this works even when no drivers are selected 509# yes, this works even when no drivers are selected
505config NET_WIRELESS 510config NET_WIRELESS
diff --git a/drivers/net/wireless/Makefile b/drivers/net/wireless/Makefile
index 3a6f7ba326ca..c86779879361 100644
--- a/drivers/net/wireless/Makefile
+++ b/drivers/net/wireless/Makefile
@@ -35,6 +35,7 @@ obj-$(CONFIG_PCMCIA_ATMEL) += atmel_cs.o
35obj-$(CONFIG_PRISM54) += prism54/ 35obj-$(CONFIG_PRISM54) += prism54/
36 36
37obj-$(CONFIG_HOSTAP) += hostap/ 37obj-$(CONFIG_HOSTAP) += hostap/
38obj-$(CONFIG_BCM43XX) += bcm43xx/
38 39
39# 16-bit wireless PCMCIA client drivers 40# 16-bit wireless PCMCIA client drivers
40obj-$(CONFIG_PCMCIA_RAYCS) += ray_cs.o 41obj-$(CONFIG_PCMCIA_RAYCS) += ray_cs.o
diff --git a/drivers/net/wireless/bcm43xx/Kconfig b/drivers/net/wireless/bcm43xx/Kconfig
new file mode 100644
index 000000000000..418465600a77
--- /dev/null
+++ b/drivers/net/wireless/bcm43xx/Kconfig
@@ -0,0 +1,62 @@
1config BCM43XX
2 tristate "Broadcom BCM43xx wireless support"
3 depends on PCI && IEEE80211 && IEEE80211_SOFTMAC && NET_RADIO && EXPERIMENTAL
4 select FW_LOADER
5 ---help---
6 This is an experimental driver for the Broadcom 43xx wireless chip,
7 found in the Apple Airport Extreme and various other devices.
8
9config BCM43XX_DEBUG
10 bool "Broadcom BCM43xx debugging (RECOMMENDED)"
11 depends on BCM43XX
12 default y
13 ---help---
14 Broadcom 43xx debugging messages.
15 Say Y, because the driver is still very experimental and
16 this will help you get it running.
17
18config BCM43XX_DMA
19 bool
20config BCM43XX_PIO
21 bool
22
23choice
24 prompt "BCM43xx data transfer mode"
25 depends on BCM43XX
26 default BCM43XX_DMA_AND_PIO_MODE
27
28config BCM43XX_DMA_AND_PIO_MODE
29 bool "DMA + PIO"
30 select BCM43XX_DMA
31 select BCM43XX_PIO
32 ---help---
33 Include both, Direct Memory Access (DMA) and Programmed I/O (PIO)
34 data transfer modes.
35 The actually used mode is selectable through the module
36 parameter "pio". If the module parameter is pio=0, DMA is used.
37 Otherwise PIO is used. DMA is default.
38
39 If unsure, choose this option.
40
41config BCM43XX_DMA_MODE
42 bool "DMA (Direct Memory Access) only"
43 select BCM43XX_DMA
44 ---help---
45 Only include Direct Memory Access (DMA).
46 This reduces the size of the driver module, by omitting the PIO code.
47
48config BCM43XX_PIO_MODE
49 bool "PIO (Programmed I/O) only"
50 select BCM43XX_PIO
51 ---help---
52 Only include Programmed I/O (PIO).
53 This reduces the size of the driver module, by omitting the DMA code.
54 Please note that PIO transfers are slow (compared to DMA).
55
56 Also note that not all devices of the 43xx series support PIO.
57 The 4306 (Apple Airport Extreme and others) supports PIO, while
58 the 4318 is known to _not_ support PIO.
59
60 Only use PIO, if DMA does not work for you.
61
62endchoice
diff --git a/drivers/net/wireless/bcm43xx/Makefile b/drivers/net/wireless/bcm43xx/Makefile
new file mode 100644
index 000000000000..bb5220c629d2
--- /dev/null
+++ b/drivers/net/wireless/bcm43xx/Makefile
@@ -0,0 +1,12 @@
1obj-$(CONFIG_BCM43XX) += bcm43xx.o
2bcm43xx-obj-$(CONFIG_BCM43XX_DEBUG) += bcm43xx_debugfs.o
3
4bcm43xx-obj-$(CONFIG_BCM43XX_DMA) += bcm43xx_dma.o
5bcm43xx-obj-$(CONFIG_BCM43XX_PIO) += bcm43xx_pio.o
6
7bcm43xx-objs := bcm43xx_main.o bcm43xx_ilt.o \
8 bcm43xx_radio.o bcm43xx_phy.o \
9 bcm43xx_power.o bcm43xx_wx.o \
10 bcm43xx_leds.o bcm43xx_ethtool.o \
11 bcm43xx_xmit.o bcm43xx_sysfs.o \
12 $(bcm43xx-obj-y)
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx.h b/drivers/net/wireless/bcm43xx/bcm43xx.h
new file mode 100644
index 000000000000..dcadd295de4f
--- /dev/null
+++ b/drivers/net/wireless/bcm43xx/bcm43xx.h
@@ -0,0 +1,926 @@
1#ifndef BCM43xx_H_
2#define BCM43xx_H_
3
4#include <linux/version.h>
5#include <linux/kernel.h>
6#include <linux/spinlock.h>
7#include <linux/interrupt.h>
8#include <linux/stringify.h>
9#include <linux/pci.h>
10#include <net/ieee80211.h>
11#include <net/ieee80211softmac.h>
12#include <asm/atomic.h>
13#include <asm/io.h>
14
15
16#include "bcm43xx_debugfs.h"
17#include "bcm43xx_leds.h"
18#include "bcm43xx_sysfs.h"
19
20
21#define PFX KBUILD_MODNAME ": "
22
23#define BCM43xx_SWITCH_CORE_MAX_RETRIES 50
24#define BCM43xx_IRQWAIT_MAX_RETRIES 50
25
26#define BCM43xx_IO_SIZE 8192
27
28/* Active Core PCI Configuration Register. */
29#define BCM43xx_PCICFG_ACTIVE_CORE 0x80
30/* SPROM control register. */
31#define BCM43xx_PCICFG_SPROMCTL 0x88
32/* Interrupt Control PCI Configuration Register. (Only on PCI cores with rev >= 6) */
33#define BCM43xx_PCICFG_ICR 0x94
34
35/* MMIO offsets */
36#define BCM43xx_MMIO_DMA1_REASON 0x20
37#define BCM43xx_MMIO_DMA1_IRQ_MASK 0x24
38#define BCM43xx_MMIO_DMA2_REASON 0x28
39#define BCM43xx_MMIO_DMA2_IRQ_MASK 0x2C
40#define BCM43xx_MMIO_DMA3_REASON 0x30
41#define BCM43xx_MMIO_DMA3_IRQ_MASK 0x34
42#define BCM43xx_MMIO_DMA4_REASON 0x38
43#define BCM43xx_MMIO_DMA4_IRQ_MASK 0x3C
44#define BCM43xx_MMIO_STATUS_BITFIELD 0x120
45#define BCM43xx_MMIO_STATUS2_BITFIELD 0x124
46#define BCM43xx_MMIO_GEN_IRQ_REASON 0x128
47#define BCM43xx_MMIO_GEN_IRQ_MASK 0x12C
48#define BCM43xx_MMIO_RAM_CONTROL 0x130
49#define BCM43xx_MMIO_RAM_DATA 0x134
50#define BCM43xx_MMIO_PS_STATUS 0x140
51#define BCM43xx_MMIO_RADIO_HWENABLED_HI 0x158
52#define BCM43xx_MMIO_SHM_CONTROL 0x160
53#define BCM43xx_MMIO_SHM_DATA 0x164
54#define BCM43xx_MMIO_SHM_DATA_UNALIGNED 0x166
55#define BCM43xx_MMIO_XMITSTAT_0 0x170
56#define BCM43xx_MMIO_XMITSTAT_1 0x174
57#define BCM43xx_MMIO_REV3PLUS_TSF_LOW 0x180 /* core rev >= 3 only */
58#define BCM43xx_MMIO_REV3PLUS_TSF_HIGH 0x184 /* core rev >= 3 only */
59#define BCM43xx_MMIO_DMA1_BASE 0x200
60#define BCM43xx_MMIO_DMA2_BASE 0x220
61#define BCM43xx_MMIO_DMA3_BASE 0x240
62#define BCM43xx_MMIO_DMA4_BASE 0x260
63#define BCM43xx_MMIO_PIO1_BASE 0x300
64#define BCM43xx_MMIO_PIO2_BASE 0x310
65#define BCM43xx_MMIO_PIO3_BASE 0x320
66#define BCM43xx_MMIO_PIO4_BASE 0x330
67#define BCM43xx_MMIO_PHY_VER 0x3E0
68#define BCM43xx_MMIO_PHY_RADIO 0x3E2
69#define BCM43xx_MMIO_ANTENNA 0x3E8
70#define BCM43xx_MMIO_CHANNEL 0x3F0
71#define BCM43xx_MMIO_CHANNEL_EXT 0x3F4
72#define BCM43xx_MMIO_RADIO_CONTROL 0x3F6
73#define BCM43xx_MMIO_RADIO_DATA_HIGH 0x3F8
74#define BCM43xx_MMIO_RADIO_DATA_LOW 0x3FA
75#define BCM43xx_MMIO_PHY_CONTROL 0x3FC
76#define BCM43xx_MMIO_PHY_DATA 0x3FE
77#define BCM43xx_MMIO_MACFILTER_CONTROL 0x420
78#define BCM43xx_MMIO_MACFILTER_DATA 0x422
79#define BCM43xx_MMIO_RADIO_HWENABLED_LO 0x49A
80#define BCM43xx_MMIO_GPIO_CONTROL 0x49C
81#define BCM43xx_MMIO_GPIO_MASK 0x49E
82#define BCM43xx_MMIO_TSF_0 0x632 /* core rev < 3 only */
83#define BCM43xx_MMIO_TSF_1 0x634 /* core rev < 3 only */
84#define BCM43xx_MMIO_TSF_2 0x636 /* core rev < 3 only */
85#define BCM43xx_MMIO_TSF_3 0x638 /* core rev < 3 only */
86#define BCM43xx_MMIO_POWERUP_DELAY 0x6A8
87
88/* SPROM offsets. */
89#define BCM43xx_SPROM_BASE 0x1000
90#define BCM43xx_SPROM_BOARDFLAGS2 0x1c
91#define BCM43xx_SPROM_IL0MACADDR 0x24
92#define BCM43xx_SPROM_ET0MACADDR 0x27
93#define BCM43xx_SPROM_ET1MACADDR 0x2a
94#define BCM43xx_SPROM_ETHPHY 0x2d
95#define BCM43xx_SPROM_BOARDREV 0x2e
96#define BCM43xx_SPROM_PA0B0 0x2f
97#define BCM43xx_SPROM_PA0B1 0x30
98#define BCM43xx_SPROM_PA0B2 0x31
99#define BCM43xx_SPROM_WL0GPIO0 0x32
100#define BCM43xx_SPROM_WL0GPIO2 0x33
101#define BCM43xx_SPROM_MAXPWR 0x34
102#define BCM43xx_SPROM_PA1B0 0x35
103#define BCM43xx_SPROM_PA1B1 0x36
104#define BCM43xx_SPROM_PA1B2 0x37
105#define BCM43xx_SPROM_IDL_TSSI_TGT 0x38
106#define BCM43xx_SPROM_BOARDFLAGS 0x39
107#define BCM43xx_SPROM_ANTENNA_GAIN 0x3a
108#define BCM43xx_SPROM_VERSION 0x3f
109
110/* BCM43xx_SPROM_BOARDFLAGS values */
111#define BCM43xx_BFL_BTCOEXIST 0x0001 /* implements Bluetooth coexistance */
112#define BCM43xx_BFL_PACTRL 0x0002 /* GPIO 9 controlling the PA */
113#define BCM43xx_BFL_AIRLINEMODE 0x0004 /* implements GPIO 13 radio disable indication */
114#define BCM43xx_BFL_RSSI 0x0008 /* software calculates nrssi slope. */
115#define BCM43xx_BFL_ENETSPI 0x0010 /* has ephy roboswitch spi */
116#define BCM43xx_BFL_XTAL_NOSLOW 0x0020 /* no slow clock available */
117#define BCM43xx_BFL_CCKHIPWR 0x0040 /* can do high power CCK transmission */
118#define BCM43xx_BFL_ENETADM 0x0080 /* has ADMtek switch */
119#define BCM43xx_BFL_ENETVLAN 0x0100 /* can do vlan */
120#define BCM43xx_BFL_AFTERBURNER 0x0200 /* supports Afterburner mode */
121#define BCM43xx_BFL_NOPCI 0x0400 /* leaves PCI floating */
122#define BCM43xx_BFL_FEM 0x0800 /* supports the Front End Module */
123#define BCM43xx_BFL_EXTLNA 0x1000 /* has an external LNA */
124#define BCM43xx_BFL_HGPA 0x2000 /* had high gain PA */
125#define BCM43xx_BFL_BTCMOD 0x4000 /* BFL_BTCOEXIST is given in alternate GPIOs */
126#define BCM43xx_BFL_ALTIQ 0x8000 /* alternate I/Q settings */
127
128/* GPIO register offset, in both ChipCommon and PCI core. */
129#define BCM43xx_GPIO_CONTROL 0x6c
130
131/* SHM Routing */
132#define BCM43xx_SHM_SHARED 0x0001
133#define BCM43xx_SHM_WIRELESS 0x0002
134#define BCM43xx_SHM_PCM 0x0003
135#define BCM43xx_SHM_HWMAC 0x0004
136#define BCM43xx_SHM_UCODE 0x0300
137
138/* MacFilter offsets. */
139#define BCM43xx_MACFILTER_SELF 0x0000
140#define BCM43xx_MACFILTER_ASSOC 0x0003
141
142/* Chipcommon registers. */
143#define BCM43xx_CHIPCOMMON_CAPABILITIES 0x04
144#define BCM43xx_CHIPCOMMON_PLLONDELAY 0xB0
145#define BCM43xx_CHIPCOMMON_FREFSELDELAY 0xB4
146#define BCM43xx_CHIPCOMMON_SLOWCLKCTL 0xB8
147#define BCM43xx_CHIPCOMMON_SYSCLKCTL 0xC0
148
149/* PCI core specific registers. */
150#define BCM43xx_PCICORE_BCAST_ADDR 0x50
151#define BCM43xx_PCICORE_BCAST_DATA 0x54
152#define BCM43xx_PCICORE_SBTOPCI2 0x108
153
154/* SBTOPCI2 values. */
155#define BCM43xx_SBTOPCI2_PREFETCH 0x4
156#define BCM43xx_SBTOPCI2_BURST 0x8
157
158/* Chipcommon capabilities. */
159#define BCM43xx_CAPABILITIES_PCTL 0x00040000
160#define BCM43xx_CAPABILITIES_PLLMASK 0x00030000
161#define BCM43xx_CAPABILITIES_PLLSHIFT 16
162#define BCM43xx_CAPABILITIES_FLASHMASK 0x00000700
163#define BCM43xx_CAPABILITIES_FLASHSHIFT 8
164#define BCM43xx_CAPABILITIES_EXTBUSPRESENT 0x00000040
165#define BCM43xx_CAPABILITIES_UARTGPIO 0x00000020
166#define BCM43xx_CAPABILITIES_UARTCLOCKMASK 0x00000018
167#define BCM43xx_CAPABILITIES_UARTCLOCKSHIFT 3
168#define BCM43xx_CAPABILITIES_MIPSBIGENDIAN 0x00000004
169#define BCM43xx_CAPABILITIES_NRUARTSMASK 0x00000003
170
171/* PowerControl */
172#define BCM43xx_PCTL_IN 0xB0
173#define BCM43xx_PCTL_OUT 0xB4
174#define BCM43xx_PCTL_OUTENABLE 0xB8
175#define BCM43xx_PCTL_XTAL_POWERUP 0x40
176#define BCM43xx_PCTL_PLL_POWERDOWN 0x80
177
178/* PowerControl Clock Modes */
179#define BCM43xx_PCTL_CLK_FAST 0x00
180#define BCM43xx_PCTL_CLK_SLOW 0x01
181#define BCM43xx_PCTL_CLK_DYNAMIC 0x02
182
183#define BCM43xx_PCTL_FORCE_SLOW 0x0800
184#define BCM43xx_PCTL_FORCE_PLL 0x1000
185#define BCM43xx_PCTL_DYN_XTAL 0x2000
186
187/* COREIDs */
188#define BCM43xx_COREID_CHIPCOMMON 0x800
189#define BCM43xx_COREID_ILINE20 0x801
190#define BCM43xx_COREID_SDRAM 0x803
191#define BCM43xx_COREID_PCI 0x804
192#define BCM43xx_COREID_MIPS 0x805
193#define BCM43xx_COREID_ETHERNET 0x806
194#define BCM43xx_COREID_V90 0x807
195#define BCM43xx_COREID_USB11_HOSTDEV 0x80a
196#define BCM43xx_COREID_IPSEC 0x80b
197#define BCM43xx_COREID_PCMCIA 0x80d
198#define BCM43xx_COREID_EXT_IF 0x80f
199#define BCM43xx_COREID_80211 0x812
200#define BCM43xx_COREID_MIPS_3302 0x816
201#define BCM43xx_COREID_USB11_HOST 0x817
202#define BCM43xx_COREID_USB11_DEV 0x818
203#define BCM43xx_COREID_USB20_HOST 0x819
204#define BCM43xx_COREID_USB20_DEV 0x81a
205#define BCM43xx_COREID_SDIO_HOST 0x81b
206
207/* Core Information Registers */
208#define BCM43xx_CIR_BASE 0xf00
209#define BCM43xx_CIR_SBTPSFLAG (BCM43xx_CIR_BASE + 0x18)
210#define BCM43xx_CIR_SBIMSTATE (BCM43xx_CIR_BASE + 0x90)
211#define BCM43xx_CIR_SBINTVEC (BCM43xx_CIR_BASE + 0x94)
212#define BCM43xx_CIR_SBTMSTATELOW (BCM43xx_CIR_BASE + 0x98)
213#define BCM43xx_CIR_SBTMSTATEHIGH (BCM43xx_CIR_BASE + 0x9c)
214#define BCM43xx_CIR_SBIMCONFIGLOW (BCM43xx_CIR_BASE + 0xa8)
215#define BCM43xx_CIR_SB_ID_HI (BCM43xx_CIR_BASE + 0xfc)
216
217/* Mask to get the Backplane Flag Number from SBTPSFLAG. */
218#define BCM43xx_BACKPLANE_FLAG_NR_MASK 0x3f
219
220/* SBIMCONFIGLOW values/masks. */
221#define BCM43xx_SBIMCONFIGLOW_SERVICE_TOUT_MASK 0x00000007
222#define BCM43xx_SBIMCONFIGLOW_SERVICE_TOUT_SHIFT 0
223#define BCM43xx_SBIMCONFIGLOW_REQUEST_TOUT_MASK 0x00000070
224#define BCM43xx_SBIMCONFIGLOW_REQUEST_TOUT_SHIFT 4
225#define BCM43xx_SBIMCONFIGLOW_CONNID_MASK 0x00ff0000
226#define BCM43xx_SBIMCONFIGLOW_CONNID_SHIFT 16
227
228/* sbtmstatelow state flags */
229#define BCM43xx_SBTMSTATELOW_RESET 0x01
230#define BCM43xx_SBTMSTATELOW_REJECT 0x02
231#define BCM43xx_SBTMSTATELOW_CLOCK 0x10000
232#define BCM43xx_SBTMSTATELOW_FORCE_GATE_CLOCK 0x20000
233
234/* sbtmstatehigh state flags */
235#define BCM43xx_SBTMSTATEHIGH_SERROR 0x1
236#define BCM43xx_SBTMSTATEHIGH_BUSY 0x4
237
238/* sbimstate flags */
239#define BCM43xx_SBIMSTATE_IB_ERROR 0x20000
240#define BCM43xx_SBIMSTATE_TIMEOUT 0x40000
241
242/* PHYVersioning */
243#define BCM43xx_PHYTYPE_A 0x00
244#define BCM43xx_PHYTYPE_B 0x01
245#define BCM43xx_PHYTYPE_G 0x02
246
247/* PHYRegisters */
248#define BCM43xx_PHY_ILT_A_CTRL 0x0072
249#define BCM43xx_PHY_ILT_A_DATA1 0x0073
250#define BCM43xx_PHY_ILT_A_DATA2 0x0074
251#define BCM43xx_PHY_G_LO_CONTROL 0x0810
252#define BCM43xx_PHY_ILT_G_CTRL 0x0472
253#define BCM43xx_PHY_ILT_G_DATA1 0x0473
254#define BCM43xx_PHY_ILT_G_DATA2 0x0474
255#define BCM43xx_PHY_A_PCTL 0x007B
256#define BCM43xx_PHY_G_PCTL 0x0029
257#define BCM43xx_PHY_A_CRS 0x0029
258#define BCM43xx_PHY_RADIO_BITFIELD 0x0401
259#define BCM43xx_PHY_G_CRS 0x0429
260#define BCM43xx_PHY_NRSSILT_CTRL 0x0803
261#define BCM43xx_PHY_NRSSILT_DATA 0x0804
262
263/* RadioRegisters */
264#define BCM43xx_RADIOCTL_ID 0x01
265
266/* StatusBitField */
267#define BCM43xx_SBF_MAC_ENABLED 0x00000001
268#define BCM43xx_SBF_2 0x00000002 /*FIXME: fix name*/
269#define BCM43xx_SBF_CORE_READY 0x00000004
270#define BCM43xx_SBF_400 0x00000400 /*FIXME: fix name*/
271#define BCM43xx_SBF_4000 0x00004000 /*FIXME: fix name*/
272#define BCM43xx_SBF_8000 0x00008000 /*FIXME: fix name*/
273#define BCM43xx_SBF_XFER_REG_BYTESWAP 0x00010000
274#define BCM43xx_SBF_MODE_NOTADHOC 0x00020000
275#define BCM43xx_SBF_MODE_AP 0x00040000
276#define BCM43xx_SBF_RADIOREG_LOCK 0x00080000
277#define BCM43xx_SBF_MODE_MONITOR 0x00400000
278#define BCM43xx_SBF_MODE_PROMISC 0x01000000
279#define BCM43xx_SBF_PS1 0x02000000
280#define BCM43xx_SBF_PS2 0x04000000
281#define BCM43xx_SBF_NO_SSID_BCAST 0x08000000
282#define BCM43xx_SBF_TIME_UPDATE 0x10000000
283#define BCM43xx_SBF_80000000 0x80000000 /*FIXME: fix name*/
284
285/* MicrocodeFlagsBitfield (addr + lo-word values?)*/
286#define BCM43xx_UCODEFLAGS_OFFSET 0x005E
287
288#define BCM43xx_UCODEFLAG_AUTODIV 0x0001
289#define BCM43xx_UCODEFLAG_UNKBGPHY 0x0002
290#define BCM43xx_UCODEFLAG_UNKBPHY 0x0004
291#define BCM43xx_UCODEFLAG_UNKGPHY 0x0020
292#define BCM43xx_UCODEFLAG_UNKPACTRL 0x0040
293#define BCM43xx_UCODEFLAG_JAPAN 0x0080
294
295/* Generic-Interrupt reasons. */
296#define BCM43xx_IRQ_READY (1 << 0)
297#define BCM43xx_IRQ_BEACON (1 << 1)
298#define BCM43xx_IRQ_PS (1 << 2)
299#define BCM43xx_IRQ_REG124 (1 << 5)
300#define BCM43xx_IRQ_PMQ (1 << 6)
301#define BCM43xx_IRQ_PIO_WORKAROUND (1 << 8)
302#define BCM43xx_IRQ_XMIT_ERROR (1 << 11)
303#define BCM43xx_IRQ_RX (1 << 15)
304#define BCM43xx_IRQ_SCAN (1 << 16)
305#define BCM43xx_IRQ_NOISE (1 << 18)
306#define BCM43xx_IRQ_XMIT_STATUS (1 << 29)
307
308#define BCM43xx_IRQ_ALL 0xffffffff
309#define BCM43xx_IRQ_INITIAL (BCM43xx_IRQ_PS | \
310 BCM43xx_IRQ_REG124 | \
311 BCM43xx_IRQ_PMQ | \
312 BCM43xx_IRQ_XMIT_ERROR | \
313 BCM43xx_IRQ_RX | \
314 BCM43xx_IRQ_SCAN | \
315 BCM43xx_IRQ_NOISE | \
316 BCM43xx_IRQ_XMIT_STATUS)
317
318
319/* Initial default iw_mode */
320#define BCM43xx_INITIAL_IWMODE IW_MODE_INFRA
321
322/* Bus type PCI. */
323#define BCM43xx_BUSTYPE_PCI 0
324/* Bus type Silicone Backplane Bus. */
325#define BCM43xx_BUSTYPE_SB 1
326/* Bus type PCMCIA. */
327#define BCM43xx_BUSTYPE_PCMCIA 2
328
329/* Threshold values. */
330#define BCM43xx_MIN_RTS_THRESHOLD 1U
331#define BCM43xx_MAX_RTS_THRESHOLD 2304U
332#define BCM43xx_DEFAULT_RTS_THRESHOLD BCM43xx_MAX_RTS_THRESHOLD
333
334#define BCM43xx_DEFAULT_SHORT_RETRY_LIMIT 7
335#define BCM43xx_DEFAULT_LONG_RETRY_LIMIT 4
336
337/* Max size of a security key */
338#define BCM43xx_SEC_KEYSIZE 16
339/* Security algorithms. */
340enum {
341 BCM43xx_SEC_ALGO_NONE = 0, /* unencrypted, as of TX header. */
342 BCM43xx_SEC_ALGO_WEP,
343 BCM43xx_SEC_ALGO_UNKNOWN,
344 BCM43xx_SEC_ALGO_AES,
345 BCM43xx_SEC_ALGO_WEP104,
346 BCM43xx_SEC_ALGO_TKIP,
347};
348
349#ifdef assert
350# undef assert
351#endif
352#ifdef CONFIG_BCM43XX_DEBUG
353#define assert(expr) \
354 do { \
355 if (unlikely(!(expr))) { \
356 printk(KERN_ERR PFX "ASSERTION FAILED (%s) at: %s:%d:%s()\n", \
357 #expr, __FILE__, __LINE__, __FUNCTION__); \
358 } \
359 } while (0)
360#else
361#define assert(expr) do { /* nothing */ } while (0)
362#endif
363
364/* rate limited printk(). */
365#ifdef printkl
366# undef printkl
367#endif
368#define printkl(f, x...) do { if (printk_ratelimit()) printk(f ,##x); } while (0)
369/* rate limited printk() for debugging */
370#ifdef dprintkl
371# undef dprintkl
372#endif
373#ifdef CONFIG_BCM43XX_DEBUG
374# define dprintkl printkl
375#else
376# define dprintkl(f, x...) do { /* nothing */ } while (0)
377#endif
378
379/* Helper macro for if branches.
380 * An if branch marked with this macro is only taken in DEBUG mode.
381 * Example:
382 * if (DEBUG_ONLY(foo == bar)) {
383 * do something
384 * }
385 * In DEBUG mode, the branch will be taken if (foo == bar).
386 * In non-DEBUG mode, the branch will never be taken.
387 */
388#ifdef DEBUG_ONLY
389# undef DEBUG_ONLY
390#endif
391#ifdef CONFIG_BCM43XX_DEBUG
392# define DEBUG_ONLY(x) (x)
393#else
394# define DEBUG_ONLY(x) 0
395#endif
396
397/* debugging printk() */
398#ifdef dprintk
399# undef dprintk
400#endif
401#ifdef CONFIG_BCM43XX_DEBUG
402# define dprintk(f, x...) do { printk(f ,##x); } while (0)
403#else
404# define dprintk(f, x...) do { /* nothing */ } while (0)
405#endif
406
407
408struct net_device;
409struct pci_dev;
410struct bcm43xx_dmaring;
411struct bcm43xx_pioqueue;
412
413struct bcm43xx_initval {
414 u16 offset;
415 u16 size;
416 u32 value;
417} __attribute__((__packed__));
418
419/* Values for bcm430x_sprominfo.locale */
420enum {
421 BCM43xx_LOCALE_WORLD = 0,
422 BCM43xx_LOCALE_THAILAND,
423 BCM43xx_LOCALE_ISRAEL,
424 BCM43xx_LOCALE_JORDAN,
425 BCM43xx_LOCALE_CHINA,
426 BCM43xx_LOCALE_JAPAN,
427 BCM43xx_LOCALE_USA_CANADA_ANZ,
428 BCM43xx_LOCALE_EUROPE,
429 BCM43xx_LOCALE_USA_LOW,
430 BCM43xx_LOCALE_JAPAN_HIGH,
431 BCM43xx_LOCALE_ALL,
432 BCM43xx_LOCALE_NONE,
433};
434
435#define BCM43xx_SPROM_SIZE 64 /* in 16-bit words. */
436struct bcm43xx_sprominfo {
437 u16 boardflags2;
438 u8 il0macaddr[6];
439 u8 et0macaddr[6];
440 u8 et1macaddr[6];
441 u8 et0phyaddr:5;
442 u8 et1phyaddr:5;
443 u8 et0mdcport:1;
444 u8 et1mdcport:1;
445 u8 boardrev;
446 u8 locale:4;
447 u8 antennas_aphy:2;
448 u8 antennas_bgphy:2;
449 u16 pa0b0;
450 u16 pa0b1;
451 u16 pa0b2;
452 u8 wl0gpio0;
453 u8 wl0gpio1;
454 u8 wl0gpio2;
455 u8 wl0gpio3;
456 u8 maxpower_aphy;
457 u8 maxpower_bgphy;
458 u16 pa1b0;
459 u16 pa1b1;
460 u16 pa1b2;
461 u8 idle_tssi_tgt_aphy;
462 u8 idle_tssi_tgt_bgphy;
463 u16 boardflags;
464 u16 antennagain_aphy;
465 u16 antennagain_bgphy;
466};
467
468/* Value pair to measure the LocalOscillator. */
469struct bcm43xx_lopair {
470 s8 low;
471 s8 high;
472 u8 used:1;
473};
474#define BCM43xx_LO_COUNT (14*4)
475
476struct bcm43xx_phyinfo {
477 /* Hardware Data */
478 u8 version;
479 u8 type;
480 u8 rev;
481 u16 antenna_diversity;
482 u16 savedpctlreg;
483 u16 minlowsig[2];
484 u16 minlowsigpos[2];
485 u8 connected:1,
486 calibrated:1,
487 is_locked:1, /* used in bcm43xx_phy_{un}lock() */
488 dyn_tssi_tbl:1; /* used in bcm43xx_phy_init_tssi2dbm_table() */
489 /* LO Measurement Data.
490 * Use bcm43xx_get_lopair() to get a value.
491 */
492 struct bcm43xx_lopair *_lo_pairs;
493
494 /* TSSI to dBm table in use */
495 const s8 *tssi2dbm;
496 /* idle TSSI value */
497 s8 idle_tssi;
498
499 /* Values from bcm43xx_calc_loopback_gain() */
500 u16 loopback_gain[2];
501
502 /* PHY lock for core.rev < 3
503 * This lock is only used by bcm43xx_phy_{un}lock()
504 */
505 spinlock_t lock;
506};
507
508
509struct bcm43xx_radioinfo {
510 u16 manufact;
511 u16 version;
512 u8 revision;
513
514 /* Desired TX power in dBm Q5.2 */
515 u16 txpower_desired;
516 /* TX Power control values. */
517 union {
518 /* B/G PHY */
519 struct {
520 u16 baseband_atten;
521 u16 radio_atten;
522 u16 txctl1;
523 u16 txctl2;
524 };
525 /* A PHY */
526 struct {
527 u16 txpwr_offset;
528 };
529 };
530
531 /* Current Interference Mitigation mode */
532 int interfmode;
533 /* Stack of saved values from the Interference Mitigation code.
534 * Each value in the stack is layed out as follows:
535 * bit 0-11: offset
536 * bit 12-15: register ID
537 * bit 16-32: value
538 * register ID is: 0x1 PHY, 0x2 Radio, 0x3 ILT
539 */
540#define BCM43xx_INTERFSTACK_SIZE 26
541 u32 interfstack[BCM43xx_INTERFSTACK_SIZE];
542
543 /* Saved values from the NRSSI Slope calculation */
544 s16 nrssi[2];
545 s32 nrssislope;
546 /* In memory nrssi lookup table. */
547 s8 nrssi_lt[64];
548
549 /* current channel */
550 u8 channel;
551 u8 initial_channel;
552
553 u16 lofcal;
554
555 u16 initval;
556
557 u8 enabled:1;
558 /* ACI (adjacent channel interference) flags. */
559 u8 aci_enable:1,
560 aci_wlan_automatic:1,
561 aci_hw_rssi:1;
562};
563
564/* Data structures for DMA transmission, per 80211 core. */
565struct bcm43xx_dma {
566 struct bcm43xx_dmaring *tx_ring0;
567 struct bcm43xx_dmaring *tx_ring1;
568 struct bcm43xx_dmaring *tx_ring2;
569 struct bcm43xx_dmaring *tx_ring3;
570 struct bcm43xx_dmaring *rx_ring0;
571 struct bcm43xx_dmaring *rx_ring1; /* only available on core.rev < 5 */
572};
573
574/* Data structures for PIO transmission, per 80211 core. */
575struct bcm43xx_pio {
576 struct bcm43xx_pioqueue *queue0;
577 struct bcm43xx_pioqueue *queue1;
578 struct bcm43xx_pioqueue *queue2;
579 struct bcm43xx_pioqueue *queue3;
580};
581
582#define BCM43xx_MAX_80211_CORES 2
583
584#ifdef CONFIG_BCM947XX
585#define core_offset(bcm) (bcm)->current_core_offset
586#else
587#define core_offset(bcm) 0
588#endif
589
590/* Generic information about a core. */
591struct bcm43xx_coreinfo {
592 u8 available:1,
593 enabled:1,
594 initialized:1;
595 /** core_id ID number */
596 u16 id;
597 /** core_rev revision number */
598 u8 rev;
599 /** Index number for _switch_core() */
600 u8 index;
601};
602
603/* Additional information for each 80211 core. */
604struct bcm43xx_coreinfo_80211 {
605 /* PHY device. */
606 struct bcm43xx_phyinfo phy;
607 /* Radio device. */
608 struct bcm43xx_radioinfo radio;
609 union {
610 /* DMA context. */
611 struct bcm43xx_dma dma;
612 /* PIO context. */
613 struct bcm43xx_pio pio;
614 };
615};
616
617/* Context information for a noise calculation (Link Quality). */
618struct bcm43xx_noise_calculation {
619 struct bcm43xx_coreinfo *core_at_start;
620 u8 channel_at_start;
621 u8 calculation_running:1;
622 u8 nr_samples;
623 s8 samples[8][4];
624};
625
626struct bcm43xx_stats {
627 u8 link_quality;
628 u8 noise;
629 struct iw_statistics wstats;
630 /* Store the last TX/RX times here for updating the leds. */
631 unsigned long last_tx;
632 unsigned long last_rx;
633};
634
635struct bcm43xx_key {
636 u8 enabled:1;
637 u8 algorithm;
638};
639
640struct bcm43xx_private {
641 struct bcm43xx_sysfs sysfs;
642
643 struct ieee80211_device *ieee;
644 struct ieee80211softmac_device *softmac;
645
646 struct net_device *net_dev;
647 struct pci_dev *pci_dev;
648 unsigned int irq;
649
650 void __iomem *mmio_addr;
651 unsigned int mmio_len;
652
653 /* Do not use the lock directly. Use the bcm43xx_lock* helper
654 * functions, to be MMIO-safe. */
655 spinlock_t _lock;
656
657 /* Driver status flags. */
658 u32 initialized:1, /* init_board() succeed */
659 was_initialized:1, /* for PCI suspend/resume. */
660 shutting_down:1, /* free_board() in progress */
661 __using_pio:1, /* Internal, use bcm43xx_using_pio(). */
662 bad_frames_preempt:1, /* Use "Bad Frames Preemption" (default off) */
663 reg124_set_0x4:1, /* Some variable to keep track of IRQ stuff. */
664 powersaving:1, /* TRUE if we are in PowerSaving mode. FALSE otherwise. */
665 short_preamble:1, /* TRUE, if short preamble is enabled. */
666 firmware_norelease:1; /* Do not release the firmware. Used on suspend. */
667
668 struct bcm43xx_stats stats;
669
670 /* Bus type we are connected to.
671 * This is currently always BCM43xx_BUSTYPE_PCI
672 */
673 u8 bustype;
674
675 u16 board_vendor;
676 u16 board_type;
677 u16 board_revision;
678
679 u16 chip_id;
680 u8 chip_rev;
681 u8 chip_package;
682
683 struct bcm43xx_sprominfo sprom;
684#define BCM43xx_NR_LEDS 4
685 struct bcm43xx_led leds[BCM43xx_NR_LEDS];
686
687 /* The currently active core. */
688 struct bcm43xx_coreinfo *current_core;
689#ifdef CONFIG_BCM947XX
690 /** current core memory offset */
691 u32 current_core_offset;
692#endif
693 struct bcm43xx_coreinfo *active_80211_core;
694 /* coreinfo structs for all possible cores follow.
695 * Note that a core might not exist.
696 * So check the coreinfo flags before using it.
697 */
698 struct bcm43xx_coreinfo core_chipcommon;
699 struct bcm43xx_coreinfo core_pci;
700 struct bcm43xx_coreinfo core_80211[ BCM43xx_MAX_80211_CORES ];
701 /* Additional information, specific to the 80211 cores. */
702 struct bcm43xx_coreinfo_80211 core_80211_ext[ BCM43xx_MAX_80211_CORES ];
703 /* Index of the current 80211 core. If current_core is not
704 * an 80211 core, this is -1.
705 */
706 int current_80211_core_idx;
707 /* Number of available 80211 cores. */
708 int nr_80211_available;
709
710 u32 chipcommon_capabilities;
711
712 /* Reason code of the last interrupt. */
713 u32 irq_reason;
714 u32 dma_reason[4];
715 /* saved irq enable/disable state bitfield. */
716 u32 irq_savedstate;
717 /* Link Quality calculation context. */
718 struct bcm43xx_noise_calculation noisecalc;
719
720 /* Threshold values. */
721 //TODO: The RTS thr has to be _used_. Currently, it is only set via WX.
722 u32 rts_threshold;
723
724 /* Interrupt Service Routine tasklet (bottom-half) */
725 struct tasklet_struct isr_tasklet;
726
727 /* Periodic tasks */
728 struct timer_list periodic_tasks;
729 unsigned int periodic_state;
730
731 struct work_struct restart_work;
732
733 /* Informational stuff. */
734 char nick[IW_ESSID_MAX_SIZE + 1];
735
736 /* encryption/decryption */
737 u16 security_offset;
738 struct bcm43xx_key key[54];
739 u8 default_key_idx;
740
741 /* Firmware. */
742 const struct firmware *ucode;
743 const struct firmware *pcm;
744 const struct firmware *initvals0;
745 const struct firmware *initvals1;
746
747 /* Debugging stuff follows. */
748#ifdef CONFIG_BCM43XX_DEBUG
749 struct bcm43xx_dfsentry *dfsentry;
750#endif
751};
752
753/* bcm43xx_(un)lock() protect struct bcm43xx_private.
754 * Note that _NO_ MMIO writes are allowed. If you want to
755 * write to the device through MMIO in the critical section, use
756 * the *_mmio lock functions.
757 * MMIO read-access is allowed, though.
758 */
759#define bcm43xx_lock(bcm, flags) spin_lock_irqsave(&(bcm)->_lock, flags)
760#define bcm43xx_unlock(bcm, flags) spin_unlock_irqrestore(&(bcm)->_lock, flags)
761/* bcm43xx_(un)lock_mmio() protect struct bcm43xx_private and MMIO.
762 * MMIO write-access to the device is allowed.
763 * All MMIO writes are flushed on unlock, so it is guaranteed to not
764 * interfere with other threads writing MMIO registers.
765 */
766#define bcm43xx_lock_mmio(bcm, flags) bcm43xx_lock(bcm, flags)
767#define bcm43xx_unlock_mmio(bcm, flags) do { mmiowb(); bcm43xx_unlock(bcm, flags); } while (0)
768
769static inline
770struct bcm43xx_private * bcm43xx_priv(struct net_device *dev)
771{
772 return ieee80211softmac_priv(dev);
773}
774
775
776/* Helper function, which returns a boolean.
777 * TRUE, if PIO is used; FALSE, if DMA is used.
778 */
779#if defined(CONFIG_BCM43XX_DMA) && defined(CONFIG_BCM43XX_PIO)
780static inline
781int bcm43xx_using_pio(struct bcm43xx_private *bcm)
782{
783 return bcm->__using_pio;
784}
785#elif defined(CONFIG_BCM43XX_DMA)
786static inline
787int bcm43xx_using_pio(struct bcm43xx_private *bcm)
788{
789 return 0;
790}
791#elif defined(CONFIG_BCM43XX_PIO)
792static inline
793int bcm43xx_using_pio(struct bcm43xx_private *bcm)
794{
795 return 1;
796}
797#else
798# error "Using neither DMA nor PIO? Confused..."
799#endif
800
801/* Helper functions to access data structures private to the 80211 cores.
802 * Note that we _must_ have an 80211 core mapped when calling
803 * any of these functions.
804 */
805static inline
806struct bcm43xx_pio * bcm43xx_current_pio(struct bcm43xx_private *bcm)
807{
808 assert(bcm43xx_using_pio(bcm));
809 assert(bcm->current_80211_core_idx >= 0);
810 assert(bcm->current_80211_core_idx < BCM43xx_MAX_80211_CORES);
811 return &(bcm->core_80211_ext[bcm->current_80211_core_idx].pio);
812}
813static inline
814struct bcm43xx_dma * bcm43xx_current_dma(struct bcm43xx_private *bcm)
815{
816 assert(!bcm43xx_using_pio(bcm));
817 assert(bcm->current_80211_core_idx >= 0);
818 assert(bcm->current_80211_core_idx < BCM43xx_MAX_80211_CORES);
819 return &(bcm->core_80211_ext[bcm->current_80211_core_idx].dma);
820}
821static inline
822struct bcm43xx_phyinfo * bcm43xx_current_phy(struct bcm43xx_private *bcm)
823{
824 assert(bcm->current_80211_core_idx >= 0);
825 assert(bcm->current_80211_core_idx < BCM43xx_MAX_80211_CORES);
826 return &(bcm->core_80211_ext[bcm->current_80211_core_idx].phy);
827}
828static inline
829struct bcm43xx_radioinfo * bcm43xx_current_radio(struct bcm43xx_private *bcm)
830{
831 assert(bcm->current_80211_core_idx >= 0);
832 assert(bcm->current_80211_core_idx < BCM43xx_MAX_80211_CORES);
833 return &(bcm->core_80211_ext[bcm->current_80211_core_idx].radio);
834}
835
836/* Are we running in init_board() context? */
837static inline
838int bcm43xx_is_initializing(struct bcm43xx_private *bcm)
839{
840 if (bcm->initialized)
841 return 0;
842 if (bcm->shutting_down)
843 return 0;
844 return 1;
845}
846
847static inline
848struct bcm43xx_lopair * bcm43xx_get_lopair(struct bcm43xx_phyinfo *phy,
849 u16 radio_attenuation,
850 u16 baseband_attenuation)
851{
852 return phy->_lo_pairs + (radio_attenuation + 14 * (baseband_attenuation / 2));
853}
854
855
856static inline
857u16 bcm43xx_read16(struct bcm43xx_private *bcm, u16 offset)
858{
859 return ioread16(bcm->mmio_addr + core_offset(bcm) + offset);
860}
861
862static inline
863void bcm43xx_write16(struct bcm43xx_private *bcm, u16 offset, u16 value)
864{
865 iowrite16(value, bcm->mmio_addr + core_offset(bcm) + offset);
866}
867
868static inline
869u32 bcm43xx_read32(struct bcm43xx_private *bcm, u16 offset)
870{
871 return ioread32(bcm->mmio_addr + core_offset(bcm) + offset);
872}
873
874static inline
875void bcm43xx_write32(struct bcm43xx_private *bcm, u16 offset, u32 value)
876{
877 iowrite32(value, bcm->mmio_addr + core_offset(bcm) + offset);
878}
879
880static inline
881int bcm43xx_pci_read_config16(struct bcm43xx_private *bcm, int offset, u16 *value)
882{
883 return pci_read_config_word(bcm->pci_dev, offset, value);
884}
885
886static inline
887int bcm43xx_pci_read_config32(struct bcm43xx_private *bcm, int offset, u32 *value)
888{
889 return pci_read_config_dword(bcm->pci_dev, offset, value);
890}
891
892static inline
893int bcm43xx_pci_write_config16(struct bcm43xx_private *bcm, int offset, u16 value)
894{
895 return pci_write_config_word(bcm->pci_dev, offset, value);
896}
897
898static inline
899int bcm43xx_pci_write_config32(struct bcm43xx_private *bcm, int offset, u32 value)
900{
901 return pci_write_config_dword(bcm->pci_dev, offset, value);
902}
903
904/** Limit a value between two limits */
905#ifdef limit_value
906# undef limit_value
907#endif
908#define limit_value(value, min, max) \
909 ({ \
910 typeof(value) __value = (value); \
911 typeof(value) __min = (min); \
912 typeof(value) __max = (max); \
913 if (__value < __min) \
914 __value = __min; \
915 else if (__value > __max) \
916 __value = __max; \
917 __value; \
918 })
919
920/** Helpers to print MAC addresses. */
921#define BCM43xx_MACFMT "%02x:%02x:%02x:%02x:%02x:%02x"
922#define BCM43xx_MACARG(x) ((u8*)(x))[0], ((u8*)(x))[1], \
923 ((u8*)(x))[2], ((u8*)(x))[3], \
924 ((u8*)(x))[4], ((u8*)(x))[5]
925
926#endif /* BCM43xx_H_ */
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_debugfs.c b/drivers/net/wireless/bcm43xx/bcm43xx_debugfs.c
new file mode 100644
index 000000000000..d2c3401e9b70
--- /dev/null
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_debugfs.c
@@ -0,0 +1,499 @@
1/*
2
3 Broadcom BCM43xx wireless driver
4
5 debugfs driver debugging code
6
7 Copyright (c) 2005 Michael Buesch <mbuesch@freenet.de>
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; see the file COPYING. If not, write to
21 the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,
22 Boston, MA 02110-1301, USA.
23
24*/
25
26
27
28#include <linux/fs.h>
29#include <linux/debugfs.h>
30#include <linux/slab.h>
31#include <linux/netdevice.h>
32#include <linux/pci.h>
33#include <asm/io.h>
34
35#include "bcm43xx.h"
36#include "bcm43xx_main.h"
37#include "bcm43xx_debugfs.h"
38#include "bcm43xx_dma.h"
39#include "bcm43xx_pio.h"
40#include "bcm43xx_xmit.h"
41
42#define REALLY_BIG_BUFFER_SIZE (1024*256)
43
44static struct bcm43xx_debugfs fs;
45static char really_big_buffer[REALLY_BIG_BUFFER_SIZE];
46static DECLARE_MUTEX(big_buffer_sem);
47
48
49static ssize_t write_file_dummy(struct file *file, const char __user *buf,
50 size_t count, loff_t *ppos)
51{
52 return count;
53}
54
55static int open_file_generic(struct inode *inode, struct file *file)
56{
57 file->private_data = inode->u.generic_ip;
58 return 0;
59}
60
61#define fappend(fmt, x...) pos += snprintf(buf + pos, len - pos, fmt , ##x)
62
63static ssize_t devinfo_read_file(struct file *file, char __user *userbuf,
64 size_t count, loff_t *ppos)
65{
66 const size_t len = REALLY_BIG_BUFFER_SIZE;
67
68 struct bcm43xx_private *bcm = file->private_data;
69 char *buf = really_big_buffer;
70 size_t pos = 0;
71 ssize_t res;
72 struct net_device *net_dev;
73 struct pci_dev *pci_dev;
74 unsigned long flags;
75 u16 tmp16;
76 int i;
77
78 down(&big_buffer_sem);
79
80 bcm43xx_lock_mmio(bcm, flags);
81 if (!bcm->initialized) {
82 fappend("Board not initialized.\n");
83 goto out;
84 }
85 net_dev = bcm->net_dev;
86 pci_dev = bcm->pci_dev;
87
88 /* This is where the information is written to the "devinfo" file */
89 fappend("*** %s devinfo ***\n", net_dev->name);
90 fappend("vendor: 0x%04x device: 0x%04x\n",
91 pci_dev->vendor, pci_dev->device);
92 fappend("subsystem_vendor: 0x%04x subsystem_device: 0x%04x\n",
93 pci_dev->subsystem_vendor, pci_dev->subsystem_device);
94 fappend("IRQ: %d\n", bcm->irq);
95 fappend("mmio_addr: 0x%p mmio_len: %u\n", bcm->mmio_addr, bcm->mmio_len);
96 fappend("chip_id: 0x%04x chip_rev: 0x%02x\n", bcm->chip_id, bcm->chip_rev);
97 if ((bcm->core_80211[0].rev >= 3) && (bcm43xx_read32(bcm, 0x0158) & (1 << 16)))
98 fappend("Radio disabled by hardware!\n");
99 if ((bcm->core_80211[0].rev < 3) && !(bcm43xx_read16(bcm, 0x049A) & (1 << 4)))
100 fappend("Radio disabled by hardware!\n");
101 fappend("board_vendor: 0x%04x board_type: 0x%04x\n", bcm->board_vendor,
102 bcm->board_type);
103
104 fappend("\nCores:\n");
105#define fappend_core(name, info) fappend("core \"" name "\" %s, %s, id: 0x%04x, " \
106 "rev: 0x%02x, index: 0x%02x\n", \
107 (info).available \
108 ? "available" : "nonavailable", \
109 (info).enabled \
110 ? "enabled" : "disabled", \
111 (info).id, (info).rev, (info).index)
112 fappend_core("CHIPCOMMON", bcm->core_chipcommon);
113 fappend_core("PCI", bcm->core_pci);
114 fappend_core("first 80211", bcm->core_80211[0]);
115 fappend_core("second 80211", bcm->core_80211[1]);
116#undef fappend_core
117 tmp16 = bcm43xx_read16(bcm, BCM43xx_MMIO_GPIO_CONTROL);
118 fappend("LEDs: ");
119 for (i = 0; i < BCM43xx_NR_LEDS; i++)
120 fappend("%d ", !!(tmp16 & (1 << i)));
121 fappend("\n");
122
123out:
124 bcm43xx_unlock_mmio(bcm, flags);
125 res = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
126 up(&big_buffer_sem);
127 return res;
128}
129
130static ssize_t drvinfo_read_file(struct file *file, char __user *userbuf,
131 size_t count, loff_t *ppos)
132{
133 const size_t len = REALLY_BIG_BUFFER_SIZE;
134
135 char *buf = really_big_buffer;
136 size_t pos = 0;
137 ssize_t res;
138
139 down(&big_buffer_sem);
140
141 /* This is where the information is written to the "driver" file */
142 fappend(KBUILD_MODNAME " driver\n");
143 fappend("Compiled at: %s %s\n", __DATE__, __TIME__);
144
145 res = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
146 up(&big_buffer_sem);
147 return res;
148}
149
150static ssize_t spromdump_read_file(struct file *file, char __user *userbuf,
151 size_t count, loff_t *ppos)
152{
153 const size_t len = REALLY_BIG_BUFFER_SIZE;
154
155 struct bcm43xx_private *bcm = file->private_data;
156 char *buf = really_big_buffer;
157 size_t pos = 0;
158 ssize_t res;
159 unsigned long flags;
160
161 down(&big_buffer_sem);
162 bcm43xx_lock_mmio(bcm, flags);
163 if (!bcm->initialized) {
164 fappend("Board not initialized.\n");
165 goto out;
166 }
167
168 /* This is where the information is written to the "sprom_dump" file */
169 fappend("boardflags: 0x%04x\n", bcm->sprom.boardflags);
170
171out:
172 bcm43xx_unlock_mmio(bcm, flags);
173 res = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
174 up(&big_buffer_sem);
175 return res;
176}
177
178static ssize_t tsf_read_file(struct file *file, char __user *userbuf,
179 size_t count, loff_t *ppos)
180{
181 const size_t len = REALLY_BIG_BUFFER_SIZE;
182
183 struct bcm43xx_private *bcm = file->private_data;
184 char *buf = really_big_buffer;
185 size_t pos = 0;
186 ssize_t res;
187 unsigned long flags;
188 u64 tsf;
189
190 down(&big_buffer_sem);
191 bcm43xx_lock_mmio(bcm, flags);
192 if (!bcm->initialized) {
193 fappend("Board not initialized.\n");
194 goto out;
195 }
196 bcm43xx_tsf_read(bcm, &tsf);
197 fappend("0x%08x%08x\n",
198 (unsigned int)((tsf & 0xFFFFFFFF00000000ULL) >> 32),
199 (unsigned int)(tsf & 0xFFFFFFFFULL));
200
201out:
202 bcm43xx_unlock_mmio(bcm, flags);
203 res = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
204 up(&big_buffer_sem);
205 return res;
206}
207
208static ssize_t tsf_write_file(struct file *file, const char __user *user_buf,
209 size_t count, loff_t *ppos)
210{
211 struct bcm43xx_private *bcm = file->private_data;
212 char *buf = really_big_buffer;
213 ssize_t buf_size;
214 ssize_t res;
215 unsigned long flags;
216 u64 tsf;
217
218 buf_size = min(count, sizeof (really_big_buffer) - 1);
219 down(&big_buffer_sem);
220 if (copy_from_user(buf, user_buf, buf_size)) {
221 res = -EFAULT;
222 goto out_up;
223 }
224 bcm43xx_lock_mmio(bcm, flags);
225 if (!bcm->initialized) {
226 printk(KERN_INFO PFX "debugfs: Board not initialized.\n");
227 res = -EFAULT;
228 goto out_unlock;
229 }
230 if (sscanf(buf, "%lli", &tsf) != 1) {
231 printk(KERN_INFO PFX "debugfs: invalid values for \"tsf\"\n");
232 res = -EINVAL;
233 goto out_unlock;
234 }
235 bcm43xx_tsf_write(bcm, tsf);
236 res = buf_size;
237
238out_unlock:
239 bcm43xx_unlock_mmio(bcm, flags);
240out_up:
241 up(&big_buffer_sem);
242 return res;
243}
244
245static ssize_t txstat_read_file(struct file *file, char __user *userbuf,
246 size_t count, loff_t *ppos)
247{
248 const size_t len = REALLY_BIG_BUFFER_SIZE;
249
250 struct bcm43xx_private *bcm = file->private_data;
251 char *buf = really_big_buffer;
252 size_t pos = 0;
253 ssize_t res;
254 unsigned long flags;
255 struct bcm43xx_dfsentry *e;
256 struct bcm43xx_xmitstatus *status;
257 int i, cnt, j = 0;
258
259 down(&big_buffer_sem);
260 bcm43xx_lock(bcm, flags);
261
262 fappend("Last %d logged xmitstatus blobs (Latest first):\n\n",
263 BCM43xx_NR_LOGGED_XMITSTATUS);
264 e = bcm->dfsentry;
265 if (e->xmitstatus_printing == 0) {
266 /* At the beginning, make a copy of all data to avoid
267 * concurrency, as this function is called multiple
268 * times for big logs. Without copying, the data might
269 * change between reads. This would result in total trash.
270 */
271 e->xmitstatus_printing = 1;
272 e->saved_xmitstatus_ptr = e->xmitstatus_ptr;
273 e->saved_xmitstatus_cnt = e->xmitstatus_cnt;
274 memcpy(e->xmitstatus_print_buffer, e->xmitstatus_buffer,
275 BCM43xx_NR_LOGGED_XMITSTATUS * sizeof(*(e->xmitstatus_buffer)));
276 }
277 i = e->saved_xmitstatus_ptr - 1;
278 if (i < 0)
279 i = BCM43xx_NR_LOGGED_XMITSTATUS - 1;
280 cnt = e->saved_xmitstatus_cnt;
281 while (cnt) {
282 status = e->xmitstatus_print_buffer + i;
283 fappend("0x%02x: cookie: 0x%04x, flags: 0x%02x, "
284 "cnt1: 0x%02x, cnt2: 0x%02x, seq: 0x%04x, "
285 "unk: 0x%04x\n", j,
286 status->cookie, status->flags,
287 status->cnt1, status->cnt2, status->seq,
288 status->unknown);
289 j++;
290 cnt--;
291 i--;
292 if (i < 0)
293 i = BCM43xx_NR_LOGGED_XMITSTATUS - 1;
294 }
295
296 bcm43xx_unlock(bcm, flags);
297 res = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
298 bcm43xx_lock(bcm, flags);
299 if (*ppos == pos) {
300 /* Done. Drop the copied data. */
301 e->xmitstatus_printing = 0;
302 }
303 bcm43xx_unlock(bcm, flags);
304 up(&big_buffer_sem);
305 return res;
306}
307
308#undef fappend
309
310
311static struct file_operations devinfo_fops = {
312 .read = devinfo_read_file,
313 .write = write_file_dummy,
314 .open = open_file_generic,
315};
316
317static struct file_operations spromdump_fops = {
318 .read = spromdump_read_file,
319 .write = write_file_dummy,
320 .open = open_file_generic,
321};
322
323static struct file_operations drvinfo_fops = {
324 .read = drvinfo_read_file,
325 .write = write_file_dummy,
326 .open = open_file_generic,
327};
328
329static struct file_operations tsf_fops = {
330 .read = tsf_read_file,
331 .write = tsf_write_file,
332 .open = open_file_generic,
333};
334
335static struct file_operations txstat_fops = {
336 .read = txstat_read_file,
337 .write = write_file_dummy,
338 .open = open_file_generic,
339};
340
341
342void bcm43xx_debugfs_add_device(struct bcm43xx_private *bcm)
343{
344 struct bcm43xx_dfsentry *e;
345 char devdir[IFNAMSIZ];
346
347 assert(bcm);
348 e = kzalloc(sizeof(*e), GFP_KERNEL);
349 if (!e) {
350 printk(KERN_ERR PFX "out of memory\n");
351 return;
352 }
353 e->bcm = bcm;
354 e->xmitstatus_buffer = kzalloc(BCM43xx_NR_LOGGED_XMITSTATUS
355 * sizeof(*(e->xmitstatus_buffer)),
356 GFP_KERNEL);
357 if (!e->xmitstatus_buffer) {
358 printk(KERN_ERR PFX "out of memory\n");
359 kfree(e);
360 return;
361 }
362 e->xmitstatus_print_buffer = kzalloc(BCM43xx_NR_LOGGED_XMITSTATUS
363 * sizeof(*(e->xmitstatus_buffer)),
364 GFP_KERNEL);
365 if (!e->xmitstatus_print_buffer) {
366 printk(KERN_ERR PFX "out of memory\n");
367 kfree(e);
368 return;
369 }
370
371
372 bcm->dfsentry = e;
373
374 strncpy(devdir, bcm->net_dev->name, ARRAY_SIZE(devdir));
375 e->subdir = debugfs_create_dir(devdir, fs.root);
376 e->dentry_devinfo = debugfs_create_file("devinfo", 0444, e->subdir,
377 bcm, &devinfo_fops);
378 if (!e->dentry_devinfo)
379 printk(KERN_ERR PFX "debugfs: creating \"devinfo\" for \"%s\" failed!\n", devdir);
380 e->dentry_spromdump = debugfs_create_file("sprom_dump", 0444, e->subdir,
381 bcm, &spromdump_fops);
382 if (!e->dentry_spromdump)
383 printk(KERN_ERR PFX "debugfs: creating \"sprom_dump\" for \"%s\" failed!\n", devdir);
384 e->dentry_tsf = debugfs_create_file("tsf", 0666, e->subdir,
385 bcm, &tsf_fops);
386 if (!e->dentry_tsf)
387 printk(KERN_ERR PFX "debugfs: creating \"tsf\" for \"%s\" failed!\n", devdir);
388 e->dentry_txstat = debugfs_create_file("tx_status", 0444, e->subdir,
389 bcm, &txstat_fops);
390 if (!e->dentry_txstat)
391 printk(KERN_ERR PFX "debugfs: creating \"tx_status\" for \"%s\" failed!\n", devdir);
392}
393
394void bcm43xx_debugfs_remove_device(struct bcm43xx_private *bcm)
395{
396 struct bcm43xx_dfsentry *e;
397
398 if (!bcm)
399 return;
400
401 e = bcm->dfsentry;
402 assert(e);
403 debugfs_remove(e->dentry_spromdump);
404 debugfs_remove(e->dentry_devinfo);
405 debugfs_remove(e->dentry_tsf);
406 debugfs_remove(e->dentry_txstat);
407 debugfs_remove(e->subdir);
408 kfree(e->xmitstatus_buffer);
409 kfree(e->xmitstatus_print_buffer);
410 kfree(e);
411}
412
413void bcm43xx_debugfs_log_txstat(struct bcm43xx_private *bcm,
414 struct bcm43xx_xmitstatus *status)
415{
416 struct bcm43xx_dfsentry *e;
417 struct bcm43xx_xmitstatus *savedstatus;
418
419 /* This is protected by bcm->_lock */
420 e = bcm->dfsentry;
421 assert(e);
422 savedstatus = e->xmitstatus_buffer + e->xmitstatus_ptr;
423 memcpy(savedstatus, status, sizeof(*status));
424 e->xmitstatus_ptr++;
425 if (e->xmitstatus_ptr >= BCM43xx_NR_LOGGED_XMITSTATUS)
426 e->xmitstatus_ptr = 0;
427 if (e->xmitstatus_cnt < BCM43xx_NR_LOGGED_XMITSTATUS)
428 e->xmitstatus_cnt++;
429}
430
431void bcm43xx_debugfs_init(void)
432{
433 memset(&fs, 0, sizeof(fs));
434 fs.root = debugfs_create_dir(KBUILD_MODNAME, NULL);
435 if (!fs.root)
436 printk(KERN_ERR PFX "debugfs: creating \"" KBUILD_MODNAME "\" subdir failed!\n");
437 fs.dentry_driverinfo = debugfs_create_file("driver", 0444, fs.root, NULL, &drvinfo_fops);
438 if (!fs.dentry_driverinfo)
439 printk(KERN_ERR PFX "debugfs: creating \"" KBUILD_MODNAME "/driver\" failed!\n");
440}
441
442void bcm43xx_debugfs_exit(void)
443{
444 debugfs_remove(fs.dentry_driverinfo);
445 debugfs_remove(fs.root);
446}
447
448void bcm43xx_printk_dump(const char *data,
449 size_t size,
450 const char *description)
451{
452 size_t i;
453 char c;
454
455 printk(KERN_INFO PFX "Data dump (%s, %u bytes):",
456 description, size);
457 for (i = 0; i < size; i++) {
458 c = data[i];
459 if (i % 8 == 0)
460 printk("\n" KERN_INFO PFX "0x%08x: 0x%02x, ", i, c & 0xff);
461 else
462 printk("0x%02x, ", c & 0xff);
463 }
464 printk("\n");
465}
466
467void bcm43xx_printk_bitdump(const unsigned char *data,
468 size_t bytes, int msb_to_lsb,
469 const char *description)
470{
471 size_t i;
472 int j;
473 const unsigned char *d;
474
475 printk(KERN_INFO PFX "*** Bitdump (%s, %u bytes, %s) ***",
476 description, bytes, msb_to_lsb ? "MSB to LSB" : "LSB to MSB");
477 for (i = 0; i < bytes; i++) {
478 d = data + i;
479 if (i % 8 == 0)
480 printk("\n" KERN_INFO PFX "0x%08x: ", i);
481 if (msb_to_lsb) {
482 for (j = 7; j >= 0; j--) {
483 if (*d & (1 << j))
484 printk("1");
485 else
486 printk("0");
487 }
488 } else {
489 for (j = 0; j < 8; j++) {
490 if (*d & (1 << j))
491 printk("1");
492 else
493 printk("0");
494 }
495 }
496 printk(" ");
497 }
498 printk("\n");
499}
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_debugfs.h b/drivers/net/wireless/bcm43xx/bcm43xx_debugfs.h
new file mode 100644
index 000000000000..50ce267f794d
--- /dev/null
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_debugfs.h
@@ -0,0 +1,117 @@
1#ifndef BCM43xx_DEBUGFS_H_
2#define BCM43xx_DEBUGFS_H_
3
4struct bcm43xx_private;
5struct bcm43xx_xmitstatus;
6
7#ifdef CONFIG_BCM43XX_DEBUG
8
9#include <linux/list.h>
10#include <asm/semaphore.h>
11
12struct dentry;
13
14/* limited by the size of the "really_big_buffer" */
15#define BCM43xx_NR_LOGGED_XMITSTATUS 100
16
17struct bcm43xx_dfsentry {
18 struct dentry *subdir;
19 struct dentry *dentry_devinfo;
20 struct dentry *dentry_spromdump;
21 struct dentry *dentry_tsf;
22 struct dentry *dentry_txstat;
23
24 struct bcm43xx_private *bcm;
25
26 /* saved xmitstatus. */
27 struct bcm43xx_xmitstatus *xmitstatus_buffer;
28 int xmitstatus_ptr;
29 int xmitstatus_cnt;
30 /* We need a seperate buffer while printing to avoid
31 * concurrency issues. (New xmitstatus can arrive
32 * while we are printing).
33 */
34 struct bcm43xx_xmitstatus *xmitstatus_print_buffer;
35 int saved_xmitstatus_ptr;
36 int saved_xmitstatus_cnt;
37 int xmitstatus_printing;
38};
39
40struct bcm43xx_debugfs {
41 struct dentry *root;
42 struct dentry *dentry_driverinfo;
43};
44
45void bcm43xx_debugfs_init(void);
46void bcm43xx_debugfs_exit(void);
47void bcm43xx_debugfs_add_device(struct bcm43xx_private *bcm);
48void bcm43xx_debugfs_remove_device(struct bcm43xx_private *bcm);
49void bcm43xx_debugfs_log_txstat(struct bcm43xx_private *bcm,
50 struct bcm43xx_xmitstatus *status);
51
52/* Debug helper: Dump binary data through printk. */
53void bcm43xx_printk_dump(const char *data,
54 size_t size,
55 const char *description);
56/* Debug helper: Dump bitwise binary data through printk. */
57void bcm43xx_printk_bitdump(const unsigned char *data,
58 size_t bytes, int msb_to_lsb,
59 const char *description);
60#define bcm43xx_printk_bitdumpt(pointer, msb_to_lsb, description) \
61 do { \
62 bcm43xx_printk_bitdump((const unsigned char *)(pointer), \
63 sizeof(*(pointer)), \
64 (msb_to_lsb), \
65 (description)); \
66 } while (0)
67
68#else /* CONFIG_BCM43XX_DEBUG*/
69
70static inline
71void bcm43xx_debugfs_init(void) { }
72static inline
73void bcm43xx_debugfs_exit(void) { }
74static inline
75void bcm43xx_debugfs_add_device(struct bcm43xx_private *bcm) { }
76static inline
77void bcm43xx_debugfs_remove_device(struct bcm43xx_private *bcm) { }
78static inline
79void bcm43xx_debugfs_log_txstat(struct bcm43xx_private *bcm,
80 struct bcm43xx_xmitstatus *status) { }
81
82static inline
83void bcm43xx_printk_dump(const char *data,
84 size_t size,
85 const char *description)
86{
87}
88static inline
89void bcm43xx_printk_bitdump(const unsigned char *data,
90 size_t bytes, int msb_to_lsb,
91 const char *description)
92{
93}
94#define bcm43xx_printk_bitdumpt(pointer, msb_to_lsb, description) do { /* nothing */ } while (0)
95
96#endif /* CONFIG_BCM43XX_DEBUG*/
97
98/* Ugly helper macros to make incomplete code more verbose on runtime */
99#ifdef TODO
100# undef TODO
101#endif
102#define TODO() \
103 do { \
104 printk(KERN_INFO PFX "TODO: Incomplete code in %s() at %s:%d\n", \
105 __FUNCTION__, __FILE__, __LINE__); \
106 } while (0)
107
108#ifdef FIXME
109# undef FIXME
110#endif
111#define FIXME() \
112 do { \
113 printk(KERN_INFO PFX "FIXME: Possibly broken code in %s() at %s:%d\n", \
114 __FUNCTION__, __FILE__, __LINE__); \
115 } while (0)
116
117#endif /* BCM43xx_DEBUGFS_H_ */
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_dma.c b/drivers/net/wireless/bcm43xx/bcm43xx_dma.c
new file mode 100644
index 000000000000..c3681b8f09b4
--- /dev/null
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_dma.c
@@ -0,0 +1,968 @@
1/*
2
3 Broadcom BCM43xx wireless driver
4
5 DMA ringbuffer and descriptor allocation/management
6
7 Copyright (c) 2005 Michael Buesch <mbuesch@freenet.de>
8
9 Some code in this file is derived from the b44.c driver
10 Copyright (C) 2002 David S. Miller
11 Copyright (C) Pekka Pietikainen
12
13 This program is free software; you can redistribute it and/or modify
14 it under the terms of the GNU General Public License as published by
15 the Free Software Foundation; either version 2 of the License, or
16 (at your option) any later version.
17
18 This program is distributed in the hope that it will be useful,
19 but WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 GNU General Public License for more details.
22
23 You should have received a copy of the GNU General Public License
24 along with this program; see the file COPYING. If not, write to
25 the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,
26 Boston, MA 02110-1301, USA.
27
28*/
29
30#include "bcm43xx.h"
31#include "bcm43xx_dma.h"
32#include "bcm43xx_main.h"
33#include "bcm43xx_debugfs.h"
34#include "bcm43xx_power.h"
35#include "bcm43xx_xmit.h"
36
37#include <linux/dma-mapping.h>
38#include <linux/pci.h>
39#include <linux/delay.h>
40#include <linux/skbuff.h>
41
42
43static inline int free_slots(struct bcm43xx_dmaring *ring)
44{
45 return (ring->nr_slots - ring->used_slots);
46}
47
48static inline int next_slot(struct bcm43xx_dmaring *ring, int slot)
49{
50 assert(slot >= -1 && slot <= ring->nr_slots - 1);
51 if (slot == ring->nr_slots - 1)
52 return 0;
53 return slot + 1;
54}
55
56static inline int prev_slot(struct bcm43xx_dmaring *ring, int slot)
57{
58 assert(slot >= 0 && slot <= ring->nr_slots - 1);
59 if (slot == 0)
60 return ring->nr_slots - 1;
61 return slot - 1;
62}
63
64/* Request a slot for usage. */
65static inline
66int request_slot(struct bcm43xx_dmaring *ring)
67{
68 int slot;
69
70 assert(ring->tx);
71 assert(!ring->suspended);
72 assert(free_slots(ring) != 0);
73
74 slot = next_slot(ring, ring->current_slot);
75 ring->current_slot = slot;
76 ring->used_slots++;
77
78 /* Check the number of available slots and suspend TX,
79 * if we are running low on free slots.
80 */
81 if (unlikely(free_slots(ring) < ring->suspend_mark)) {
82 netif_stop_queue(ring->bcm->net_dev);
83 ring->suspended = 1;
84 }
85#ifdef CONFIG_BCM43XX_DEBUG
86 if (ring->used_slots > ring->max_used_slots)
87 ring->max_used_slots = ring->used_slots;
88#endif /* CONFIG_BCM43XX_DEBUG*/
89
90 return slot;
91}
92
93/* Return a slot to the free slots. */
94static inline
95void return_slot(struct bcm43xx_dmaring *ring, int slot)
96{
97 assert(ring->tx);
98
99 ring->used_slots--;
100
101 /* Check if TX is suspended and check if we have
102 * enough free slots to resume it again.
103 */
104 if (unlikely(ring->suspended)) {
105 if (free_slots(ring) >= ring->resume_mark) {
106 ring->suspended = 0;
107 netif_wake_queue(ring->bcm->net_dev);
108 }
109 }
110}
111
112static inline
113dma_addr_t map_descbuffer(struct bcm43xx_dmaring *ring,
114 unsigned char *buf,
115 size_t len,
116 int tx)
117{
118 dma_addr_t dmaaddr;
119
120 if (tx) {
121 dmaaddr = dma_map_single(&ring->bcm->pci_dev->dev,
122 buf, len,
123 DMA_TO_DEVICE);
124 } else {
125 dmaaddr = dma_map_single(&ring->bcm->pci_dev->dev,
126 buf, len,
127 DMA_FROM_DEVICE);
128 }
129
130 return dmaaddr;
131}
132
133static inline
134void unmap_descbuffer(struct bcm43xx_dmaring *ring,
135 dma_addr_t addr,
136 size_t len,
137 int tx)
138{
139 if (tx) {
140 dma_unmap_single(&ring->bcm->pci_dev->dev,
141 addr, len,
142 DMA_TO_DEVICE);
143 } else {
144 dma_unmap_single(&ring->bcm->pci_dev->dev,
145 addr, len,
146 DMA_FROM_DEVICE);
147 }
148}
149
150static inline
151void sync_descbuffer_for_cpu(struct bcm43xx_dmaring *ring,
152 dma_addr_t addr,
153 size_t len)
154{
155 assert(!ring->tx);
156
157 dma_sync_single_for_cpu(&ring->bcm->pci_dev->dev,
158 addr, len, DMA_FROM_DEVICE);
159}
160
161static inline
162void sync_descbuffer_for_device(struct bcm43xx_dmaring *ring,
163 dma_addr_t addr,
164 size_t len)
165{
166 assert(!ring->tx);
167
168 dma_sync_single_for_device(&ring->bcm->pci_dev->dev,
169 addr, len, DMA_FROM_DEVICE);
170}
171
172/* Unmap and free a descriptor buffer. */
173static inline
174void free_descriptor_buffer(struct bcm43xx_dmaring *ring,
175 struct bcm43xx_dmadesc *desc,
176 struct bcm43xx_dmadesc_meta *meta,
177 int irq_context)
178{
179 assert(meta->skb);
180 if (irq_context)
181 dev_kfree_skb_irq(meta->skb);
182 else
183 dev_kfree_skb(meta->skb);
184 meta->skb = NULL;
185}
186
187static int alloc_ringmemory(struct bcm43xx_dmaring *ring)
188{
189 struct device *dev = &(ring->bcm->pci_dev->dev);
190
191 ring->vbase = dma_alloc_coherent(dev, BCM43xx_DMA_RINGMEMSIZE,
192 &(ring->dmabase), GFP_KERNEL);
193 if (!ring->vbase) {
194 printk(KERN_ERR PFX "DMA ringmemory allocation failed\n");
195 return -ENOMEM;
196 }
197 if (ring->dmabase + BCM43xx_DMA_RINGMEMSIZE > BCM43xx_DMA_BUSADDRMAX) {
198 printk(KERN_ERR PFX ">>>FATAL ERROR<<< DMA RINGMEMORY >1G "
199 "(0x%08x, len: %lu)\n",
200 ring->dmabase, BCM43xx_DMA_RINGMEMSIZE);
201 dma_free_coherent(dev, BCM43xx_DMA_RINGMEMSIZE,
202 ring->vbase, ring->dmabase);
203 return -ENOMEM;
204 }
205 assert(!(ring->dmabase & 0x000003FF));
206 memset(ring->vbase, 0, BCM43xx_DMA_RINGMEMSIZE);
207
208 return 0;
209}
210
211static void free_ringmemory(struct bcm43xx_dmaring *ring)
212{
213 struct device *dev = &(ring->bcm->pci_dev->dev);
214
215 dma_free_coherent(dev, BCM43xx_DMA_RINGMEMSIZE,
216 ring->vbase, ring->dmabase);
217}
218
219/* Reset the RX DMA channel */
220int bcm43xx_dmacontroller_rx_reset(struct bcm43xx_private *bcm,
221 u16 mmio_base)
222{
223 int i;
224 u32 value;
225
226 bcm43xx_write32(bcm,
227 mmio_base + BCM43xx_DMA_RX_CONTROL,
228 0x00000000);
229 for (i = 0; i < 1000; i++) {
230 value = bcm43xx_read32(bcm,
231 mmio_base + BCM43xx_DMA_RX_STATUS);
232 value &= BCM43xx_DMA_RXSTAT_STAT_MASK;
233 if (value == BCM43xx_DMA_RXSTAT_STAT_DISABLED) {
234 i = -1;
235 break;
236 }
237 udelay(10);
238 }
239 if (i != -1) {
240 printk(KERN_ERR PFX "Error: Wait on DMA RX status timed out.\n");
241 return -ENODEV;
242 }
243
244 return 0;
245}
246
247/* Reset the RX DMA channel */
248int bcm43xx_dmacontroller_tx_reset(struct bcm43xx_private *bcm,
249 u16 mmio_base)
250{
251 int i;
252 u32 value;
253
254 for (i = 0; i < 1000; i++) {
255 value = bcm43xx_read32(bcm,
256 mmio_base + BCM43xx_DMA_TX_STATUS);
257 value &= BCM43xx_DMA_TXSTAT_STAT_MASK;
258 if (value == BCM43xx_DMA_TXSTAT_STAT_DISABLED ||
259 value == BCM43xx_DMA_TXSTAT_STAT_IDLEWAIT ||
260 value == BCM43xx_DMA_TXSTAT_STAT_STOPPED)
261 break;
262 udelay(10);
263 }
264 bcm43xx_write32(bcm,
265 mmio_base + BCM43xx_DMA_TX_CONTROL,
266 0x00000000);
267 for (i = 0; i < 1000; i++) {
268 value = bcm43xx_read32(bcm,
269 mmio_base + BCM43xx_DMA_TX_STATUS);
270 value &= BCM43xx_DMA_TXSTAT_STAT_MASK;
271 if (value == BCM43xx_DMA_TXSTAT_STAT_DISABLED) {
272 i = -1;
273 break;
274 }
275 udelay(10);
276 }
277 if (i != -1) {
278 printk(KERN_ERR PFX "Error: Wait on DMA TX status timed out.\n");
279 return -ENODEV;
280 }
281 /* ensure the reset is completed. */
282 udelay(300);
283
284 return 0;
285}
286
287static int setup_rx_descbuffer(struct bcm43xx_dmaring *ring,
288 struct bcm43xx_dmadesc *desc,
289 struct bcm43xx_dmadesc_meta *meta,
290 gfp_t gfp_flags)
291{
292 struct bcm43xx_rxhdr *rxhdr;
293 dma_addr_t dmaaddr;
294 u32 desc_addr;
295 u32 desc_ctl;
296 const int slot = (int)(desc - ring->vbase);
297 struct sk_buff *skb;
298
299 assert(slot >= 0 && slot < ring->nr_slots);
300 assert(!ring->tx);
301
302 skb = __dev_alloc_skb(ring->rx_buffersize, gfp_flags);
303 if (unlikely(!skb))
304 return -ENOMEM;
305 dmaaddr = map_descbuffer(ring, skb->data, ring->rx_buffersize, 0);
306 if (unlikely(dmaaddr + ring->rx_buffersize > BCM43xx_DMA_BUSADDRMAX)) {
307 unmap_descbuffer(ring, dmaaddr, ring->rx_buffersize, 0);
308 dev_kfree_skb_any(skb);
309 printk(KERN_ERR PFX ">>>FATAL ERROR<<< DMA RX SKB >1G "
310 "(0x%08x, len: %u)\n",
311 dmaaddr, ring->rx_buffersize);
312 return -ENOMEM;
313 }
314 meta->skb = skb;
315 meta->dmaaddr = dmaaddr;
316 skb->dev = ring->bcm->net_dev;
317 desc_addr = (u32)(dmaaddr + ring->memoffset);
318 desc_ctl = (BCM43xx_DMADTOR_BYTECNT_MASK &
319 (u32)(ring->rx_buffersize - ring->frameoffset));
320 if (slot == ring->nr_slots - 1)
321 desc_ctl |= BCM43xx_DMADTOR_DTABLEEND;
322 set_desc_addr(desc, desc_addr);
323 set_desc_ctl(desc, desc_ctl);
324
325 rxhdr = (struct bcm43xx_rxhdr *)(skb->data);
326 rxhdr->frame_length = 0;
327 rxhdr->flags1 = 0;
328
329 return 0;
330}
331
332/* Allocate the initial descbuffers.
333 * This is used for an RX ring only.
334 */
335static int alloc_initial_descbuffers(struct bcm43xx_dmaring *ring)
336{
337 int i, err = -ENOMEM;
338 struct bcm43xx_dmadesc *desc;
339 struct bcm43xx_dmadesc_meta *meta;
340
341 for (i = 0; i < ring->nr_slots; i++) {
342 desc = ring->vbase + i;
343 meta = ring->meta + i;
344
345 err = setup_rx_descbuffer(ring, desc, meta, GFP_KERNEL);
346 if (err)
347 goto err_unwind;
348 }
349 ring->used_slots = ring->nr_slots;
350 err = 0;
351out:
352 return err;
353
354err_unwind:
355 for (i--; i >= 0; i--) {
356 desc = ring->vbase + i;
357 meta = ring->meta + i;
358
359 unmap_descbuffer(ring, meta->dmaaddr, ring->rx_buffersize, 0);
360 dev_kfree_skb(meta->skb);
361 }
362 goto out;
363}
364
365/* Do initial setup of the DMA controller.
366 * Reset the controller, write the ring busaddress
367 * and switch the "enable" bit on.
368 */
369static int dmacontroller_setup(struct bcm43xx_dmaring *ring)
370{
371 int err = 0;
372 u32 value;
373
374 if (ring->tx) {
375 /* Set Transmit Control register to "transmit enable" */
376 bcm43xx_dma_write(ring, BCM43xx_DMA_TX_CONTROL,
377 BCM43xx_DMA_TXCTRL_ENABLE);
378 /* Set Transmit Descriptor ring address. */
379 bcm43xx_dma_write(ring, BCM43xx_DMA_TX_DESC_RING,
380 ring->dmabase + ring->memoffset);
381 } else {
382 err = alloc_initial_descbuffers(ring);
383 if (err)
384 goto out;
385 /* Set Receive Control "receive enable" and frame offset */
386 value = (ring->frameoffset << BCM43xx_DMA_RXCTRL_FRAMEOFF_SHIFT);
387 value |= BCM43xx_DMA_RXCTRL_ENABLE;
388 bcm43xx_dma_write(ring, BCM43xx_DMA_RX_CONTROL, value);
389 /* Set Receive Descriptor ring address. */
390 bcm43xx_dma_write(ring, BCM43xx_DMA_RX_DESC_RING,
391 ring->dmabase + ring->memoffset);
392 /* Init the descriptor pointer. */
393 bcm43xx_dma_write(ring, BCM43xx_DMA_RX_DESC_INDEX, 200);
394 }
395
396out:
397 return err;
398}
399
400/* Shutdown the DMA controller. */
401static void dmacontroller_cleanup(struct bcm43xx_dmaring *ring)
402{
403 if (ring->tx) {
404 bcm43xx_dmacontroller_tx_reset(ring->bcm, ring->mmio_base);
405 /* Zero out Transmit Descriptor ring address. */
406 bcm43xx_dma_write(ring, BCM43xx_DMA_TX_DESC_RING, 0);
407 } else {
408 bcm43xx_dmacontroller_rx_reset(ring->bcm, ring->mmio_base);
409 /* Zero out Receive Descriptor ring address. */
410 bcm43xx_dma_write(ring, BCM43xx_DMA_RX_DESC_RING, 0);
411 }
412}
413
414static void free_all_descbuffers(struct bcm43xx_dmaring *ring)
415{
416 struct bcm43xx_dmadesc *desc;
417 struct bcm43xx_dmadesc_meta *meta;
418 int i;
419
420 if (!ring->used_slots)
421 return;
422 for (i = 0; i < ring->nr_slots; i++) {
423 desc = ring->vbase + i;
424 meta = ring->meta + i;
425
426 if (!meta->skb) {
427 assert(ring->tx);
428 continue;
429 }
430 if (ring->tx) {
431 unmap_descbuffer(ring, meta->dmaaddr,
432 meta->skb->len, 1);
433 } else {
434 unmap_descbuffer(ring, meta->dmaaddr,
435 ring->rx_buffersize, 0);
436 }
437 free_descriptor_buffer(ring, desc, meta, 0);
438 }
439}
440
441/* Main initialization function. */
442static
443struct bcm43xx_dmaring * bcm43xx_setup_dmaring(struct bcm43xx_private *bcm,
444 u16 dma_controller_base,
445 int nr_descriptor_slots,
446 int tx)
447{
448 struct bcm43xx_dmaring *ring;
449 int err;
450
451 ring = kzalloc(sizeof(*ring), GFP_KERNEL);
452 if (!ring)
453 goto out;
454
455 ring->meta = kzalloc(sizeof(*ring->meta) * nr_descriptor_slots,
456 GFP_KERNEL);
457 if (!ring->meta)
458 goto err_kfree_ring;
459
460 ring->memoffset = BCM43xx_DMA_DMABUSADDROFFSET;
461#ifdef CONFIG_BCM947XX
462 if (bcm->pci_dev->bus->number == 0)
463 ring->memoffset = 0;
464#endif
465
466 ring->bcm = bcm;
467 ring->nr_slots = nr_descriptor_slots;
468 ring->suspend_mark = ring->nr_slots * BCM43xx_TXSUSPEND_PERCENT / 100;
469 ring->resume_mark = ring->nr_slots * BCM43xx_TXRESUME_PERCENT / 100;
470 assert(ring->suspend_mark < ring->resume_mark);
471 ring->mmio_base = dma_controller_base;
472 if (tx) {
473 ring->tx = 1;
474 ring->current_slot = -1;
475 } else {
476 switch (dma_controller_base) {
477 case BCM43xx_MMIO_DMA1_BASE:
478 ring->rx_buffersize = BCM43xx_DMA1_RXBUFFERSIZE;
479 ring->frameoffset = BCM43xx_DMA1_RX_FRAMEOFFSET;
480 break;
481 case BCM43xx_MMIO_DMA4_BASE:
482 ring->rx_buffersize = BCM43xx_DMA4_RXBUFFERSIZE;
483 ring->frameoffset = BCM43xx_DMA4_RX_FRAMEOFFSET;
484 break;
485 default:
486 assert(0);
487 }
488 }
489
490 err = alloc_ringmemory(ring);
491 if (err)
492 goto err_kfree_meta;
493 err = dmacontroller_setup(ring);
494 if (err)
495 goto err_free_ringmemory;
496
497out:
498 return ring;
499
500err_free_ringmemory:
501 free_ringmemory(ring);
502err_kfree_meta:
503 kfree(ring->meta);
504err_kfree_ring:
505 kfree(ring);
506 ring = NULL;
507 goto out;
508}
509
510/* Main cleanup function. */
511static void bcm43xx_destroy_dmaring(struct bcm43xx_dmaring *ring)
512{
513 if (!ring)
514 return;
515
516 dprintk(KERN_INFO PFX "DMA 0x%04x (%s) max used slots: %d/%d\n",
517 ring->mmio_base,
518 (ring->tx) ? "TX" : "RX",
519 ring->max_used_slots, ring->nr_slots);
520 /* Device IRQs are disabled prior entering this function,
521 * so no need to take care of concurrency with rx handler stuff.
522 */
523 dmacontroller_cleanup(ring);
524 free_all_descbuffers(ring);
525 free_ringmemory(ring);
526
527 kfree(ring->meta);
528 kfree(ring);
529}
530
531void bcm43xx_dma_free(struct bcm43xx_private *bcm)
532{
533 struct bcm43xx_dma *dma;
534
535 if (bcm43xx_using_pio(bcm))
536 return;
537 dma = bcm43xx_current_dma(bcm);
538
539 bcm43xx_destroy_dmaring(dma->rx_ring1);
540 dma->rx_ring1 = NULL;
541 bcm43xx_destroy_dmaring(dma->rx_ring0);
542 dma->rx_ring0 = NULL;
543 bcm43xx_destroy_dmaring(dma->tx_ring3);
544 dma->tx_ring3 = NULL;
545 bcm43xx_destroy_dmaring(dma->tx_ring2);
546 dma->tx_ring2 = NULL;
547 bcm43xx_destroy_dmaring(dma->tx_ring1);
548 dma->tx_ring1 = NULL;
549 bcm43xx_destroy_dmaring(dma->tx_ring0);
550 dma->tx_ring0 = NULL;
551}
552
553int bcm43xx_dma_init(struct bcm43xx_private *bcm)
554{
555 struct bcm43xx_dma *dma = bcm43xx_current_dma(bcm);
556 struct bcm43xx_dmaring *ring;
557 int err = -ENOMEM;
558
559 /* setup TX DMA channels. */
560 ring = bcm43xx_setup_dmaring(bcm, BCM43xx_MMIO_DMA1_BASE,
561 BCM43xx_TXRING_SLOTS, 1);
562 if (!ring)
563 goto out;
564 dma->tx_ring0 = ring;
565
566 ring = bcm43xx_setup_dmaring(bcm, BCM43xx_MMIO_DMA2_BASE,
567 BCM43xx_TXRING_SLOTS, 1);
568 if (!ring)
569 goto err_destroy_tx0;
570 dma->tx_ring1 = ring;
571
572 ring = bcm43xx_setup_dmaring(bcm, BCM43xx_MMIO_DMA3_BASE,
573 BCM43xx_TXRING_SLOTS, 1);
574 if (!ring)
575 goto err_destroy_tx1;
576 dma->tx_ring2 = ring;
577
578 ring = bcm43xx_setup_dmaring(bcm, BCM43xx_MMIO_DMA4_BASE,
579 BCM43xx_TXRING_SLOTS, 1);
580 if (!ring)
581 goto err_destroy_tx2;
582 dma->tx_ring3 = ring;
583
584 /* setup RX DMA channels. */
585 ring = bcm43xx_setup_dmaring(bcm, BCM43xx_MMIO_DMA1_BASE,
586 BCM43xx_RXRING_SLOTS, 0);
587 if (!ring)
588 goto err_destroy_tx3;
589 dma->rx_ring0 = ring;
590
591 if (bcm->current_core->rev < 5) {
592 ring = bcm43xx_setup_dmaring(bcm, BCM43xx_MMIO_DMA4_BASE,
593 BCM43xx_RXRING_SLOTS, 0);
594 if (!ring)
595 goto err_destroy_rx0;
596 dma->rx_ring1 = ring;
597 }
598
599 dprintk(KERN_INFO PFX "DMA initialized\n");
600 err = 0;
601out:
602 return err;
603
604err_destroy_rx0:
605 bcm43xx_destroy_dmaring(dma->rx_ring0);
606 dma->rx_ring0 = NULL;
607err_destroy_tx3:
608 bcm43xx_destroy_dmaring(dma->tx_ring3);
609 dma->tx_ring3 = NULL;
610err_destroy_tx2:
611 bcm43xx_destroy_dmaring(dma->tx_ring2);
612 dma->tx_ring2 = NULL;
613err_destroy_tx1:
614 bcm43xx_destroy_dmaring(dma->tx_ring1);
615 dma->tx_ring1 = NULL;
616err_destroy_tx0:
617 bcm43xx_destroy_dmaring(dma->tx_ring0);
618 dma->tx_ring0 = NULL;
619 goto out;
620}
621
622/* Generate a cookie for the TX header. */
623static u16 generate_cookie(struct bcm43xx_dmaring *ring,
624 int slot)
625{
626 u16 cookie = 0x0000;
627
628 /* Use the upper 4 bits of the cookie as
629 * DMA controller ID and store the slot number
630 * in the lower 12 bits
631 */
632 switch (ring->mmio_base) {
633 default:
634 assert(0);
635 case BCM43xx_MMIO_DMA1_BASE:
636 break;
637 case BCM43xx_MMIO_DMA2_BASE:
638 cookie = 0x1000;
639 break;
640 case BCM43xx_MMIO_DMA3_BASE:
641 cookie = 0x2000;
642 break;
643 case BCM43xx_MMIO_DMA4_BASE:
644 cookie = 0x3000;
645 break;
646 }
647 assert(((u16)slot & 0xF000) == 0x0000);
648 cookie |= (u16)slot;
649
650 return cookie;
651}
652
653/* Inspect a cookie and find out to which controller/slot it belongs. */
654static
655struct bcm43xx_dmaring * parse_cookie(struct bcm43xx_private *bcm,
656 u16 cookie, int *slot)
657{
658 struct bcm43xx_dma *dma = bcm43xx_current_dma(bcm);
659 struct bcm43xx_dmaring *ring = NULL;
660
661 switch (cookie & 0xF000) {
662 case 0x0000:
663 ring = dma->tx_ring0;
664 break;
665 case 0x1000:
666 ring = dma->tx_ring1;
667 break;
668 case 0x2000:
669 ring = dma->tx_ring2;
670 break;
671 case 0x3000:
672 ring = dma->tx_ring3;
673 break;
674 default:
675 assert(0);
676 }
677 *slot = (cookie & 0x0FFF);
678 assert(*slot >= 0 && *slot < ring->nr_slots);
679
680 return ring;
681}
682
683static void dmacontroller_poke_tx(struct bcm43xx_dmaring *ring,
684 int slot)
685{
686 /* Everything is ready to start. Buffers are DMA mapped and
687 * associated with slots.
688 * "slot" is the last slot of the new frame we want to transmit.
689 * Close your seat belts now, please.
690 */
691 wmb();
692 slot = next_slot(ring, slot);
693 bcm43xx_dma_write(ring, BCM43xx_DMA_TX_DESC_INDEX,
694 (u32)(slot * sizeof(struct bcm43xx_dmadesc)));
695}
696
697static int dma_tx_fragment(struct bcm43xx_dmaring *ring,
698 struct sk_buff *skb,
699 u8 cur_frag)
700{
701 int slot;
702 struct bcm43xx_dmadesc *desc;
703 struct bcm43xx_dmadesc_meta *meta;
704 u32 desc_ctl;
705 u32 desc_addr;
706
707 assert(skb_shinfo(skb)->nr_frags == 0);
708
709 slot = request_slot(ring);
710 desc = ring->vbase + slot;
711 meta = ring->meta + slot;
712
713 /* Add a device specific TX header. */
714 assert(skb_headroom(skb) >= sizeof(struct bcm43xx_txhdr));
715 /* Reserve enough headroom for the device tx header. */
716 __skb_push(skb, sizeof(struct bcm43xx_txhdr));
717 /* Now calculate and add the tx header.
718 * The tx header includes the PLCP header.
719 */
720 bcm43xx_generate_txhdr(ring->bcm,
721 (struct bcm43xx_txhdr *)skb->data,
722 skb->data + sizeof(struct bcm43xx_txhdr),
723 skb->len - sizeof(struct bcm43xx_txhdr),
724 (cur_frag == 0),
725 generate_cookie(ring, slot));
726
727 meta->skb = skb;
728 meta->dmaaddr = map_descbuffer(ring, skb->data, skb->len, 1);
729 if (unlikely(meta->dmaaddr + skb->len > BCM43xx_DMA_BUSADDRMAX)) {
730 return_slot(ring, slot);
731 printk(KERN_ERR PFX ">>>FATAL ERROR<<< DMA TX SKB >1G "
732 "(0x%08x, len: %u)\n",
733 meta->dmaaddr, skb->len);
734 return -ENOMEM;
735 }
736
737 desc_addr = (u32)(meta->dmaaddr + ring->memoffset);
738 desc_ctl = BCM43xx_DMADTOR_FRAMESTART | BCM43xx_DMADTOR_FRAMEEND;
739 desc_ctl |= BCM43xx_DMADTOR_COMPIRQ;
740 desc_ctl |= (BCM43xx_DMADTOR_BYTECNT_MASK &
741 (u32)(meta->skb->len - ring->frameoffset));
742 if (slot == ring->nr_slots - 1)
743 desc_ctl |= BCM43xx_DMADTOR_DTABLEEND;
744
745 set_desc_ctl(desc, desc_ctl);
746 set_desc_addr(desc, desc_addr);
747 /* Now transfer the whole frame. */
748 dmacontroller_poke_tx(ring, slot);
749
750 return 0;
751}
752
753int bcm43xx_dma_tx(struct bcm43xx_private *bcm,
754 struct ieee80211_txb *txb)
755{
756 /* We just received a packet from the kernel network subsystem.
757 * Add headers and DMA map the memory. Poke
758 * the device to send the stuff.
759 * Note that this is called from atomic context.
760 */
761 struct bcm43xx_dmaring *ring = bcm43xx_current_dma(bcm)->tx_ring1;
762 u8 i;
763 struct sk_buff *skb;
764
765 assert(ring->tx);
766 if (unlikely(free_slots(ring) < txb->nr_frags)) {
767 /* The queue should be stopped,
768 * if we are low on free slots.
769 * If this ever triggers, we have to lower the suspend_mark.
770 */
771 dprintkl(KERN_ERR PFX "Out of DMA descriptor slots!\n");
772 return -ENOMEM;
773 }
774
775 for (i = 0; i < txb->nr_frags; i++) {
776 skb = txb->fragments[i];
777 /* Take skb from ieee80211_txb_free */
778 txb->fragments[i] = NULL;
779 dma_tx_fragment(ring, skb, i);
780 //TODO: handle failure of dma_tx_fragment
781 }
782 ieee80211_txb_free(txb);
783
784 return 0;
785}
786
787void bcm43xx_dma_handle_xmitstatus(struct bcm43xx_private *bcm,
788 struct bcm43xx_xmitstatus *status)
789{
790 struct bcm43xx_dmaring *ring;
791 struct bcm43xx_dmadesc *desc;
792 struct bcm43xx_dmadesc_meta *meta;
793 int is_last_fragment;
794 int slot;
795
796 ring = parse_cookie(bcm, status->cookie, &slot);
797 assert(ring);
798 assert(ring->tx);
799 assert(get_desc_ctl(ring->vbase + slot) & BCM43xx_DMADTOR_FRAMESTART);
800 while (1) {
801 assert(slot >= 0 && slot < ring->nr_slots);
802 desc = ring->vbase + slot;
803 meta = ring->meta + slot;
804
805 is_last_fragment = !!(get_desc_ctl(desc) & BCM43xx_DMADTOR_FRAMEEND);
806 unmap_descbuffer(ring, meta->dmaaddr, meta->skb->len, 1);
807 free_descriptor_buffer(ring, desc, meta, 1);
808 /* Everything belonging to the slot is unmapped
809 * and freed, so we can return it.
810 */
811 return_slot(ring, slot);
812
813 if (is_last_fragment)
814 break;
815 slot = next_slot(ring, slot);
816 }
817 bcm->stats.last_tx = jiffies;
818}
819
820static void dma_rx(struct bcm43xx_dmaring *ring,
821 int *slot)
822{
823 struct bcm43xx_dmadesc *desc;
824 struct bcm43xx_dmadesc_meta *meta;
825 struct bcm43xx_rxhdr *rxhdr;
826 struct sk_buff *skb;
827 u16 len;
828 int err;
829 dma_addr_t dmaaddr;
830
831 desc = ring->vbase + *slot;
832 meta = ring->meta + *slot;
833
834 sync_descbuffer_for_cpu(ring, meta->dmaaddr, ring->rx_buffersize);
835 skb = meta->skb;
836
837 if (ring->mmio_base == BCM43xx_MMIO_DMA4_BASE) {
838 /* We received an xmit status. */
839 struct bcm43xx_hwxmitstatus *hw = (struct bcm43xx_hwxmitstatus *)skb->data;
840 struct bcm43xx_xmitstatus stat;
841
842 stat.cookie = le16_to_cpu(hw->cookie);
843 stat.flags = hw->flags;
844 stat.cnt1 = hw->cnt1;
845 stat.cnt2 = hw->cnt2;
846 stat.seq = le16_to_cpu(hw->seq);
847 stat.unknown = le16_to_cpu(hw->unknown);
848
849 bcm43xx_debugfs_log_txstat(ring->bcm, &stat);
850 bcm43xx_dma_handle_xmitstatus(ring->bcm, &stat);
851 /* recycle the descriptor buffer. */
852 sync_descbuffer_for_device(ring, meta->dmaaddr, ring->rx_buffersize);
853
854 return;
855 }
856 rxhdr = (struct bcm43xx_rxhdr *)skb->data;
857 len = le16_to_cpu(rxhdr->frame_length);
858 if (len == 0) {
859 int i = 0;
860
861 do {
862 udelay(2);
863 barrier();
864 len = le16_to_cpu(rxhdr->frame_length);
865 } while (len == 0 && i++ < 5);
866 if (unlikely(len == 0)) {
867 /* recycle the descriptor buffer. */
868 sync_descbuffer_for_device(ring, meta->dmaaddr,
869 ring->rx_buffersize);
870 goto drop;
871 }
872 }
873 if (unlikely(len > ring->rx_buffersize)) {
874 /* The data did not fit into one descriptor buffer
875 * and is split over multiple buffers.
876 * This should never happen, as we try to allocate buffers
877 * big enough. So simply ignore this packet.
878 */
879 int cnt = 0;
880 s32 tmp = len;
881
882 while (1) {
883 desc = ring->vbase + *slot;
884 meta = ring->meta + *slot;
885 /* recycle the descriptor buffer. */
886 sync_descbuffer_for_device(ring, meta->dmaaddr,
887 ring->rx_buffersize);
888 *slot = next_slot(ring, *slot);
889 cnt++;
890 tmp -= ring->rx_buffersize;
891 if (tmp <= 0)
892 break;
893 }
894 printkl(KERN_ERR PFX "DMA RX buffer too small "
895 "(len: %u, buffer: %u, nr-dropped: %d)\n",
896 len, ring->rx_buffersize, cnt);
897 goto drop;
898 }
899 len -= IEEE80211_FCS_LEN;
900
901 dmaaddr = meta->dmaaddr;
902 err = setup_rx_descbuffer(ring, desc, meta, GFP_ATOMIC);
903 if (unlikely(err)) {
904 dprintkl(KERN_ERR PFX "DMA RX: setup_rx_descbuffer() failed\n");
905 sync_descbuffer_for_device(ring, dmaaddr,
906 ring->rx_buffersize);
907 goto drop;
908 }
909
910 unmap_descbuffer(ring, dmaaddr, ring->rx_buffersize, 0);
911 skb_put(skb, len + ring->frameoffset);
912 skb_pull(skb, ring->frameoffset);
913
914 err = bcm43xx_rx(ring->bcm, skb, rxhdr);
915 if (err) {
916 dev_kfree_skb_irq(skb);
917 goto drop;
918 }
919
920drop:
921 return;
922}
923
924void bcm43xx_dma_rx(struct bcm43xx_dmaring *ring)
925{
926 u32 status;
927 u16 descptr;
928 int slot, current_slot;
929#ifdef CONFIG_BCM43XX_DEBUG
930 int used_slots = 0;
931#endif
932
933 assert(!ring->tx);
934 status = bcm43xx_dma_read(ring, BCM43xx_DMA_RX_STATUS);
935 descptr = (status & BCM43xx_DMA_RXSTAT_DPTR_MASK);
936 current_slot = descptr / sizeof(struct bcm43xx_dmadesc);
937 assert(current_slot >= 0 && current_slot < ring->nr_slots);
938
939 slot = ring->current_slot;
940 for ( ; slot != current_slot; slot = next_slot(ring, slot)) {
941 dma_rx(ring, &slot);
942#ifdef CONFIG_BCM43XX_DEBUG
943 if (++used_slots > ring->max_used_slots)
944 ring->max_used_slots = used_slots;
945#endif
946 }
947 bcm43xx_dma_write(ring, BCM43xx_DMA_RX_DESC_INDEX,
948 (u32)(slot * sizeof(struct bcm43xx_dmadesc)));
949 ring->current_slot = slot;
950}
951
952void bcm43xx_dma_tx_suspend(struct bcm43xx_dmaring *ring)
953{
954 assert(ring->tx);
955 bcm43xx_power_saving_ctl_bits(ring->bcm, -1, 1);
956 bcm43xx_dma_write(ring, BCM43xx_DMA_TX_CONTROL,
957 bcm43xx_dma_read(ring, BCM43xx_DMA_TX_CONTROL)
958 | BCM43xx_DMA_TXCTRL_SUSPEND);
959}
960
961void bcm43xx_dma_tx_resume(struct bcm43xx_dmaring *ring)
962{
963 assert(ring->tx);
964 bcm43xx_dma_write(ring, BCM43xx_DMA_TX_CONTROL,
965 bcm43xx_dma_read(ring, BCM43xx_DMA_TX_CONTROL)
966 & ~BCM43xx_DMA_TXCTRL_SUSPEND);
967 bcm43xx_power_saving_ctl_bits(ring->bcm, -1, -1);
968}
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_dma.h b/drivers/net/wireless/bcm43xx/bcm43xx_dma.h
new file mode 100644
index 000000000000..2d520e4b0276
--- /dev/null
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_dma.h
@@ -0,0 +1,218 @@
1#ifndef BCM43xx_DMA_H_
2#define BCM43xx_DMA_H_
3
4#include <linux/list.h>
5#include <linux/spinlock.h>
6#include <linux/workqueue.h>
7#include <linux/linkage.h>
8#include <asm/atomic.h>
9
10
11/* DMA-Interrupt reasons. */
12#define BCM43xx_DMAIRQ_FATALMASK ((1 << 10) | (1 << 11) | (1 << 12) \
13 | (1 << 14) | (1 << 15))
14#define BCM43xx_DMAIRQ_NONFATALMASK (1 << 13)
15#define BCM43xx_DMAIRQ_RX_DONE (1 << 16)
16
17/* DMA controller register offsets. (relative to BCM43xx_DMA#_BASE) */
18#define BCM43xx_DMA_TX_CONTROL 0x00
19#define BCM43xx_DMA_TX_DESC_RING 0x04
20#define BCM43xx_DMA_TX_DESC_INDEX 0x08
21#define BCM43xx_DMA_TX_STATUS 0x0c
22#define BCM43xx_DMA_RX_CONTROL 0x10
23#define BCM43xx_DMA_RX_DESC_RING 0x14
24#define BCM43xx_DMA_RX_DESC_INDEX 0x18
25#define BCM43xx_DMA_RX_STATUS 0x1c
26
27/* DMA controller channel control word values. */
28#define BCM43xx_DMA_TXCTRL_ENABLE (1 << 0)
29#define BCM43xx_DMA_TXCTRL_SUSPEND (1 << 1)
30#define BCM43xx_DMA_TXCTRL_LOOPBACK (1 << 2)
31#define BCM43xx_DMA_TXCTRL_FLUSH (1 << 4)
32#define BCM43xx_DMA_RXCTRL_ENABLE (1 << 0)
33#define BCM43xx_DMA_RXCTRL_FRAMEOFF_MASK 0x000000fe
34#define BCM43xx_DMA_RXCTRL_FRAMEOFF_SHIFT 1
35#define BCM43xx_DMA_RXCTRL_PIO (1 << 8)
36/* DMA controller channel status word values. */
37#define BCM43xx_DMA_TXSTAT_DPTR_MASK 0x00000fff
38#define BCM43xx_DMA_TXSTAT_STAT_MASK 0x0000f000
39#define BCM43xx_DMA_TXSTAT_STAT_DISABLED 0x00000000
40#define BCM43xx_DMA_TXSTAT_STAT_ACTIVE 0x00001000
41#define BCM43xx_DMA_TXSTAT_STAT_IDLEWAIT 0x00002000
42#define BCM43xx_DMA_TXSTAT_STAT_STOPPED 0x00003000
43#define BCM43xx_DMA_TXSTAT_STAT_SUSP 0x00004000
44#define BCM43xx_DMA_TXSTAT_ERROR_MASK 0x000f0000
45#define BCM43xx_DMA_TXSTAT_FLUSHED (1 << 20)
46#define BCM43xx_DMA_RXSTAT_DPTR_MASK 0x00000fff
47#define BCM43xx_DMA_RXSTAT_STAT_MASK 0x0000f000
48#define BCM43xx_DMA_RXSTAT_STAT_DISABLED 0x00000000
49#define BCM43xx_DMA_RXSTAT_STAT_ACTIVE 0x00001000
50#define BCM43xx_DMA_RXSTAT_STAT_IDLEWAIT 0x00002000
51#define BCM43xx_DMA_RXSTAT_STAT_RESERVED 0x00003000
52#define BCM43xx_DMA_RXSTAT_STAT_ERRORS 0x00004000
53#define BCM43xx_DMA_RXSTAT_ERROR_MASK 0x000f0000
54
55/* DMA descriptor control field values. */
56#define BCM43xx_DMADTOR_BYTECNT_MASK 0x00001fff
57#define BCM43xx_DMADTOR_DTABLEEND (1 << 28) /* End of descriptor table */
58#define BCM43xx_DMADTOR_COMPIRQ (1 << 29) /* IRQ on completion request */
59#define BCM43xx_DMADTOR_FRAMEEND (1 << 30)
60#define BCM43xx_DMADTOR_FRAMESTART (1 << 31)
61
62/* Misc DMA constants */
63#define BCM43xx_DMA_RINGMEMSIZE PAGE_SIZE
64#define BCM43xx_DMA_BUSADDRMAX 0x3FFFFFFF
65#define BCM43xx_DMA_DMABUSADDROFFSET (1 << 30)
66#define BCM43xx_DMA1_RX_FRAMEOFFSET 30
67#define BCM43xx_DMA4_RX_FRAMEOFFSET 0
68
69/* DMA engine tuning knobs */
70#define BCM43xx_TXRING_SLOTS 512
71#define BCM43xx_RXRING_SLOTS 64
72#define BCM43xx_DMA1_RXBUFFERSIZE (2304 + 100)
73#define BCM43xx_DMA4_RXBUFFERSIZE 16
74/* Suspend the tx queue, if less than this percent slots are free. */
75#define BCM43xx_TXSUSPEND_PERCENT 20
76/* Resume the tx queue, if more than this percent slots are free. */
77#define BCM43xx_TXRESUME_PERCENT 50
78
79
80
81#ifdef CONFIG_BCM43XX_DMA
82
83
84struct sk_buff;
85struct bcm43xx_private;
86struct bcm43xx_xmitstatus;
87
88
89struct bcm43xx_dmadesc {
90 __le32 _control;
91 __le32 _address;
92} __attribute__((__packed__));
93
94/* Macros to access the bcm43xx_dmadesc struct */
95#define get_desc_ctl(desc) le32_to_cpu((desc)->_control)
96#define set_desc_ctl(desc, ctl) do { (desc)->_control = cpu_to_le32(ctl); } while (0)
97#define get_desc_addr(desc) le32_to_cpu((desc)->_address)
98#define set_desc_addr(desc, addr) do { (desc)->_address = cpu_to_le32(addr); } while (0)
99
100struct bcm43xx_dmadesc_meta {
101 /* The kernel DMA-able buffer. */
102 struct sk_buff *skb;
103 /* DMA base bus-address of the descriptor buffer. */
104 dma_addr_t dmaaddr;
105};
106
107struct bcm43xx_dmaring {
108 struct bcm43xx_private *bcm;
109 /* Kernel virtual base address of the ring memory. */
110 struct bcm43xx_dmadesc *vbase;
111 /* DMA memory offset */
112 dma_addr_t memoffset;
113 /* (Unadjusted) DMA base bus-address of the ring memory. */
114 dma_addr_t dmabase;
115 /* Meta data about all descriptors. */
116 struct bcm43xx_dmadesc_meta *meta;
117 /* Number of descriptor slots in the ring. */
118 int nr_slots;
119 /* Number of used descriptor slots. */
120 int used_slots;
121 /* Currently used slot in the ring. */
122 int current_slot;
123 /* Marks to suspend/resume the queue. */
124 int suspend_mark;
125 int resume_mark;
126 /* Frameoffset in octets. */
127 u32 frameoffset;
128 /* Descriptor buffer size. */
129 u16 rx_buffersize;
130 /* The MMIO base register of the DMA controller, this
131 * ring is posted to.
132 */
133 u16 mmio_base;
134 u8 tx:1, /* TRUE, if this is a TX ring. */
135 suspended:1; /* TRUE, if transfers are suspended on this ring. */
136#ifdef CONFIG_BCM43XX_DEBUG
137 /* Maximum number of used slots. */
138 int max_used_slots;
139#endif /* CONFIG_BCM43XX_DEBUG*/
140};
141
142
143static inline
144u32 bcm43xx_dma_read(struct bcm43xx_dmaring *ring,
145 u16 offset)
146{
147 return bcm43xx_read32(ring->bcm, ring->mmio_base + offset);
148}
149
150static inline
151void bcm43xx_dma_write(struct bcm43xx_dmaring *ring,
152 u16 offset, u32 value)
153{
154 bcm43xx_write32(ring->bcm, ring->mmio_base + offset, value);
155}
156
157
158int bcm43xx_dma_init(struct bcm43xx_private *bcm);
159void bcm43xx_dma_free(struct bcm43xx_private *bcm);
160
161int bcm43xx_dmacontroller_rx_reset(struct bcm43xx_private *bcm,
162 u16 dmacontroller_mmio_base);
163int bcm43xx_dmacontroller_tx_reset(struct bcm43xx_private *bcm,
164 u16 dmacontroller_mmio_base);
165
166void bcm43xx_dma_tx_suspend(struct bcm43xx_dmaring *ring);
167void bcm43xx_dma_tx_resume(struct bcm43xx_dmaring *ring);
168
169void bcm43xx_dma_handle_xmitstatus(struct bcm43xx_private *bcm,
170 struct bcm43xx_xmitstatus *status);
171
172int bcm43xx_dma_tx(struct bcm43xx_private *bcm,
173 struct ieee80211_txb *txb);
174void bcm43xx_dma_rx(struct bcm43xx_dmaring *ring);
175
176
177#else /* CONFIG_BCM43XX_DMA */
178
179
180static inline
181int bcm43xx_dma_init(struct bcm43xx_private *bcm)
182{
183 return 0;
184}
185static inline
186void bcm43xx_dma_free(struct bcm43xx_private *bcm)
187{
188}
189static inline
190int bcm43xx_dmacontroller_rx_reset(struct bcm43xx_private *bcm,
191 u16 dmacontroller_mmio_base)
192{
193 return 0;
194}
195static inline
196int bcm43xx_dmacontroller_tx_reset(struct bcm43xx_private *bcm,
197 u16 dmacontroller_mmio_base)
198{
199 return 0;
200}
201static inline
202int bcm43xx_dma_tx(struct bcm43xx_private *bcm,
203 struct ieee80211_txb *txb)
204{
205 return 0;
206}
207static inline
208void bcm43xx_dma_handle_xmitstatus(struct bcm43xx_private *bcm,
209 struct bcm43xx_xmitstatus *status)
210{
211}
212static inline
213void bcm43xx_dma_rx(struct bcm43xx_dmaring *ring)
214{
215}
216
217#endif /* CONFIG_BCM43XX_DMA */
218#endif /* BCM43xx_DMA_H_ */
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_ethtool.c b/drivers/net/wireless/bcm43xx/bcm43xx_ethtool.c
new file mode 100644
index 000000000000..b3ffcf501311
--- /dev/null
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_ethtool.c
@@ -0,0 +1,50 @@
1/*
2
3 Broadcom BCM43xx wireless driver
4
5 ethtool support
6
7 Copyright (c) 2006 Jason Lunz <lunz@falooley.org>
8
9 Some code in this file is derived from the 8139too.c driver
10 Copyright (C) 2002 Jeff Garzik
11
12 This program is free software; you can redistribute it and/or modify
13 it under the terms of the GNU General Public License as published by
14 the Free Software Foundation; either version 2 of the License, or
15 (at your option) any later version.
16
17 This program is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 GNU General Public License for more details.
21
22 You should have received a copy of the GNU General Public License
23 along with this program; see the file COPYING. If not, write to
24 the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,
25 Boston, MA 02110-1301, USA.
26
27*/
28
29#include "bcm43xx.h"
30#include "bcm43xx_ethtool.h"
31
32#include <linux/netdevice.h>
33#include <linux/pci.h>
34#include <linux/string.h>
35#include <linux/version.h>
36
37
38static void bcm43xx_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
39{
40 struct bcm43xx_private *bcm = bcm43xx_priv(dev);
41
42 strncpy(info->driver, KBUILD_MODNAME, sizeof(info->driver));
43 strncpy(info->version, UTS_RELEASE, sizeof(info->version));
44 strncpy(info->bus_info, pci_name(bcm->pci_dev), ETHTOOL_BUSINFO_LEN);
45}
46
47struct ethtool_ops bcm43xx_ethtool_ops = {
48 .get_drvinfo = bcm43xx_get_drvinfo,
49 .get_link = ethtool_op_get_link,
50};
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_ethtool.h b/drivers/net/wireless/bcm43xx/bcm43xx_ethtool.h
new file mode 100644
index 000000000000..813704991f62
--- /dev/null
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_ethtool.h
@@ -0,0 +1,8 @@
1#ifndef BCM43xx_ETHTOOL_H_
2#define BCM43xx_ETHTOOL_H_
3
4#include <linux/ethtool.h>
5
6extern struct ethtool_ops bcm43xx_ethtool_ops;
7
8#endif /* BCM43xx_ETHTOOL_H_ */
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_ilt.c b/drivers/net/wireless/bcm43xx/bcm43xx_ilt.c
new file mode 100644
index 000000000000..ad8e569d1faf
--- /dev/null
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_ilt.c
@@ -0,0 +1,337 @@
1/*
2
3 Broadcom BCM43xx wireless driver
4
5 Copyright (c) 2005 Martin Langer <martin-langer@gmx.de>,
6 Stefano Brivio <st3@riseup.net>
7 Michael Buesch <mbuesch@freenet.de>
8 Danny van Dyk <kugelfang@gentoo.org>
9 Andreas Jaggi <andreas.jaggi@waterwave.ch>
10
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 2 of the License, or
14 (at your option) any later version.
15
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
20
21 You should have received a copy of the GNU General Public License
22 along with this program; see the file COPYING. If not, write to
23 the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,
24 Boston, MA 02110-1301, USA.
25
26*/
27
28#include "bcm43xx.h"
29#include "bcm43xx_ilt.h"
30#include "bcm43xx_phy.h"
31
32
33/**** Initial Internal Lookup Tables ****/
34
35const u32 bcm43xx_ilt_rotor[BCM43xx_ILT_ROTOR_SIZE] = {
36 0xFEB93FFD, 0xFEC63FFD, /* 0 */
37 0xFED23FFD, 0xFEDF3FFD,
38 0xFEEC3FFE, 0xFEF83FFE,
39 0xFF053FFE, 0xFF113FFE,
40 0xFF1E3FFE, 0xFF2A3FFF, /* 8 */
41 0xFF373FFF, 0xFF443FFF,
42 0xFF503FFF, 0xFF5D3FFF,
43 0xFF693FFF, 0xFF763FFF,
44 0xFF824000, 0xFF8F4000, /* 16 */
45 0xFF9B4000, 0xFFA84000,
46 0xFFB54000, 0xFFC14000,
47 0xFFCE4000, 0xFFDA4000,
48 0xFFE74000, 0xFFF34000, /* 24 */
49 0x00004000, 0x000D4000,
50 0x00194000, 0x00264000,
51 0x00324000, 0x003F4000,
52 0x004B4000, 0x00584000, /* 32 */
53 0x00654000, 0x00714000,
54 0x007E4000, 0x008A3FFF,
55 0x00973FFF, 0x00A33FFF,
56 0x00B03FFF, 0x00BC3FFF, /* 40 */
57 0x00C93FFF, 0x00D63FFF,
58 0x00E23FFE, 0x00EF3FFE,
59 0x00FB3FFE, 0x01083FFE,
60 0x01143FFE, 0x01213FFD, /* 48 */
61 0x012E3FFD, 0x013A3FFD,
62 0x01473FFD,
63};
64
65const u32 bcm43xx_ilt_retard[BCM43xx_ILT_RETARD_SIZE] = {
66 0xDB93CB87, 0xD666CF64, /* 0 */
67 0xD1FDD358, 0xCDA6D826,
68 0xCA38DD9F, 0xC729E2B4,
69 0xC469E88E, 0xC26AEE2B,
70 0xC0DEF46C, 0xC073FA62, /* 8 */
71 0xC01D00D5, 0xC0760743,
72 0xC1560D1E, 0xC2E51369,
73 0xC4ED18FF, 0xC7AC1ED7,
74 0xCB2823B2, 0xCEFA28D9, /* 16 */
75 0xD2F62D3F, 0xD7BB3197,
76 0xDCE53568, 0xE1FE3875,
77 0xE7D13B35, 0xED663D35,
78 0xF39B3EC4, 0xF98E3FA7, /* 24 */
79 0x00004000, 0x06723FA7,
80 0x0C653EC4, 0x129A3D35,
81 0x182F3B35, 0x1E023875,
82 0x231B3568, 0x28453197, /* 32 */
83 0x2D0A2D3F, 0x310628D9,
84 0x34D823B2, 0x38541ED7,
85 0x3B1318FF, 0x3D1B1369,
86 0x3EAA0D1E, 0x3F8A0743, /* 40 */
87 0x3FE300D5, 0x3F8DFA62,
88 0x3F22F46C, 0x3D96EE2B,
89 0x3B97E88E, 0x38D7E2B4,
90 0x35C8DD9F, 0x325AD826, /* 48 */
91 0x2E03D358, 0x299ACF64,
92 0x246DCB87,
93};
94
95const u16 bcm43xx_ilt_finefreqa[BCM43xx_ILT_FINEFREQA_SIZE] = {
96 0x0082, 0x0082, 0x0102, 0x0182, /* 0 */
97 0x0202, 0x0282, 0x0302, 0x0382,
98 0x0402, 0x0482, 0x0502, 0x0582,
99 0x05E2, 0x0662, 0x06E2, 0x0762,
100 0x07E2, 0x0842, 0x08C2, 0x0942, /* 16 */
101 0x09C2, 0x0A22, 0x0AA2, 0x0B02,
102 0x0B82, 0x0BE2, 0x0C62, 0x0CC2,
103 0x0D42, 0x0DA2, 0x0E02, 0x0E62,
104 0x0EE2, 0x0F42, 0x0FA2, 0x1002, /* 32 */
105 0x1062, 0x10C2, 0x1122, 0x1182,
106 0x11E2, 0x1242, 0x12A2, 0x12E2,
107 0x1342, 0x13A2, 0x1402, 0x1442,
108 0x14A2, 0x14E2, 0x1542, 0x1582, /* 48 */
109 0x15E2, 0x1622, 0x1662, 0x16C1,
110 0x1701, 0x1741, 0x1781, 0x17E1,
111 0x1821, 0x1861, 0x18A1, 0x18E1,
112 0x1921, 0x1961, 0x19A1, 0x19E1, /* 64 */
113 0x1A21, 0x1A61, 0x1AA1, 0x1AC1,
114 0x1B01, 0x1B41, 0x1B81, 0x1BA1,
115 0x1BE1, 0x1C21, 0x1C41, 0x1C81,
116 0x1CA1, 0x1CE1, 0x1D01, 0x1D41, /* 80 */
117 0x1D61, 0x1DA1, 0x1DC1, 0x1E01,
118 0x1E21, 0x1E61, 0x1E81, 0x1EA1,
119 0x1EE1, 0x1F01, 0x1F21, 0x1F41,
120 0x1F81, 0x1FA1, 0x1FC1, 0x1FE1, /* 96 */
121 0x2001, 0x2041, 0x2061, 0x2081,
122 0x20A1, 0x20C1, 0x20E1, 0x2101,
123 0x2121, 0x2141, 0x2161, 0x2181,
124 0x21A1, 0x21C1, 0x21E1, 0x2201, /* 112 */
125 0x2221, 0x2241, 0x2261, 0x2281,
126 0x22A1, 0x22C1, 0x22C1, 0x22E1,
127 0x2301, 0x2321, 0x2341, 0x2361,
128 0x2361, 0x2381, 0x23A1, 0x23C1, /* 128 */
129 0x23E1, 0x23E1, 0x2401, 0x2421,
130 0x2441, 0x2441, 0x2461, 0x2481,
131 0x2481, 0x24A1, 0x24C1, 0x24C1,
132 0x24E1, 0x2501, 0x2501, 0x2521, /* 144 */
133 0x2541, 0x2541, 0x2561, 0x2561,
134 0x2581, 0x25A1, 0x25A1, 0x25C1,
135 0x25C1, 0x25E1, 0x2601, 0x2601,
136 0x2621, 0x2621, 0x2641, 0x2641, /* 160 */
137 0x2661, 0x2661, 0x2681, 0x2681,
138 0x26A1, 0x26A1, 0x26C1, 0x26C1,
139 0x26E1, 0x26E1, 0x2701, 0x2701,
140 0x2721, 0x2721, 0x2740, 0x2740, /* 176 */
141 0x2760, 0x2760, 0x2780, 0x2780,
142 0x2780, 0x27A0, 0x27A0, 0x27C0,
143 0x27C0, 0x27E0, 0x27E0, 0x27E0,
144 0x2800, 0x2800, 0x2820, 0x2820, /* 192 */
145 0x2820, 0x2840, 0x2840, 0x2840,
146 0x2860, 0x2860, 0x2880, 0x2880,
147 0x2880, 0x28A0, 0x28A0, 0x28A0,
148 0x28C0, 0x28C0, 0x28C0, 0x28E0, /* 208 */
149 0x28E0, 0x28E0, 0x2900, 0x2900,
150 0x2900, 0x2920, 0x2920, 0x2920,
151 0x2940, 0x2940, 0x2940, 0x2960,
152 0x2960, 0x2960, 0x2960, 0x2980, /* 224 */
153 0x2980, 0x2980, 0x29A0, 0x29A0,
154 0x29A0, 0x29A0, 0x29C0, 0x29C0,
155 0x29C0, 0x29E0, 0x29E0, 0x29E0,
156 0x29E0, 0x2A00, 0x2A00, 0x2A00, /* 240 */
157 0x2A00, 0x2A20, 0x2A20, 0x2A20,
158 0x2A20, 0x2A40, 0x2A40, 0x2A40,
159 0x2A40, 0x2A60, 0x2A60, 0x2A60,
160};
161
162const u16 bcm43xx_ilt_finefreqg[BCM43xx_ILT_FINEFREQG_SIZE] = {
163 0x0089, 0x02E9, 0x0409, 0x04E9, /* 0 */
164 0x05A9, 0x0669, 0x0709, 0x0789,
165 0x0829, 0x08A9, 0x0929, 0x0989,
166 0x0A09, 0x0A69, 0x0AC9, 0x0B29,
167 0x0BA9, 0x0BE9, 0x0C49, 0x0CA9, /* 16 */
168 0x0D09, 0x0D69, 0x0DA9, 0x0E09,
169 0x0E69, 0x0EA9, 0x0F09, 0x0F49,
170 0x0FA9, 0x0FE9, 0x1029, 0x1089,
171 0x10C9, 0x1109, 0x1169, 0x11A9, /* 32 */
172 0x11E9, 0x1229, 0x1289, 0x12C9,
173 0x1309, 0x1349, 0x1389, 0x13C9,
174 0x1409, 0x1449, 0x14A9, 0x14E9,
175 0x1529, 0x1569, 0x15A9, 0x15E9, /* 48 */
176 0x1629, 0x1669, 0x16A9, 0x16E8,
177 0x1728, 0x1768, 0x17A8, 0x17E8,
178 0x1828, 0x1868, 0x18A8, 0x18E8,
179 0x1928, 0x1968, 0x19A8, 0x19E8, /* 64 */
180 0x1A28, 0x1A68, 0x1AA8, 0x1AE8,
181 0x1B28, 0x1B68, 0x1BA8, 0x1BE8,
182 0x1C28, 0x1C68, 0x1CA8, 0x1CE8,
183 0x1D28, 0x1D68, 0x1DC8, 0x1E08, /* 80 */
184 0x1E48, 0x1E88, 0x1EC8, 0x1F08,
185 0x1F48, 0x1F88, 0x1FE8, 0x2028,
186 0x2068, 0x20A8, 0x2108, 0x2148,
187 0x2188, 0x21C8, 0x2228, 0x2268, /* 96 */
188 0x22C8, 0x2308, 0x2348, 0x23A8,
189 0x23E8, 0x2448, 0x24A8, 0x24E8,
190 0x2548, 0x25A8, 0x2608, 0x2668,
191 0x26C8, 0x2728, 0x2787, 0x27E7, /* 112 */
192 0x2847, 0x28C7, 0x2947, 0x29A7,
193 0x2A27, 0x2AC7, 0x2B47, 0x2BE7,
194 0x2CA7, 0x2D67, 0x2E47, 0x2F67,
195 0x3247, 0x3526, 0x3646, 0x3726, /* 128 */
196 0x3806, 0x38A6, 0x3946, 0x39E6,
197 0x3A66, 0x3AE6, 0x3B66, 0x3BC6,
198 0x3C45, 0x3CA5, 0x3D05, 0x3D85,
199 0x3DE5, 0x3E45, 0x3EA5, 0x3EE5, /* 144 */
200 0x3F45, 0x3FA5, 0x4005, 0x4045,
201 0x40A5, 0x40E5, 0x4145, 0x4185,
202 0x41E5, 0x4225, 0x4265, 0x42C5,
203 0x4305, 0x4345, 0x43A5, 0x43E5, /* 160 */
204 0x4424, 0x4464, 0x44C4, 0x4504,
205 0x4544, 0x4584, 0x45C4, 0x4604,
206 0x4644, 0x46A4, 0x46E4, 0x4724,
207 0x4764, 0x47A4, 0x47E4, 0x4824, /* 176 */
208 0x4864, 0x48A4, 0x48E4, 0x4924,
209 0x4964, 0x49A4, 0x49E4, 0x4A24,
210 0x4A64, 0x4AA4, 0x4AE4, 0x4B23,
211 0x4B63, 0x4BA3, 0x4BE3, 0x4C23, /* 192 */
212 0x4C63, 0x4CA3, 0x4CE3, 0x4D23,
213 0x4D63, 0x4DA3, 0x4DE3, 0x4E23,
214 0x4E63, 0x4EA3, 0x4EE3, 0x4F23,
215 0x4F63, 0x4FC3, 0x5003, 0x5043, /* 208 */
216 0x5083, 0x50C3, 0x5103, 0x5143,
217 0x5183, 0x51E2, 0x5222, 0x5262,
218 0x52A2, 0x52E2, 0x5342, 0x5382,
219 0x53C2, 0x5402, 0x5462, 0x54A2, /* 224 */
220 0x5502, 0x5542, 0x55A2, 0x55E2,
221 0x5642, 0x5682, 0x56E2, 0x5722,
222 0x5782, 0x57E1, 0x5841, 0x58A1,
223 0x5901, 0x5961, 0x59C1, 0x5A21, /* 240 */
224 0x5AA1, 0x5B01, 0x5B81, 0x5BE1,
225 0x5C61, 0x5D01, 0x5D80, 0x5E20,
226 0x5EE0, 0x5FA0, 0x6080, 0x61C0,
227};
228
229const u16 bcm43xx_ilt_noisea2[BCM43xx_ILT_NOISEA2_SIZE] = {
230 0x0001, 0x0001, 0x0001, 0xFFFE,
231 0xFFFE, 0x3FFF, 0x1000, 0x0393,
232};
233
234const u16 bcm43xx_ilt_noisea3[BCM43xx_ILT_NOISEA3_SIZE] = {
235 0x4C4C, 0x4C4C, 0x4C4C, 0x2D36,
236 0x4C4C, 0x4C4C, 0x4C4C, 0x2D36,
237};
238
239const u16 bcm43xx_ilt_noiseg1[BCM43xx_ILT_NOISEG1_SIZE] = {
240 0x013C, 0x01F5, 0x031A, 0x0631,
241 0x0001, 0x0001, 0x0001, 0x0001,
242};
243
244const u16 bcm43xx_ilt_noiseg2[BCM43xx_ILT_NOISEG2_SIZE] = {
245 0x5484, 0x3C40, 0x0000, 0x0000,
246 0x0000, 0x0000, 0x0000, 0x0000,
247};
248
249const u16 bcm43xx_ilt_noisescaleg1[BCM43xx_ILT_NOISESCALEG_SIZE] = {
250 0x6C77, 0x5162, 0x3B40, 0x3335, /* 0 */
251 0x2F2D, 0x2A2A, 0x2527, 0x1F21,
252 0x1A1D, 0x1719, 0x1616, 0x1414,
253 0x1414, 0x1400, 0x1414, 0x1614,
254 0x1716, 0x1A19, 0x1F1D, 0x2521, /* 16 */
255 0x2A27, 0x2F2A, 0x332D, 0x3B35,
256 0x5140, 0x6C62, 0x0077,
257};
258
259const u16 bcm43xx_ilt_noisescaleg2[BCM43xx_ILT_NOISESCALEG_SIZE] = {
260 0xD8DD, 0xCBD4, 0xBCC0, 0XB6B7, /* 0 */
261 0xB2B0, 0xADAD, 0xA7A9, 0x9FA1,
262 0x969B, 0x9195, 0x8F8F, 0x8A8A,
263 0x8A8A, 0x8A00, 0x8A8A, 0x8F8A,
264 0x918F, 0x9695, 0x9F9B, 0xA7A1, /* 16 */
265 0xADA9, 0xB2AD, 0xB6B0, 0xBCB7,
266 0xCBC0, 0xD8D4, 0x00DD,
267};
268
269const u16 bcm43xx_ilt_noisescaleg3[BCM43xx_ILT_NOISESCALEG_SIZE] = {
270 0xA4A4, 0xA4A4, 0xA4A4, 0xA4A4, /* 0 */
271 0xA4A4, 0xA4A4, 0xA4A4, 0xA4A4,
272 0xA4A4, 0xA4A4, 0xA4A4, 0xA4A4,
273 0xA4A4, 0xA400, 0xA4A4, 0xA4A4,
274 0xA4A4, 0xA4A4, 0xA4A4, 0xA4A4, /* 16 */
275 0xA4A4, 0xA4A4, 0xA4A4, 0xA4A4,
276 0xA4A4, 0xA4A4, 0x00A4,
277};
278
279const u16 bcm43xx_ilt_sigmasqr1[BCM43xx_ILT_SIGMASQR_SIZE] = {
280 0x007A, 0x0075, 0x0071, 0x006C, /* 0 */
281 0x0067, 0x0063, 0x005E, 0x0059,
282 0x0054, 0x0050, 0x004B, 0x0046,
283 0x0042, 0x003D, 0x003D, 0x003D,
284 0x003D, 0x003D, 0x003D, 0x003D, /* 16 */
285 0x003D, 0x003D, 0x003D, 0x003D,
286 0x003D, 0x003D, 0x0000, 0x003D,
287 0x003D, 0x003D, 0x003D, 0x003D,
288 0x003D, 0x003D, 0x003D, 0x003D, /* 32 */
289 0x003D, 0x003D, 0x003D, 0x003D,
290 0x0042, 0x0046, 0x004B, 0x0050,
291 0x0054, 0x0059, 0x005E, 0x0063,
292 0x0067, 0x006C, 0x0071, 0x0075, /* 48 */
293 0x007A,
294};
295
296const u16 bcm43xx_ilt_sigmasqr2[BCM43xx_ILT_SIGMASQR_SIZE] = {
297 0x00DE, 0x00DC, 0x00DA, 0x00D8, /* 0 */
298 0x00D6, 0x00D4, 0x00D2, 0x00CF,
299 0x00CD, 0x00CA, 0x00C7, 0x00C4,
300 0x00C1, 0x00BE, 0x00BE, 0x00BE,
301 0x00BE, 0x00BE, 0x00BE, 0x00BE, /* 16 */
302 0x00BE, 0x00BE, 0x00BE, 0x00BE,
303 0x00BE, 0x00BE, 0x0000, 0x00BE,
304 0x00BE, 0x00BE, 0x00BE, 0x00BE,
305 0x00BE, 0x00BE, 0x00BE, 0x00BE, /* 32 */
306 0x00BE, 0x00BE, 0x00BE, 0x00BE,
307 0x00C1, 0x00C4, 0x00C7, 0x00CA,
308 0x00CD, 0x00CF, 0x00D2, 0x00D4,
309 0x00D6, 0x00D8, 0x00DA, 0x00DC, /* 48 */
310 0x00DE,
311};
312
313/**** Helper functions to access the device Internal Lookup Tables ****/
314
315void bcm43xx_ilt_write(struct bcm43xx_private *bcm, u16 offset, u16 val)
316{
317 if (bcm43xx_current_phy(bcm)->type == BCM43xx_PHYTYPE_A) {
318 bcm43xx_phy_write(bcm, BCM43xx_PHY_ILT_A_CTRL, offset);
319 mmiowb();
320 bcm43xx_phy_write(bcm, BCM43xx_PHY_ILT_A_DATA1, val);
321 } else {
322 bcm43xx_phy_write(bcm, BCM43xx_PHY_ILT_G_CTRL, offset);
323 mmiowb();
324 bcm43xx_phy_write(bcm, BCM43xx_PHY_ILT_G_DATA1, val);
325 }
326}
327
328u16 bcm43xx_ilt_read(struct bcm43xx_private *bcm, u16 offset)
329{
330 if (bcm43xx_current_phy(bcm)->type == BCM43xx_PHYTYPE_A) {
331 bcm43xx_phy_write(bcm, BCM43xx_PHY_ILT_A_CTRL, offset);
332 return bcm43xx_phy_read(bcm, BCM43xx_PHY_ILT_A_DATA1);
333 } else {
334 bcm43xx_phy_write(bcm, BCM43xx_PHY_ILT_G_CTRL, offset);
335 return bcm43xx_phy_read(bcm, BCM43xx_PHY_ILT_G_DATA1);
336 }
337}
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_ilt.h b/drivers/net/wireless/bcm43xx/bcm43xx_ilt.h
new file mode 100644
index 000000000000..464521abf73c
--- /dev/null
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_ilt.h
@@ -0,0 +1,32 @@
1#ifndef BCM43xx_ILT_H_
2#define BCM43xx_ILT_H_
3
4#define BCM43xx_ILT_ROTOR_SIZE 53
5extern const u32 bcm43xx_ilt_rotor[BCM43xx_ILT_ROTOR_SIZE];
6#define BCM43xx_ILT_RETARD_SIZE 53
7extern const u32 bcm43xx_ilt_retard[BCM43xx_ILT_RETARD_SIZE];
8#define BCM43xx_ILT_FINEFREQA_SIZE 256
9extern const u16 bcm43xx_ilt_finefreqa[BCM43xx_ILT_FINEFREQA_SIZE];
10#define BCM43xx_ILT_FINEFREQG_SIZE 256
11extern const u16 bcm43xx_ilt_finefreqg[BCM43xx_ILT_FINEFREQG_SIZE];
12#define BCM43xx_ILT_NOISEA2_SIZE 8
13extern const u16 bcm43xx_ilt_noisea2[BCM43xx_ILT_NOISEA2_SIZE];
14#define BCM43xx_ILT_NOISEA3_SIZE 8
15extern const u16 bcm43xx_ilt_noisea3[BCM43xx_ILT_NOISEA3_SIZE];
16#define BCM43xx_ILT_NOISEG1_SIZE 8
17extern const u16 bcm43xx_ilt_noiseg1[BCM43xx_ILT_NOISEG1_SIZE];
18#define BCM43xx_ILT_NOISEG2_SIZE 8
19extern const u16 bcm43xx_ilt_noiseg2[BCM43xx_ILT_NOISEG2_SIZE];
20#define BCM43xx_ILT_NOISESCALEG_SIZE 27
21extern const u16 bcm43xx_ilt_noisescaleg1[BCM43xx_ILT_NOISESCALEG_SIZE];
22extern const u16 bcm43xx_ilt_noisescaleg2[BCM43xx_ILT_NOISESCALEG_SIZE];
23extern const u16 bcm43xx_ilt_noisescaleg3[BCM43xx_ILT_NOISESCALEG_SIZE];
24#define BCM43xx_ILT_SIGMASQR_SIZE 53
25extern const u16 bcm43xx_ilt_sigmasqr1[BCM43xx_ILT_SIGMASQR_SIZE];
26extern const u16 bcm43xx_ilt_sigmasqr2[BCM43xx_ILT_SIGMASQR_SIZE];
27
28
29void bcm43xx_ilt_write(struct bcm43xx_private *bcm, u16 offset, u16 val);
30u16 bcm43xx_ilt_read(struct bcm43xx_private *bcm, u16 offset);
31
32#endif /* BCM43xx_ILT_H_ */
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_leds.c b/drivers/net/wireless/bcm43xx/bcm43xx_leds.c
new file mode 100644
index 000000000000..4b2c02c0b31e
--- /dev/null
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_leds.c
@@ -0,0 +1,293 @@
1/*
2
3 Broadcom BCM43xx wireless driver
4
5 Copyright (c) 2005 Martin Langer <martin-langer@gmx.de>,
6 Stefano Brivio <st3@riseup.net>
7 Michael Buesch <mbuesch@freenet.de>
8 Danny van Dyk <kugelfang@gentoo.org>
9 Andreas Jaggi <andreas.jaggi@waterwave.ch>
10
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 2 of the License, or
14 (at your option) any later version.
15
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
20
21 You should have received a copy of the GNU General Public License
22 along with this program; see the file COPYING. If not, write to
23 the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,
24 Boston, MA 02110-1301, USA.
25
26*/
27
28#include "bcm43xx_leds.h"
29#include "bcm43xx.h"
30
31#include <asm/bitops.h>
32
33
34static void bcm43xx_led_changestate(struct bcm43xx_led *led)
35{
36 struct bcm43xx_private *bcm = led->bcm;
37 const int index = bcm43xx_led_index(led);
38 const u16 mask = (1 << index);
39 u16 ledctl;
40
41 assert(index >= 0 && index < BCM43xx_NR_LEDS);
42 assert(led->blink_interval);
43 ledctl = bcm43xx_read16(bcm, BCM43xx_MMIO_GPIO_CONTROL);
44 ledctl = (ledctl & mask) ? (ledctl & ~mask) : (ledctl | mask);
45 bcm43xx_write16(bcm, BCM43xx_MMIO_GPIO_CONTROL, ledctl);
46}
47
48static void bcm43xx_led_blink(unsigned long d)
49{
50 struct bcm43xx_led *led = (struct bcm43xx_led *)d;
51 struct bcm43xx_private *bcm = led->bcm;
52 unsigned long flags;
53
54 bcm43xx_lock_mmio(bcm, flags);
55 if (led->blink_interval) {
56 bcm43xx_led_changestate(led);
57 mod_timer(&led->blink_timer, jiffies + led->blink_interval);
58 }
59 bcm43xx_unlock_mmio(bcm, flags);
60}
61
62static void bcm43xx_led_blink_start(struct bcm43xx_led *led,
63 unsigned long interval)
64{
65 if (led->blink_interval)
66 return;
67 led->blink_interval = interval;
68 bcm43xx_led_changestate(led);
69 led->blink_timer.expires = jiffies + interval;
70 add_timer(&led->blink_timer);
71}
72
73static void bcm43xx_led_blink_stop(struct bcm43xx_led *led, int sync)
74{
75 struct bcm43xx_private *bcm = led->bcm;
76 const int index = bcm43xx_led_index(led);
77 u16 ledctl;
78
79 if (!led->blink_interval)
80 return;
81 if (unlikely(sync))
82 del_timer_sync(&led->blink_timer);
83 else
84 del_timer(&led->blink_timer);
85 led->blink_interval = 0;
86
87 /* Make sure the LED is turned off. */
88 assert(index >= 0 && index < BCM43xx_NR_LEDS);
89 ledctl = bcm43xx_read16(bcm, BCM43xx_MMIO_GPIO_CONTROL);
90 if (led->activelow)
91 ledctl |= (1 << index);
92 else
93 ledctl &= ~(1 << index);
94 bcm43xx_write16(bcm, BCM43xx_MMIO_GPIO_CONTROL, ledctl);
95}
96
97static void bcm43xx_led_init_hardcoded(struct bcm43xx_private *bcm,
98 struct bcm43xx_led *led,
99 int led_index)
100{
101 /* This function is called, if the behaviour (and activelow)
102 * information for a LED is missing in the SPROM.
103 * We hardcode the behaviour values for various devices here.
104 * Note that the BCM43xx_LED_TEST_XXX behaviour values can
105 * be used to figure out which led is mapped to which index.
106 */
107
108 switch (led_index) {
109 case 0:
110 led->behaviour = BCM43xx_LED_ACTIVITY;
111 if (bcm->board_vendor == PCI_VENDOR_ID_COMPAQ)
112 led->behaviour = BCM43xx_LED_RADIO_ALL;
113 break;
114 case 1:
115 led->behaviour = BCM43xx_LED_RADIO_B;
116 if (bcm->board_vendor == PCI_VENDOR_ID_ASUSTEK)
117 led->behaviour = BCM43xx_LED_ASSOC;
118 break;
119 case 2:
120 led->behaviour = BCM43xx_LED_RADIO_A;
121 break;
122 case 3:
123 led->behaviour = BCM43xx_LED_OFF;
124 break;
125 default:
126 assert(0);
127 }
128}
129
130int bcm43xx_leds_init(struct bcm43xx_private *bcm)
131{
132 struct bcm43xx_led *led;
133 u8 sprom[4];
134 int i;
135
136 sprom[0] = bcm->sprom.wl0gpio0;
137 sprom[1] = bcm->sprom.wl0gpio1;
138 sprom[2] = bcm->sprom.wl0gpio2;
139 sprom[3] = bcm->sprom.wl0gpio3;
140
141 for (i = 0; i < BCM43xx_NR_LEDS; i++) {
142 led = &(bcm->leds[i]);
143 led->bcm = bcm;
144 setup_timer(&led->blink_timer,
145 bcm43xx_led_blink,
146 (unsigned long)led);
147
148 if (sprom[i] == 0xFF) {
149 bcm43xx_led_init_hardcoded(bcm, led, i);
150 } else {
151 led->behaviour = sprom[i] & BCM43xx_LED_BEHAVIOUR;
152 led->activelow = !!(sprom[i] & BCM43xx_LED_ACTIVELOW);
153 }
154 }
155
156 return 0;
157}
158
159void bcm43xx_leds_exit(struct bcm43xx_private *bcm)
160{
161 struct bcm43xx_led *led;
162 int i;
163
164 for (i = 0; i < BCM43xx_NR_LEDS; i++) {
165 led = &(bcm->leds[i]);
166 bcm43xx_led_blink_stop(led, 1);
167 }
168 bcm43xx_leds_switch_all(bcm, 0);
169}
170
171void bcm43xx_leds_update(struct bcm43xx_private *bcm, int activity)
172{
173 struct bcm43xx_led *led;
174 struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm);
175 struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
176 const int transferring = (jiffies - bcm->stats.last_tx) < BCM43xx_LED_XFER_THRES;
177 int i, turn_on;
178 unsigned long interval = 0;
179 u16 ledctl;
180
181 ledctl = bcm43xx_read16(bcm, BCM43xx_MMIO_GPIO_CONTROL);
182 for (i = 0; i < BCM43xx_NR_LEDS; i++) {
183 led = &(bcm->leds[i]);
184
185 turn_on = 0;
186 switch (led->behaviour) {
187 case BCM43xx_LED_INACTIVE:
188 continue;
189 case BCM43xx_LED_OFF:
190 break;
191 case BCM43xx_LED_ON:
192 turn_on = 1;
193 break;
194 case BCM43xx_LED_ACTIVITY:
195 turn_on = activity;
196 break;
197 case BCM43xx_LED_RADIO_ALL:
198 turn_on = radio->enabled;
199 break;
200 case BCM43xx_LED_RADIO_A:
201 turn_on = (radio->enabled && phy->type == BCM43xx_PHYTYPE_A);
202 break;
203 case BCM43xx_LED_RADIO_B:
204 turn_on = (radio->enabled &&
205 (phy->type == BCM43xx_PHYTYPE_B ||
206 phy->type == BCM43xx_PHYTYPE_G));
207 break;
208 case BCM43xx_LED_MODE_BG:
209 if (phy->type == BCM43xx_PHYTYPE_G &&
210 1/*FIXME: using G rates.*/)
211 turn_on = 1;
212 break;
213 case BCM43xx_LED_TRANSFER:
214 if (transferring)
215 bcm43xx_led_blink_start(led, BCM43xx_LEDBLINK_MEDIUM);
216 else
217 bcm43xx_led_blink_stop(led, 0);
218 continue;
219 case BCM43xx_LED_APTRANSFER:
220 if (bcm->ieee->iw_mode == IW_MODE_MASTER) {
221 if (transferring) {
222 interval = BCM43xx_LEDBLINK_FAST;
223 turn_on = 1;
224 }
225 } else {
226 turn_on = 1;
227 if (0/*TODO: not assoc*/)
228 interval = BCM43xx_LEDBLINK_SLOW;
229 else if (transferring)
230 interval = BCM43xx_LEDBLINK_FAST;
231 else
232 turn_on = 0;
233 }
234 if (turn_on)
235 bcm43xx_led_blink_start(led, interval);
236 else
237 bcm43xx_led_blink_stop(led, 0);
238 continue;
239 case BCM43xx_LED_WEIRD:
240 //TODO
241 break;
242 case BCM43xx_LED_ASSOC:
243 if (bcm->softmac->associated)
244 turn_on = 1;
245 break;
246#ifdef CONFIG_BCM43XX_DEBUG
247 case BCM43xx_LED_TEST_BLINKSLOW:
248 bcm43xx_led_blink_start(led, BCM43xx_LEDBLINK_SLOW);
249 continue;
250 case BCM43xx_LED_TEST_BLINKMEDIUM:
251 bcm43xx_led_blink_start(led, BCM43xx_LEDBLINK_MEDIUM);
252 continue;
253 case BCM43xx_LED_TEST_BLINKFAST:
254 bcm43xx_led_blink_start(led, BCM43xx_LEDBLINK_FAST);
255 continue;
256#endif /* CONFIG_BCM43XX_DEBUG */
257 default:
258 assert(0);
259 };
260
261 if (led->activelow)
262 turn_on = !turn_on;
263 if (turn_on)
264 ledctl |= (1 << i);
265 else
266 ledctl &= ~(1 << i);
267 }
268 bcm43xx_write16(bcm, BCM43xx_MMIO_GPIO_CONTROL, ledctl);
269}
270
271void bcm43xx_leds_switch_all(struct bcm43xx_private *bcm, int on)
272{
273 struct bcm43xx_led *led;
274 u16 ledctl;
275 int i;
276 int bit_on;
277
278 ledctl = bcm43xx_read16(bcm, BCM43xx_MMIO_GPIO_CONTROL);
279 for (i = 0; i < BCM43xx_NR_LEDS; i++) {
280 led = &(bcm->leds[i]);
281 if (led->behaviour == BCM43xx_LED_INACTIVE)
282 continue;
283 if (on)
284 bit_on = led->activelow ? 0 : 1;
285 else
286 bit_on = led->activelow ? 1 : 0;
287 if (bit_on)
288 ledctl |= (1 << i);
289 else
290 ledctl &= ~(1 << i);
291 }
292 bcm43xx_write16(bcm, BCM43xx_MMIO_GPIO_CONTROL, ledctl);
293}
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_leds.h b/drivers/net/wireless/bcm43xx/bcm43xx_leds.h
new file mode 100644
index 000000000000..d3716cf3aebc
--- /dev/null
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_leds.h
@@ -0,0 +1,56 @@
1#ifndef BCM43xx_LEDS_H_
2#define BCM43xx_LEDS_H_
3
4#include <linux/types.h>
5#include <linux/timer.h>
6
7
8struct bcm43xx_led {
9 u8 behaviour:7;
10 u8 activelow:1;
11
12 struct bcm43xx_private *bcm;
13 struct timer_list blink_timer;
14 unsigned long blink_interval;
15};
16#define bcm43xx_led_index(led) ((int)((led) - (led)->bcm->leds))
17
18/* Delay between state changes when blinking in jiffies */
19#define BCM43xx_LEDBLINK_SLOW (HZ / 1)
20#define BCM43xx_LEDBLINK_MEDIUM (HZ / 4)
21#define BCM43xx_LEDBLINK_FAST (HZ / 8)
22
23#define BCM43xx_LED_XFER_THRES (HZ / 100)
24
25#define BCM43xx_LED_BEHAVIOUR 0x7F
26#define BCM43xx_LED_ACTIVELOW 0x80
27enum { /* LED behaviour values */
28 BCM43xx_LED_OFF,
29 BCM43xx_LED_ON,
30 BCM43xx_LED_ACTIVITY,
31 BCM43xx_LED_RADIO_ALL,
32 BCM43xx_LED_RADIO_A,
33 BCM43xx_LED_RADIO_B,
34 BCM43xx_LED_MODE_BG,
35 BCM43xx_LED_TRANSFER,
36 BCM43xx_LED_APTRANSFER,
37 BCM43xx_LED_WEIRD,//FIXME
38 BCM43xx_LED_ASSOC,
39 BCM43xx_LED_INACTIVE,
40
41 /* Behaviour values for testing.
42 * With these values it is easier to figure out
43 * the real behaviour of leds, in case the SPROM
44 * is missing information.
45 */
46 BCM43xx_LED_TEST_BLINKSLOW,
47 BCM43xx_LED_TEST_BLINKMEDIUM,
48 BCM43xx_LED_TEST_BLINKFAST,
49};
50
51int bcm43xx_leds_init(struct bcm43xx_private *bcm);
52void bcm43xx_leds_exit(struct bcm43xx_private *bcm);
53void bcm43xx_leds_update(struct bcm43xx_private *bcm, int activity);
54void bcm43xx_leds_switch_all(struct bcm43xx_private *bcm, int on);
55
56#endif /* BCM43xx_LEDS_H_ */
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_main.c b/drivers/net/wireless/bcm43xx/bcm43xx_main.c
new file mode 100644
index 000000000000..c37371fc9e01
--- /dev/null
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_main.c
@@ -0,0 +1,3973 @@
1/*
2
3 Broadcom BCM43xx wireless driver
4
5 Copyright (c) 2005 Martin Langer <martin-langer@gmx.de>,
6 Stefano Brivio <st3@riseup.net>
7 Michael Buesch <mbuesch@freenet.de>
8 Danny van Dyk <kugelfang@gentoo.org>
9 Andreas Jaggi <andreas.jaggi@waterwave.ch>
10
11 Some parts of the code in this file are derived from the ipw2200
12 driver Copyright(c) 2003 - 2004 Intel Corporation.
13
14 This program is free software; you can redistribute it and/or modify
15 it under the terms of the GNU General Public License as published by
16 the Free Software Foundation; either version 2 of the License, or
17 (at your option) any later version.
18
19 This program is distributed in the hope that it will be useful,
20 but WITHOUT ANY WARRANTY; without even the implied warranty of
21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 GNU General Public License for more details.
23
24 You should have received a copy of the GNU General Public License
25 along with this program; see the file COPYING. If not, write to
26 the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,
27 Boston, MA 02110-1301, USA.
28
29*/
30
31#include <linux/delay.h>
32#include <linux/init.h>
33#include <linux/moduleparam.h>
34#include <linux/if_arp.h>
35#include <linux/etherdevice.h>
36#include <linux/version.h>
37#include <linux/firmware.h>
38#include <linux/wireless.h>
39#include <linux/workqueue.h>
40#include <linux/skbuff.h>
41#include <linux/dma-mapping.h>
42#include <net/iw_handler.h>
43
44#include "bcm43xx.h"
45#include "bcm43xx_main.h"
46#include "bcm43xx_debugfs.h"
47#include "bcm43xx_radio.h"
48#include "bcm43xx_phy.h"
49#include "bcm43xx_dma.h"
50#include "bcm43xx_pio.h"
51#include "bcm43xx_power.h"
52#include "bcm43xx_wx.h"
53#include "bcm43xx_ethtool.h"
54#include "bcm43xx_xmit.h"
55
56
57MODULE_DESCRIPTION("Broadcom BCM43xx wireless driver");
58MODULE_AUTHOR("Martin Langer");
59MODULE_AUTHOR("Stefano Brivio");
60MODULE_AUTHOR("Michael Buesch");
61MODULE_LICENSE("GPL");
62
63#ifdef CONFIG_BCM947XX
64extern char *nvram_get(char *name);
65#endif
66
67#if defined(CONFIG_BCM43XX_DMA) && defined(CONFIG_BCM43XX_PIO)
68static int modparam_pio;
69module_param_named(pio, modparam_pio, int, 0444);
70MODULE_PARM_DESC(pio, "enable(1) / disable(0) PIO mode");
71#elif defined(CONFIG_BCM43XX_DMA)
72# define modparam_pio 0
73#elif defined(CONFIG_BCM43XX_PIO)
74# define modparam_pio 1
75#endif
76
77static int modparam_bad_frames_preempt;
78module_param_named(bad_frames_preempt, modparam_bad_frames_preempt, int, 0444);
79MODULE_PARM_DESC(bad_frames_preempt, "enable(1) / disable(0) Bad Frames Preemption");
80
81static int modparam_short_retry = BCM43xx_DEFAULT_SHORT_RETRY_LIMIT;
82module_param_named(short_retry, modparam_short_retry, int, 0444);
83MODULE_PARM_DESC(short_retry, "Short-Retry-Limit (0 - 15)");
84
85static int modparam_long_retry = BCM43xx_DEFAULT_LONG_RETRY_LIMIT;
86module_param_named(long_retry, modparam_long_retry, int, 0444);
87MODULE_PARM_DESC(long_retry, "Long-Retry-Limit (0 - 15)");
88
89static int modparam_locale = -1;
90module_param_named(locale, modparam_locale, int, 0444);
91MODULE_PARM_DESC(country, "Select LocaleCode 0-11 (For travelers)");
92
93static int modparam_noleds;
94module_param_named(noleds, modparam_noleds, int, 0444);
95MODULE_PARM_DESC(noleds, "Turn off all LED activity");
96
97#ifdef CONFIG_BCM43XX_DEBUG
98static char modparam_fwpostfix[64];
99module_param_string(fwpostfix, modparam_fwpostfix, 64, 0444);
100MODULE_PARM_DESC(fwpostfix, "Postfix for .fw files. Useful for debugging.");
101#else
102# define modparam_fwpostfix ""
103#endif /* CONFIG_BCM43XX_DEBUG*/
104
105
106/* If you want to debug with just a single device, enable this,
107 * where the string is the pci device ID (as given by the kernel's
108 * pci_name function) of the device to be used.
109 */
110//#define DEBUG_SINGLE_DEVICE_ONLY "0001:11:00.0"
111
112/* If you want to enable printing of each MMIO access, enable this. */
113//#define DEBUG_ENABLE_MMIO_PRINT
114
115/* If you want to enable printing of MMIO access within
116 * ucode/pcm upload, initvals write, enable this.
117 */
118//#define DEBUG_ENABLE_UCODE_MMIO_PRINT
119
120/* If you want to enable printing of PCI Config Space access, enable this */
121//#define DEBUG_ENABLE_PCILOG
122
123
124/* Detailed list maintained at:
125 * http://openfacts.berlios.de/index-en.phtml?title=Bcm43xxDevices
126 */
127 static struct pci_device_id bcm43xx_pci_tbl[] = {
128 /* Broadcom 4303 802.11b */
129 { PCI_VENDOR_ID_BROADCOM, 0x4301, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
130 /* Broadcom 4307 802.11b */
131 { PCI_VENDOR_ID_BROADCOM, 0x4307, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
132 /* Broadcom 4318 802.11b/g */
133 { PCI_VENDOR_ID_BROADCOM, 0x4318, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
134 /* Broadcom 4306 802.11b/g */
135 { PCI_VENDOR_ID_BROADCOM, 0x4320, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
136 /* Broadcom 4306 802.11a */
137// { PCI_VENDOR_ID_BROADCOM, 0x4321, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
138 /* Broadcom 4309 802.11a/b/g */
139 { PCI_VENDOR_ID_BROADCOM, 0x4324, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
140 /* Broadcom 43XG 802.11b/g */
141 { PCI_VENDOR_ID_BROADCOM, 0x4325, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
142#ifdef CONFIG_BCM947XX
143 /* SB bus on BCM947xx */
144 { PCI_VENDOR_ID_BROADCOM, 0x0800, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
145#endif
146 { 0 },
147};
148MODULE_DEVICE_TABLE(pci, bcm43xx_pci_tbl);
149
150static void bcm43xx_ram_write(struct bcm43xx_private *bcm, u16 offset, u32 val)
151{
152 u32 status;
153
154 status = bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD);
155 if (!(status & BCM43xx_SBF_XFER_REG_BYTESWAP))
156 val = swab32(val);
157
158 bcm43xx_write32(bcm, BCM43xx_MMIO_RAM_CONTROL, offset);
159 mmiowb();
160 bcm43xx_write32(bcm, BCM43xx_MMIO_RAM_DATA, val);
161}
162
163static inline
164void bcm43xx_shm_control_word(struct bcm43xx_private *bcm,
165 u16 routing, u16 offset)
166{
167 u32 control;
168
169 /* "offset" is the WORD offset. */
170
171 control = routing;
172 control <<= 16;
173 control |= offset;
174 bcm43xx_write32(bcm, BCM43xx_MMIO_SHM_CONTROL, control);
175}
176
177u32 bcm43xx_shm_read32(struct bcm43xx_private *bcm,
178 u16 routing, u16 offset)
179{
180 u32 ret;
181
182 if (routing == BCM43xx_SHM_SHARED) {
183 if (offset & 0x0003) {
184 /* Unaligned access */
185 bcm43xx_shm_control_word(bcm, routing, offset >> 2);
186 ret = bcm43xx_read16(bcm, BCM43xx_MMIO_SHM_DATA_UNALIGNED);
187 ret <<= 16;
188 bcm43xx_shm_control_word(bcm, routing, (offset >> 2) + 1);
189 ret |= bcm43xx_read16(bcm, BCM43xx_MMIO_SHM_DATA);
190
191 return ret;
192 }
193 offset >>= 2;
194 }
195 bcm43xx_shm_control_word(bcm, routing, offset);
196 ret = bcm43xx_read32(bcm, BCM43xx_MMIO_SHM_DATA);
197
198 return ret;
199}
200
201u16 bcm43xx_shm_read16(struct bcm43xx_private *bcm,
202 u16 routing, u16 offset)
203{
204 u16 ret;
205
206 if (routing == BCM43xx_SHM_SHARED) {
207 if (offset & 0x0003) {
208 /* Unaligned access */
209 bcm43xx_shm_control_word(bcm, routing, offset >> 2);
210 ret = bcm43xx_read16(bcm, BCM43xx_MMIO_SHM_DATA_UNALIGNED);
211
212 return ret;
213 }
214 offset >>= 2;
215 }
216 bcm43xx_shm_control_word(bcm, routing, offset);
217 ret = bcm43xx_read16(bcm, BCM43xx_MMIO_SHM_DATA);
218
219 return ret;
220}
221
222void bcm43xx_shm_write32(struct bcm43xx_private *bcm,
223 u16 routing, u16 offset,
224 u32 value)
225{
226 if (routing == BCM43xx_SHM_SHARED) {
227 if (offset & 0x0003) {
228 /* Unaligned access */
229 bcm43xx_shm_control_word(bcm, routing, offset >> 2);
230 mmiowb();
231 bcm43xx_write16(bcm, BCM43xx_MMIO_SHM_DATA_UNALIGNED,
232 (value >> 16) & 0xffff);
233 mmiowb();
234 bcm43xx_shm_control_word(bcm, routing, (offset >> 2) + 1);
235 mmiowb();
236 bcm43xx_write16(bcm, BCM43xx_MMIO_SHM_DATA,
237 value & 0xffff);
238 return;
239 }
240 offset >>= 2;
241 }
242 bcm43xx_shm_control_word(bcm, routing, offset);
243 mmiowb();
244 bcm43xx_write32(bcm, BCM43xx_MMIO_SHM_DATA, value);
245}
246
247void bcm43xx_shm_write16(struct bcm43xx_private *bcm,
248 u16 routing, u16 offset,
249 u16 value)
250{
251 if (routing == BCM43xx_SHM_SHARED) {
252 if (offset & 0x0003) {
253 /* Unaligned access */
254 bcm43xx_shm_control_word(bcm, routing, offset >> 2);
255 mmiowb();
256 bcm43xx_write16(bcm, BCM43xx_MMIO_SHM_DATA_UNALIGNED,
257 value);
258 return;
259 }
260 offset >>= 2;
261 }
262 bcm43xx_shm_control_word(bcm, routing, offset);
263 mmiowb();
264 bcm43xx_write16(bcm, BCM43xx_MMIO_SHM_DATA, value);
265}
266
267void bcm43xx_tsf_read(struct bcm43xx_private *bcm, u64 *tsf)
268{
269 /* We need to be careful. As we read the TSF from multiple
270 * registers, we should take care of register overflows.
271 * In theory, the whole tsf read process should be atomic.
272 * We try to be atomic here, by restaring the read process,
273 * if any of the high registers changed (overflew).
274 */
275 if (bcm->current_core->rev >= 3) {
276 u32 low, high, high2;
277
278 do {
279 high = bcm43xx_read32(bcm, BCM43xx_MMIO_REV3PLUS_TSF_HIGH);
280 low = bcm43xx_read32(bcm, BCM43xx_MMIO_REV3PLUS_TSF_LOW);
281 high2 = bcm43xx_read32(bcm, BCM43xx_MMIO_REV3PLUS_TSF_HIGH);
282 } while (unlikely(high != high2));
283
284 *tsf = high;
285 *tsf <<= 32;
286 *tsf |= low;
287 } else {
288 u64 tmp;
289 u16 v0, v1, v2, v3;
290 u16 test1, test2, test3;
291
292 do {
293 v3 = bcm43xx_read16(bcm, BCM43xx_MMIO_TSF_3);
294 v2 = bcm43xx_read16(bcm, BCM43xx_MMIO_TSF_2);
295 v1 = bcm43xx_read16(bcm, BCM43xx_MMIO_TSF_1);
296 v0 = bcm43xx_read16(bcm, BCM43xx_MMIO_TSF_0);
297
298 test3 = bcm43xx_read16(bcm, BCM43xx_MMIO_TSF_3);
299 test2 = bcm43xx_read16(bcm, BCM43xx_MMIO_TSF_2);
300 test1 = bcm43xx_read16(bcm, BCM43xx_MMIO_TSF_1);
301 } while (v3 != test3 || v2 != test2 || v1 != test1);
302
303 *tsf = v3;
304 *tsf <<= 48;
305 tmp = v2;
306 tmp <<= 32;
307 *tsf |= tmp;
308 tmp = v1;
309 tmp <<= 16;
310 *tsf |= tmp;
311 *tsf |= v0;
312 }
313}
314
315void bcm43xx_tsf_write(struct bcm43xx_private *bcm, u64 tsf)
316{
317 u32 status;
318
319 status = bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD);
320 status |= BCM43xx_SBF_TIME_UPDATE;
321 bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD, status);
322 mmiowb();
323
324 /* Be careful with the in-progress timer.
325 * First zero out the low register, so we have a full
326 * register-overflow duration to complete the operation.
327 */
328 if (bcm->current_core->rev >= 3) {
329 u32 lo = (tsf & 0x00000000FFFFFFFFULL);
330 u32 hi = (tsf & 0xFFFFFFFF00000000ULL) >> 32;
331
332 bcm43xx_write32(bcm, BCM43xx_MMIO_REV3PLUS_TSF_LOW, 0);
333 mmiowb();
334 bcm43xx_write32(bcm, BCM43xx_MMIO_REV3PLUS_TSF_HIGH, hi);
335 mmiowb();
336 bcm43xx_write32(bcm, BCM43xx_MMIO_REV3PLUS_TSF_LOW, lo);
337 } else {
338 u16 v0 = (tsf & 0x000000000000FFFFULL);
339 u16 v1 = (tsf & 0x00000000FFFF0000ULL) >> 16;
340 u16 v2 = (tsf & 0x0000FFFF00000000ULL) >> 32;
341 u16 v3 = (tsf & 0xFFFF000000000000ULL) >> 48;
342
343 bcm43xx_write16(bcm, BCM43xx_MMIO_TSF_0, 0);
344 mmiowb();
345 bcm43xx_write16(bcm, BCM43xx_MMIO_TSF_3, v3);
346 mmiowb();
347 bcm43xx_write16(bcm, BCM43xx_MMIO_TSF_2, v2);
348 mmiowb();
349 bcm43xx_write16(bcm, BCM43xx_MMIO_TSF_1, v1);
350 mmiowb();
351 bcm43xx_write16(bcm, BCM43xx_MMIO_TSF_0, v0);
352 }
353
354 status = bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD);
355 status &= ~BCM43xx_SBF_TIME_UPDATE;
356 bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD, status);
357}
358
359static
360void bcm43xx_macfilter_set(struct bcm43xx_private *bcm,
361 u16 offset,
362 const u8 *mac)
363{
364 u16 data;
365
366 offset |= 0x0020;
367 bcm43xx_write16(bcm, BCM43xx_MMIO_MACFILTER_CONTROL, offset);
368
369 data = mac[0];
370 data |= mac[1] << 8;
371 bcm43xx_write16(bcm, BCM43xx_MMIO_MACFILTER_DATA, data);
372 data = mac[2];
373 data |= mac[3] << 8;
374 bcm43xx_write16(bcm, BCM43xx_MMIO_MACFILTER_DATA, data);
375 data = mac[4];
376 data |= mac[5] << 8;
377 bcm43xx_write16(bcm, BCM43xx_MMIO_MACFILTER_DATA, data);
378}
379
380static void bcm43xx_macfilter_clear(struct bcm43xx_private *bcm,
381 u16 offset)
382{
383 const u8 zero_addr[ETH_ALEN] = { 0 };
384
385 bcm43xx_macfilter_set(bcm, offset, zero_addr);
386}
387
388static void bcm43xx_write_mac_bssid_templates(struct bcm43xx_private *bcm)
389{
390 const u8 *mac = (const u8 *)(bcm->net_dev->dev_addr);
391 const u8 *bssid = (const u8 *)(bcm->ieee->bssid);
392 u8 mac_bssid[ETH_ALEN * 2];
393 int i;
394
395 memcpy(mac_bssid, mac, ETH_ALEN);
396 memcpy(mac_bssid + ETH_ALEN, bssid, ETH_ALEN);
397
398 /* Write our MAC address and BSSID to template ram */
399 for (i = 0; i < ARRAY_SIZE(mac_bssid); i += sizeof(u32))
400 bcm43xx_ram_write(bcm, 0x20 + i, *((u32 *)(mac_bssid + i)));
401 for (i = 0; i < ARRAY_SIZE(mac_bssid); i += sizeof(u32))
402 bcm43xx_ram_write(bcm, 0x78 + i, *((u32 *)(mac_bssid + i)));
403 for (i = 0; i < ARRAY_SIZE(mac_bssid); i += sizeof(u32))
404 bcm43xx_ram_write(bcm, 0x478 + i, *((u32 *)(mac_bssid + i)));
405}
406
407//FIXME: Well, we should probably call them from somewhere.
408#if 0
409static void bcm43xx_set_slot_time(struct bcm43xx_private *bcm, u16 slot_time)
410{
411 /* slot_time is in usec. */
412 if (bcm43xx_current_phy(bcm)->type != BCM43xx_PHYTYPE_G)
413 return;
414 bcm43xx_write16(bcm, 0x684, 510 + slot_time);
415 bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, 0x0010, slot_time);
416}
417
418static void bcm43xx_short_slot_timing_enable(struct bcm43xx_private *bcm)
419{
420 bcm43xx_set_slot_time(bcm, 9);
421}
422
423static void bcm43xx_short_slot_timing_disable(struct bcm43xx_private *bcm)
424{
425 bcm43xx_set_slot_time(bcm, 20);
426}
427#endif
428
429/* FIXME: To get the MAC-filter working, we need to implement the
430 * following functions (and rename them :)
431 */
432#if 0
433static void bcm43xx_disassociate(struct bcm43xx_private *bcm)
434{
435 bcm43xx_mac_suspend(bcm);
436 bcm43xx_macfilter_clear(bcm, BCM43xx_MACFILTER_ASSOC);
437
438 bcm43xx_ram_write(bcm, 0x0026, 0x0000);
439 bcm43xx_ram_write(bcm, 0x0028, 0x0000);
440 bcm43xx_ram_write(bcm, 0x007E, 0x0000);
441 bcm43xx_ram_write(bcm, 0x0080, 0x0000);
442 bcm43xx_ram_write(bcm, 0x047E, 0x0000);
443 bcm43xx_ram_write(bcm, 0x0480, 0x0000);
444
445 if (bcm->current_core->rev < 3) {
446 bcm43xx_write16(bcm, 0x0610, 0x8000);
447 bcm43xx_write16(bcm, 0x060E, 0x0000);
448 } else
449 bcm43xx_write32(bcm, 0x0188, 0x80000000);
450
451 bcm43xx_shm_write32(bcm, BCM43xx_SHM_WIRELESS, 0x0004, 0x000003ff);
452
453 if (bcm43xx_current_phy(bcm)->type == BCM43xx_PHYTYPE_G &&
454 ieee80211_is_ofdm_rate(bcm->softmac->txrates.default_rate))
455 bcm43xx_short_slot_timing_enable(bcm);
456
457 bcm43xx_mac_enable(bcm);
458}
459
460static void bcm43xx_associate(struct bcm43xx_private *bcm,
461 const u8 *mac)
462{
463 memcpy(bcm->ieee->bssid, mac, ETH_ALEN);
464
465 bcm43xx_mac_suspend(bcm);
466 bcm43xx_macfilter_set(bcm, BCM43xx_MACFILTER_ASSOC, mac);
467 bcm43xx_write_mac_bssid_templates(bcm);
468 bcm43xx_mac_enable(bcm);
469}
470#endif
471
472/* Enable a Generic IRQ. "mask" is the mask of which IRQs to enable.
473 * Returns the _previously_ enabled IRQ mask.
474 */
475static inline u32 bcm43xx_interrupt_enable(struct bcm43xx_private *bcm, u32 mask)
476{
477 u32 old_mask;
478
479 old_mask = bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_MASK);
480 bcm43xx_write32(bcm, BCM43xx_MMIO_GEN_IRQ_MASK, old_mask | mask);
481
482 return old_mask;
483}
484
485/* Disable a Generic IRQ. "mask" is the mask of which IRQs to disable.
486 * Returns the _previously_ enabled IRQ mask.
487 */
488static inline u32 bcm43xx_interrupt_disable(struct bcm43xx_private *bcm, u32 mask)
489{
490 u32 old_mask;
491
492 old_mask = bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_MASK);
493 bcm43xx_write32(bcm, BCM43xx_MMIO_GEN_IRQ_MASK, old_mask & ~mask);
494
495 return old_mask;
496}
497
498/* Make sure we don't receive more data from the device. */
499static int bcm43xx_disable_interrupts_sync(struct bcm43xx_private *bcm, u32 *oldstate)
500{
501 u32 old;
502 unsigned long flags;
503
504 bcm43xx_lock_mmio(bcm, flags);
505 if (bcm43xx_is_initializing(bcm) || bcm->shutting_down) {
506 bcm43xx_unlock_mmio(bcm, flags);
507 return -EBUSY;
508 }
509 old = bcm43xx_interrupt_disable(bcm, BCM43xx_IRQ_ALL);
510 tasklet_disable(&bcm->isr_tasklet);
511 bcm43xx_unlock_mmio(bcm, flags);
512 if (oldstate)
513 *oldstate = old;
514
515 return 0;
516}
517
518static int bcm43xx_read_radioinfo(struct bcm43xx_private *bcm)
519{
520 struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm);
521 struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
522 u32 radio_id;
523 u16 manufact;
524 u16 version;
525 u8 revision;
526 s8 i;
527
528 if (bcm->chip_id == 0x4317) {
529 if (bcm->chip_rev == 0x00)
530 radio_id = 0x3205017F;
531 else if (bcm->chip_rev == 0x01)
532 radio_id = 0x4205017F;
533 else
534 radio_id = 0x5205017F;
535 } else {
536 bcm43xx_write16(bcm, BCM43xx_MMIO_RADIO_CONTROL, BCM43xx_RADIOCTL_ID);
537 radio_id = bcm43xx_read16(bcm, BCM43xx_MMIO_RADIO_DATA_HIGH);
538 radio_id <<= 16;
539 bcm43xx_write16(bcm, BCM43xx_MMIO_RADIO_CONTROL, BCM43xx_RADIOCTL_ID);
540 radio_id |= bcm43xx_read16(bcm, BCM43xx_MMIO_RADIO_DATA_LOW);
541 }
542
543 manufact = (radio_id & 0x00000FFF);
544 version = (radio_id & 0x0FFFF000) >> 12;
545 revision = (radio_id & 0xF0000000) >> 28;
546
547 dprintk(KERN_INFO PFX "Detected Radio: ID: %x (Manuf: %x Ver: %x Rev: %x)\n",
548 radio_id, manufact, version, revision);
549
550 switch (phy->type) {
551 case BCM43xx_PHYTYPE_A:
552 if ((version != 0x2060) || (revision != 1) || (manufact != 0x17f))
553 goto err_unsupported_radio;
554 break;
555 case BCM43xx_PHYTYPE_B:
556 if ((version & 0xFFF0) != 0x2050)
557 goto err_unsupported_radio;
558 break;
559 case BCM43xx_PHYTYPE_G:
560 if (version != 0x2050)
561 goto err_unsupported_radio;
562 break;
563 }
564
565 radio->manufact = manufact;
566 radio->version = version;
567 radio->revision = revision;
568
569 /* Set default attenuation values. */
570 radio->baseband_atten = bcm43xx_default_baseband_attenuation(bcm);
571 radio->radio_atten = bcm43xx_default_radio_attenuation(bcm);
572 radio->txctl1 = bcm43xx_default_txctl1(bcm);
573 radio->txctl2 = 0xFFFF;
574 if (phy->type == BCM43xx_PHYTYPE_A)
575 radio->txpower_desired = bcm->sprom.maxpower_aphy;
576 else
577 radio->txpower_desired = bcm->sprom.maxpower_bgphy;
578
579 /* Initialize the in-memory nrssi Lookup Table. */
580 for (i = 0; i < 64; i++)
581 radio->nrssi_lt[i] = i;
582
583 return 0;
584
585err_unsupported_radio:
586 printk(KERN_ERR PFX "Unsupported Radio connected to the PHY!\n");
587 return -ENODEV;
588}
589
590static const char * bcm43xx_locale_iso(u8 locale)
591{
592 /* ISO 3166-1 country codes.
593 * Note that there aren't ISO 3166-1 codes for
594 * all or locales. (Not all locales are countries)
595 */
596 switch (locale) {
597 case BCM43xx_LOCALE_WORLD:
598 case BCM43xx_LOCALE_ALL:
599 return "XX";
600 case BCM43xx_LOCALE_THAILAND:
601 return "TH";
602 case BCM43xx_LOCALE_ISRAEL:
603 return "IL";
604 case BCM43xx_LOCALE_JORDAN:
605 return "JO";
606 case BCM43xx_LOCALE_CHINA:
607 return "CN";
608 case BCM43xx_LOCALE_JAPAN:
609 case BCM43xx_LOCALE_JAPAN_HIGH:
610 return "JP";
611 case BCM43xx_LOCALE_USA_CANADA_ANZ:
612 case BCM43xx_LOCALE_USA_LOW:
613 return "US";
614 case BCM43xx_LOCALE_EUROPE:
615 return "EU";
616 case BCM43xx_LOCALE_NONE:
617 return " ";
618 }
619 assert(0);
620 return " ";
621}
622
623static const char * bcm43xx_locale_string(u8 locale)
624{
625 switch (locale) {
626 case BCM43xx_LOCALE_WORLD:
627 return "World";
628 case BCM43xx_LOCALE_THAILAND:
629 return "Thailand";
630 case BCM43xx_LOCALE_ISRAEL:
631 return "Israel";
632 case BCM43xx_LOCALE_JORDAN:
633 return "Jordan";
634 case BCM43xx_LOCALE_CHINA:
635 return "China";
636 case BCM43xx_LOCALE_JAPAN:
637 return "Japan";
638 case BCM43xx_LOCALE_USA_CANADA_ANZ:
639 return "USA/Canada/ANZ";
640 case BCM43xx_LOCALE_EUROPE:
641 return "Europe";
642 case BCM43xx_LOCALE_USA_LOW:
643 return "USAlow";
644 case BCM43xx_LOCALE_JAPAN_HIGH:
645 return "JapanHigh";
646 case BCM43xx_LOCALE_ALL:
647 return "All";
648 case BCM43xx_LOCALE_NONE:
649 return "None";
650 }
651 assert(0);
652 return "";
653}
654
655static inline u8 bcm43xx_crc8(u8 crc, u8 data)
656{
657 static const u8 t[] = {
658 0x00, 0xF7, 0xB9, 0x4E, 0x25, 0xD2, 0x9C, 0x6B,
659 0x4A, 0xBD, 0xF3, 0x04, 0x6F, 0x98, 0xD6, 0x21,
660 0x94, 0x63, 0x2D, 0xDA, 0xB1, 0x46, 0x08, 0xFF,
661 0xDE, 0x29, 0x67, 0x90, 0xFB, 0x0C, 0x42, 0xB5,
662 0x7F, 0x88, 0xC6, 0x31, 0x5A, 0xAD, 0xE3, 0x14,
663 0x35, 0xC2, 0x8C, 0x7B, 0x10, 0xE7, 0xA9, 0x5E,
664 0xEB, 0x1C, 0x52, 0xA5, 0xCE, 0x39, 0x77, 0x80,
665 0xA1, 0x56, 0x18, 0xEF, 0x84, 0x73, 0x3D, 0xCA,
666 0xFE, 0x09, 0x47, 0xB0, 0xDB, 0x2C, 0x62, 0x95,
667 0xB4, 0x43, 0x0D, 0xFA, 0x91, 0x66, 0x28, 0xDF,
668 0x6A, 0x9D, 0xD3, 0x24, 0x4F, 0xB8, 0xF6, 0x01,
669 0x20, 0xD7, 0x99, 0x6E, 0x05, 0xF2, 0xBC, 0x4B,
670 0x81, 0x76, 0x38, 0xCF, 0xA4, 0x53, 0x1D, 0xEA,
671 0xCB, 0x3C, 0x72, 0x85, 0xEE, 0x19, 0x57, 0xA0,
672 0x15, 0xE2, 0xAC, 0x5B, 0x30, 0xC7, 0x89, 0x7E,
673 0x5F, 0xA8, 0xE6, 0x11, 0x7A, 0x8D, 0xC3, 0x34,
674 0xAB, 0x5C, 0x12, 0xE5, 0x8E, 0x79, 0x37, 0xC0,
675 0xE1, 0x16, 0x58, 0xAF, 0xC4, 0x33, 0x7D, 0x8A,
676 0x3F, 0xC8, 0x86, 0x71, 0x1A, 0xED, 0xA3, 0x54,
677 0x75, 0x82, 0xCC, 0x3B, 0x50, 0xA7, 0xE9, 0x1E,
678 0xD4, 0x23, 0x6D, 0x9A, 0xF1, 0x06, 0x48, 0xBF,
679 0x9E, 0x69, 0x27, 0xD0, 0xBB, 0x4C, 0x02, 0xF5,
680 0x40, 0xB7, 0xF9, 0x0E, 0x65, 0x92, 0xDC, 0x2B,
681 0x0A, 0xFD, 0xB3, 0x44, 0x2F, 0xD8, 0x96, 0x61,
682 0x55, 0xA2, 0xEC, 0x1B, 0x70, 0x87, 0xC9, 0x3E,
683 0x1F, 0xE8, 0xA6, 0x51, 0x3A, 0xCD, 0x83, 0x74,
684 0xC1, 0x36, 0x78, 0x8F, 0xE4, 0x13, 0x5D, 0xAA,
685 0x8B, 0x7C, 0x32, 0xC5, 0xAE, 0x59, 0x17, 0xE0,
686 0x2A, 0xDD, 0x93, 0x64, 0x0F, 0xF8, 0xB6, 0x41,
687 0x60, 0x97, 0xD9, 0x2E, 0x45, 0xB2, 0xFC, 0x0B,
688 0xBE, 0x49, 0x07, 0xF0, 0x9B, 0x6C, 0x22, 0xD5,
689 0xF4, 0x03, 0x4D, 0xBA, 0xD1, 0x26, 0x68, 0x9F,
690 };
691 return t[crc ^ data];
692}
693
694static u8 bcm43xx_sprom_crc(const u16 *sprom)
695{
696 int word;
697 u8 crc = 0xFF;
698
699 for (word = 0; word < BCM43xx_SPROM_SIZE - 1; word++) {
700 crc = bcm43xx_crc8(crc, sprom[word] & 0x00FF);
701 crc = bcm43xx_crc8(crc, (sprom[word] & 0xFF00) >> 8);
702 }
703 crc = bcm43xx_crc8(crc, sprom[BCM43xx_SPROM_VERSION] & 0x00FF);
704 crc ^= 0xFF;
705
706 return crc;
707}
708
709int bcm43xx_sprom_read(struct bcm43xx_private *bcm, u16 *sprom)
710{
711 int i;
712 u8 crc, expected_crc;
713
714 for (i = 0; i < BCM43xx_SPROM_SIZE; i++)
715 sprom[i] = bcm43xx_read16(bcm, BCM43xx_SPROM_BASE + (i * 2));
716 /* CRC-8 check. */
717 crc = bcm43xx_sprom_crc(sprom);
718 expected_crc = (sprom[BCM43xx_SPROM_VERSION] & 0xFF00) >> 8;
719 if (crc != expected_crc) {
720 printk(KERN_WARNING PFX "WARNING: Invalid SPROM checksum "
721 "(0x%02X, expected: 0x%02X)\n",
722 crc, expected_crc);
723 return -EINVAL;
724 }
725
726 return 0;
727}
728
729int bcm43xx_sprom_write(struct bcm43xx_private *bcm, const u16 *sprom)
730{
731 int i, err;
732 u8 crc, expected_crc;
733 u32 spromctl;
734
735 /* CRC-8 validation of the input data. */
736 crc = bcm43xx_sprom_crc(sprom);
737 expected_crc = (sprom[BCM43xx_SPROM_VERSION] & 0xFF00) >> 8;
738 if (crc != expected_crc) {
739 printk(KERN_ERR PFX "SPROM input data: Invalid CRC\n");
740 return -EINVAL;
741 }
742
743 printk(KERN_INFO PFX "Writing SPROM. Do NOT turn off the power! Please stand by...\n");
744 err = bcm43xx_pci_read_config32(bcm, BCM43xx_PCICFG_SPROMCTL, &spromctl);
745 if (err)
746 goto err_ctlreg;
747 spromctl |= 0x10; /* SPROM WRITE enable. */
748 bcm43xx_pci_write_config32(bcm, BCM43xx_PCICFG_SPROMCTL, spromctl);
749 if (err)
750 goto err_ctlreg;
751 /* We must burn lots of CPU cycles here, but that does not
752 * really matter as one does not write the SPROM every other minute...
753 */
754 printk(KERN_INFO PFX "[ 0%%");
755 mdelay(500);
756 for (i = 0; i < BCM43xx_SPROM_SIZE; i++) {
757 if (i == 16)
758 printk("25%%");
759 else if (i == 32)
760 printk("50%%");
761 else if (i == 48)
762 printk("75%%");
763 else if (i % 2)
764 printk(".");
765 bcm43xx_write16(bcm, BCM43xx_SPROM_BASE + (i * 2), sprom[i]);
766 mmiowb();
767 mdelay(20);
768 }
769 spromctl &= ~0x10; /* SPROM WRITE enable. */
770 bcm43xx_pci_write_config32(bcm, BCM43xx_PCICFG_SPROMCTL, spromctl);
771 if (err)
772 goto err_ctlreg;
773 mdelay(500);
774 printk("100%% ]\n");
775 printk(KERN_INFO PFX "SPROM written.\n");
776 bcm43xx_controller_restart(bcm, "SPROM update");
777
778 return 0;
779err_ctlreg:
780 printk(KERN_ERR PFX "Could not access SPROM control register.\n");
781 return -ENODEV;
782}
783
784static int bcm43xx_sprom_extract(struct bcm43xx_private *bcm)
785{
786 u16 value;
787 u16 *sprom;
788#ifdef CONFIG_BCM947XX
789 char *c;
790#endif
791
792 sprom = kzalloc(BCM43xx_SPROM_SIZE * sizeof(u16),
793 GFP_KERNEL);
794 if (!sprom) {
795 printk(KERN_ERR PFX "sprom_extract OOM\n");
796 return -ENOMEM;
797 }
798#ifdef CONFIG_BCM947XX
799 sprom[BCM43xx_SPROM_BOARDFLAGS2] = atoi(nvram_get("boardflags2"));
800 sprom[BCM43xx_SPROM_BOARDFLAGS] = atoi(nvram_get("boardflags"));
801
802 if ((c = nvram_get("il0macaddr")) != NULL)
803 e_aton(c, (char *) &(sprom[BCM43xx_SPROM_IL0MACADDR]));
804
805 if ((c = nvram_get("et1macaddr")) != NULL)
806 e_aton(c, (char *) &(sprom[BCM43xx_SPROM_ET1MACADDR]));
807
808 sprom[BCM43xx_SPROM_PA0B0] = atoi(nvram_get("pa0b0"));
809 sprom[BCM43xx_SPROM_PA0B1] = atoi(nvram_get("pa0b1"));
810 sprom[BCM43xx_SPROM_PA0B2] = atoi(nvram_get("pa0b2"));
811
812 sprom[BCM43xx_SPROM_PA1B0] = atoi(nvram_get("pa1b0"));
813 sprom[BCM43xx_SPROM_PA1B1] = atoi(nvram_get("pa1b1"));
814 sprom[BCM43xx_SPROM_PA1B2] = atoi(nvram_get("pa1b2"));
815
816 sprom[BCM43xx_SPROM_BOARDREV] = atoi(nvram_get("boardrev"));
817#else
818 bcm43xx_sprom_read(bcm, sprom);
819#endif
820
821 /* boardflags2 */
822 value = sprom[BCM43xx_SPROM_BOARDFLAGS2];
823 bcm->sprom.boardflags2 = value;
824
825 /* il0macaddr */
826 value = sprom[BCM43xx_SPROM_IL0MACADDR + 0];
827 *(((u16 *)bcm->sprom.il0macaddr) + 0) = cpu_to_be16(value);
828 value = sprom[BCM43xx_SPROM_IL0MACADDR + 1];
829 *(((u16 *)bcm->sprom.il0macaddr) + 1) = cpu_to_be16(value);
830 value = sprom[BCM43xx_SPROM_IL0MACADDR + 2];
831 *(((u16 *)bcm->sprom.il0macaddr) + 2) = cpu_to_be16(value);
832
833 /* et0macaddr */
834 value = sprom[BCM43xx_SPROM_ET0MACADDR + 0];
835 *(((u16 *)bcm->sprom.et0macaddr) + 0) = cpu_to_be16(value);
836 value = sprom[BCM43xx_SPROM_ET0MACADDR + 1];
837 *(((u16 *)bcm->sprom.et0macaddr) + 1) = cpu_to_be16(value);
838 value = sprom[BCM43xx_SPROM_ET0MACADDR + 2];
839 *(((u16 *)bcm->sprom.et0macaddr) + 2) = cpu_to_be16(value);
840
841 /* et1macaddr */
842 value = sprom[BCM43xx_SPROM_ET1MACADDR + 0];
843 *(((u16 *)bcm->sprom.et1macaddr) + 0) = cpu_to_be16(value);
844 value = sprom[BCM43xx_SPROM_ET1MACADDR + 1];
845 *(((u16 *)bcm->sprom.et1macaddr) + 1) = cpu_to_be16(value);
846 value = sprom[BCM43xx_SPROM_ET1MACADDR + 2];
847 *(((u16 *)bcm->sprom.et1macaddr) + 2) = cpu_to_be16(value);
848
849 /* ethernet phy settings */
850 value = sprom[BCM43xx_SPROM_ETHPHY];
851 bcm->sprom.et0phyaddr = (value & 0x001F);
852 bcm->sprom.et1phyaddr = (value & 0x03E0) >> 5;
853 bcm->sprom.et0mdcport = (value & (1 << 14)) >> 14;
854 bcm->sprom.et1mdcport = (value & (1 << 15)) >> 15;
855
856 /* boardrev, antennas, locale */
857 value = sprom[BCM43xx_SPROM_BOARDREV];
858 bcm->sprom.boardrev = (value & 0x00FF);
859 bcm->sprom.locale = (value & 0x0F00) >> 8;
860 bcm->sprom.antennas_aphy = (value & 0x3000) >> 12;
861 bcm->sprom.antennas_bgphy = (value & 0xC000) >> 14;
862 if (modparam_locale != -1) {
863 if (modparam_locale >= 0 && modparam_locale <= 11) {
864 bcm->sprom.locale = modparam_locale;
865 printk(KERN_WARNING PFX "Operating with modified "
866 "LocaleCode %u (%s)\n",
867 bcm->sprom.locale,
868 bcm43xx_locale_string(bcm->sprom.locale));
869 } else {
870 printk(KERN_WARNING PFX "Module parameter \"locale\" "
871 "invalid value. (0 - 11)\n");
872 }
873 }
874
875 /* pa0b* */
876 value = sprom[BCM43xx_SPROM_PA0B0];
877 bcm->sprom.pa0b0 = value;
878 value = sprom[BCM43xx_SPROM_PA0B1];
879 bcm->sprom.pa0b1 = value;
880 value = sprom[BCM43xx_SPROM_PA0B2];
881 bcm->sprom.pa0b2 = value;
882
883 /* wl0gpio* */
884 value = sprom[BCM43xx_SPROM_WL0GPIO0];
885 if (value == 0x0000)
886 value = 0xFFFF;
887 bcm->sprom.wl0gpio0 = value & 0x00FF;
888 bcm->sprom.wl0gpio1 = (value & 0xFF00) >> 8;
889 value = sprom[BCM43xx_SPROM_WL0GPIO2];
890 if (value == 0x0000)
891 value = 0xFFFF;
892 bcm->sprom.wl0gpio2 = value & 0x00FF;
893 bcm->sprom.wl0gpio3 = (value & 0xFF00) >> 8;
894
895 /* maxpower */
896 value = sprom[BCM43xx_SPROM_MAXPWR];
897 bcm->sprom.maxpower_aphy = (value & 0xFF00) >> 8;
898 bcm->sprom.maxpower_bgphy = value & 0x00FF;
899
900 /* pa1b* */
901 value = sprom[BCM43xx_SPROM_PA1B0];
902 bcm->sprom.pa1b0 = value;
903 value = sprom[BCM43xx_SPROM_PA1B1];
904 bcm->sprom.pa1b1 = value;
905 value = sprom[BCM43xx_SPROM_PA1B2];
906 bcm->sprom.pa1b2 = value;
907
908 /* idle tssi target */
909 value = sprom[BCM43xx_SPROM_IDL_TSSI_TGT];
910 bcm->sprom.idle_tssi_tgt_aphy = value & 0x00FF;
911 bcm->sprom.idle_tssi_tgt_bgphy = (value & 0xFF00) >> 8;
912
913 /* boardflags */
914 value = sprom[BCM43xx_SPROM_BOARDFLAGS];
915 if (value == 0xFFFF)
916 value = 0x0000;
917 bcm->sprom.boardflags = value;
918 /* boardflags workarounds */
919 if (bcm->board_vendor == PCI_VENDOR_ID_DELL &&
920 bcm->chip_id == 0x4301 &&
921 bcm->board_revision == 0x74)
922 bcm->sprom.boardflags |= BCM43xx_BFL_BTCOEXIST;
923 if (bcm->board_vendor == PCI_VENDOR_ID_APPLE &&
924 bcm->board_type == 0x4E &&
925 bcm->board_revision > 0x40)
926 bcm->sprom.boardflags |= BCM43xx_BFL_PACTRL;
927
928 /* antenna gain */
929 value = sprom[BCM43xx_SPROM_ANTENNA_GAIN];
930 if (value == 0x0000 || value == 0xFFFF)
931 value = 0x0202;
932 /* convert values to Q5.2 */
933 bcm->sprom.antennagain_aphy = ((value & 0xFF00) >> 8) * 4;
934 bcm->sprom.antennagain_bgphy = (value & 0x00FF) * 4;
935
936 kfree(sprom);
937
938 return 0;
939}
940
941static void bcm43xx_geo_init(struct bcm43xx_private *bcm)
942{
943 struct ieee80211_geo geo;
944 struct ieee80211_channel *chan;
945 int have_a = 0, have_bg = 0;
946 int i;
947 u8 channel;
948 struct bcm43xx_phyinfo *phy;
949 const char *iso_country;
950
951 memset(&geo, 0, sizeof(geo));
952 for (i = 0; i < bcm->nr_80211_available; i++) {
953 phy = &(bcm->core_80211_ext[i].phy);
954 switch (phy->type) {
955 case BCM43xx_PHYTYPE_B:
956 case BCM43xx_PHYTYPE_G:
957 have_bg = 1;
958 break;
959 case BCM43xx_PHYTYPE_A:
960 have_a = 1;
961 break;
962 default:
963 assert(0);
964 }
965 }
966 iso_country = bcm43xx_locale_iso(bcm->sprom.locale);
967
968 if (have_a) {
969 for (i = 0, channel = 0; channel < 201; channel++) {
970 chan = &geo.a[i++];
971 chan->freq = bcm43xx_channel_to_freq_a(channel);
972 chan->channel = channel;
973 }
974 geo.a_channels = i;
975 }
976 if (have_bg) {
977 for (i = 0, channel = 1; channel < 15; channel++) {
978 chan = &geo.bg[i++];
979 chan->freq = bcm43xx_channel_to_freq_bg(channel);
980 chan->channel = channel;
981 }
982 geo.bg_channels = i;
983 }
984 memcpy(geo.name, iso_country, 2);
985 if (0 /*TODO: Outdoor use only */)
986 geo.name[2] = 'O';
987 else if (0 /*TODO: Indoor use only */)
988 geo.name[2] = 'I';
989 else
990 geo.name[2] = ' ';
991 geo.name[3] = '\0';
992
993 ieee80211_set_geo(bcm->ieee, &geo);
994}
995
996/* DummyTransmission function, as documented on
997 * http://bcm-specs.sipsolutions.net/DummyTransmission
998 */
999void bcm43xx_dummy_transmission(struct bcm43xx_private *bcm)
1000{
1001 struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
1002 struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm);
1003 unsigned int i, max_loop;
1004 u16 value = 0;
1005 u32 buffer[5] = {
1006 0x00000000,
1007 0x0000D400,
1008 0x00000000,
1009 0x00000001,
1010 0x00000000,
1011 };
1012
1013 switch (phy->type) {
1014 case BCM43xx_PHYTYPE_A:
1015 max_loop = 0x1E;
1016 buffer[0] = 0xCC010200;
1017 break;
1018 case BCM43xx_PHYTYPE_B:
1019 case BCM43xx_PHYTYPE_G:
1020 max_loop = 0xFA;
1021 buffer[0] = 0x6E840B00;
1022 break;
1023 default:
1024 assert(0);
1025 return;
1026 }
1027
1028 for (i = 0; i < 5; i++)
1029 bcm43xx_ram_write(bcm, i * 4, buffer[i]);
1030
1031 bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD); /* dummy read */
1032
1033 bcm43xx_write16(bcm, 0x0568, 0x0000);
1034 bcm43xx_write16(bcm, 0x07C0, 0x0000);
1035 bcm43xx_write16(bcm, 0x050C, ((phy->type == BCM43xx_PHYTYPE_A) ? 1 : 0));
1036 bcm43xx_write16(bcm, 0x0508, 0x0000);
1037 bcm43xx_write16(bcm, 0x050A, 0x0000);
1038 bcm43xx_write16(bcm, 0x054C, 0x0000);
1039 bcm43xx_write16(bcm, 0x056A, 0x0014);
1040 bcm43xx_write16(bcm, 0x0568, 0x0826);
1041 bcm43xx_write16(bcm, 0x0500, 0x0000);
1042 bcm43xx_write16(bcm, 0x0502, 0x0030);
1043
1044 if (radio->version == 0x2050 && radio->revision <= 0x5)
1045 bcm43xx_radio_write16(bcm, 0x0051, 0x0017);
1046 for (i = 0x00; i < max_loop; i++) {
1047 value = bcm43xx_read16(bcm, 0x050E);
1048 if (value & 0x0080)
1049 break;
1050 udelay(10);
1051 }
1052 for (i = 0x00; i < 0x0A; i++) {
1053 value = bcm43xx_read16(bcm, 0x050E);
1054 if (value & 0x0400)
1055 break;
1056 udelay(10);
1057 }
1058 for (i = 0x00; i < 0x0A; i++) {
1059 value = bcm43xx_read16(bcm, 0x0690);
1060 if (!(value & 0x0100))
1061 break;
1062 udelay(10);
1063 }
1064 if (radio->version == 0x2050 && radio->revision <= 0x5)
1065 bcm43xx_radio_write16(bcm, 0x0051, 0x0037);
1066}
1067
1068static void key_write(struct bcm43xx_private *bcm,
1069 u8 index, u8 algorithm, const u16 *key)
1070{
1071 unsigned int i, basic_wep = 0;
1072 u32 offset;
1073 u16 value;
1074
1075 /* Write associated key information */
1076 bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, 0x100 + (index * 2),
1077 ((index << 4) | (algorithm & 0x0F)));
1078
1079 /* The first 4 WEP keys need extra love */
1080 if (((algorithm == BCM43xx_SEC_ALGO_WEP) ||
1081 (algorithm == BCM43xx_SEC_ALGO_WEP104)) && (index < 4))
1082 basic_wep = 1;
1083
1084 /* Write key payload, 8 little endian words */
1085 offset = bcm->security_offset + (index * BCM43xx_SEC_KEYSIZE);
1086 for (i = 0; i < (BCM43xx_SEC_KEYSIZE / sizeof(u16)); i++) {
1087 value = cpu_to_le16(key[i]);
1088 bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED,
1089 offset + (i * 2), value);
1090
1091 if (!basic_wep)
1092 continue;
1093
1094 bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED,
1095 offset + (i * 2) + 4 * BCM43xx_SEC_KEYSIZE,
1096 value);
1097 }
1098}
1099
1100static void keymac_write(struct bcm43xx_private *bcm,
1101 u8 index, const u32 *addr)
1102{
1103 /* for keys 0-3 there is no associated mac address */
1104 if (index < 4)
1105 return;
1106
1107 index -= 4;
1108 if (bcm->current_core->rev >= 5) {
1109 bcm43xx_shm_write32(bcm,
1110 BCM43xx_SHM_HWMAC,
1111 index * 2,
1112 cpu_to_be32(*addr));
1113 bcm43xx_shm_write16(bcm,
1114 BCM43xx_SHM_HWMAC,
1115 (index * 2) + 1,
1116 cpu_to_be16(*((u16 *)(addr + 1))));
1117 } else {
1118 if (index < 8) {
1119 TODO(); /* Put them in the macaddress filter */
1120 } else {
1121 TODO();
1122 /* Put them BCM43xx_SHM_SHARED, stating index 0x0120.
1123 Keep in mind to update the count of keymacs in 0x003E as well! */
1124 }
1125 }
1126}
1127
1128static int bcm43xx_key_write(struct bcm43xx_private *bcm,
1129 u8 index, u8 algorithm,
1130 const u8 *_key, int key_len,
1131 const u8 *mac_addr)
1132{
1133 u8 key[BCM43xx_SEC_KEYSIZE] = { 0 };
1134
1135 if (index >= ARRAY_SIZE(bcm->key))
1136 return -EINVAL;
1137 if (key_len > ARRAY_SIZE(key))
1138 return -EINVAL;
1139 if (algorithm < 1 || algorithm > 5)
1140 return -EINVAL;
1141
1142 memcpy(key, _key, key_len);
1143 key_write(bcm, index, algorithm, (const u16 *)key);
1144 keymac_write(bcm, index, (const u32 *)mac_addr);
1145
1146 bcm->key[index].algorithm = algorithm;
1147
1148 return 0;
1149}
1150
1151static void bcm43xx_clear_keys(struct bcm43xx_private *bcm)
1152{
1153 static const u32 zero_mac[2] = { 0 };
1154 unsigned int i,j, nr_keys = 54;
1155 u16 offset;
1156
1157 if (bcm->current_core->rev < 5)
1158 nr_keys = 16;
1159 assert(nr_keys <= ARRAY_SIZE(bcm->key));
1160
1161 for (i = 0; i < nr_keys; i++) {
1162 bcm->key[i].enabled = 0;
1163 /* returns for i < 4 immediately */
1164 keymac_write(bcm, i, zero_mac);
1165 bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED,
1166 0x100 + (i * 2), 0x0000);
1167 for (j = 0; j < 8; j++) {
1168 offset = bcm->security_offset + (j * 4) + (i * BCM43xx_SEC_KEYSIZE);
1169 bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED,
1170 offset, 0x0000);
1171 }
1172 }
1173 dprintk(KERN_INFO PFX "Keys cleared\n");
1174}
1175
1176/* Lowlevel core-switch function. This is only to be used in
1177 * bcm43xx_switch_core() and bcm43xx_probe_cores()
1178 */
1179static int _switch_core(struct bcm43xx_private *bcm, int core)
1180{
1181 int err;
1182 int attempts = 0;
1183 u32 current_core;
1184
1185 assert(core >= 0);
1186 while (1) {
1187 err = bcm43xx_pci_write_config32(bcm, BCM43xx_PCICFG_ACTIVE_CORE,
1188 (core * 0x1000) + 0x18000000);
1189 if (unlikely(err))
1190 goto error;
1191 err = bcm43xx_pci_read_config32(bcm, BCM43xx_PCICFG_ACTIVE_CORE,
1192 &current_core);
1193 if (unlikely(err))
1194 goto error;
1195 current_core = (current_core - 0x18000000) / 0x1000;
1196 if (current_core == core)
1197 break;
1198
1199 if (unlikely(attempts++ > BCM43xx_SWITCH_CORE_MAX_RETRIES))
1200 goto error;
1201 udelay(10);
1202 }
1203#ifdef CONFIG_BCM947XX
1204 if (bcm->pci_dev->bus->number == 0)
1205 bcm->current_core_offset = 0x1000 * core;
1206 else
1207 bcm->current_core_offset = 0;
1208#endif
1209
1210 return 0;
1211error:
1212 printk(KERN_ERR PFX "Failed to switch to core %d\n", core);
1213 return -ENODEV;
1214}
1215
1216int bcm43xx_switch_core(struct bcm43xx_private *bcm, struct bcm43xx_coreinfo *new_core)
1217{
1218 int err;
1219
1220 if (unlikely(!new_core))
1221 return 0;
1222 if (!new_core->available)
1223 return -ENODEV;
1224 if (bcm->current_core == new_core)
1225 return 0;
1226 err = _switch_core(bcm, new_core->index);
1227 if (unlikely(err))
1228 goto out;
1229
1230 bcm->current_core = new_core;
1231 bcm->current_80211_core_idx = -1;
1232 if (new_core->id == BCM43xx_COREID_80211)
1233 bcm->current_80211_core_idx = (int)(new_core - &(bcm->core_80211[0]));
1234
1235out:
1236 return err;
1237}
1238
1239static int bcm43xx_core_enabled(struct bcm43xx_private *bcm)
1240{
1241 u32 value;
1242
1243 value = bcm43xx_read32(bcm, BCM43xx_CIR_SBTMSTATELOW);
1244 value &= BCM43xx_SBTMSTATELOW_CLOCK | BCM43xx_SBTMSTATELOW_RESET
1245 | BCM43xx_SBTMSTATELOW_REJECT;
1246
1247 return (value == BCM43xx_SBTMSTATELOW_CLOCK);
1248}
1249
1250/* disable current core */
1251static int bcm43xx_core_disable(struct bcm43xx_private *bcm, u32 core_flags)
1252{
1253 u32 sbtmstatelow;
1254 u32 sbtmstatehigh;
1255 int i;
1256
1257 /* fetch sbtmstatelow from core information registers */
1258 sbtmstatelow = bcm43xx_read32(bcm, BCM43xx_CIR_SBTMSTATELOW);
1259
1260 /* core is already in reset */
1261 if (sbtmstatelow & BCM43xx_SBTMSTATELOW_RESET)
1262 goto out;
1263
1264 if (sbtmstatelow & BCM43xx_SBTMSTATELOW_CLOCK) {
1265 sbtmstatelow = BCM43xx_SBTMSTATELOW_CLOCK |
1266 BCM43xx_SBTMSTATELOW_REJECT;
1267 bcm43xx_write32(bcm, BCM43xx_CIR_SBTMSTATELOW, sbtmstatelow);
1268
1269 for (i = 0; i < 1000; i++) {
1270 sbtmstatelow = bcm43xx_read32(bcm, BCM43xx_CIR_SBTMSTATELOW);
1271 if (sbtmstatelow & BCM43xx_SBTMSTATELOW_REJECT) {
1272 i = -1;
1273 break;
1274 }
1275 udelay(10);
1276 }
1277 if (i != -1) {
1278 printk(KERN_ERR PFX "Error: core_disable() REJECT timeout!\n");
1279 return -EBUSY;
1280 }
1281
1282 for (i = 0; i < 1000; i++) {
1283 sbtmstatehigh = bcm43xx_read32(bcm, BCM43xx_CIR_SBTMSTATEHIGH);
1284 if (!(sbtmstatehigh & BCM43xx_SBTMSTATEHIGH_BUSY)) {
1285 i = -1;
1286 break;
1287 }
1288 udelay(10);
1289 }
1290 if (i != -1) {
1291 printk(KERN_ERR PFX "Error: core_disable() BUSY timeout!\n");
1292 return -EBUSY;
1293 }
1294
1295 sbtmstatelow = BCM43xx_SBTMSTATELOW_FORCE_GATE_CLOCK |
1296 BCM43xx_SBTMSTATELOW_REJECT |
1297 BCM43xx_SBTMSTATELOW_RESET |
1298 BCM43xx_SBTMSTATELOW_CLOCK |
1299 core_flags;
1300 bcm43xx_write32(bcm, BCM43xx_CIR_SBTMSTATELOW, sbtmstatelow);
1301 udelay(10);
1302 }
1303
1304 sbtmstatelow = BCM43xx_SBTMSTATELOW_RESET |
1305 BCM43xx_SBTMSTATELOW_REJECT |
1306 core_flags;
1307 bcm43xx_write32(bcm, BCM43xx_CIR_SBTMSTATELOW, sbtmstatelow);
1308
1309out:
1310 bcm->current_core->enabled = 0;
1311
1312 return 0;
1313}
1314
1315/* enable (reset) current core */
1316static int bcm43xx_core_enable(struct bcm43xx_private *bcm, u32 core_flags)
1317{
1318 u32 sbtmstatelow;
1319 u32 sbtmstatehigh;
1320 u32 sbimstate;
1321 int err;
1322
1323 err = bcm43xx_core_disable(bcm, core_flags);
1324 if (err)
1325 goto out;
1326
1327 sbtmstatelow = BCM43xx_SBTMSTATELOW_CLOCK |
1328 BCM43xx_SBTMSTATELOW_RESET |
1329 BCM43xx_SBTMSTATELOW_FORCE_GATE_CLOCK |
1330 core_flags;
1331 bcm43xx_write32(bcm, BCM43xx_CIR_SBTMSTATELOW, sbtmstatelow);
1332 udelay(1);
1333
1334 sbtmstatehigh = bcm43xx_read32(bcm, BCM43xx_CIR_SBTMSTATEHIGH);
1335 if (sbtmstatehigh & BCM43xx_SBTMSTATEHIGH_SERROR) {
1336 sbtmstatehigh = 0x00000000;
1337 bcm43xx_write32(bcm, BCM43xx_CIR_SBTMSTATEHIGH, sbtmstatehigh);
1338 }
1339
1340 sbimstate = bcm43xx_read32(bcm, BCM43xx_CIR_SBIMSTATE);
1341 if (sbimstate & (BCM43xx_SBIMSTATE_IB_ERROR | BCM43xx_SBIMSTATE_TIMEOUT)) {
1342 sbimstate &= ~(BCM43xx_SBIMSTATE_IB_ERROR | BCM43xx_SBIMSTATE_TIMEOUT);
1343 bcm43xx_write32(bcm, BCM43xx_CIR_SBIMSTATE, sbimstate);
1344 }
1345
1346 sbtmstatelow = BCM43xx_SBTMSTATELOW_CLOCK |
1347 BCM43xx_SBTMSTATELOW_FORCE_GATE_CLOCK |
1348 core_flags;
1349 bcm43xx_write32(bcm, BCM43xx_CIR_SBTMSTATELOW, sbtmstatelow);
1350 udelay(1);
1351
1352 sbtmstatelow = BCM43xx_SBTMSTATELOW_CLOCK | core_flags;
1353 bcm43xx_write32(bcm, BCM43xx_CIR_SBTMSTATELOW, sbtmstatelow);
1354 udelay(1);
1355
1356 bcm->current_core->enabled = 1;
1357 assert(err == 0);
1358out:
1359 return err;
1360}
1361
1362/* http://bcm-specs.sipsolutions.net/80211CoreReset */
1363void bcm43xx_wireless_core_reset(struct bcm43xx_private *bcm, int connect_phy)
1364{
1365 u32 flags = 0x00040000;
1366
1367 if ((bcm43xx_core_enabled(bcm)) &&
1368 !bcm43xx_using_pio(bcm)) {
1369//FIXME: Do we _really_ want #ifndef CONFIG_BCM947XX here?
1370#ifndef CONFIG_BCM947XX
1371 /* reset all used DMA controllers. */
1372 bcm43xx_dmacontroller_tx_reset(bcm, BCM43xx_MMIO_DMA1_BASE);
1373 bcm43xx_dmacontroller_tx_reset(bcm, BCM43xx_MMIO_DMA2_BASE);
1374 bcm43xx_dmacontroller_tx_reset(bcm, BCM43xx_MMIO_DMA3_BASE);
1375 bcm43xx_dmacontroller_tx_reset(bcm, BCM43xx_MMIO_DMA4_BASE);
1376 bcm43xx_dmacontroller_rx_reset(bcm, BCM43xx_MMIO_DMA1_BASE);
1377 if (bcm->current_core->rev < 5)
1378 bcm43xx_dmacontroller_rx_reset(bcm, BCM43xx_MMIO_DMA4_BASE);
1379#endif
1380 }
1381 if (bcm->shutting_down) {
1382 bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD,
1383 bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD)
1384 & ~(BCM43xx_SBF_MAC_ENABLED | 0x00000002));
1385 } else {
1386 if (connect_phy)
1387 flags |= 0x20000000;
1388 bcm43xx_phy_connect(bcm, connect_phy);
1389 bcm43xx_core_enable(bcm, flags);
1390 bcm43xx_write16(bcm, 0x03E6, 0x0000);
1391 bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD,
1392 bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD)
1393 | BCM43xx_SBF_400);
1394 }
1395}
1396
1397static void bcm43xx_wireless_core_disable(struct bcm43xx_private *bcm)
1398{
1399 bcm43xx_radio_turn_off(bcm);
1400 bcm43xx_write16(bcm, 0x03E6, 0x00F4);
1401 bcm43xx_core_disable(bcm, 0);
1402}
1403
1404/* Mark the current 80211 core inactive.
1405 * "active_80211_core" is the other 80211 core, which is used.
1406 */
1407static int bcm43xx_wireless_core_mark_inactive(struct bcm43xx_private *bcm,
1408 struct bcm43xx_coreinfo *active_80211_core)
1409{
1410 u32 sbtmstatelow;
1411 struct bcm43xx_coreinfo *old_core;
1412 int err = 0;
1413
1414 bcm43xx_interrupt_disable(bcm, BCM43xx_IRQ_ALL);
1415 bcm43xx_radio_turn_off(bcm);
1416 sbtmstatelow = bcm43xx_read32(bcm, BCM43xx_CIR_SBTMSTATELOW);
1417 sbtmstatelow &= ~0x200a0000;
1418 sbtmstatelow |= 0xa0000;
1419 bcm43xx_write32(bcm, BCM43xx_CIR_SBTMSTATELOW, sbtmstatelow);
1420 udelay(1);
1421 sbtmstatelow = bcm43xx_read32(bcm, BCM43xx_CIR_SBTMSTATELOW);
1422 sbtmstatelow &= ~0xa0000;
1423 sbtmstatelow |= 0x80000;
1424 bcm43xx_write32(bcm, BCM43xx_CIR_SBTMSTATELOW, sbtmstatelow);
1425 udelay(1);
1426
1427 if (bcm43xx_current_phy(bcm)->type == BCM43xx_PHYTYPE_G) {
1428 old_core = bcm->current_core;
1429 err = bcm43xx_switch_core(bcm, active_80211_core);
1430 if (err)
1431 goto out;
1432 sbtmstatelow = bcm43xx_read32(bcm, BCM43xx_CIR_SBTMSTATELOW);
1433 sbtmstatelow &= ~0x20000000;
1434 sbtmstatelow |= 0x20000000;
1435 bcm43xx_write32(bcm, BCM43xx_CIR_SBTMSTATELOW, sbtmstatelow);
1436 err = bcm43xx_switch_core(bcm, old_core);
1437 }
1438
1439out:
1440 return err;
1441}
1442
1443static void handle_irq_transmit_status(struct bcm43xx_private *bcm)
1444{
1445 u32 v0, v1;
1446 u16 tmp;
1447 struct bcm43xx_xmitstatus stat;
1448
1449 while (1) {
1450 v0 = bcm43xx_read32(bcm, BCM43xx_MMIO_XMITSTAT_0);
1451 if (!v0)
1452 break;
1453 v1 = bcm43xx_read32(bcm, BCM43xx_MMIO_XMITSTAT_1);
1454
1455 stat.cookie = (v0 >> 16) & 0x0000FFFF;
1456 tmp = (u16)((v0 & 0xFFF0) | ((v0 & 0xF) >> 1));
1457 stat.flags = tmp & 0xFF;
1458 stat.cnt1 = (tmp & 0x0F00) >> 8;
1459 stat.cnt2 = (tmp & 0xF000) >> 12;
1460 stat.seq = (u16)(v1 & 0xFFFF);
1461 stat.unknown = (u16)((v1 >> 16) & 0xFF);
1462
1463 bcm43xx_debugfs_log_txstat(bcm, &stat);
1464
1465 if (stat.flags & BCM43xx_TXSTAT_FLAG_IGNORE)
1466 continue;
1467 if (!(stat.flags & BCM43xx_TXSTAT_FLAG_ACK)) {
1468 //TODO: packet was not acked (was lost)
1469 }
1470 //TODO: There are more (unknown) flags to test. see bcm43xx_main.h
1471
1472 if (bcm43xx_using_pio(bcm))
1473 bcm43xx_pio_handle_xmitstatus(bcm, &stat);
1474 else
1475 bcm43xx_dma_handle_xmitstatus(bcm, &stat);
1476 }
1477}
1478
1479static void bcm43xx_generate_noise_sample(struct bcm43xx_private *bcm)
1480{
1481 bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, 0x408, 0x7F7F);
1482 bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, 0x40A, 0x7F7F);
1483 bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS2_BITFIELD,
1484 bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS2_BITFIELD) | (1 << 4));
1485 assert(bcm->noisecalc.core_at_start == bcm->current_core);
1486 assert(bcm->noisecalc.channel_at_start == bcm43xx_current_radio(bcm)->channel);
1487}
1488
1489static void bcm43xx_calculate_link_quality(struct bcm43xx_private *bcm)
1490{
1491 /* Top half of Link Quality calculation. */
1492
1493 if (bcm->noisecalc.calculation_running)
1494 return;
1495 bcm->noisecalc.core_at_start = bcm->current_core;
1496 bcm->noisecalc.channel_at_start = bcm43xx_current_radio(bcm)->channel;
1497 bcm->noisecalc.calculation_running = 1;
1498 bcm->noisecalc.nr_samples = 0;
1499
1500 bcm43xx_generate_noise_sample(bcm);
1501}
1502
1503static void handle_irq_noise(struct bcm43xx_private *bcm)
1504{
1505 struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm);
1506 u16 tmp;
1507 u8 noise[4];
1508 u8 i, j;
1509 s32 average;
1510
1511 /* Bottom half of Link Quality calculation. */
1512
1513 assert(bcm->noisecalc.calculation_running);
1514 if (bcm->noisecalc.core_at_start != bcm->current_core ||
1515 bcm->noisecalc.channel_at_start != radio->channel)
1516 goto drop_calculation;
1517 tmp = bcm43xx_shm_read16(bcm, BCM43xx_SHM_SHARED, 0x408);
1518 noise[0] = (tmp & 0x00FF);
1519 noise[1] = (tmp & 0xFF00) >> 8;
1520 tmp = bcm43xx_shm_read16(bcm, BCM43xx_SHM_SHARED, 0x40A);
1521 noise[2] = (tmp & 0x00FF);
1522 noise[3] = (tmp & 0xFF00) >> 8;
1523 if (noise[0] == 0x7F || noise[1] == 0x7F ||
1524 noise[2] == 0x7F || noise[3] == 0x7F)
1525 goto generate_new;
1526
1527 /* Get the noise samples. */
1528 assert(bcm->noisecalc.nr_samples <= 8);
1529 i = bcm->noisecalc.nr_samples;
1530 noise[0] = limit_value(noise[0], 0, ARRAY_SIZE(radio->nrssi_lt) - 1);
1531 noise[1] = limit_value(noise[1], 0, ARRAY_SIZE(radio->nrssi_lt) - 1);
1532 noise[2] = limit_value(noise[2], 0, ARRAY_SIZE(radio->nrssi_lt) - 1);
1533 noise[3] = limit_value(noise[3], 0, ARRAY_SIZE(radio->nrssi_lt) - 1);
1534 bcm->noisecalc.samples[i][0] = radio->nrssi_lt[noise[0]];
1535 bcm->noisecalc.samples[i][1] = radio->nrssi_lt[noise[1]];
1536 bcm->noisecalc.samples[i][2] = radio->nrssi_lt[noise[2]];
1537 bcm->noisecalc.samples[i][3] = radio->nrssi_lt[noise[3]];
1538 bcm->noisecalc.nr_samples++;
1539 if (bcm->noisecalc.nr_samples == 8) {
1540 /* Calculate the Link Quality by the noise samples. */
1541 average = 0;
1542 for (i = 0; i < 8; i++) {
1543 for (j = 0; j < 4; j++)
1544 average += bcm->noisecalc.samples[i][j];
1545 }
1546 average /= (8 * 4);
1547 average *= 125;
1548 average += 64;
1549 average /= 128;
1550
1551 tmp = bcm43xx_shm_read16(bcm, BCM43xx_SHM_SHARED, 0x40C);
1552 tmp = (tmp / 128) & 0x1F;
1553 if (tmp >= 8)
1554 average += 2;
1555 else
1556 average -= 25;
1557 if (tmp == 8)
1558 average -= 72;
1559 else
1560 average -= 48;
1561
1562/* FIXME: This is wrong, but people want fancy stats. well... */
1563bcm->stats.noise = average;
1564 if (average > -65)
1565 bcm->stats.link_quality = 0;
1566 else if (average > -75)
1567 bcm->stats.link_quality = 1;
1568 else if (average > -85)
1569 bcm->stats.link_quality = 2;
1570 else
1571 bcm->stats.link_quality = 3;
1572// dprintk(KERN_INFO PFX "Link Quality: %u (avg was %d)\n", bcm->stats.link_quality, average);
1573drop_calculation:
1574 bcm->noisecalc.calculation_running = 0;
1575 return;
1576 }
1577generate_new:
1578 bcm43xx_generate_noise_sample(bcm);
1579}
1580
1581static void handle_irq_ps(struct bcm43xx_private *bcm)
1582{
1583 if (bcm->ieee->iw_mode == IW_MODE_MASTER) {
1584 ///TODO: PS TBTT
1585 } else {
1586 if (1/*FIXME: the last PSpoll frame was sent successfully */)
1587 bcm43xx_power_saving_ctl_bits(bcm, -1, -1);
1588 }
1589 if (bcm->ieee->iw_mode == IW_MODE_ADHOC)
1590 bcm->reg124_set_0x4 = 1;
1591 //FIXME else set to false?
1592}
1593
1594static void handle_irq_reg124(struct bcm43xx_private *bcm)
1595{
1596 if (!bcm->reg124_set_0x4)
1597 return;
1598 bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS2_BITFIELD,
1599 bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS2_BITFIELD)
1600 | 0x4);
1601 //FIXME: reset reg124_set_0x4 to false?
1602}
1603
1604static void handle_irq_pmq(struct bcm43xx_private *bcm)
1605{
1606 u32 tmp;
1607
1608 //TODO: AP mode.
1609
1610 while (1) {
1611 tmp = bcm43xx_read32(bcm, BCM43xx_MMIO_PS_STATUS);
1612 if (!(tmp & 0x00000008))
1613 break;
1614 }
1615 /* 16bit write is odd, but correct. */
1616 bcm43xx_write16(bcm, BCM43xx_MMIO_PS_STATUS, 0x0002);
1617}
1618
1619static void bcm43xx_generate_beacon_template(struct bcm43xx_private *bcm,
1620 u16 ram_offset, u16 shm_size_offset)
1621{
1622 u32 value;
1623 u16 size = 0;
1624
1625 /* Timestamp. */
1626 //FIXME: assumption: The chip sets the timestamp
1627 value = 0;
1628 bcm43xx_ram_write(bcm, ram_offset++, value);
1629 bcm43xx_ram_write(bcm, ram_offset++, value);
1630 size += 8;
1631
1632 /* Beacon Interval / Capability Information */
1633 value = 0x0000;//FIXME: Which interval?
1634 value |= (1 << 0) << 16; /* ESS */
1635 value |= (1 << 2) << 16; /* CF Pollable */ //FIXME?
1636 value |= (1 << 3) << 16; /* CF Poll Request */ //FIXME?
1637 if (!bcm->ieee->open_wep)
1638 value |= (1 << 4) << 16; /* Privacy */
1639 bcm43xx_ram_write(bcm, ram_offset++, value);
1640 size += 4;
1641
1642 /* SSID */
1643 //TODO
1644
1645 /* FH Parameter Set */
1646 //TODO
1647
1648 /* DS Parameter Set */
1649 //TODO
1650
1651 /* CF Parameter Set */
1652 //TODO
1653
1654 /* TIM */
1655 //TODO
1656
1657 bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, shm_size_offset, size);
1658}
1659
1660static void handle_irq_beacon(struct bcm43xx_private *bcm)
1661{
1662 u32 status;
1663
1664 bcm->irq_savedstate &= ~BCM43xx_IRQ_BEACON;
1665 status = bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS2_BITFIELD);
1666
1667 if ((status & 0x1) && (status & 0x2)) {
1668 /* ACK beacon IRQ. */
1669 bcm43xx_write32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON,
1670 BCM43xx_IRQ_BEACON);
1671 bcm->irq_savedstate |= BCM43xx_IRQ_BEACON;
1672 return;
1673 }
1674 if (!(status & 0x1)) {
1675 bcm43xx_generate_beacon_template(bcm, 0x68, 0x18);
1676 status |= 0x1;
1677 bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS2_BITFIELD, status);
1678 }
1679 if (!(status & 0x2)) {
1680 bcm43xx_generate_beacon_template(bcm, 0x468, 0x1A);
1681 status |= 0x2;
1682 bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS2_BITFIELD, status);
1683 }
1684}
1685
1686/* Interrupt handler bottom-half */
1687static void bcm43xx_interrupt_tasklet(struct bcm43xx_private *bcm)
1688{
1689 u32 reason;
1690 u32 dma_reason[4];
1691 int activity = 0;
1692 unsigned long flags;
1693
1694#ifdef CONFIG_BCM43XX_DEBUG
1695 u32 _handled = 0x00000000;
1696# define bcmirq_handled(irq) do { _handled |= (irq); } while (0)
1697#else
1698# define bcmirq_handled(irq) do { /* nothing */ } while (0)
1699#endif /* CONFIG_BCM43XX_DEBUG*/
1700
1701 bcm43xx_lock_mmio(bcm, flags);
1702 reason = bcm->irq_reason;
1703 dma_reason[0] = bcm->dma_reason[0];
1704 dma_reason[1] = bcm->dma_reason[1];
1705 dma_reason[2] = bcm->dma_reason[2];
1706 dma_reason[3] = bcm->dma_reason[3];
1707
1708 if (unlikely(reason & BCM43xx_IRQ_XMIT_ERROR)) {
1709 /* TX error. We get this when Template Ram is written in wrong endianess
1710 * in dummy_tx(). We also get this if something is wrong with the TX header
1711 * on DMA or PIO queues.
1712 * Maybe we get this in other error conditions, too.
1713 */
1714 printkl(KERN_ERR PFX "FATAL ERROR: BCM43xx_IRQ_XMIT_ERROR\n");
1715 bcmirq_handled(BCM43xx_IRQ_XMIT_ERROR);
1716 }
1717 if (unlikely((dma_reason[0] & BCM43xx_DMAIRQ_FATALMASK) |
1718 (dma_reason[1] & BCM43xx_DMAIRQ_FATALMASK) |
1719 (dma_reason[2] & BCM43xx_DMAIRQ_FATALMASK) |
1720 (dma_reason[3] & BCM43xx_DMAIRQ_FATALMASK))) {
1721 printkl(KERN_ERR PFX "FATAL ERROR: Fatal DMA error: "
1722 "0x%08X, 0x%08X, 0x%08X, 0x%08X\n",
1723 dma_reason[0], dma_reason[1],
1724 dma_reason[2], dma_reason[3]);
1725 bcm43xx_controller_restart(bcm, "DMA error");
1726 bcm43xx_unlock_mmio(bcm, flags);
1727 return;
1728 }
1729 if (unlikely((dma_reason[0] & BCM43xx_DMAIRQ_NONFATALMASK) |
1730 (dma_reason[1] & BCM43xx_DMAIRQ_NONFATALMASK) |
1731 (dma_reason[2] & BCM43xx_DMAIRQ_NONFATALMASK) |
1732 (dma_reason[3] & BCM43xx_DMAIRQ_NONFATALMASK))) {
1733 printkl(KERN_ERR PFX "DMA error: "
1734 "0x%08X, 0x%08X, 0x%08X, 0x%08X\n",
1735 dma_reason[0], dma_reason[1],
1736 dma_reason[2], dma_reason[3]);
1737 }
1738
1739 if (reason & BCM43xx_IRQ_PS) {
1740 handle_irq_ps(bcm);
1741 bcmirq_handled(BCM43xx_IRQ_PS);
1742 }
1743
1744 if (reason & BCM43xx_IRQ_REG124) {
1745 handle_irq_reg124(bcm);
1746 bcmirq_handled(BCM43xx_IRQ_REG124);
1747 }
1748
1749 if (reason & BCM43xx_IRQ_BEACON) {
1750 if (bcm->ieee->iw_mode == IW_MODE_MASTER)
1751 handle_irq_beacon(bcm);
1752 bcmirq_handled(BCM43xx_IRQ_BEACON);
1753 }
1754
1755 if (reason & BCM43xx_IRQ_PMQ) {
1756 handle_irq_pmq(bcm);
1757 bcmirq_handled(BCM43xx_IRQ_PMQ);
1758 }
1759
1760 if (reason & BCM43xx_IRQ_SCAN) {
1761 /*TODO*/
1762 //bcmirq_handled(BCM43xx_IRQ_SCAN);
1763 }
1764
1765 if (reason & BCM43xx_IRQ_NOISE) {
1766 handle_irq_noise(bcm);
1767 bcmirq_handled(BCM43xx_IRQ_NOISE);
1768 }
1769
1770 /* Check the DMA reason registers for received data. */
1771 assert(!(dma_reason[1] & BCM43xx_DMAIRQ_RX_DONE));
1772 assert(!(dma_reason[2] & BCM43xx_DMAIRQ_RX_DONE));
1773 if (dma_reason[0] & BCM43xx_DMAIRQ_RX_DONE) {
1774 if (bcm43xx_using_pio(bcm))
1775 bcm43xx_pio_rx(bcm43xx_current_pio(bcm)->queue0);
1776 else
1777 bcm43xx_dma_rx(bcm43xx_current_dma(bcm)->rx_ring0);
1778 /* We intentionally don't set "activity" to 1, here. */
1779 }
1780 if (dma_reason[3] & BCM43xx_DMAIRQ_RX_DONE) {
1781 if (bcm43xx_using_pio(bcm))
1782 bcm43xx_pio_rx(bcm43xx_current_pio(bcm)->queue3);
1783 else
1784 bcm43xx_dma_rx(bcm43xx_current_dma(bcm)->rx_ring1);
1785 activity = 1;
1786 }
1787 bcmirq_handled(BCM43xx_IRQ_RX);
1788
1789 if (reason & BCM43xx_IRQ_XMIT_STATUS) {
1790 handle_irq_transmit_status(bcm);
1791 activity = 1;
1792 //TODO: In AP mode, this also causes sending of powersave responses.
1793 bcmirq_handled(BCM43xx_IRQ_XMIT_STATUS);
1794 }
1795
1796 /* IRQ_PIO_WORKAROUND is handled in the top-half. */
1797 bcmirq_handled(BCM43xx_IRQ_PIO_WORKAROUND);
1798#ifdef CONFIG_BCM43XX_DEBUG
1799 if (unlikely(reason & ~_handled)) {
1800 printkl(KERN_WARNING PFX
1801 "Unhandled IRQ! Reason: 0x%08x, Unhandled: 0x%08x, "
1802 "DMA: 0x%08x, 0x%08x, 0x%08x, 0x%08x\n",
1803 reason, (reason & ~_handled),
1804 dma_reason[0], dma_reason[1],
1805 dma_reason[2], dma_reason[3]);
1806 }
1807#endif
1808#undef bcmirq_handled
1809
1810 if (!modparam_noleds)
1811 bcm43xx_leds_update(bcm, activity);
1812 bcm43xx_interrupt_enable(bcm, bcm->irq_savedstate);
1813 bcm43xx_unlock_mmio(bcm, flags);
1814}
1815
1816static void pio_irq_workaround(struct bcm43xx_private *bcm,
1817 u16 base, int queueidx)
1818{
1819 u16 rxctl;
1820
1821 rxctl = bcm43xx_read16(bcm, base + BCM43xx_PIO_RXCTL);
1822 if (rxctl & BCM43xx_PIO_RXCTL_DATAAVAILABLE)
1823 bcm->dma_reason[queueidx] |= BCM43xx_DMAIRQ_RX_DONE;
1824 else
1825 bcm->dma_reason[queueidx] &= ~BCM43xx_DMAIRQ_RX_DONE;
1826}
1827
1828static void bcm43xx_interrupt_ack(struct bcm43xx_private *bcm, u32 reason)
1829{
1830 if (bcm43xx_using_pio(bcm) &&
1831 (bcm->current_core->rev < 3) &&
1832 (!(reason & BCM43xx_IRQ_PIO_WORKAROUND))) {
1833 /* Apply a PIO specific workaround to the dma_reasons */
1834 pio_irq_workaround(bcm, BCM43xx_MMIO_PIO1_BASE, 0);
1835 pio_irq_workaround(bcm, BCM43xx_MMIO_PIO2_BASE, 1);
1836 pio_irq_workaround(bcm, BCM43xx_MMIO_PIO3_BASE, 2);
1837 pio_irq_workaround(bcm, BCM43xx_MMIO_PIO4_BASE, 3);
1838 }
1839
1840 bcm43xx_write32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON, reason);
1841
1842 bcm43xx_write32(bcm, BCM43xx_MMIO_DMA1_REASON,
1843 bcm->dma_reason[0]);
1844 bcm43xx_write32(bcm, BCM43xx_MMIO_DMA2_REASON,
1845 bcm->dma_reason[1]);
1846 bcm43xx_write32(bcm, BCM43xx_MMIO_DMA3_REASON,
1847 bcm->dma_reason[2]);
1848 bcm43xx_write32(bcm, BCM43xx_MMIO_DMA4_REASON,
1849 bcm->dma_reason[3]);
1850}
1851
1852/* Interrupt handler top-half */
1853static irqreturn_t bcm43xx_interrupt_handler(int irq, void *dev_id, struct pt_regs *regs)
1854{
1855 irqreturn_t ret = IRQ_HANDLED;
1856 struct bcm43xx_private *bcm = dev_id;
1857 u32 reason;
1858
1859 if (!bcm)
1860 return IRQ_NONE;
1861
1862 spin_lock(&bcm->_lock);
1863
1864 reason = bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON);
1865 if (reason == 0xffffffff) {
1866 /* irq not for us (shared irq) */
1867 ret = IRQ_NONE;
1868 goto out;
1869 }
1870 reason &= bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_MASK);
1871 if (!reason)
1872 goto out;
1873
1874 bcm->dma_reason[0] = bcm43xx_read32(bcm, BCM43xx_MMIO_DMA1_REASON)
1875 & 0x0001dc00;
1876 bcm->dma_reason[1] = bcm43xx_read32(bcm, BCM43xx_MMIO_DMA2_REASON)
1877 & 0x0000dc00;
1878 bcm->dma_reason[2] = bcm43xx_read32(bcm, BCM43xx_MMIO_DMA3_REASON)
1879 & 0x0000dc00;
1880 bcm->dma_reason[3] = bcm43xx_read32(bcm, BCM43xx_MMIO_DMA4_REASON)
1881 & 0x0001dc00;
1882
1883 bcm43xx_interrupt_ack(bcm, reason);
1884
1885 /* Only accept IRQs, if we are initialized properly.
1886 * This avoids an RX race while initializing.
1887 * We should probably not enable IRQs before we are initialized
1888 * completely, but some careful work is needed to fix this. I think it
1889 * is best to stay with this cheap workaround for now... .
1890 */
1891 if (likely(bcm->initialized)) {
1892 /* disable all IRQs. They are enabled again in the bottom half. */
1893 bcm->irq_savedstate = bcm43xx_interrupt_disable(bcm, BCM43xx_IRQ_ALL);
1894 /* save the reason code and call our bottom half. */
1895 bcm->irq_reason = reason;
1896 tasklet_schedule(&bcm->isr_tasklet);
1897 }
1898
1899out:
1900 mmiowb();
1901 spin_unlock(&bcm->_lock);
1902
1903 return ret;
1904}
1905
1906static void bcm43xx_release_firmware(struct bcm43xx_private *bcm, int force)
1907{
1908 if (bcm->firmware_norelease && !force)
1909 return; /* Suspending or controller reset. */
1910 release_firmware(bcm->ucode);
1911 bcm->ucode = NULL;
1912 release_firmware(bcm->pcm);
1913 bcm->pcm = NULL;
1914 release_firmware(bcm->initvals0);
1915 bcm->initvals0 = NULL;
1916 release_firmware(bcm->initvals1);
1917 bcm->initvals1 = NULL;
1918}
1919
1920static int bcm43xx_request_firmware(struct bcm43xx_private *bcm)
1921{
1922 struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
1923 u8 rev = bcm->current_core->rev;
1924 int err = 0;
1925 int nr;
1926 char buf[22 + sizeof(modparam_fwpostfix) - 1] = { 0 };
1927
1928 if (!bcm->ucode) {
1929 snprintf(buf, ARRAY_SIZE(buf), "bcm43xx_microcode%d%s.fw",
1930 (rev >= 5 ? 5 : rev),
1931 modparam_fwpostfix);
1932 err = request_firmware(&bcm->ucode, buf, &bcm->pci_dev->dev);
1933 if (err) {
1934 printk(KERN_ERR PFX
1935 "Error: Microcode \"%s\" not available or load failed.\n",
1936 buf);
1937 goto error;
1938 }
1939 }
1940
1941 if (!bcm->pcm) {
1942 snprintf(buf, ARRAY_SIZE(buf),
1943 "bcm43xx_pcm%d%s.fw",
1944 (rev < 5 ? 4 : 5),
1945 modparam_fwpostfix);
1946 err = request_firmware(&bcm->pcm, buf, &bcm->pci_dev->dev);
1947 if (err) {
1948 printk(KERN_ERR PFX
1949 "Error: PCM \"%s\" not available or load failed.\n",
1950 buf);
1951 goto error;
1952 }
1953 }
1954
1955 if (!bcm->initvals0) {
1956 if (rev == 2 || rev == 4) {
1957 switch (phy->type) {
1958 case BCM43xx_PHYTYPE_A:
1959 nr = 3;
1960 break;
1961 case BCM43xx_PHYTYPE_B:
1962 case BCM43xx_PHYTYPE_G:
1963 nr = 1;
1964 break;
1965 default:
1966 goto err_noinitval;
1967 }
1968
1969 } else if (rev >= 5) {
1970 switch (phy->type) {
1971 case BCM43xx_PHYTYPE_A:
1972 nr = 7;
1973 break;
1974 case BCM43xx_PHYTYPE_B:
1975 case BCM43xx_PHYTYPE_G:
1976 nr = 5;
1977 break;
1978 default:
1979 goto err_noinitval;
1980 }
1981 } else
1982 goto err_noinitval;
1983 snprintf(buf, ARRAY_SIZE(buf), "bcm43xx_initval%02d%s.fw",
1984 nr, modparam_fwpostfix);
1985
1986 err = request_firmware(&bcm->initvals0, buf, &bcm->pci_dev->dev);
1987 if (err) {
1988 printk(KERN_ERR PFX
1989 "Error: InitVals \"%s\" not available or load failed.\n",
1990 buf);
1991 goto error;
1992 }
1993 if (bcm->initvals0->size % sizeof(struct bcm43xx_initval)) {
1994 printk(KERN_ERR PFX "InitVals fileformat error.\n");
1995 goto error;
1996 }
1997 }
1998
1999 if (!bcm->initvals1) {
2000 if (rev >= 5) {
2001 u32 sbtmstatehigh;
2002
2003 switch (phy->type) {
2004 case BCM43xx_PHYTYPE_A:
2005 sbtmstatehigh = bcm43xx_read32(bcm, BCM43xx_CIR_SBTMSTATEHIGH);
2006 if (sbtmstatehigh & 0x00010000)
2007 nr = 9;
2008 else
2009 nr = 10;
2010 break;
2011 case BCM43xx_PHYTYPE_B:
2012 case BCM43xx_PHYTYPE_G:
2013 nr = 6;
2014 break;
2015 default:
2016 goto err_noinitval;
2017 }
2018 snprintf(buf, ARRAY_SIZE(buf), "bcm43xx_initval%02d%s.fw",
2019 nr, modparam_fwpostfix);
2020
2021 err = request_firmware(&bcm->initvals1, buf, &bcm->pci_dev->dev);
2022 if (err) {
2023 printk(KERN_ERR PFX
2024 "Error: InitVals \"%s\" not available or load failed.\n",
2025 buf);
2026 goto error;
2027 }
2028 if (bcm->initvals1->size % sizeof(struct bcm43xx_initval)) {
2029 printk(KERN_ERR PFX "InitVals fileformat error.\n");
2030 goto error;
2031 }
2032 }
2033 }
2034
2035out:
2036 return err;
2037error:
2038 bcm43xx_release_firmware(bcm, 1);
2039 goto out;
2040err_noinitval:
2041 printk(KERN_ERR PFX "Error: No InitVals available!\n");
2042 err = -ENOENT;
2043 goto error;
2044}
2045
2046static void bcm43xx_upload_microcode(struct bcm43xx_private *bcm)
2047{
2048 const u32 *data;
2049 unsigned int i, len;
2050
2051 /* Upload Microcode. */
2052 data = (u32 *)(bcm->ucode->data);
2053 len = bcm->ucode->size / sizeof(u32);
2054 bcm43xx_shm_control_word(bcm, BCM43xx_SHM_UCODE, 0x0000);
2055 for (i = 0; i < len; i++) {
2056 bcm43xx_write32(bcm, BCM43xx_MMIO_SHM_DATA,
2057 be32_to_cpu(data[i]));
2058 udelay(10);
2059 }
2060
2061 /* Upload PCM data. */
2062 data = (u32 *)(bcm->pcm->data);
2063 len = bcm->pcm->size / sizeof(u32);
2064 bcm43xx_shm_control_word(bcm, BCM43xx_SHM_PCM, 0x01ea);
2065 bcm43xx_write32(bcm, BCM43xx_MMIO_SHM_DATA, 0x00004000);
2066 bcm43xx_shm_control_word(bcm, BCM43xx_SHM_PCM, 0x01eb);
2067 for (i = 0; i < len; i++) {
2068 bcm43xx_write32(bcm, BCM43xx_MMIO_SHM_DATA,
2069 be32_to_cpu(data[i]));
2070 udelay(10);
2071 }
2072}
2073
2074static int bcm43xx_write_initvals(struct bcm43xx_private *bcm,
2075 const struct bcm43xx_initval *data,
2076 const unsigned int len)
2077{
2078 u16 offset, size;
2079 u32 value;
2080 unsigned int i;
2081
2082 for (i = 0; i < len; i++) {
2083 offset = be16_to_cpu(data[i].offset);
2084 size = be16_to_cpu(data[i].size);
2085 value = be32_to_cpu(data[i].value);
2086
2087 if (unlikely(offset >= 0x1000))
2088 goto err_format;
2089 if (size == 2) {
2090 if (unlikely(value & 0xFFFF0000))
2091 goto err_format;
2092 bcm43xx_write16(bcm, offset, (u16)value);
2093 } else if (size == 4) {
2094 bcm43xx_write32(bcm, offset, value);
2095 } else
2096 goto err_format;
2097 }
2098
2099 return 0;
2100
2101err_format:
2102 printk(KERN_ERR PFX "InitVals (bcm43xx_initvalXX.fw) file-format error. "
2103 "Please fix your bcm43xx firmware files.\n");
2104 return -EPROTO;
2105}
2106
2107static int bcm43xx_upload_initvals(struct bcm43xx_private *bcm)
2108{
2109 int err;
2110
2111 err = bcm43xx_write_initvals(bcm, (struct bcm43xx_initval *)bcm->initvals0->data,
2112 bcm->initvals0->size / sizeof(struct bcm43xx_initval));
2113 if (err)
2114 goto out;
2115 if (bcm->initvals1) {
2116 err = bcm43xx_write_initvals(bcm, (struct bcm43xx_initval *)bcm->initvals1->data,
2117 bcm->initvals1->size / sizeof(struct bcm43xx_initval));
2118 if (err)
2119 goto out;
2120 }
2121out:
2122 return err;
2123}
2124
2125static int bcm43xx_initialize_irq(struct bcm43xx_private *bcm)
2126{
2127 int res;
2128 unsigned int i;
2129 u32 data;
2130
2131 bcm->irq = bcm->pci_dev->irq;
2132#ifdef CONFIG_BCM947XX
2133 if (bcm->pci_dev->bus->number == 0) {
2134 struct pci_dev *d = NULL;
2135 /* FIXME: we will probably need more device IDs here... */
2136 d = pci_find_device(PCI_VENDOR_ID_BROADCOM, 0x4324, NULL);
2137 if (d != NULL) {
2138 bcm->irq = d->irq;
2139 }
2140 }
2141#endif
2142 res = request_irq(bcm->irq, bcm43xx_interrupt_handler,
2143 SA_SHIRQ, KBUILD_MODNAME, bcm);
2144 if (res) {
2145 printk(KERN_ERR PFX "Cannot register IRQ%d\n", bcm->irq);
2146 return -ENODEV;
2147 }
2148 bcm43xx_write32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON, 0xffffffff);
2149 bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD, 0x00020402);
2150 i = 0;
2151 while (1) {
2152 data = bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON);
2153 if (data == BCM43xx_IRQ_READY)
2154 break;
2155 i++;
2156 if (i >= BCM43xx_IRQWAIT_MAX_RETRIES) {
2157 printk(KERN_ERR PFX "Card IRQ register not responding. "
2158 "Giving up.\n");
2159 free_irq(bcm->irq, bcm);
2160 return -ENODEV;
2161 }
2162 udelay(10);
2163 }
2164 // dummy read
2165 bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON);
2166
2167 return 0;
2168}
2169
2170/* Switch to the core used to write the GPIO register.
2171 * This is either the ChipCommon, or the PCI core.
2172 */
2173static int switch_to_gpio_core(struct bcm43xx_private *bcm)
2174{
2175 int err;
2176
2177 /* Where to find the GPIO register depends on the chipset.
2178 * If it has a ChipCommon, its register at offset 0x6c is the GPIO
2179 * control register. Otherwise the register at offset 0x6c in the
2180 * PCI core is the GPIO control register.
2181 */
2182 err = bcm43xx_switch_core(bcm, &bcm->core_chipcommon);
2183 if (err == -ENODEV) {
2184 err = bcm43xx_switch_core(bcm, &bcm->core_pci);
2185 if (unlikely(err == -ENODEV)) {
2186 printk(KERN_ERR PFX "gpio error: "
2187 "Neither ChipCommon nor PCI core available!\n");
2188 }
2189 }
2190
2191 return err;
2192}
2193
2194/* Initialize the GPIOs
2195 * http://bcm-specs.sipsolutions.net/GPIO
2196 */
2197static int bcm43xx_gpio_init(struct bcm43xx_private *bcm)
2198{
2199 struct bcm43xx_coreinfo *old_core;
2200 int err;
2201 u32 mask, set;
2202
2203 bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD,
2204 bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD)
2205 & 0xFFFF3FFF);
2206
2207 bcm43xx_leds_switch_all(bcm, 0);
2208 bcm43xx_write16(bcm, BCM43xx_MMIO_GPIO_MASK,
2209 bcm43xx_read16(bcm, BCM43xx_MMIO_GPIO_MASK) | 0x000F);
2210
2211 mask = 0x0000001F;
2212 set = 0x0000000F;
2213 if (bcm->chip_id == 0x4301) {
2214 mask |= 0x0060;
2215 set |= 0x0060;
2216 }
2217 if (0 /* FIXME: conditional unknown */) {
2218 bcm43xx_write16(bcm, BCM43xx_MMIO_GPIO_MASK,
2219 bcm43xx_read16(bcm, BCM43xx_MMIO_GPIO_MASK)
2220 | 0x0100);
2221 mask |= 0x0180;
2222 set |= 0x0180;
2223 }
2224 if (bcm->sprom.boardflags & BCM43xx_BFL_PACTRL) {
2225 bcm43xx_write16(bcm, BCM43xx_MMIO_GPIO_MASK,
2226 bcm43xx_read16(bcm, BCM43xx_MMIO_GPIO_MASK)
2227 | 0x0200);
2228 mask |= 0x0200;
2229 set |= 0x0200;
2230 }
2231 if (bcm->current_core->rev >= 2)
2232 mask |= 0x0010; /* FIXME: This is redundant. */
2233
2234 old_core = bcm->current_core;
2235 err = switch_to_gpio_core(bcm);
2236 if (err)
2237 goto out;
2238 bcm43xx_write32(bcm, BCM43xx_GPIO_CONTROL,
2239 (bcm43xx_read32(bcm, BCM43xx_GPIO_CONTROL) & mask) | set);
2240 err = bcm43xx_switch_core(bcm, old_core);
2241out:
2242 return err;
2243}
2244
2245/* Turn off all GPIO stuff. Call this on module unload, for example. */
2246static int bcm43xx_gpio_cleanup(struct bcm43xx_private *bcm)
2247{
2248 struct bcm43xx_coreinfo *old_core;
2249 int err;
2250
2251 old_core = bcm->current_core;
2252 err = switch_to_gpio_core(bcm);
2253 if (err)
2254 return err;
2255 bcm43xx_write32(bcm, BCM43xx_GPIO_CONTROL, 0x00000000);
2256 err = bcm43xx_switch_core(bcm, old_core);
2257 assert(err == 0);
2258
2259 return 0;
2260}
2261
2262/* http://bcm-specs.sipsolutions.net/EnableMac */
2263void bcm43xx_mac_enable(struct bcm43xx_private *bcm)
2264{
2265 bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD,
2266 bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD)
2267 | BCM43xx_SBF_MAC_ENABLED);
2268 bcm43xx_write32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON, BCM43xx_IRQ_READY);
2269 bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD); /* dummy read */
2270 bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON); /* dummy read */
2271 bcm43xx_power_saving_ctl_bits(bcm, -1, -1);
2272}
2273
2274/* http://bcm-specs.sipsolutions.net/SuspendMAC */
2275void bcm43xx_mac_suspend(struct bcm43xx_private *bcm)
2276{
2277 int i;
2278 u32 tmp;
2279
2280 bcm43xx_power_saving_ctl_bits(bcm, -1, 1);
2281 bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD,
2282 bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD)
2283 & ~BCM43xx_SBF_MAC_ENABLED);
2284 bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON); /* dummy read */
2285 for (i = 100000; i; i--) {
2286 tmp = bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON);
2287 if (tmp & BCM43xx_IRQ_READY)
2288 return;
2289 udelay(10);
2290 }
2291 printkl(KERN_ERR PFX "MAC suspend failed\n");
2292}
2293
2294void bcm43xx_set_iwmode(struct bcm43xx_private *bcm,
2295 int iw_mode)
2296{
2297 unsigned long flags;
2298 struct net_device *net_dev = bcm->net_dev;
2299 u32 status;
2300 u16 value;
2301
2302 spin_lock_irqsave(&bcm->ieee->lock, flags);
2303 bcm->ieee->iw_mode = iw_mode;
2304 spin_unlock_irqrestore(&bcm->ieee->lock, flags);
2305 if (iw_mode == IW_MODE_MONITOR)
2306 net_dev->type = ARPHRD_IEEE80211;
2307 else
2308 net_dev->type = ARPHRD_ETHER;
2309
2310 status = bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD);
2311 /* Reset status to infrastructured mode */
2312 status &= ~(BCM43xx_SBF_MODE_AP | BCM43xx_SBF_MODE_MONITOR);
2313 status &= ~BCM43xx_SBF_MODE_PROMISC;
2314 status |= BCM43xx_SBF_MODE_NOTADHOC;
2315
2316/* FIXME: Always enable promisc mode, until we get the MAC filters working correctly. */
2317status |= BCM43xx_SBF_MODE_PROMISC;
2318
2319 switch (iw_mode) {
2320 case IW_MODE_MONITOR:
2321 status |= BCM43xx_SBF_MODE_MONITOR;
2322 status |= BCM43xx_SBF_MODE_PROMISC;
2323 break;
2324 case IW_MODE_ADHOC:
2325 status &= ~BCM43xx_SBF_MODE_NOTADHOC;
2326 break;
2327 case IW_MODE_MASTER:
2328 status |= BCM43xx_SBF_MODE_AP;
2329 break;
2330 case IW_MODE_SECOND:
2331 case IW_MODE_REPEAT:
2332 TODO(); /* TODO */
2333 break;
2334 case IW_MODE_INFRA:
2335 /* nothing to be done here... */
2336 break;
2337 default:
2338 dprintk(KERN_ERR PFX "Unknown mode in set_iwmode: %d\n", iw_mode);
2339 }
2340 if (net_dev->flags & IFF_PROMISC)
2341 status |= BCM43xx_SBF_MODE_PROMISC;
2342 bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD, status);
2343
2344 value = 0x0002;
2345 if (iw_mode != IW_MODE_ADHOC && iw_mode != IW_MODE_MASTER) {
2346 if (bcm->chip_id == 0x4306 && bcm->chip_rev == 3)
2347 value = 0x0064;
2348 else
2349 value = 0x0032;
2350 }
2351 bcm43xx_write16(bcm, 0x0612, value);
2352}
2353
2354/* This is the opposite of bcm43xx_chip_init() */
2355static void bcm43xx_chip_cleanup(struct bcm43xx_private *bcm)
2356{
2357 bcm43xx_radio_turn_off(bcm);
2358 if (!modparam_noleds)
2359 bcm43xx_leds_exit(bcm);
2360 bcm43xx_gpio_cleanup(bcm);
2361 free_irq(bcm->irq, bcm);
2362 bcm43xx_release_firmware(bcm, 0);
2363}
2364
2365/* Initialize the chip
2366 * http://bcm-specs.sipsolutions.net/ChipInit
2367 */
2368static int bcm43xx_chip_init(struct bcm43xx_private *bcm)
2369{
2370 struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm);
2371 struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
2372 int err;
2373 int tmp;
2374 u32 value32;
2375 u16 value16;
2376
2377 bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD,
2378 BCM43xx_SBF_CORE_READY
2379 | BCM43xx_SBF_400);
2380
2381 err = bcm43xx_request_firmware(bcm);
2382 if (err)
2383 goto out;
2384 bcm43xx_upload_microcode(bcm);
2385
2386 err = bcm43xx_initialize_irq(bcm);
2387 if (err)
2388 goto err_release_fw;
2389
2390 err = bcm43xx_gpio_init(bcm);
2391 if (err)
2392 goto err_free_irq;
2393
2394 err = bcm43xx_upload_initvals(bcm);
2395 if (err)
2396 goto err_gpio_cleanup;
2397 bcm43xx_radio_turn_on(bcm);
2398
2399 bcm43xx_write16(bcm, 0x03E6, 0x0000);
2400 err = bcm43xx_phy_init(bcm);
2401 if (err)
2402 goto err_radio_off;
2403
2404 /* Select initial Interference Mitigation. */
2405 tmp = radio->interfmode;
2406 radio->interfmode = BCM43xx_RADIO_INTERFMODE_NONE;
2407 bcm43xx_radio_set_interference_mitigation(bcm, tmp);
2408
2409 bcm43xx_phy_set_antenna_diversity(bcm);
2410 bcm43xx_radio_set_txantenna(bcm, BCM43xx_RADIO_TXANTENNA_DEFAULT);
2411 if (phy->type == BCM43xx_PHYTYPE_B) {
2412 value16 = bcm43xx_read16(bcm, 0x005E);
2413 value16 |= 0x0004;
2414 bcm43xx_write16(bcm, 0x005E, value16);
2415 }
2416 bcm43xx_write32(bcm, 0x0100, 0x01000000);
2417 if (bcm->current_core->rev < 5)
2418 bcm43xx_write32(bcm, 0x010C, 0x01000000);
2419
2420 value32 = bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD);
2421 value32 &= ~ BCM43xx_SBF_MODE_NOTADHOC;
2422 bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD, value32);
2423 value32 = bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD);
2424 value32 |= BCM43xx_SBF_MODE_NOTADHOC;
2425 bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD, value32);
2426
2427 value32 = bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD);
2428 value32 |= 0x100000;
2429 bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD, value32);
2430
2431 if (bcm43xx_using_pio(bcm)) {
2432 bcm43xx_write32(bcm, 0x0210, 0x00000100);
2433 bcm43xx_write32(bcm, 0x0230, 0x00000100);
2434 bcm43xx_write32(bcm, 0x0250, 0x00000100);
2435 bcm43xx_write32(bcm, 0x0270, 0x00000100);
2436 bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, 0x0034, 0x0000);
2437 }
2438
2439 /* Probe Response Timeout value */
2440 /* FIXME: Default to 0, has to be set by ioctl probably... :-/ */
2441 bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, 0x0074, 0x0000);
2442
2443 /* Initially set the wireless operation mode. */
2444 bcm43xx_set_iwmode(bcm, bcm->ieee->iw_mode);
2445
2446 if (bcm->current_core->rev < 3) {
2447 bcm43xx_write16(bcm, 0x060E, 0x0000);
2448 bcm43xx_write16(bcm, 0x0610, 0x8000);
2449 bcm43xx_write16(bcm, 0x0604, 0x0000);
2450 bcm43xx_write16(bcm, 0x0606, 0x0200);
2451 } else {
2452 bcm43xx_write32(bcm, 0x0188, 0x80000000);
2453 bcm43xx_write32(bcm, 0x018C, 0x02000000);
2454 }
2455 bcm43xx_write32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON, 0x00004000);
2456 bcm43xx_write32(bcm, BCM43xx_MMIO_DMA1_IRQ_MASK, 0x0001DC00);
2457 bcm43xx_write32(bcm, BCM43xx_MMIO_DMA2_IRQ_MASK, 0x0000DC00);
2458 bcm43xx_write32(bcm, BCM43xx_MMIO_DMA3_IRQ_MASK, 0x0000DC00);
2459 bcm43xx_write32(bcm, BCM43xx_MMIO_DMA4_IRQ_MASK, 0x0001DC00);
2460
2461 value32 = bcm43xx_read32(bcm, BCM43xx_CIR_SBTMSTATELOW);
2462 value32 |= 0x00100000;
2463 bcm43xx_write32(bcm, BCM43xx_CIR_SBTMSTATELOW, value32);
2464
2465 bcm43xx_write16(bcm, BCM43xx_MMIO_POWERUP_DELAY, bcm43xx_pctl_powerup_delay(bcm));
2466
2467 assert(err == 0);
2468 dprintk(KERN_INFO PFX "Chip initialized\n");
2469out:
2470 return err;
2471
2472err_radio_off:
2473 bcm43xx_radio_turn_off(bcm);
2474err_gpio_cleanup:
2475 bcm43xx_gpio_cleanup(bcm);
2476err_free_irq:
2477 free_irq(bcm->irq, bcm);
2478err_release_fw:
2479 bcm43xx_release_firmware(bcm, 1);
2480 goto out;
2481}
2482
2483/* Validate chip access
2484 * http://bcm-specs.sipsolutions.net/ValidateChipAccess */
2485static int bcm43xx_validate_chip(struct bcm43xx_private *bcm)
2486{
2487 u32 value;
2488 u32 shm_backup;
2489
2490 shm_backup = bcm43xx_shm_read32(bcm, BCM43xx_SHM_SHARED, 0x0000);
2491 bcm43xx_shm_write32(bcm, BCM43xx_SHM_SHARED, 0x0000, 0xAA5555AA);
2492 if (bcm43xx_shm_read32(bcm, BCM43xx_SHM_SHARED, 0x0000) != 0xAA5555AA)
2493 goto error;
2494 bcm43xx_shm_write32(bcm, BCM43xx_SHM_SHARED, 0x0000, 0x55AAAA55);
2495 if (bcm43xx_shm_read32(bcm, BCM43xx_SHM_SHARED, 0x0000) != 0x55AAAA55)
2496 goto error;
2497 bcm43xx_shm_write32(bcm, BCM43xx_SHM_SHARED, 0x0000, shm_backup);
2498
2499 value = bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD);
2500 if ((value | 0x80000000) != 0x80000400)
2501 goto error;
2502
2503 value = bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON);
2504 if (value != 0x00000000)
2505 goto error;
2506
2507 return 0;
2508error:
2509 printk(KERN_ERR PFX "Failed to validate the chipaccess\n");
2510 return -ENODEV;
2511}
2512
2513static void bcm43xx_init_struct_phyinfo(struct bcm43xx_phyinfo *phy)
2514{
2515 /* Initialize a "phyinfo" structure. The structure is already
2516 * zeroed out.
2517 */
2518 phy->antenna_diversity = 0xFFFF;
2519 phy->savedpctlreg = 0xFFFF;
2520 phy->minlowsig[0] = 0xFFFF;
2521 phy->minlowsig[1] = 0xFFFF;
2522 spin_lock_init(&phy->lock);
2523}
2524
2525static void bcm43xx_init_struct_radioinfo(struct bcm43xx_radioinfo *radio)
2526{
2527 /* Initialize a "radioinfo" structure. The structure is already
2528 * zeroed out.
2529 */
2530 radio->interfmode = BCM43xx_RADIO_INTERFMODE_NONE;
2531 radio->channel = 0xFF;
2532 radio->initial_channel = 0xFF;
2533 radio->lofcal = 0xFFFF;
2534 radio->initval = 0xFFFF;
2535 radio->nrssi[0] = -1000;
2536 radio->nrssi[1] = -1000;
2537}
2538
2539static int bcm43xx_probe_cores(struct bcm43xx_private *bcm)
2540{
2541 int err, i;
2542 int current_core;
2543 u32 core_vendor, core_id, core_rev;
2544 u32 sb_id_hi, chip_id_32 = 0;
2545 u16 pci_device, chip_id_16;
2546 u8 core_count;
2547
2548 memset(&bcm->core_chipcommon, 0, sizeof(struct bcm43xx_coreinfo));
2549 memset(&bcm->core_pci, 0, sizeof(struct bcm43xx_coreinfo));
2550 memset(&bcm->core_80211, 0, sizeof(struct bcm43xx_coreinfo)
2551 * BCM43xx_MAX_80211_CORES);
2552 memset(&bcm->core_80211_ext, 0, sizeof(struct bcm43xx_coreinfo_80211)
2553 * BCM43xx_MAX_80211_CORES);
2554 bcm->current_80211_core_idx = -1;
2555 bcm->nr_80211_available = 0;
2556 bcm->current_core = NULL;
2557 bcm->active_80211_core = NULL;
2558
2559 /* map core 0 */
2560 err = _switch_core(bcm, 0);
2561 if (err)
2562 goto out;
2563
2564 /* fetch sb_id_hi from core information registers */
2565 sb_id_hi = bcm43xx_read32(bcm, BCM43xx_CIR_SB_ID_HI);
2566
2567 core_id = (sb_id_hi & 0xFFF0) >> 4;
2568 core_rev = (sb_id_hi & 0xF);
2569 core_vendor = (sb_id_hi & 0xFFFF0000) >> 16;
2570
2571 /* if present, chipcommon is always core 0; read the chipid from it */
2572 if (core_id == BCM43xx_COREID_CHIPCOMMON) {
2573 chip_id_32 = bcm43xx_read32(bcm, 0);
2574 chip_id_16 = chip_id_32 & 0xFFFF;
2575 bcm->core_chipcommon.available = 1;
2576 bcm->core_chipcommon.id = core_id;
2577 bcm->core_chipcommon.rev = core_rev;
2578 bcm->core_chipcommon.index = 0;
2579 /* While we are at it, also read the capabilities. */
2580 bcm->chipcommon_capabilities = bcm43xx_read32(bcm, BCM43xx_CHIPCOMMON_CAPABILITIES);
2581 } else {
2582 /* without a chipCommon, use a hard coded table. */
2583 pci_device = bcm->pci_dev->device;
2584 if (pci_device == 0x4301)
2585 chip_id_16 = 0x4301;
2586 else if ((pci_device >= 0x4305) && (pci_device <= 0x4307))
2587 chip_id_16 = 0x4307;
2588 else if ((pci_device >= 0x4402) && (pci_device <= 0x4403))
2589 chip_id_16 = 0x4402;
2590 else if ((pci_device >= 0x4610) && (pci_device <= 0x4615))
2591 chip_id_16 = 0x4610;
2592 else if ((pci_device >= 0x4710) && (pci_device <= 0x4715))
2593 chip_id_16 = 0x4710;
2594#ifdef CONFIG_BCM947XX
2595 else if ((pci_device >= 0x4320) && (pci_device <= 0x4325))
2596 chip_id_16 = 0x4309;
2597#endif
2598 else {
2599 printk(KERN_ERR PFX "Could not determine Chip ID\n");
2600 return -ENODEV;
2601 }
2602 }
2603
2604 /* ChipCommon with Core Rev >=4 encodes number of cores,
2605 * otherwise consult hardcoded table */
2606 if ((core_id == BCM43xx_COREID_CHIPCOMMON) && (core_rev >= 4)) {
2607 core_count = (chip_id_32 & 0x0F000000) >> 24;
2608 } else {
2609 switch (chip_id_16) {
2610 case 0x4610:
2611 case 0x4704:
2612 case 0x4710:
2613 core_count = 9;
2614 break;
2615 case 0x4310:
2616 core_count = 8;
2617 break;
2618 case 0x5365:
2619 core_count = 7;
2620 break;
2621 case 0x4306:
2622 core_count = 6;
2623 break;
2624 case 0x4301:
2625 case 0x4307:
2626 core_count = 5;
2627 break;
2628 case 0x4402:
2629 core_count = 3;
2630 break;
2631 default:
2632 /* SOL if we get here */
2633 assert(0);
2634 core_count = 1;
2635 }
2636 }
2637
2638 bcm->chip_id = chip_id_16;
2639 bcm->chip_rev = (chip_id_32 & 0x000F0000) >> 16;
2640 bcm->chip_package = (chip_id_32 & 0x00F00000) >> 20;
2641
2642 dprintk(KERN_INFO PFX "Chip ID 0x%x, rev 0x%x\n",
2643 bcm->chip_id, bcm->chip_rev);
2644 dprintk(KERN_INFO PFX "Number of cores: %d\n", core_count);
2645 if (bcm->core_chipcommon.available) {
2646 dprintk(KERN_INFO PFX "Core 0: ID 0x%x, rev 0x%x, vendor 0x%x, %s\n",
2647 core_id, core_rev, core_vendor,
2648 bcm43xx_core_enabled(bcm) ? "enabled" : "disabled");
2649 }
2650
2651 if (bcm->core_chipcommon.available)
2652 current_core = 1;
2653 else
2654 current_core = 0;
2655 for ( ; current_core < core_count; current_core++) {
2656 struct bcm43xx_coreinfo *core;
2657 struct bcm43xx_coreinfo_80211 *ext_80211;
2658
2659 err = _switch_core(bcm, current_core);
2660 if (err)
2661 goto out;
2662 /* Gather information */
2663 /* fetch sb_id_hi from core information registers */
2664 sb_id_hi = bcm43xx_read32(bcm, BCM43xx_CIR_SB_ID_HI);
2665
2666 /* extract core_id, core_rev, core_vendor */
2667 core_id = (sb_id_hi & 0xFFF0) >> 4;
2668 core_rev = (sb_id_hi & 0xF);
2669 core_vendor = (sb_id_hi & 0xFFFF0000) >> 16;
2670
2671 dprintk(KERN_INFO PFX "Core %d: ID 0x%x, rev 0x%x, vendor 0x%x, %s\n",
2672 current_core, core_id, core_rev, core_vendor,
2673 bcm43xx_core_enabled(bcm) ? "enabled" : "disabled" );
2674
2675 core = NULL;
2676 switch (core_id) {
2677 case BCM43xx_COREID_PCI:
2678 core = &bcm->core_pci;
2679 if (core->available) {
2680 printk(KERN_WARNING PFX "Multiple PCI cores found.\n");
2681 continue;
2682 }
2683 break;
2684 case BCM43xx_COREID_80211:
2685 for (i = 0; i < BCM43xx_MAX_80211_CORES; i++) {
2686 core = &(bcm->core_80211[i]);
2687 ext_80211 = &(bcm->core_80211_ext[i]);
2688 if (!core->available)
2689 break;
2690 core = NULL;
2691 }
2692 if (!core) {
2693 printk(KERN_WARNING PFX "More than %d cores of type 802.11 found.\n",
2694 BCM43xx_MAX_80211_CORES);
2695 continue;
2696 }
2697 if (i != 0) {
2698 /* More than one 80211 core is only supported
2699 * by special chips.
2700 * There are chips with two 80211 cores, but with
2701 * dangling pins on the second core. Be careful
2702 * and ignore these cores here.
2703 */
2704 if (bcm->pci_dev->device != 0x4324) {
2705 dprintk(KERN_INFO PFX "Ignoring additional 802.11 core.\n");
2706 continue;
2707 }
2708 }
2709 switch (core_rev) {
2710 case 2:
2711 case 4:
2712 case 5:
2713 case 6:
2714 case 7:
2715 case 9:
2716 break;
2717 default:
2718 printk(KERN_ERR PFX "Error: Unsupported 80211 core revision %u\n",
2719 core_rev);
2720 err = -ENODEV;
2721 goto out;
2722 }
2723 bcm->nr_80211_available++;
2724 bcm43xx_init_struct_phyinfo(&ext_80211->phy);
2725 bcm43xx_init_struct_radioinfo(&ext_80211->radio);
2726 break;
2727 case BCM43xx_COREID_CHIPCOMMON:
2728 printk(KERN_WARNING PFX "Multiple CHIPCOMMON cores found.\n");
2729 break;
2730 }
2731 if (core) {
2732 core->available = 1;
2733 core->id = core_id;
2734 core->rev = core_rev;
2735 core->index = current_core;
2736 }
2737 }
2738
2739 if (!bcm->core_80211[0].available) {
2740 printk(KERN_ERR PFX "Error: No 80211 core found!\n");
2741 err = -ENODEV;
2742 goto out;
2743 }
2744
2745 err = bcm43xx_switch_core(bcm, &bcm->core_80211[0]);
2746
2747 assert(err == 0);
2748out:
2749 return err;
2750}
2751
2752static void bcm43xx_gen_bssid(struct bcm43xx_private *bcm)
2753{
2754 const u8 *mac = (const u8*)(bcm->net_dev->dev_addr);
2755 u8 *bssid = bcm->ieee->bssid;
2756
2757 switch (bcm->ieee->iw_mode) {
2758 case IW_MODE_ADHOC:
2759 random_ether_addr(bssid);
2760 break;
2761 case IW_MODE_MASTER:
2762 case IW_MODE_INFRA:
2763 case IW_MODE_REPEAT:
2764 case IW_MODE_SECOND:
2765 case IW_MODE_MONITOR:
2766 memcpy(bssid, mac, ETH_ALEN);
2767 break;
2768 default:
2769 assert(0);
2770 }
2771}
2772
2773static void bcm43xx_rate_memory_write(struct bcm43xx_private *bcm,
2774 u16 rate,
2775 int is_ofdm)
2776{
2777 u16 offset;
2778
2779 if (is_ofdm) {
2780 offset = 0x480;
2781 offset += (bcm43xx_plcp_get_ratecode_ofdm(rate) & 0x000F) * 2;
2782 }
2783 else {
2784 offset = 0x4C0;
2785 offset += (bcm43xx_plcp_get_ratecode_cck(rate) & 0x000F) * 2;
2786 }
2787 bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, offset + 0x20,
2788 bcm43xx_shm_read16(bcm, BCM43xx_SHM_SHARED, offset));
2789}
2790
2791static void bcm43xx_rate_memory_init(struct bcm43xx_private *bcm)
2792{
2793 switch (bcm43xx_current_phy(bcm)->type) {
2794 case BCM43xx_PHYTYPE_A:
2795 case BCM43xx_PHYTYPE_G:
2796 bcm43xx_rate_memory_write(bcm, IEEE80211_OFDM_RATE_6MB, 1);
2797 bcm43xx_rate_memory_write(bcm, IEEE80211_OFDM_RATE_12MB, 1);
2798 bcm43xx_rate_memory_write(bcm, IEEE80211_OFDM_RATE_18MB, 1);
2799 bcm43xx_rate_memory_write(bcm, IEEE80211_OFDM_RATE_24MB, 1);
2800 bcm43xx_rate_memory_write(bcm, IEEE80211_OFDM_RATE_36MB, 1);
2801 bcm43xx_rate_memory_write(bcm, IEEE80211_OFDM_RATE_48MB, 1);
2802 bcm43xx_rate_memory_write(bcm, IEEE80211_OFDM_RATE_54MB, 1);
2803 case BCM43xx_PHYTYPE_B:
2804 bcm43xx_rate_memory_write(bcm, IEEE80211_CCK_RATE_1MB, 0);
2805 bcm43xx_rate_memory_write(bcm, IEEE80211_CCK_RATE_2MB, 0);
2806 bcm43xx_rate_memory_write(bcm, IEEE80211_CCK_RATE_5MB, 0);
2807 bcm43xx_rate_memory_write(bcm, IEEE80211_CCK_RATE_11MB, 0);
2808 break;
2809 default:
2810 assert(0);
2811 }
2812}
2813
2814static void bcm43xx_wireless_core_cleanup(struct bcm43xx_private *bcm)
2815{
2816 bcm43xx_chip_cleanup(bcm);
2817 bcm43xx_pio_free(bcm);
2818 bcm43xx_dma_free(bcm);
2819
2820 bcm->current_core->initialized = 0;
2821}
2822
2823/* http://bcm-specs.sipsolutions.net/80211Init */
2824static int bcm43xx_wireless_core_init(struct bcm43xx_private *bcm)
2825{
2826 struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
2827 struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm);
2828 u32 ucodeflags;
2829 int err;
2830 u32 sbimconfiglow;
2831 u8 limit;
2832
2833 if (bcm->chip_rev < 5) {
2834 sbimconfiglow = bcm43xx_read32(bcm, BCM43xx_CIR_SBIMCONFIGLOW);
2835 sbimconfiglow &= ~ BCM43xx_SBIMCONFIGLOW_REQUEST_TOUT_MASK;
2836 sbimconfiglow &= ~ BCM43xx_SBIMCONFIGLOW_SERVICE_TOUT_MASK;
2837 if (bcm->bustype == BCM43xx_BUSTYPE_PCI)
2838 sbimconfiglow |= 0x32;
2839 else if (bcm->bustype == BCM43xx_BUSTYPE_SB)
2840 sbimconfiglow |= 0x53;
2841 else
2842 assert(0);
2843 bcm43xx_write32(bcm, BCM43xx_CIR_SBIMCONFIGLOW, sbimconfiglow);
2844 }
2845
2846 bcm43xx_phy_calibrate(bcm);
2847 err = bcm43xx_chip_init(bcm);
2848 if (err)
2849 goto out;
2850
2851 bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, 0x0016, bcm->current_core->rev);
2852 ucodeflags = bcm43xx_shm_read32(bcm, BCM43xx_SHM_SHARED, BCM43xx_UCODEFLAGS_OFFSET);
2853
2854 if (0 /*FIXME: which condition has to be used here? */)
2855 ucodeflags |= 0x00000010;
2856
2857 /* HW decryption needs to be set now */
2858 ucodeflags |= 0x40000000;
2859
2860 if (phy->type == BCM43xx_PHYTYPE_G) {
2861 ucodeflags |= BCM43xx_UCODEFLAG_UNKBGPHY;
2862 if (phy->rev == 1)
2863 ucodeflags |= BCM43xx_UCODEFLAG_UNKGPHY;
2864 if (bcm->sprom.boardflags & BCM43xx_BFL_PACTRL)
2865 ucodeflags |= BCM43xx_UCODEFLAG_UNKPACTRL;
2866 } else if (phy->type == BCM43xx_PHYTYPE_B) {
2867 ucodeflags |= BCM43xx_UCODEFLAG_UNKBGPHY;
2868 if (phy->rev >= 2 && radio->version == 0x2050)
2869 ucodeflags &= ~BCM43xx_UCODEFLAG_UNKGPHY;
2870 }
2871
2872 if (ucodeflags != bcm43xx_shm_read32(bcm, BCM43xx_SHM_SHARED,
2873 BCM43xx_UCODEFLAGS_OFFSET)) {
2874 bcm43xx_shm_write32(bcm, BCM43xx_SHM_SHARED,
2875 BCM43xx_UCODEFLAGS_OFFSET, ucodeflags);
2876 }
2877
2878 /* Short/Long Retry Limit.
2879 * The retry-limit is a 4-bit counter. Enforce this to avoid overflowing
2880 * the chip-internal counter.
2881 */
2882 limit = limit_value(modparam_short_retry, 0, 0xF);
2883 bcm43xx_shm_write32(bcm, BCM43xx_SHM_WIRELESS, 0x0006, limit);
2884 limit = limit_value(modparam_long_retry, 0, 0xF);
2885 bcm43xx_shm_write32(bcm, BCM43xx_SHM_WIRELESS, 0x0007, limit);
2886
2887 bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, 0x0044, 3);
2888 bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, 0x0046, 2);
2889
2890 bcm43xx_rate_memory_init(bcm);
2891
2892 /* Minimum Contention Window */
2893 if (phy->type == BCM43xx_PHYTYPE_B)
2894 bcm43xx_shm_write32(bcm, BCM43xx_SHM_WIRELESS, 0x0003, 0x0000001f);
2895 else
2896 bcm43xx_shm_write32(bcm, BCM43xx_SHM_WIRELESS, 0x0003, 0x0000000f);
2897 /* Maximum Contention Window */
2898 bcm43xx_shm_write32(bcm, BCM43xx_SHM_WIRELESS, 0x0004, 0x000003ff);
2899
2900 bcm43xx_gen_bssid(bcm);
2901 bcm43xx_write_mac_bssid_templates(bcm);
2902
2903 if (bcm->current_core->rev >= 5)
2904 bcm43xx_write16(bcm, 0x043C, 0x000C);
2905
2906 if (bcm43xx_using_pio(bcm))
2907 err = bcm43xx_pio_init(bcm);
2908 else
2909 err = bcm43xx_dma_init(bcm);
2910 if (err)
2911 goto err_chip_cleanup;
2912 bcm43xx_write16(bcm, 0x0612, 0x0050);
2913 bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, 0x0416, 0x0050);
2914 bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, 0x0414, 0x01F4);
2915
2916 bcm43xx_mac_enable(bcm);
2917 bcm43xx_interrupt_enable(bcm, bcm->irq_savedstate);
2918
2919 bcm->current_core->initialized = 1;
2920out:
2921 return err;
2922
2923err_chip_cleanup:
2924 bcm43xx_chip_cleanup(bcm);
2925 goto out;
2926}
2927
2928static int bcm43xx_chipset_attach(struct bcm43xx_private *bcm)
2929{
2930 int err;
2931 u16 pci_status;
2932
2933 err = bcm43xx_pctl_set_crystal(bcm, 1);
2934 if (err)
2935 goto out;
2936 bcm43xx_pci_read_config16(bcm, PCI_STATUS, &pci_status);
2937 bcm43xx_pci_write_config16(bcm, PCI_STATUS, pci_status & ~PCI_STATUS_SIG_TARGET_ABORT);
2938
2939out:
2940 return err;
2941}
2942
2943static void bcm43xx_chipset_detach(struct bcm43xx_private *bcm)
2944{
2945 bcm43xx_pctl_set_clock(bcm, BCM43xx_PCTL_CLK_SLOW);
2946 bcm43xx_pctl_set_crystal(bcm, 0);
2947}
2948
2949static void bcm43xx_pcicore_broadcast_value(struct bcm43xx_private *bcm,
2950 u32 address,
2951 u32 data)
2952{
2953 bcm43xx_write32(bcm, BCM43xx_PCICORE_BCAST_ADDR, address);
2954 bcm43xx_write32(bcm, BCM43xx_PCICORE_BCAST_DATA, data);
2955}
2956
2957static int bcm43xx_pcicore_commit_settings(struct bcm43xx_private *bcm)
2958{
2959 int err;
2960 struct bcm43xx_coreinfo *old_core;
2961
2962 old_core = bcm->current_core;
2963 err = bcm43xx_switch_core(bcm, &bcm->core_pci);
2964 if (err)
2965 goto out;
2966
2967 bcm43xx_pcicore_broadcast_value(bcm, 0xfd8, 0x00000000);
2968
2969 bcm43xx_switch_core(bcm, old_core);
2970 assert(err == 0);
2971out:
2972 return err;
2973}
2974
2975/* Make an I/O Core usable. "core_mask" is the bitmask of the cores to enable.
2976 * To enable core 0, pass a core_mask of 1<<0
2977 */
2978static int bcm43xx_setup_backplane_pci_connection(struct bcm43xx_private *bcm,
2979 u32 core_mask)
2980{
2981 u32 backplane_flag_nr;
2982 u32 value;
2983 struct bcm43xx_coreinfo *old_core;
2984 int err = 0;
2985
2986 value = bcm43xx_read32(bcm, BCM43xx_CIR_SBTPSFLAG);
2987 backplane_flag_nr = value & BCM43xx_BACKPLANE_FLAG_NR_MASK;
2988
2989 old_core = bcm->current_core;
2990 err = bcm43xx_switch_core(bcm, &bcm->core_pci);
2991 if (err)
2992 goto out;
2993
2994 if (bcm->core_pci.rev < 6) {
2995 value = bcm43xx_read32(bcm, BCM43xx_CIR_SBINTVEC);
2996 value |= (1 << backplane_flag_nr);
2997 bcm43xx_write32(bcm, BCM43xx_CIR_SBINTVEC, value);
2998 } else {
2999 err = bcm43xx_pci_read_config32(bcm, BCM43xx_PCICFG_ICR, &value);
3000 if (err) {
3001 printk(KERN_ERR PFX "Error: ICR setup failure!\n");
3002 goto out_switch_back;
3003 }
3004 value |= core_mask << 8;
3005 err = bcm43xx_pci_write_config32(bcm, BCM43xx_PCICFG_ICR, value);
3006 if (err) {
3007 printk(KERN_ERR PFX "Error: ICR setup failure!\n");
3008 goto out_switch_back;
3009 }
3010 }
3011
3012 value = bcm43xx_read32(bcm, BCM43xx_PCICORE_SBTOPCI2);
3013 value |= BCM43xx_SBTOPCI2_PREFETCH | BCM43xx_SBTOPCI2_BURST;
3014 bcm43xx_write32(bcm, BCM43xx_PCICORE_SBTOPCI2, value);
3015
3016 if (bcm->core_pci.rev < 5) {
3017 value = bcm43xx_read32(bcm, BCM43xx_CIR_SBIMCONFIGLOW);
3018 value |= (2 << BCM43xx_SBIMCONFIGLOW_SERVICE_TOUT_SHIFT)
3019 & BCM43xx_SBIMCONFIGLOW_SERVICE_TOUT_MASK;
3020 value |= (3 << BCM43xx_SBIMCONFIGLOW_REQUEST_TOUT_SHIFT)
3021 & BCM43xx_SBIMCONFIGLOW_REQUEST_TOUT_MASK;
3022 bcm43xx_write32(bcm, BCM43xx_CIR_SBIMCONFIGLOW, value);
3023 err = bcm43xx_pcicore_commit_settings(bcm);
3024 assert(err == 0);
3025 }
3026
3027out_switch_back:
3028 err = bcm43xx_switch_core(bcm, old_core);
3029out:
3030 return err;
3031}
3032
3033static void bcm43xx_softmac_init(struct bcm43xx_private *bcm)
3034{
3035 ieee80211softmac_start(bcm->net_dev);
3036}
3037
3038static void bcm43xx_periodic_every120sec(struct bcm43xx_private *bcm)
3039{
3040 struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
3041
3042 if (phy->type != BCM43xx_PHYTYPE_G || phy->rev < 2)
3043 return;
3044
3045 bcm43xx_mac_suspend(bcm);
3046 bcm43xx_phy_lo_g_measure(bcm);
3047 bcm43xx_mac_enable(bcm);
3048}
3049
3050static void bcm43xx_periodic_every60sec(struct bcm43xx_private *bcm)
3051{
3052 bcm43xx_phy_lo_mark_all_unused(bcm);
3053 if (bcm->sprom.boardflags & BCM43xx_BFL_RSSI) {
3054 bcm43xx_mac_suspend(bcm);
3055 bcm43xx_calc_nrssi_slope(bcm);
3056 bcm43xx_mac_enable(bcm);
3057 }
3058}
3059
3060static void bcm43xx_periodic_every30sec(struct bcm43xx_private *bcm)
3061{
3062 /* Update device statistics. */
3063 bcm43xx_calculate_link_quality(bcm);
3064}
3065
3066static void bcm43xx_periodic_every15sec(struct bcm43xx_private *bcm)
3067{
3068 struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
3069 struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm);
3070
3071 if (phy->type == BCM43xx_PHYTYPE_G) {
3072 //TODO: update_aci_moving_average
3073 if (radio->aci_enable && radio->aci_wlan_automatic) {
3074 bcm43xx_mac_suspend(bcm);
3075 if (!radio->aci_enable && 1 /*TODO: not scanning? */) {
3076 if (0 /*TODO: bunch of conditions*/) {
3077 bcm43xx_radio_set_interference_mitigation(bcm,
3078 BCM43xx_RADIO_INTERFMODE_MANUALWLAN);
3079 }
3080 } else if (1/*TODO*/) {
3081 /*
3082 if ((aci_average > 1000) && !(bcm43xx_radio_aci_scan(bcm))) {
3083 bcm43xx_radio_set_interference_mitigation(bcm,
3084 BCM43xx_RADIO_INTERFMODE_NONE);
3085 }
3086 */
3087 }
3088 bcm43xx_mac_enable(bcm);
3089 } else if (radio->interfmode == BCM43xx_RADIO_INTERFMODE_NONWLAN &&
3090 phy->rev == 1) {
3091 //TODO: implement rev1 workaround
3092 }
3093 }
3094 bcm43xx_phy_xmitpower(bcm); //FIXME: unless scanning?
3095 //TODO for APHY (temperature?)
3096}
3097
3098static void bcm43xx_periodic_task_handler(unsigned long d)
3099{
3100 struct bcm43xx_private *bcm = (struct bcm43xx_private *)d;
3101 unsigned long flags;
3102 unsigned int state;
3103
3104 bcm43xx_lock_mmio(bcm, flags);
3105
3106 assert(bcm->initialized);
3107 state = bcm->periodic_state;
3108 if (state % 8 == 0)
3109 bcm43xx_periodic_every120sec(bcm);
3110 if (state % 4 == 0)
3111 bcm43xx_periodic_every60sec(bcm);
3112 if (state % 2 == 0)
3113 bcm43xx_periodic_every30sec(bcm);
3114 bcm43xx_periodic_every15sec(bcm);
3115 bcm->periodic_state = state + 1;
3116
3117 mod_timer(&bcm->periodic_tasks, jiffies + (HZ * 15));
3118
3119 bcm43xx_unlock_mmio(bcm, flags);
3120}
3121
3122static void bcm43xx_periodic_tasks_delete(struct bcm43xx_private *bcm)
3123{
3124 del_timer_sync(&bcm->periodic_tasks);
3125}
3126
3127static void bcm43xx_periodic_tasks_setup(struct bcm43xx_private *bcm)
3128{
3129 struct timer_list *timer = &(bcm->periodic_tasks);
3130
3131 assert(bcm->initialized);
3132 setup_timer(timer,
3133 bcm43xx_periodic_task_handler,
3134 (unsigned long)bcm);
3135 timer->expires = jiffies;
3136 add_timer(timer);
3137}
3138
3139static void bcm43xx_security_init(struct bcm43xx_private *bcm)
3140{
3141 bcm->security_offset = bcm43xx_shm_read16(bcm, BCM43xx_SHM_SHARED,
3142 0x0056) * 2;
3143 bcm43xx_clear_keys(bcm);
3144}
3145
3146/* This is the opposite of bcm43xx_init_board() */
3147static void bcm43xx_free_board(struct bcm43xx_private *bcm)
3148{
3149 int i, err;
3150 unsigned long flags;
3151
3152 bcm43xx_sysfs_unregister(bcm);
3153
3154 bcm43xx_periodic_tasks_delete(bcm);
3155
3156 bcm43xx_lock(bcm, flags);
3157 bcm->initialized = 0;
3158 bcm->shutting_down = 1;
3159 bcm43xx_unlock(bcm, flags);
3160
3161 for (i = 0; i < BCM43xx_MAX_80211_CORES; i++) {
3162 if (!bcm->core_80211[i].available)
3163 continue;
3164 if (!bcm->core_80211[i].initialized)
3165 continue;
3166
3167 err = bcm43xx_switch_core(bcm, &bcm->core_80211[i]);
3168 assert(err == 0);
3169 bcm43xx_wireless_core_cleanup(bcm);
3170 }
3171
3172 bcm43xx_pctl_set_crystal(bcm, 0);
3173
3174 bcm43xx_lock(bcm, flags);
3175 bcm->shutting_down = 0;
3176 bcm43xx_unlock(bcm, flags);
3177}
3178
3179static int bcm43xx_init_board(struct bcm43xx_private *bcm)
3180{
3181 int i, err;
3182 int connect_phy;
3183 unsigned long flags;
3184
3185 might_sleep();
3186
3187 bcm43xx_lock(bcm, flags);
3188 bcm->initialized = 0;
3189 bcm->shutting_down = 0;
3190 bcm43xx_unlock(bcm, flags);
3191
3192 err = bcm43xx_pctl_set_crystal(bcm, 1);
3193 if (err)
3194 goto out;
3195 err = bcm43xx_pctl_init(bcm);
3196 if (err)
3197 goto err_crystal_off;
3198 err = bcm43xx_pctl_set_clock(bcm, BCM43xx_PCTL_CLK_FAST);
3199 if (err)
3200 goto err_crystal_off;
3201
3202 tasklet_enable(&bcm->isr_tasklet);
3203 for (i = 0; i < bcm->nr_80211_available; i++) {
3204 err = bcm43xx_switch_core(bcm, &bcm->core_80211[i]);
3205 assert(err != -ENODEV);
3206 if (err)
3207 goto err_80211_unwind;
3208
3209 /* Enable the selected wireless core.
3210 * Connect PHY only on the first core.
3211 */
3212 if (!bcm43xx_core_enabled(bcm)) {
3213 if (bcm->nr_80211_available == 1) {
3214 connect_phy = bcm43xx_current_phy(bcm)->connected;
3215 } else {
3216 if (i == 0)
3217 connect_phy = 1;
3218 else
3219 connect_phy = 0;
3220 }
3221 bcm43xx_wireless_core_reset(bcm, connect_phy);
3222 }
3223
3224 if (i != 0)
3225 bcm43xx_wireless_core_mark_inactive(bcm, &bcm->core_80211[0]);
3226
3227 err = bcm43xx_wireless_core_init(bcm);
3228 if (err)
3229 goto err_80211_unwind;
3230
3231 if (i != 0) {
3232 bcm43xx_mac_suspend(bcm);
3233 bcm43xx_interrupt_disable(bcm, BCM43xx_IRQ_ALL);
3234 bcm43xx_radio_turn_off(bcm);
3235 }
3236 }
3237 bcm->active_80211_core = &bcm->core_80211[0];
3238 if (bcm->nr_80211_available >= 2) {
3239 bcm43xx_switch_core(bcm, &bcm->core_80211[0]);
3240 bcm43xx_mac_enable(bcm);
3241 }
3242 bcm43xx_macfilter_clear(bcm, BCM43xx_MACFILTER_ASSOC);
3243 bcm43xx_macfilter_set(bcm, BCM43xx_MACFILTER_SELF, (u8 *)(bcm->net_dev->dev_addr));
3244 dprintk(KERN_INFO PFX "80211 cores initialized\n");
3245 bcm43xx_security_init(bcm);
3246 bcm43xx_softmac_init(bcm);
3247
3248 bcm43xx_pctl_set_clock(bcm, BCM43xx_PCTL_CLK_DYNAMIC);
3249
3250 if (bcm43xx_current_radio(bcm)->initial_channel != 0xFF) {
3251 bcm43xx_mac_suspend(bcm);
3252 bcm43xx_radio_selectchannel(bcm, bcm43xx_current_radio(bcm)->initial_channel, 0);
3253 bcm43xx_mac_enable(bcm);
3254 }
3255
3256 /* Initialization of the board is done. Flag it as such. */
3257 bcm43xx_lock(bcm, flags);
3258 bcm->initialized = 1;
3259 bcm43xx_unlock(bcm, flags);
3260
3261 bcm43xx_periodic_tasks_setup(bcm);
3262 bcm43xx_sysfs_register(bcm);
3263 //FIXME: check for bcm43xx_sysfs_register failure. This function is a bit messy regarding unwinding, though...
3264
3265 assert(err == 0);
3266out:
3267 return err;
3268
3269err_80211_unwind:
3270 tasklet_disable(&bcm->isr_tasklet);
3271 /* unwind all 80211 initialization */
3272 for (i = 0; i < bcm->nr_80211_available; i++) {
3273 if (!bcm->core_80211[i].initialized)
3274 continue;
3275 bcm43xx_interrupt_disable(bcm, BCM43xx_IRQ_ALL);
3276 bcm43xx_wireless_core_cleanup(bcm);
3277 }
3278err_crystal_off:
3279 bcm43xx_pctl_set_crystal(bcm, 0);
3280 goto out;
3281}
3282
3283static void bcm43xx_detach_board(struct bcm43xx_private *bcm)
3284{
3285 struct pci_dev *pci_dev = bcm->pci_dev;
3286 int i;
3287
3288 bcm43xx_chipset_detach(bcm);
3289 /* Do _not_ access the chip, after it is detached. */
3290 iounmap(bcm->mmio_addr);
3291
3292 pci_release_regions(pci_dev);
3293 pci_disable_device(pci_dev);
3294
3295 /* Free allocated structures/fields */
3296 for (i = 0; i < BCM43xx_MAX_80211_CORES; i++) {
3297 kfree(bcm->core_80211_ext[i].phy._lo_pairs);
3298 if (bcm->core_80211_ext[i].phy.dyn_tssi_tbl)
3299 kfree(bcm->core_80211_ext[i].phy.tssi2dbm);
3300 }
3301}
3302
3303static int bcm43xx_read_phyinfo(struct bcm43xx_private *bcm)
3304{
3305 struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
3306 u16 value;
3307 u8 phy_version;
3308 u8 phy_type;
3309 u8 phy_rev;
3310 int phy_rev_ok = 1;
3311 void *p;
3312
3313 value = bcm43xx_read16(bcm, BCM43xx_MMIO_PHY_VER);
3314
3315 phy_version = (value & 0xF000) >> 12;
3316 phy_type = (value & 0x0F00) >> 8;
3317 phy_rev = (value & 0x000F);
3318
3319 dprintk(KERN_INFO PFX "Detected PHY: Version: %x, Type %x, Revision %x\n",
3320 phy_version, phy_type, phy_rev);
3321
3322 switch (phy_type) {
3323 case BCM43xx_PHYTYPE_A:
3324 if (phy_rev >= 4)
3325 phy_rev_ok = 0;
3326 /*FIXME: We need to switch the ieee->modulation, etc.. flags,
3327 * if we switch 80211 cores after init is done.
3328 * As we do not implement on the fly switching between
3329 * wireless cores, I will leave this as a future task.
3330 */
3331 bcm->ieee->modulation = IEEE80211_OFDM_MODULATION;
3332 bcm->ieee->mode = IEEE_A;
3333 bcm->ieee->freq_band = IEEE80211_52GHZ_BAND |
3334 IEEE80211_24GHZ_BAND;
3335 break;
3336 case BCM43xx_PHYTYPE_B:
3337 if (phy_rev != 2 && phy_rev != 4 && phy_rev != 6 && phy_rev != 7)
3338 phy_rev_ok = 0;
3339 bcm->ieee->modulation = IEEE80211_CCK_MODULATION;
3340 bcm->ieee->mode = IEEE_B;
3341 bcm->ieee->freq_band = IEEE80211_24GHZ_BAND;
3342 break;
3343 case BCM43xx_PHYTYPE_G:
3344 if (phy_rev > 7)
3345 phy_rev_ok = 0;
3346 bcm->ieee->modulation = IEEE80211_OFDM_MODULATION |
3347 IEEE80211_CCK_MODULATION;
3348 bcm->ieee->mode = IEEE_G;
3349 bcm->ieee->freq_band = IEEE80211_24GHZ_BAND;
3350 break;
3351 default:
3352 printk(KERN_ERR PFX "Error: Unknown PHY Type %x\n",
3353 phy_type);
3354 return -ENODEV;
3355 };
3356 if (!phy_rev_ok) {
3357 printk(KERN_WARNING PFX "Invalid PHY Revision %x\n",
3358 phy_rev);
3359 }
3360
3361 phy->version = phy_version;
3362 phy->type = phy_type;
3363 phy->rev = phy_rev;
3364 if ((phy_type == BCM43xx_PHYTYPE_B) || (phy_type == BCM43xx_PHYTYPE_G)) {
3365 p = kzalloc(sizeof(struct bcm43xx_lopair) * BCM43xx_LO_COUNT,
3366 GFP_KERNEL);
3367 if (!p)
3368 return -ENOMEM;
3369 phy->_lo_pairs = p;
3370 }
3371
3372 return 0;
3373}
3374
3375static int bcm43xx_attach_board(struct bcm43xx_private *bcm)
3376{
3377 struct pci_dev *pci_dev = bcm->pci_dev;
3378 struct net_device *net_dev = bcm->net_dev;
3379 int err;
3380 int i;
3381 unsigned long mmio_start, mmio_flags, mmio_len;
3382 u32 coremask;
3383
3384 err = pci_enable_device(pci_dev);
3385 if (err) {
3386 printk(KERN_ERR PFX "unable to wake up pci device (%i)\n", err);
3387 goto out;
3388 }
3389 mmio_start = pci_resource_start(pci_dev, 0);
3390 mmio_flags = pci_resource_flags(pci_dev, 0);
3391 mmio_len = pci_resource_len(pci_dev, 0);
3392 if (!(mmio_flags & IORESOURCE_MEM)) {
3393 printk(KERN_ERR PFX
3394 "%s, region #0 not an MMIO resource, aborting\n",
3395 pci_name(pci_dev));
3396 err = -ENODEV;
3397 goto err_pci_disable;
3398 }
3399 err = pci_request_regions(pci_dev, KBUILD_MODNAME);
3400 if (err) {
3401 printk(KERN_ERR PFX
3402 "could not access PCI resources (%i)\n", err);
3403 goto err_pci_disable;
3404 }
3405 /* enable PCI bus-mastering */
3406 pci_set_master(pci_dev);
3407 bcm->mmio_addr = ioremap(mmio_start, mmio_len);
3408 if (!bcm->mmio_addr) {
3409 printk(KERN_ERR PFX "%s: cannot remap MMIO, aborting\n",
3410 pci_name(pci_dev));
3411 err = -EIO;
3412 goto err_pci_release;
3413 }
3414 bcm->mmio_len = mmio_len;
3415 net_dev->base_addr = (unsigned long)bcm->mmio_addr;
3416
3417 bcm43xx_pci_read_config16(bcm, PCI_SUBSYSTEM_VENDOR_ID,
3418 &bcm->board_vendor);
3419 bcm43xx_pci_read_config16(bcm, PCI_SUBSYSTEM_ID,
3420 &bcm->board_type);
3421 bcm43xx_pci_read_config16(bcm, PCI_REVISION_ID,
3422 &bcm->board_revision);
3423
3424 err = bcm43xx_chipset_attach(bcm);
3425 if (err)
3426 goto err_iounmap;
3427 err = bcm43xx_pctl_init(bcm);
3428 if (err)
3429 goto err_chipset_detach;
3430 err = bcm43xx_probe_cores(bcm);
3431 if (err)
3432 goto err_chipset_detach;
3433
3434 /* Attach all IO cores to the backplane. */
3435 coremask = 0;
3436 for (i = 0; i < bcm->nr_80211_available; i++)
3437 coremask |= (1 << bcm->core_80211[i].index);
3438 //FIXME: Also attach some non80211 cores?
3439 err = bcm43xx_setup_backplane_pci_connection(bcm, coremask);
3440 if (err) {
3441 printk(KERN_ERR PFX "Backplane->PCI connection failed!\n");
3442 goto err_chipset_detach;
3443 }
3444
3445 err = bcm43xx_sprom_extract(bcm);
3446 if (err)
3447 goto err_chipset_detach;
3448 err = bcm43xx_leds_init(bcm);
3449 if (err)
3450 goto err_chipset_detach;
3451
3452 for (i = 0; i < bcm->nr_80211_available; i++) {
3453 err = bcm43xx_switch_core(bcm, &bcm->core_80211[i]);
3454 assert(err != -ENODEV);
3455 if (err)
3456 goto err_80211_unwind;
3457
3458 /* Enable the selected wireless core.
3459 * Connect PHY only on the first core.
3460 */
3461 bcm43xx_wireless_core_reset(bcm, (i == 0));
3462
3463 err = bcm43xx_read_phyinfo(bcm);
3464 if (err && (i == 0))
3465 goto err_80211_unwind;
3466
3467 err = bcm43xx_read_radioinfo(bcm);
3468 if (err && (i == 0))
3469 goto err_80211_unwind;
3470
3471 err = bcm43xx_validate_chip(bcm);
3472 if (err && (i == 0))
3473 goto err_80211_unwind;
3474
3475 bcm43xx_radio_turn_off(bcm);
3476 err = bcm43xx_phy_init_tssi2dbm_table(bcm);
3477 if (err)
3478 goto err_80211_unwind;
3479 bcm43xx_wireless_core_disable(bcm);
3480 }
3481 bcm43xx_pctl_set_crystal(bcm, 0);
3482
3483 /* Set the MAC address in the networking subsystem */
3484 if (bcm43xx_current_phy(bcm)->type == BCM43xx_PHYTYPE_A)
3485 memcpy(bcm->net_dev->dev_addr, bcm->sprom.et1macaddr, 6);
3486 else
3487 memcpy(bcm->net_dev->dev_addr, bcm->sprom.il0macaddr, 6);
3488
3489 bcm43xx_geo_init(bcm);
3490
3491 snprintf(bcm->nick, IW_ESSID_MAX_SIZE,
3492 "Broadcom %04X", bcm->chip_id);
3493
3494 assert(err == 0);
3495out:
3496 return err;
3497
3498err_80211_unwind:
3499 for (i = 0; i < BCM43xx_MAX_80211_CORES; i++) {
3500 kfree(bcm->core_80211_ext[i].phy._lo_pairs);
3501 if (bcm->core_80211_ext[i].phy.dyn_tssi_tbl)
3502 kfree(bcm->core_80211_ext[i].phy.tssi2dbm);
3503 }
3504err_chipset_detach:
3505 bcm43xx_chipset_detach(bcm);
3506err_iounmap:
3507 iounmap(bcm->mmio_addr);
3508err_pci_release:
3509 pci_release_regions(pci_dev);
3510err_pci_disable:
3511 pci_disable_device(pci_dev);
3512 goto out;
3513}
3514
3515/* Do the Hardware IO operations to send the txb */
3516static inline int bcm43xx_tx(struct bcm43xx_private *bcm,
3517 struct ieee80211_txb *txb)
3518{
3519 int err = -ENODEV;
3520
3521 if (bcm43xx_using_pio(bcm))
3522 err = bcm43xx_pio_tx(bcm, txb);
3523 else
3524 err = bcm43xx_dma_tx(bcm, txb);
3525
3526 return err;
3527}
3528
3529static void bcm43xx_ieee80211_set_chan(struct net_device *net_dev,
3530 u8 channel)
3531{
3532 struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
3533 struct bcm43xx_radioinfo *radio;
3534 unsigned long flags;
3535
3536 bcm43xx_lock_mmio(bcm, flags);
3537 if (bcm->initialized) {
3538 bcm43xx_mac_suspend(bcm);
3539 bcm43xx_radio_selectchannel(bcm, channel, 0);
3540 bcm43xx_mac_enable(bcm);
3541 } else {
3542 radio = bcm43xx_current_radio(bcm);
3543 radio->initial_channel = channel;
3544 }
3545 bcm43xx_unlock_mmio(bcm, flags);
3546}
3547
3548/* set_security() callback in struct ieee80211_device */
3549static void bcm43xx_ieee80211_set_security(struct net_device *net_dev,
3550 struct ieee80211_security *sec)
3551{
3552 struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
3553 struct ieee80211_security *secinfo = &bcm->ieee->sec;
3554 unsigned long flags;
3555 int keyidx;
3556
3557 dprintk(KERN_INFO PFX "set security called\n");
3558
3559 bcm43xx_lock_mmio(bcm, flags);
3560
3561 for (keyidx = 0; keyidx<WEP_KEYS; keyidx++)
3562 if (sec->flags & (1<<keyidx)) {
3563 secinfo->encode_alg[keyidx] = sec->encode_alg[keyidx];
3564 secinfo->key_sizes[keyidx] = sec->key_sizes[keyidx];
3565 memcpy(secinfo->keys[keyidx], sec->keys[keyidx], SCM_KEY_LEN);
3566 }
3567
3568 if (sec->flags & SEC_ACTIVE_KEY) {
3569 secinfo->active_key = sec->active_key;
3570 dprintk(KERN_INFO PFX " .active_key = %d\n", sec->active_key);
3571 }
3572 if (sec->flags & SEC_UNICAST_GROUP) {
3573 secinfo->unicast_uses_group = sec->unicast_uses_group;
3574 dprintk(KERN_INFO PFX " .unicast_uses_group = %d\n", sec->unicast_uses_group);
3575 }
3576 if (sec->flags & SEC_LEVEL) {
3577 secinfo->level = sec->level;
3578 dprintk(KERN_INFO PFX " .level = %d\n", sec->level);
3579 }
3580 if (sec->flags & SEC_ENABLED) {
3581 secinfo->enabled = sec->enabled;
3582 dprintk(KERN_INFO PFX " .enabled = %d\n", sec->enabled);
3583 }
3584 if (sec->flags & SEC_ENCRYPT) {
3585 secinfo->encrypt = sec->encrypt;
3586 dprintk(KERN_INFO PFX " .encrypt = %d\n", sec->encrypt);
3587 }
3588 if (bcm->initialized && !bcm->ieee->host_encrypt) {
3589 if (secinfo->enabled) {
3590 /* upload WEP keys to hardware */
3591 char null_address[6] = { 0 };
3592 u8 algorithm = 0;
3593 for (keyidx = 0; keyidx<WEP_KEYS; keyidx++) {
3594 if (!(sec->flags & (1<<keyidx)))
3595 continue;
3596 switch (sec->encode_alg[keyidx]) {
3597 case SEC_ALG_NONE: algorithm = BCM43xx_SEC_ALGO_NONE; break;
3598 case SEC_ALG_WEP:
3599 algorithm = BCM43xx_SEC_ALGO_WEP;
3600 if (secinfo->key_sizes[keyidx] == 13)
3601 algorithm = BCM43xx_SEC_ALGO_WEP104;
3602 break;
3603 case SEC_ALG_TKIP:
3604 FIXME();
3605 algorithm = BCM43xx_SEC_ALGO_TKIP;
3606 break;
3607 case SEC_ALG_CCMP:
3608 FIXME();
3609 algorithm = BCM43xx_SEC_ALGO_AES;
3610 break;
3611 default:
3612 assert(0);
3613 break;
3614 }
3615 bcm43xx_key_write(bcm, keyidx, algorithm, sec->keys[keyidx], secinfo->key_sizes[keyidx], &null_address[0]);
3616 bcm->key[keyidx].enabled = 1;
3617 bcm->key[keyidx].algorithm = algorithm;
3618 }
3619 } else
3620 bcm43xx_clear_keys(bcm);
3621 }
3622 bcm43xx_unlock_mmio(bcm, flags);
3623}
3624
3625/* hard_start_xmit() callback in struct ieee80211_device */
3626static int bcm43xx_ieee80211_hard_start_xmit(struct ieee80211_txb *txb,
3627 struct net_device *net_dev,
3628 int pri)
3629{
3630 struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
3631 int err = -ENODEV;
3632 unsigned long flags;
3633
3634 bcm43xx_lock_mmio(bcm, flags);
3635 if (likely(bcm->initialized))
3636 err = bcm43xx_tx(bcm, txb);
3637 bcm43xx_unlock_mmio(bcm, flags);
3638
3639 return err;
3640}
3641
3642static struct net_device_stats * bcm43xx_net_get_stats(struct net_device *net_dev)
3643{
3644 return &(bcm43xx_priv(net_dev)->ieee->stats);
3645}
3646
3647static void bcm43xx_net_tx_timeout(struct net_device *net_dev)
3648{
3649 struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
3650 unsigned long flags;
3651
3652 bcm43xx_lock_mmio(bcm, flags);
3653 bcm43xx_controller_restart(bcm, "TX timeout");
3654 bcm43xx_unlock_mmio(bcm, flags);
3655}
3656
3657#ifdef CONFIG_NET_POLL_CONTROLLER
3658static void bcm43xx_net_poll_controller(struct net_device *net_dev)
3659{
3660 struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
3661 unsigned long flags;
3662
3663 local_irq_save(flags);
3664 bcm43xx_interrupt_handler(bcm->irq, bcm, NULL);
3665 local_irq_restore(flags);
3666}
3667#endif /* CONFIG_NET_POLL_CONTROLLER */
3668
3669static int bcm43xx_net_open(struct net_device *net_dev)
3670{
3671 struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
3672
3673 return bcm43xx_init_board(bcm);
3674}
3675
3676static int bcm43xx_net_stop(struct net_device *net_dev)
3677{
3678 struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
3679
3680 ieee80211softmac_stop(net_dev);
3681 bcm43xx_disable_interrupts_sync(bcm, NULL);
3682 bcm43xx_free_board(bcm);
3683
3684 return 0;
3685}
3686
3687static int bcm43xx_init_private(struct bcm43xx_private *bcm,
3688 struct net_device *net_dev,
3689 struct pci_dev *pci_dev)
3690{
3691 int err;
3692
3693 bcm->ieee = netdev_priv(net_dev);
3694 bcm->softmac = ieee80211_priv(net_dev);
3695 bcm->softmac->set_channel = bcm43xx_ieee80211_set_chan;
3696
3697 bcm->irq_savedstate = BCM43xx_IRQ_INITIAL;
3698 bcm->pci_dev = pci_dev;
3699 bcm->net_dev = net_dev;
3700 bcm->bad_frames_preempt = modparam_bad_frames_preempt;
3701 spin_lock_init(&bcm->_lock);
3702 tasklet_init(&bcm->isr_tasklet,
3703 (void (*)(unsigned long))bcm43xx_interrupt_tasklet,
3704 (unsigned long)bcm);
3705 tasklet_disable_nosync(&bcm->isr_tasklet);
3706 if (modparam_pio) {
3707 bcm->__using_pio = 1;
3708 } else {
3709 err = pci_set_dma_mask(pci_dev, DMA_30BIT_MASK);
3710 err |= pci_set_consistent_dma_mask(pci_dev, DMA_30BIT_MASK);
3711 if (err) {
3712#ifdef CONFIG_BCM43XX_PIO
3713 printk(KERN_WARNING PFX "DMA not supported. Falling back to PIO.\n");
3714 bcm->__using_pio = 1;
3715#else
3716 printk(KERN_ERR PFX "FATAL: DMA not supported and PIO not configured. "
3717 "Recompile the driver with PIO support, please.\n");
3718 return -ENODEV;
3719#endif /* CONFIG_BCM43XX_PIO */
3720 }
3721 }
3722 bcm->rts_threshold = BCM43xx_DEFAULT_RTS_THRESHOLD;
3723
3724 /* default to sw encryption for now */
3725 bcm->ieee->host_build_iv = 0;
3726 bcm->ieee->host_encrypt = 1;
3727 bcm->ieee->host_decrypt = 1;
3728
3729 bcm->ieee->iw_mode = BCM43xx_INITIAL_IWMODE;
3730 bcm->ieee->tx_headroom = sizeof(struct bcm43xx_txhdr);
3731 bcm->ieee->set_security = bcm43xx_ieee80211_set_security;
3732 bcm->ieee->hard_start_xmit = bcm43xx_ieee80211_hard_start_xmit;
3733
3734 return 0;
3735}
3736
3737static int __devinit bcm43xx_init_one(struct pci_dev *pdev,
3738 const struct pci_device_id *ent)
3739{
3740 struct net_device *net_dev;
3741 struct bcm43xx_private *bcm;
3742 int err;
3743
3744#ifdef CONFIG_BCM947XX
3745 if ((pdev->bus->number == 0) && (pdev->device != 0x0800))
3746 return -ENODEV;
3747#endif
3748
3749#ifdef DEBUG_SINGLE_DEVICE_ONLY
3750 if (strcmp(pci_name(pdev), DEBUG_SINGLE_DEVICE_ONLY))
3751 return -ENODEV;
3752#endif
3753
3754 net_dev = alloc_ieee80211softmac(sizeof(*bcm));
3755 if (!net_dev) {
3756 printk(KERN_ERR PFX
3757 "could not allocate ieee80211 device %s\n",
3758 pci_name(pdev));
3759 err = -ENOMEM;
3760 goto out;
3761 }
3762 /* initialize the net_device struct */
3763 SET_MODULE_OWNER(net_dev);
3764 SET_NETDEV_DEV(net_dev, &pdev->dev);
3765
3766 net_dev->open = bcm43xx_net_open;
3767 net_dev->stop = bcm43xx_net_stop;
3768 net_dev->get_stats = bcm43xx_net_get_stats;
3769 net_dev->tx_timeout = bcm43xx_net_tx_timeout;
3770#ifdef CONFIG_NET_POLL_CONTROLLER
3771 net_dev->poll_controller = bcm43xx_net_poll_controller;
3772#endif
3773 net_dev->wireless_handlers = &bcm43xx_wx_handlers_def;
3774 net_dev->irq = pdev->irq;
3775 SET_ETHTOOL_OPS(net_dev, &bcm43xx_ethtool_ops);
3776
3777 /* initialize the bcm43xx_private struct */
3778 bcm = bcm43xx_priv(net_dev);
3779 memset(bcm, 0, sizeof(*bcm));
3780 err = bcm43xx_init_private(bcm, net_dev, pdev);
3781 if (err)
3782 goto err_free_netdev;
3783
3784 pci_set_drvdata(pdev, net_dev);
3785
3786 err = bcm43xx_attach_board(bcm);
3787 if (err)
3788 goto err_free_netdev;
3789
3790 err = register_netdev(net_dev);
3791 if (err) {
3792 printk(KERN_ERR PFX "Cannot register net device, "
3793 "aborting.\n");
3794 err = -ENOMEM;
3795 goto err_detach_board;
3796 }
3797
3798 bcm43xx_debugfs_add_device(bcm);
3799
3800 assert(err == 0);
3801out:
3802 return err;
3803
3804err_detach_board:
3805 bcm43xx_detach_board(bcm);
3806err_free_netdev:
3807 free_ieee80211softmac(net_dev);
3808 goto out;
3809}
3810
3811static void __devexit bcm43xx_remove_one(struct pci_dev *pdev)
3812{
3813 struct net_device *net_dev = pci_get_drvdata(pdev);
3814 struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
3815
3816 bcm43xx_debugfs_remove_device(bcm);
3817 unregister_netdev(net_dev);
3818 bcm43xx_detach_board(bcm);
3819 assert(bcm->ucode == NULL);
3820 free_ieee80211softmac(net_dev);
3821}
3822
3823/* Hard-reset the chip. Do not call this directly.
3824 * Use bcm43xx_controller_restart()
3825 */
3826static void bcm43xx_chip_reset(void *_bcm)
3827{
3828 struct bcm43xx_private *bcm = _bcm;
3829 struct net_device *net_dev = bcm->net_dev;
3830 struct pci_dev *pci_dev = bcm->pci_dev;
3831 int err;
3832 int was_initialized = bcm->initialized;
3833
3834 netif_stop_queue(bcm->net_dev);
3835 tasklet_disable(&bcm->isr_tasklet);
3836
3837 bcm->firmware_norelease = 1;
3838 if (was_initialized)
3839 bcm43xx_free_board(bcm);
3840 bcm->firmware_norelease = 0;
3841 bcm43xx_detach_board(bcm);
3842 err = bcm43xx_init_private(bcm, net_dev, pci_dev);
3843 if (err)
3844 goto failure;
3845 err = bcm43xx_attach_board(bcm);
3846 if (err)
3847 goto failure;
3848 if (was_initialized) {
3849 err = bcm43xx_init_board(bcm);
3850 if (err)
3851 goto failure;
3852 }
3853 netif_wake_queue(bcm->net_dev);
3854 printk(KERN_INFO PFX "Controller restarted\n");
3855
3856 return;
3857failure:
3858 printk(KERN_ERR PFX "Controller restart failed\n");
3859}
3860
3861/* Hard-reset the chip.
3862 * This can be called from interrupt or process context.
3863 * Make sure to _not_ re-enable device interrupts after this has been called.
3864*/
3865void bcm43xx_controller_restart(struct bcm43xx_private *bcm, const char *reason)
3866{
3867 bcm43xx_interrupt_disable(bcm, BCM43xx_IRQ_ALL);
3868 bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD); /* dummy read */
3869 printk(KERN_ERR PFX "Controller RESET (%s) ...\n", reason);
3870 INIT_WORK(&bcm->restart_work, bcm43xx_chip_reset, bcm);
3871 schedule_work(&bcm->restart_work);
3872}
3873
3874#ifdef CONFIG_PM
3875
3876static int bcm43xx_suspend(struct pci_dev *pdev, pm_message_t state)
3877{
3878 struct net_device *net_dev = pci_get_drvdata(pdev);
3879 struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
3880 unsigned long flags;
3881 int try_to_shutdown = 0, err;
3882
3883 dprintk(KERN_INFO PFX "Suspending...\n");
3884
3885 bcm43xx_lock(bcm, flags);
3886 bcm->was_initialized = bcm->initialized;
3887 if (bcm->initialized)
3888 try_to_shutdown = 1;
3889 bcm43xx_unlock(bcm, flags);
3890
3891 netif_device_detach(net_dev);
3892 if (try_to_shutdown) {
3893 ieee80211softmac_stop(net_dev);
3894 err = bcm43xx_disable_interrupts_sync(bcm, &bcm->irq_savedstate);
3895 if (unlikely(err)) {
3896 dprintk(KERN_ERR PFX "Suspend failed.\n");
3897 return -EAGAIN;
3898 }
3899 bcm->firmware_norelease = 1;
3900 bcm43xx_free_board(bcm);
3901 bcm->firmware_norelease = 0;
3902 }
3903 bcm43xx_chipset_detach(bcm);
3904
3905 pci_save_state(pdev);
3906 pci_disable_device(pdev);
3907 pci_set_power_state(pdev, pci_choose_state(pdev, state));
3908
3909 dprintk(KERN_INFO PFX "Device suspended.\n");
3910
3911 return 0;
3912}
3913
3914static int bcm43xx_resume(struct pci_dev *pdev)
3915{
3916 struct net_device *net_dev = pci_get_drvdata(pdev);
3917 struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
3918 int err = 0;
3919
3920 dprintk(KERN_INFO PFX "Resuming...\n");
3921
3922 pci_set_power_state(pdev, 0);
3923 pci_enable_device(pdev);
3924 pci_restore_state(pdev);
3925
3926 bcm43xx_chipset_attach(bcm);
3927 if (bcm->was_initialized) {
3928 bcm->irq_savedstate = BCM43xx_IRQ_INITIAL;
3929 err = bcm43xx_init_board(bcm);
3930 }
3931 if (err) {
3932 printk(KERN_ERR PFX "Resume failed!\n");
3933 return err;
3934 }
3935
3936 netif_device_attach(net_dev);
3937
3938 /*FIXME: This should be handled by softmac instead. */
3939 schedule_work(&bcm->softmac->associnfo.work);
3940
3941 dprintk(KERN_INFO PFX "Device resumed.\n");
3942
3943 return 0;
3944}
3945
3946#endif /* CONFIG_PM */
3947
3948static struct pci_driver bcm43xx_pci_driver = {
3949 .name = KBUILD_MODNAME,
3950 .id_table = bcm43xx_pci_tbl,
3951 .probe = bcm43xx_init_one,
3952 .remove = __devexit_p(bcm43xx_remove_one),
3953#ifdef CONFIG_PM
3954 .suspend = bcm43xx_suspend,
3955 .resume = bcm43xx_resume,
3956#endif /* CONFIG_PM */
3957};
3958
3959static int __init bcm43xx_init(void)
3960{
3961 printk(KERN_INFO KBUILD_MODNAME " driver\n");
3962 bcm43xx_debugfs_init();
3963 return pci_register_driver(&bcm43xx_pci_driver);
3964}
3965
3966static void __exit bcm43xx_exit(void)
3967{
3968 pci_unregister_driver(&bcm43xx_pci_driver);
3969 bcm43xx_debugfs_exit();
3970}
3971
3972module_init(bcm43xx_init)
3973module_exit(bcm43xx_exit)
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_main.h b/drivers/net/wireless/bcm43xx/bcm43xx_main.h
new file mode 100644
index 000000000000..eca79a38594a
--- /dev/null
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_main.h
@@ -0,0 +1,168 @@
1/*
2
3 Broadcom BCM43xx wireless driver
4
5 Copyright (c) 2005 Martin Langer <martin-langer@gmx.de>,
6 Stefano Brivio <st3@riseup.net>
7 Michael Buesch <mbuesch@freenet.de>
8 Danny van Dyk <kugelfang@gentoo.org>
9 Andreas Jaggi <andreas.jaggi@waterwave.ch>
10
11 Some parts of the code in this file are derived from the ipw2200
12 driver Copyright(c) 2003 - 2004 Intel Corporation.
13
14 This program is free software; you can redistribute it and/or modify
15 it under the terms of the GNU General Public License as published by
16 the Free Software Foundation; either version 2 of the License, or
17 (at your option) any later version.
18
19 This program is distributed in the hope that it will be useful,
20 but WITHOUT ANY WARRANTY; without even the implied warranty of
21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 GNU General Public License for more details.
23
24 You should have received a copy of the GNU General Public License
25 along with this program; see the file COPYING. If not, write to
26 the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,
27 Boston, MA 02110-1301, USA.
28
29*/
30
31#ifndef BCM43xx_MAIN_H_
32#define BCM43xx_MAIN_H_
33
34#include "bcm43xx.h"
35
36#ifdef CONFIG_BCM947XX
37#define atoi(str) simple_strtoul(((str != NULL) ? str : ""), NULL, 0)
38
39static inline void e_aton(char *str, char *dest)
40{
41 int i = 0;
42 u16 *d = (u16 *) dest;
43
44 for (;;) {
45 dest[i++] = (char) simple_strtoul(str, NULL, 16);
46 str += 2;
47 if (!*str++ || i == 6)
48 break;
49 }
50 for (i = 0; i < 3; i++)
51 d[i] = cpu_to_be16(d[i]);
52}
53#endif
54
55#define P4D_BYT3S(magic, nr_bytes) u8 __p4dding##magic[nr_bytes]
56#define P4D_BYTES(line, nr_bytes) P4D_BYT3S(line, nr_bytes)
57/* Magic helper macro to pad structures. Ignore those above. It's magic. */
58#define PAD_BYTES(nr_bytes) P4D_BYTES( __LINE__ , (nr_bytes))
59
60
61/* Lightweight function to convert a frequency (in Mhz) to a channel number. */
62static inline
63u8 bcm43xx_freq_to_channel_a(int freq)
64{
65 return ((freq - 5000) / 5);
66}
67static inline
68u8 bcm43xx_freq_to_channel_bg(int freq)
69{
70 u8 channel;
71
72 if (freq == 2484)
73 channel = 14;
74 else
75 channel = (freq - 2407) / 5;
76
77 return channel;
78}
79static inline
80u8 bcm43xx_freq_to_channel(struct bcm43xx_private *bcm,
81 int freq)
82{
83 if (bcm43xx_current_phy(bcm)->type == BCM43xx_PHYTYPE_A)
84 return bcm43xx_freq_to_channel_a(freq);
85 return bcm43xx_freq_to_channel_bg(freq);
86}
87
88/* Lightweight function to convert a channel number to a frequency (in Mhz). */
89static inline
90int bcm43xx_channel_to_freq_a(u8 channel)
91{
92 return (5000 + (5 * channel));
93}
94static inline
95int bcm43xx_channel_to_freq_bg(u8 channel)
96{
97 int freq;
98
99 if (channel == 14)
100 freq = 2484;
101 else
102 freq = 2407 + (5 * channel);
103
104 return freq;
105}
106static inline
107int bcm43xx_channel_to_freq(struct bcm43xx_private *bcm,
108 u8 channel)
109{
110 if (bcm43xx_current_phy(bcm)->type == BCM43xx_PHYTYPE_A)
111 return bcm43xx_channel_to_freq_a(channel);
112 return bcm43xx_channel_to_freq_bg(channel);
113}
114
115/* Lightweight function to check if a channel number is valid.
116 * Note that this does _NOT_ check for geographical restrictions!
117 */
118static inline
119int bcm43xx_is_valid_channel_a(u8 channel)
120{
121 return (channel <= 200);
122}
123static inline
124int bcm43xx_is_valid_channel_bg(u8 channel)
125{
126 return (channel >= 1 && channel <= 14);
127}
128static inline
129int bcm43xx_is_valid_channel(struct bcm43xx_private *bcm,
130 u8 channel)
131{
132 if (bcm43xx_current_phy(bcm)->type == BCM43xx_PHYTYPE_A)
133 return bcm43xx_is_valid_channel_a(channel);
134 return bcm43xx_is_valid_channel_bg(channel);
135}
136
137void bcm43xx_tsf_read(struct bcm43xx_private *bcm, u64 *tsf);
138void bcm43xx_tsf_write(struct bcm43xx_private *bcm, u64 tsf);
139
140void bcm43xx_set_iwmode(struct bcm43xx_private *bcm,
141 int iw_mode);
142
143u32 bcm43xx_shm_read32(struct bcm43xx_private *bcm,
144 u16 routing, u16 offset);
145u16 bcm43xx_shm_read16(struct bcm43xx_private *bcm,
146 u16 routing, u16 offset);
147void bcm43xx_shm_write32(struct bcm43xx_private *bcm,
148 u16 routing, u16 offset,
149 u32 value);
150void bcm43xx_shm_write16(struct bcm43xx_private *bcm,
151 u16 routing, u16 offset,
152 u16 value);
153
154void bcm43xx_dummy_transmission(struct bcm43xx_private *bcm);
155
156int bcm43xx_switch_core(struct bcm43xx_private *bcm, struct bcm43xx_coreinfo *new_core);
157
158void bcm43xx_wireless_core_reset(struct bcm43xx_private *bcm, int connect_phy);
159
160void bcm43xx_mac_suspend(struct bcm43xx_private *bcm);
161void bcm43xx_mac_enable(struct bcm43xx_private *bcm);
162
163void bcm43xx_controller_restart(struct bcm43xx_private *bcm, const char *reason);
164
165int bcm43xx_sprom_read(struct bcm43xx_private *bcm, u16 *sprom);
166int bcm43xx_sprom_write(struct bcm43xx_private *bcm, const u16 *sprom);
167
168#endif /* BCM43xx_MAIN_H_ */
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_phy.c b/drivers/net/wireless/bcm43xx/bcm43xx_phy.c
new file mode 100644
index 000000000000..0a66f43ca0c0
--- /dev/null
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_phy.c
@@ -0,0 +1,2345 @@
1/*
2
3 Broadcom BCM43xx wireless driver
4
5 Copyright (c) 2005 Martin Langer <martin-langer@gmx.de>,
6 Stefano Brivio <st3@riseup.net>
7 Michael Buesch <mbuesch@freenet.de>
8 Danny van Dyk <kugelfang@gentoo.org>
9 Andreas Jaggi <andreas.jaggi@waterwave.ch>
10
11 Some parts of the code in this file are derived from the ipw2200
12 driver Copyright(c) 2003 - 2004 Intel Corporation.
13
14 This program is free software; you can redistribute it and/or modify
15 it under the terms of the GNU General Public License as published by
16 the Free Software Foundation; either version 2 of the License, or
17 (at your option) any later version.
18
19 This program is distributed in the hope that it will be useful,
20 but WITHOUT ANY WARRANTY; without even the implied warranty of
21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 GNU General Public License for more details.
23
24 You should have received a copy of the GNU General Public License
25 along with this program; see the file COPYING. If not, write to
26 the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,
27 Boston, MA 02110-1301, USA.
28
29*/
30
31#include <linux/delay.h>
32#include <linux/pci.h>
33#include <linux/types.h>
34
35#include "bcm43xx.h"
36#include "bcm43xx_phy.h"
37#include "bcm43xx_main.h"
38#include "bcm43xx_radio.h"
39#include "bcm43xx_ilt.h"
40#include "bcm43xx_power.h"
41
42
43static const s8 bcm43xx_tssi2dbm_b_table[] = {
44 0x4D, 0x4C, 0x4B, 0x4A,
45 0x4A, 0x49, 0x48, 0x47,
46 0x47, 0x46, 0x45, 0x45,
47 0x44, 0x43, 0x42, 0x42,
48 0x41, 0x40, 0x3F, 0x3E,
49 0x3D, 0x3C, 0x3B, 0x3A,
50 0x39, 0x38, 0x37, 0x36,
51 0x35, 0x34, 0x32, 0x31,
52 0x30, 0x2F, 0x2D, 0x2C,
53 0x2B, 0x29, 0x28, 0x26,
54 0x25, 0x23, 0x21, 0x1F,
55 0x1D, 0x1A, 0x17, 0x14,
56 0x10, 0x0C, 0x06, 0x00,
57 -7, -7, -7, -7,
58 -7, -7, -7, -7,
59 -7, -7, -7, -7,
60};
61
62static const s8 bcm43xx_tssi2dbm_g_table[] = {
63 77, 77, 77, 76,
64 76, 76, 75, 75,
65 74, 74, 73, 73,
66 73, 72, 72, 71,
67 71, 70, 70, 69,
68 68, 68, 67, 67,
69 66, 65, 65, 64,
70 63, 63, 62, 61,
71 60, 59, 58, 57,
72 56, 55, 54, 53,
73 52, 50, 49, 47,
74 45, 43, 40, 37,
75 33, 28, 22, 14,
76 5, -7, -20, -20,
77 -20, -20, -20, -20,
78 -20, -20, -20, -20,
79};
80
81static void bcm43xx_phy_initg(struct bcm43xx_private *bcm);
82
83
84void bcm43xx_raw_phy_lock(struct bcm43xx_private *bcm)
85{
86 struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
87
88 assert(irqs_disabled());
89 if (bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD) == 0x00000000) {
90 phy->is_locked = 0;
91 return;
92 }
93 if (bcm->current_core->rev < 3) {
94 bcm43xx_mac_suspend(bcm);
95 spin_lock(&phy->lock);
96 } else {
97 if (bcm->ieee->iw_mode != IW_MODE_MASTER)
98 bcm43xx_power_saving_ctl_bits(bcm, -1, 1);
99 }
100 phy->is_locked = 1;
101}
102
103void bcm43xx_raw_phy_unlock(struct bcm43xx_private *bcm)
104{
105 struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
106
107 assert(irqs_disabled());
108 if (bcm->current_core->rev < 3) {
109 if (phy->is_locked) {
110 spin_unlock(&phy->lock);
111 bcm43xx_mac_enable(bcm);
112 }
113 } else {
114 if (bcm->ieee->iw_mode != IW_MODE_MASTER)
115 bcm43xx_power_saving_ctl_bits(bcm, -1, -1);
116 }
117 phy->is_locked = 0;
118}
119
120u16 bcm43xx_phy_read(struct bcm43xx_private *bcm, u16 offset)
121{
122 bcm43xx_write16(bcm, BCM43xx_MMIO_PHY_CONTROL, offset);
123 return bcm43xx_read16(bcm, BCM43xx_MMIO_PHY_DATA);
124}
125
126void bcm43xx_phy_write(struct bcm43xx_private *bcm, u16 offset, u16 val)
127{
128 bcm43xx_write16(bcm, BCM43xx_MMIO_PHY_CONTROL, offset);
129 mmiowb();
130 bcm43xx_write16(bcm, BCM43xx_MMIO_PHY_DATA, val);
131}
132
133void bcm43xx_phy_calibrate(struct bcm43xx_private *bcm)
134{
135 struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
136 unsigned long flags;
137
138 bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD); /* Dummy read. */
139 if (phy->calibrated)
140 return;
141 if (phy->type == BCM43xx_PHYTYPE_G && phy->rev == 1) {
142 /* We do not want to be preempted while calibrating
143 * the hardware.
144 */
145 local_irq_save(flags);
146
147 bcm43xx_wireless_core_reset(bcm, 0);
148 bcm43xx_phy_initg(bcm);
149 bcm43xx_wireless_core_reset(bcm, 1);
150
151 local_irq_restore(flags);
152 }
153 phy->calibrated = 1;
154}
155
156/* Connect the PHY
157 * http://bcm-specs.sipsolutions.net/SetPHY
158 */
159int bcm43xx_phy_connect(struct bcm43xx_private *bcm, int connect)
160{
161 struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
162 u32 flags;
163
164 if (bcm->current_core->rev < 5)
165 goto out;
166
167 flags = bcm43xx_read32(bcm, BCM43xx_CIR_SBTMSTATEHIGH);
168 if (connect) {
169 if (!(flags & 0x00010000))
170 return -ENODEV;
171 flags = bcm43xx_read32(bcm, BCM43xx_CIR_SBTMSTATELOW);
172 flags |= (0x800 << 18);
173 bcm43xx_write32(bcm, BCM43xx_CIR_SBTMSTATELOW, flags);
174 } else {
175 if (!(flags & 0x00020000))
176 return -ENODEV;
177 flags = bcm43xx_read32(bcm, BCM43xx_CIR_SBTMSTATELOW);
178 flags &= ~(0x800 << 18);
179 bcm43xx_write32(bcm, BCM43xx_CIR_SBTMSTATELOW, flags);
180 }
181out:
182 phy->connected = connect;
183 if (connect)
184 dprintk(KERN_INFO PFX "PHY connected\n");
185 else
186 dprintk(KERN_INFO PFX "PHY disconnected\n");
187
188 return 0;
189}
190
191/* intialize B PHY power control
192 * as described in http://bcm-specs.sipsolutions.net/InitPowerControl
193 */
194static void bcm43xx_phy_init_pctl(struct bcm43xx_private *bcm)
195{
196 struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
197 struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm);
198 u16 saved_batt = 0, saved_ratt = 0, saved_txctl1 = 0;
199 int must_reset_txpower = 0;
200
201 assert(phy->type != BCM43xx_PHYTYPE_A);
202 if ((bcm->board_vendor == PCI_VENDOR_ID_BROADCOM) &&
203 (bcm->board_type == 0x0416))
204 return;
205
206 bcm43xx_write16(bcm, 0x03E6, bcm43xx_read16(bcm, 0x03E6) & 0xFFDF);
207 bcm43xx_phy_write(bcm, 0x0028, 0x8018);
208
209 if (phy->type == BCM43xx_PHYTYPE_G) {
210 if (!phy->connected)
211 return;
212 bcm43xx_phy_write(bcm, 0x047A, 0xC111);
213 }
214 if (phy->savedpctlreg != 0xFFFF)
215 return;
216
217 if (phy->type == BCM43xx_PHYTYPE_B &&
218 phy->rev >= 2 &&
219 radio->version == 0x2050) {
220 bcm43xx_radio_write16(bcm, 0x0076,
221 bcm43xx_radio_read16(bcm, 0x0076) | 0x0084);
222 } else {
223 saved_batt = radio->baseband_atten;
224 saved_ratt = radio->radio_atten;
225 saved_txctl1 = radio->txctl1;
226 if ((radio->revision >= 6) && (radio->revision <= 8)
227 && /*FIXME: incomplete specs for 5 < revision < 9 */ 0)
228 bcm43xx_radio_set_txpower_bg(bcm, 0xB, 0x1F, 0);
229 else
230 bcm43xx_radio_set_txpower_bg(bcm, 0xB, 9, 0);
231 must_reset_txpower = 1;
232 }
233 bcm43xx_dummy_transmission(bcm);
234
235 phy->savedpctlreg = bcm43xx_phy_read(bcm, BCM43xx_PHY_G_PCTL);
236
237 if (must_reset_txpower)
238 bcm43xx_radio_set_txpower_bg(bcm, saved_batt, saved_ratt, saved_txctl1);
239 else
240 bcm43xx_radio_write16(bcm, 0x0076, bcm43xx_radio_read16(bcm, 0x0076) & 0xFF7B);
241 bcm43xx_radio_clear_tssi(bcm);
242}
243
244static void bcm43xx_phy_agcsetup(struct bcm43xx_private *bcm)
245{
246 struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
247 u16 offset = 0x0000;
248
249 if (phy->rev == 1)
250 offset = 0x4C00;
251
252 bcm43xx_ilt_write(bcm, offset, 0x00FE);
253 bcm43xx_ilt_write(bcm, offset + 1, 0x000D);
254 bcm43xx_ilt_write(bcm, offset + 2, 0x0013);
255 bcm43xx_ilt_write(bcm, offset + 3, 0x0019);
256
257 if (phy->rev == 1) {
258 bcm43xx_ilt_write(bcm, 0x1800, 0x2710);
259 bcm43xx_ilt_write(bcm, 0x1801, 0x9B83);
260 bcm43xx_ilt_write(bcm, 0x1802, 0x9B83);
261 bcm43xx_ilt_write(bcm, 0x1803, 0x0F8D);
262 bcm43xx_phy_write(bcm, 0x0455, 0x0004);
263 }
264
265 bcm43xx_phy_write(bcm, 0x04A5, (bcm43xx_phy_read(bcm, 0x04A5) & 0x00FF) | 0x5700);
266 bcm43xx_phy_write(bcm, 0x041A, (bcm43xx_phy_read(bcm, 0x041A) & 0xFF80) | 0x000F);
267 bcm43xx_phy_write(bcm, 0x041A, (bcm43xx_phy_read(bcm, 0x041A) & 0xC07F) | 0x2B80);
268 bcm43xx_phy_write(bcm, 0x048C, (bcm43xx_phy_read(bcm, 0x048C) & 0xF0FF) | 0x0300);
269
270 bcm43xx_radio_write16(bcm, 0x007A, bcm43xx_radio_read16(bcm, 0x007A) | 0x0008);
271
272 bcm43xx_phy_write(bcm, 0x04A0, (bcm43xx_phy_read(bcm, 0x04A0) & 0xFFF0) | 0x0008);
273 bcm43xx_phy_write(bcm, 0x04A1, (bcm43xx_phy_read(bcm, 0x04A1) & 0xF0FF) | 0x0600);
274 bcm43xx_phy_write(bcm, 0x04A2, (bcm43xx_phy_read(bcm, 0x04A2) & 0xF0FF) | 0x0700);
275 bcm43xx_phy_write(bcm, 0x04A0, (bcm43xx_phy_read(bcm, 0x04A0) & 0xF0FF) | 0x0100);
276
277 if (phy->rev == 1)
278 bcm43xx_phy_write(bcm, 0x04A2, (bcm43xx_phy_read(bcm, 0x04A2) & 0xFFF0) | 0x0007);
279
280 bcm43xx_phy_write(bcm, 0x0488, (bcm43xx_phy_read(bcm, 0x0488) & 0xFF00) | 0x001C);
281 bcm43xx_phy_write(bcm, 0x0488, (bcm43xx_phy_read(bcm, 0x0488) & 0xC0FF) | 0x0200);
282 bcm43xx_phy_write(bcm, 0x0496, (bcm43xx_phy_read(bcm, 0x0496) & 0xFF00) | 0x001C);
283 bcm43xx_phy_write(bcm, 0x0489, (bcm43xx_phy_read(bcm, 0x0489) & 0xFF00) | 0x0020);
284 bcm43xx_phy_write(bcm, 0x0489, (bcm43xx_phy_read(bcm, 0x0489) & 0xC0FF) | 0x0200);
285 bcm43xx_phy_write(bcm, 0x0482, (bcm43xx_phy_read(bcm, 0x0482) & 0xFF00) | 0x002E);
286 bcm43xx_phy_write(bcm, 0x0496, (bcm43xx_phy_read(bcm, 0x0496) & 0x00FF) | 0x1A00);
287 bcm43xx_phy_write(bcm, 0x0481, (bcm43xx_phy_read(bcm, 0x0481) & 0xFF00) | 0x0028);
288 bcm43xx_phy_write(bcm, 0x0481, (bcm43xx_phy_read(bcm, 0x0481) & 0x00FF) | 0x2C00);
289
290 if (phy->rev == 1) {
291 bcm43xx_phy_write(bcm, 0x0430, 0x092B);
292 bcm43xx_phy_write(bcm, 0x041B, (bcm43xx_phy_read(bcm, 0x041B) & 0xFFE1) | 0x0002);
293 } else {
294 bcm43xx_phy_write(bcm, 0x041B, bcm43xx_phy_read(bcm, 0x041B) & 0xFFE1);
295 bcm43xx_phy_write(bcm, 0x041F, 0x287A);
296 bcm43xx_phy_write(bcm, 0x0420, (bcm43xx_phy_read(bcm, 0x0420) & 0xFFF0) | 0x0004);
297 }
298
299 if (phy->rev > 2) {
300 bcm43xx_phy_write(bcm, 0x0422, 0x287A);
301 bcm43xx_phy_write(bcm, 0x0420, (bcm43xx_phy_read(bcm, 0x0420) & 0x0FFF) | 0x3000);
302 }
303
304 bcm43xx_phy_write(bcm, 0x04A8, (bcm43xx_phy_read(bcm, 0x04A8) & 0x8080) | 0x7874);
305 bcm43xx_phy_write(bcm, 0x048E, 0x1C00);
306
307 if (phy->rev == 1) {
308 bcm43xx_phy_write(bcm, 0x04AB, (bcm43xx_phy_read(bcm, 0x04AB) & 0xF0FF) | 0x0600);
309 bcm43xx_phy_write(bcm, 0x048B, 0x005E);
310 bcm43xx_phy_write(bcm, 0x048C, (bcm43xx_phy_read(bcm, 0x048C) & 0xFF00) | 0x001E);
311 bcm43xx_phy_write(bcm, 0x048D, 0x0002);
312 }
313
314 bcm43xx_ilt_write(bcm, offset + 0x0800, 0);
315 bcm43xx_ilt_write(bcm, offset + 0x0801, 7);
316 bcm43xx_ilt_write(bcm, offset + 0x0802, 16);
317 bcm43xx_ilt_write(bcm, offset + 0x0803, 28);
318}
319
320static void bcm43xx_phy_setupg(struct bcm43xx_private *bcm)
321{
322 struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
323 u16 i;
324
325 assert(phy->type == BCM43xx_PHYTYPE_G);
326 if (phy->rev == 1) {
327 bcm43xx_phy_write(bcm, 0x0406, 0x4F19);
328 bcm43xx_phy_write(bcm, BCM43xx_PHY_G_CRS,
329 (bcm43xx_phy_read(bcm, BCM43xx_PHY_G_CRS) & 0xFC3F) | 0x0340);
330 bcm43xx_phy_write(bcm, 0x042C, 0x005A);
331 bcm43xx_phy_write(bcm, 0x0427, 0x001A);
332
333 for (i = 0; i < BCM43xx_ILT_FINEFREQG_SIZE; i++)
334 bcm43xx_ilt_write(bcm, 0x5800 + i, bcm43xx_ilt_finefreqg[i]);
335 for (i = 0; i < BCM43xx_ILT_NOISEG1_SIZE; i++)
336 bcm43xx_ilt_write(bcm, 0x1800 + i, bcm43xx_ilt_noiseg1[i]);
337 for (i = 0; i < BCM43xx_ILT_ROTOR_SIZE; i++)
338 bcm43xx_ilt_write(bcm, 0x2000 + i, bcm43xx_ilt_rotor[i]);
339 } else {
340 /* nrssi values are signed 6-bit values. Not sure why we write 0x7654 here... */
341 bcm43xx_nrssi_hw_write(bcm, 0xBA98, (s16)0x7654);
342
343 if (phy->rev == 2) {
344 bcm43xx_phy_write(bcm, 0x04C0, 0x1861);
345 bcm43xx_phy_write(bcm, 0x04C1, 0x0271);
346 } else if (phy->rev > 2) {
347 bcm43xx_phy_write(bcm, 0x04C0, 0x0098);
348 bcm43xx_phy_write(bcm, 0x04C1, 0x0070);
349 bcm43xx_phy_write(bcm, 0x04C9, 0x0080);
350 }
351 bcm43xx_phy_write(bcm, 0x042B, bcm43xx_phy_read(bcm, 0x042B) | 0x800);
352
353 for (i = 0; i < 64; i++)
354 bcm43xx_ilt_write(bcm, 0x4000 + i, i);
355 for (i = 0; i < BCM43xx_ILT_NOISEG2_SIZE; i++)
356 bcm43xx_ilt_write(bcm, 0x1800 + i, bcm43xx_ilt_noiseg2[i]);
357 }
358
359 if (phy->rev <= 2)
360 for (i = 0; i < BCM43xx_ILT_NOISESCALEG_SIZE; i++)
361 bcm43xx_ilt_write(bcm, 0x1400 + i, bcm43xx_ilt_noisescaleg1[i]);
362 else if ((phy->rev == 7) && (bcm43xx_phy_read(bcm, 0x0449) & 0x0200))
363 for (i = 0; i < BCM43xx_ILT_NOISESCALEG_SIZE; i++)
364 bcm43xx_ilt_write(bcm, 0x1400 + i, bcm43xx_ilt_noisescaleg3[i]);
365 else
366 for (i = 0; i < BCM43xx_ILT_NOISESCALEG_SIZE; i++)
367 bcm43xx_ilt_write(bcm, 0x1400 + i, bcm43xx_ilt_noisescaleg2[i]);
368
369 if (phy->rev == 2)
370 for (i = 0; i < BCM43xx_ILT_SIGMASQR_SIZE; i++)
371 bcm43xx_ilt_write(bcm, 0x5000 + i, bcm43xx_ilt_sigmasqr1[i]);
372 else if ((phy->rev > 2) && (phy->rev <= 7))
373 for (i = 0; i < BCM43xx_ILT_SIGMASQR_SIZE; i++)
374 bcm43xx_ilt_write(bcm, 0x5000 + i, bcm43xx_ilt_sigmasqr2[i]);
375
376 if (phy->rev == 1) {
377 for (i = 0; i < BCM43xx_ILT_RETARD_SIZE; i++)
378 bcm43xx_ilt_write(bcm, 0x2400 + i, bcm43xx_ilt_retard[i]);
379 for (i = 0; i < 4; i++) {
380 bcm43xx_ilt_write(bcm, 0x5404 + i, 0x0020);
381 bcm43xx_ilt_write(bcm, 0x5408 + i, 0x0020);
382 bcm43xx_ilt_write(bcm, 0x540C + i, 0x0020);
383 bcm43xx_ilt_write(bcm, 0x5410 + i, 0x0020);
384 }
385 bcm43xx_phy_agcsetup(bcm);
386
387 if ((bcm->board_vendor == PCI_VENDOR_ID_BROADCOM) &&
388 (bcm->board_type == 0x0416) &&
389 (bcm->board_revision == 0x0017))
390 return;
391
392 bcm43xx_ilt_write(bcm, 0x5001, 0x0002);
393 bcm43xx_ilt_write(bcm, 0x5002, 0x0001);
394 } else {
395 for (i = 0; i <= 0x2F; i++)
396 bcm43xx_ilt_write(bcm, 0x1000 + i, 0x0820);
397 bcm43xx_phy_agcsetup(bcm);
398 bcm43xx_phy_read(bcm, 0x0400); /* dummy read */
399 bcm43xx_phy_write(bcm, 0x0403, 0x1000);
400 bcm43xx_ilt_write(bcm, 0x3C02, 0x000F);
401 bcm43xx_ilt_write(bcm, 0x3C03, 0x0014);
402
403 if ((bcm->board_vendor == PCI_VENDOR_ID_BROADCOM) &&
404 (bcm->board_type == 0x0416) &&
405 (bcm->board_revision == 0x0017))
406 return;
407
408 bcm43xx_ilt_write(bcm, 0x0401, 0x0002);
409 bcm43xx_ilt_write(bcm, 0x0402, 0x0001);
410 }
411}
412
413/* Initialize the noisescaletable for APHY */
414static void bcm43xx_phy_init_noisescaletbl(struct bcm43xx_private *bcm)
415{
416 struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
417 int i;
418
419 bcm43xx_phy_write(bcm, BCM43xx_PHY_ILT_A_CTRL, 0x1400);
420 for (i = 0; i < 12; i++) {
421 if (phy->rev == 2)
422 bcm43xx_phy_write(bcm, BCM43xx_PHY_ILT_A_DATA1, 0x6767);
423 else
424 bcm43xx_phy_write(bcm, BCM43xx_PHY_ILT_A_DATA1, 0x2323);
425 }
426 if (phy->rev == 2)
427 bcm43xx_phy_write(bcm, BCM43xx_PHY_ILT_A_DATA1, 0x6700);
428 else
429 bcm43xx_phy_write(bcm, BCM43xx_PHY_ILT_A_DATA1, 0x2300);
430 for (i = 0; i < 11; i++) {
431 if (phy->rev == 2)
432 bcm43xx_phy_write(bcm, BCM43xx_PHY_ILT_A_DATA1, 0x6767);
433 else
434 bcm43xx_phy_write(bcm, BCM43xx_PHY_ILT_A_DATA1, 0x2323);
435 }
436 if (phy->rev == 2)
437 bcm43xx_phy_write(bcm, BCM43xx_PHY_ILT_A_DATA1, 0x0067);
438 else
439 bcm43xx_phy_write(bcm, BCM43xx_PHY_ILT_A_DATA1, 0x0023);
440}
441
442static void bcm43xx_phy_setupa(struct bcm43xx_private *bcm)
443{
444 struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
445 u16 i;
446
447 assert(phy->type == BCM43xx_PHYTYPE_A);
448 switch (phy->rev) {
449 case 2:
450 bcm43xx_phy_write(bcm, 0x008E, 0x3800);
451 bcm43xx_phy_write(bcm, 0x0035, 0x03FF);
452 bcm43xx_phy_write(bcm, 0x0036, 0x0400);
453
454 bcm43xx_ilt_write(bcm, 0x3807, 0x0051);
455
456 bcm43xx_phy_write(bcm, 0x001C, 0x0FF9);
457 bcm43xx_phy_write(bcm, 0x0020, bcm43xx_phy_read(bcm, 0x0020) & 0xFF0F);
458 bcm43xx_ilt_write(bcm, 0x3C0C, 0x07BF);
459 bcm43xx_radio_write16(bcm, 0x0002, 0x07BF);
460
461 bcm43xx_phy_write(bcm, 0x0024, 0x4680);
462 bcm43xx_phy_write(bcm, 0x0020, 0x0003);
463 bcm43xx_phy_write(bcm, 0x001D, 0x0F40);
464 bcm43xx_phy_write(bcm, 0x001F, 0x1C00);
465
466 bcm43xx_phy_write(bcm, 0x002A, (bcm43xx_phy_read(bcm, 0x002A) & 0x00FF) | 0x0400);
467 bcm43xx_phy_write(bcm, 0x002B, bcm43xx_phy_read(bcm, 0x002B) & 0xFBFF);
468 bcm43xx_phy_write(bcm, 0x008E, 0x58C1);
469
470 bcm43xx_ilt_write(bcm, 0x0803, 0x000F);
471 bcm43xx_ilt_write(bcm, 0x0804, 0x001F);
472 bcm43xx_ilt_write(bcm, 0x0805, 0x002A);
473 bcm43xx_ilt_write(bcm, 0x0805, 0x0030);
474 bcm43xx_ilt_write(bcm, 0x0807, 0x003A);
475
476 bcm43xx_ilt_write(bcm, 0x0000, 0x0013);
477 bcm43xx_ilt_write(bcm, 0x0001, 0x0013);
478 bcm43xx_ilt_write(bcm, 0x0002, 0x0013);
479 bcm43xx_ilt_write(bcm, 0x0003, 0x0013);
480 bcm43xx_ilt_write(bcm, 0x0004, 0x0015);
481 bcm43xx_ilt_write(bcm, 0x0005, 0x0015);
482 bcm43xx_ilt_write(bcm, 0x0006, 0x0019);
483
484 bcm43xx_ilt_write(bcm, 0x0404, 0x0003);
485 bcm43xx_ilt_write(bcm, 0x0405, 0x0003);
486 bcm43xx_ilt_write(bcm, 0x0406, 0x0007);
487
488 for (i = 0; i < 16; i++)
489 bcm43xx_ilt_write(bcm, 0x4000 + i, (0x8 + i) & 0x000F);
490
491 bcm43xx_ilt_write(bcm, 0x3003, 0x1044);
492 bcm43xx_ilt_write(bcm, 0x3004, 0x7201);
493 bcm43xx_ilt_write(bcm, 0x3006, 0x0040);
494 bcm43xx_ilt_write(bcm, 0x3001, (bcm43xx_ilt_read(bcm, 0x3001) & 0x0010) | 0x0008);
495
496 for (i = 0; i < BCM43xx_ILT_FINEFREQA_SIZE; i++)
497 bcm43xx_ilt_write(bcm, 0x5800 + i, bcm43xx_ilt_finefreqa[i]);
498 for (i = 0; i < BCM43xx_ILT_NOISEA2_SIZE; i++)
499 bcm43xx_ilt_write(bcm, 0x1800 + i, bcm43xx_ilt_noisea2[i]);
500 for (i = 0; i < BCM43xx_ILT_ROTOR_SIZE; i++)
501 bcm43xx_ilt_write(bcm, 0x2000 + i, bcm43xx_ilt_rotor[i]);
502 bcm43xx_phy_init_noisescaletbl(bcm);
503 for (i = 0; i < BCM43xx_ILT_RETARD_SIZE; i++)
504 bcm43xx_ilt_write(bcm, 0x2400 + i, bcm43xx_ilt_retard[i]);
505 break;
506 case 3:
507 for (i = 0; i < 64; i++)
508 bcm43xx_ilt_write(bcm, 0x4000 + i, i);
509
510 bcm43xx_ilt_write(bcm, 0x3807, 0x0051);
511
512 bcm43xx_phy_write(bcm, 0x001C, 0x0FF9);
513 bcm43xx_phy_write(bcm, 0x0020, bcm43xx_phy_read(bcm, 0x0020) & 0xFF0F);
514 bcm43xx_radio_write16(bcm, 0x0002, 0x07BF);
515
516 bcm43xx_phy_write(bcm, 0x0024, 0x4680);
517 bcm43xx_phy_write(bcm, 0x0020, 0x0003);
518 bcm43xx_phy_write(bcm, 0x001D, 0x0F40);
519 bcm43xx_phy_write(bcm, 0x001F, 0x1C00);
520 bcm43xx_phy_write(bcm, 0x002A, (bcm43xx_phy_read(bcm, 0x002A) & 0x00FF) | 0x0400);
521
522 bcm43xx_ilt_write(bcm, 0x3001, (bcm43xx_ilt_read(bcm, 0x3001) & 0x0010) | 0x0008);
523 for (i = 0; i < BCM43xx_ILT_NOISEA3_SIZE; i++)
524 bcm43xx_ilt_write(bcm, 0x1800 + i, bcm43xx_ilt_noisea3[i]);
525 bcm43xx_phy_init_noisescaletbl(bcm);
526 for (i = 0; i < BCM43xx_ILT_SIGMASQR_SIZE; i++)
527 bcm43xx_ilt_write(bcm, 0x5000 + i, bcm43xx_ilt_sigmasqr1[i]);
528
529 bcm43xx_phy_write(bcm, 0x0003, 0x1808);
530
531 bcm43xx_ilt_write(bcm, 0x0803, 0x000F);
532 bcm43xx_ilt_write(bcm, 0x0804, 0x001F);
533 bcm43xx_ilt_write(bcm, 0x0805, 0x002A);
534 bcm43xx_ilt_write(bcm, 0x0805, 0x0030);
535 bcm43xx_ilt_write(bcm, 0x0807, 0x003A);
536
537 bcm43xx_ilt_write(bcm, 0x0000, 0x0013);
538 bcm43xx_ilt_write(bcm, 0x0001, 0x0013);
539 bcm43xx_ilt_write(bcm, 0x0002, 0x0013);
540 bcm43xx_ilt_write(bcm, 0x0003, 0x0013);
541 bcm43xx_ilt_write(bcm, 0x0004, 0x0015);
542 bcm43xx_ilt_write(bcm, 0x0005, 0x0015);
543 bcm43xx_ilt_write(bcm, 0x0006, 0x0019);
544
545 bcm43xx_ilt_write(bcm, 0x0404, 0x0003);
546 bcm43xx_ilt_write(bcm, 0x0405, 0x0003);
547 bcm43xx_ilt_write(bcm, 0x0406, 0x0007);
548
549 bcm43xx_ilt_write(bcm, 0x3C02, 0x000F);
550 bcm43xx_ilt_write(bcm, 0x3C03, 0x0014);
551 break;
552 default:
553 assert(0);
554 }
555}
556
557/* Initialize APHY. This is also called for the GPHY in some cases. */
558static void bcm43xx_phy_inita(struct bcm43xx_private *bcm)
559{
560 struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
561 struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm);
562 u16 tval;
563
564 if (phy->type == BCM43xx_PHYTYPE_A) {
565 bcm43xx_phy_setupa(bcm);
566 } else {
567 bcm43xx_phy_setupg(bcm);
568 if (bcm->sprom.boardflags & BCM43xx_BFL_PACTRL)
569 bcm43xx_phy_write(bcm, 0x046E, 0x03CF);
570 return;
571 }
572
573 bcm43xx_phy_write(bcm, BCM43xx_PHY_A_CRS,
574 (bcm43xx_phy_read(bcm, BCM43xx_PHY_A_CRS) & 0xF83C) | 0x0340);
575 bcm43xx_phy_write(bcm, 0x0034, 0x0001);
576
577 TODO();//TODO: RSSI AGC
578 bcm43xx_phy_write(bcm, BCM43xx_PHY_A_CRS,
579 bcm43xx_phy_read(bcm, BCM43xx_PHY_A_CRS) | (1 << 14));
580 bcm43xx_radio_init2060(bcm);
581
582 if ((bcm->board_vendor == PCI_VENDOR_ID_BROADCOM)
583 && ((bcm->board_type == 0x0416) || (bcm->board_type == 0x040A))) {
584 if (radio->lofcal == 0xFFFF) {
585 TODO();//TODO: LOF Cal
586 bcm43xx_radio_set_tx_iq(bcm);
587 } else
588 bcm43xx_radio_write16(bcm, 0x001E, radio->lofcal);
589 }
590
591 bcm43xx_phy_write(bcm, 0x007A, 0xF111);
592
593 if (phy->savedpctlreg == 0xFFFF) {
594 bcm43xx_radio_write16(bcm, 0x0019, 0x0000);
595 bcm43xx_radio_write16(bcm, 0x0017, 0x0020);
596
597 tval = bcm43xx_ilt_read(bcm, 0x3001);
598 if (phy->rev == 1) {
599 bcm43xx_ilt_write(bcm, 0x3001,
600 (bcm43xx_ilt_read(bcm, 0x3001) & 0xFF87)
601 | 0x0058);
602 } else {
603 bcm43xx_ilt_write(bcm, 0x3001,
604 (bcm43xx_ilt_read(bcm, 0x3001) & 0xFFC3)
605 | 0x002C);
606 }
607 bcm43xx_dummy_transmission(bcm);
608 phy->savedpctlreg = bcm43xx_phy_read(bcm, BCM43xx_PHY_A_PCTL);
609 bcm43xx_ilt_write(bcm, 0x3001, tval);
610
611 bcm43xx_radio_set_txpower_a(bcm, 0x0018);
612 }
613 bcm43xx_radio_clear_tssi(bcm);
614}
615
616static void bcm43xx_phy_initb2(struct bcm43xx_private *bcm)
617{
618 struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm);
619 u16 offset, val;
620
621 bcm43xx_write16(bcm, 0x03EC, 0x3F22);
622 bcm43xx_phy_write(bcm, 0x0020, 0x301C);
623 bcm43xx_phy_write(bcm, 0x0026, 0x0000);
624 bcm43xx_phy_write(bcm, 0x0030, 0x00C6);
625 bcm43xx_phy_write(bcm, 0x0088, 0x3E00);
626 val = 0x3C3D;
627 for (offset = 0x0089; offset < 0x00A7; offset++) {
628 bcm43xx_phy_write(bcm, offset, val);
629 val -= 0x0202;
630 }
631 bcm43xx_phy_write(bcm, 0x03E4, 0x3000);
632 if (radio->channel == 0xFF)
633 bcm43xx_radio_selectchannel(bcm, BCM43xx_RADIO_DEFAULT_CHANNEL_BG, 0);
634 else
635 bcm43xx_radio_selectchannel(bcm, radio->channel, 0);
636 if (radio->version != 0x2050) {
637 bcm43xx_radio_write16(bcm, 0x0075, 0x0080);
638 bcm43xx_radio_write16(bcm, 0x0079, 0x0081);
639 }
640 bcm43xx_radio_write16(bcm, 0x0050, 0x0020);
641 bcm43xx_radio_write16(bcm, 0x0050, 0x0023);
642 if (radio->version == 0x2050) {
643 bcm43xx_radio_write16(bcm, 0x0050, 0x0020);
644 bcm43xx_radio_write16(bcm, 0x005A, 0x0070);
645 bcm43xx_radio_write16(bcm, 0x005B, 0x007B);
646 bcm43xx_radio_write16(bcm, 0x005C, 0x00B0);
647 bcm43xx_radio_write16(bcm, 0x007A, 0x000F);
648 bcm43xx_phy_write(bcm, 0x0038, 0x0677);
649 bcm43xx_radio_init2050(bcm);
650 }
651 bcm43xx_phy_write(bcm, 0x0014, 0x0080);
652 bcm43xx_phy_write(bcm, 0x0032, 0x00CA);
653 bcm43xx_phy_write(bcm, 0x0032, 0x00CC);
654 bcm43xx_phy_write(bcm, 0x0035, 0x07C2);
655 bcm43xx_phy_lo_b_measure(bcm);
656 bcm43xx_phy_write(bcm, 0x0026, 0xCC00);
657 if (radio->version != 0x2050)
658 bcm43xx_phy_write(bcm, 0x0026, 0xCE00);
659 bcm43xx_write16(bcm, BCM43xx_MMIO_CHANNEL_EXT, 0x1000);
660 bcm43xx_phy_write(bcm, 0x002A, 0x88A3);
661 if (radio->version != 0x2050)
662 bcm43xx_phy_write(bcm, 0x002A, 0x88C2);
663 bcm43xx_radio_set_txpower_bg(bcm, 0xFFFF, 0xFFFF, 0xFFFF);
664 bcm43xx_phy_init_pctl(bcm);
665}
666
667static void bcm43xx_phy_initb4(struct bcm43xx_private *bcm)
668{
669 struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm);
670 u16 offset, val;
671
672 bcm43xx_write16(bcm, 0x03EC, 0x3F22);
673 bcm43xx_phy_write(bcm, 0x0020, 0x301C);
674 bcm43xx_phy_write(bcm, 0x0026, 0x0000);
675 bcm43xx_phy_write(bcm, 0x0030, 0x00C6);
676 bcm43xx_phy_write(bcm, 0x0088, 0x3E00);
677 val = 0x3C3D;
678 for (offset = 0x0089; offset < 0x00A7; offset++) {
679 bcm43xx_phy_write(bcm, offset, val);
680 val -= 0x0202;
681 }
682 bcm43xx_phy_write(bcm, 0x03E4, 0x3000);
683 if (radio->channel == 0xFF)
684 bcm43xx_radio_selectchannel(bcm, BCM43xx_RADIO_DEFAULT_CHANNEL_BG, 0);
685 else
686 bcm43xx_radio_selectchannel(bcm, radio->channel, 0);
687 if (radio->version != 0x2050) {
688 bcm43xx_radio_write16(bcm, 0x0075, 0x0080);
689 bcm43xx_radio_write16(bcm, 0x0079, 0x0081);
690 }
691 bcm43xx_radio_write16(bcm, 0x0050, 0x0020);
692 bcm43xx_radio_write16(bcm, 0x0050, 0x0023);
693 if (radio->version == 0x2050) {
694 bcm43xx_radio_write16(bcm, 0x0050, 0x0020);
695 bcm43xx_radio_write16(bcm, 0x005A, 0x0070);
696 bcm43xx_radio_write16(bcm, 0x005B, 0x007B);
697 bcm43xx_radio_write16(bcm, 0x005C, 0x00B0);
698 bcm43xx_radio_write16(bcm, 0x007A, 0x000F);
699 bcm43xx_phy_write(bcm, 0x0038, 0x0677);
700 bcm43xx_radio_init2050(bcm);
701 }
702 bcm43xx_phy_write(bcm, 0x0014, 0x0080);
703 bcm43xx_phy_write(bcm, 0x0032, 0x00CA);
704 if (radio->version == 0x2050)
705 bcm43xx_phy_write(bcm, 0x0032, 0x00E0);
706 bcm43xx_phy_write(bcm, 0x0035, 0x07C2);
707
708 bcm43xx_phy_lo_b_measure(bcm);
709
710 bcm43xx_phy_write(bcm, 0x0026, 0xCC00);
711 if (radio->version == 0x2050)
712 bcm43xx_phy_write(bcm, 0x0026, 0xCE00);
713 bcm43xx_write16(bcm, BCM43xx_MMIO_CHANNEL_EXT, 0x1100);
714 bcm43xx_phy_write(bcm, 0x002A, 0x88A3);
715 if (radio->version == 0x2050)
716 bcm43xx_phy_write(bcm, 0x002A, 0x88C2);
717 bcm43xx_radio_set_txpower_bg(bcm, 0xFFFF, 0xFFFF, 0xFFFF);
718 if (bcm->sprom.boardflags & BCM43xx_BFL_RSSI) {
719 bcm43xx_calc_nrssi_slope(bcm);
720 bcm43xx_calc_nrssi_threshold(bcm);
721 }
722 bcm43xx_phy_init_pctl(bcm);
723}
724
725static void bcm43xx_phy_initb5(struct bcm43xx_private *bcm)
726{
727 struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
728 struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm);
729 u16 offset;
730
731 if (phy->version == 1 &&
732 radio->version == 0x2050) {
733 bcm43xx_radio_write16(bcm, 0x007A,
734 bcm43xx_radio_read16(bcm, 0x007A)
735 | 0x0050);
736 }
737 if ((bcm->board_vendor != PCI_VENDOR_ID_BROADCOM) &&
738 (bcm->board_type != 0x0416)) {
739 for (offset = 0x00A8 ; offset < 0x00C7; offset++) {
740 bcm43xx_phy_write(bcm, offset,
741 (bcm43xx_phy_read(bcm, offset) + 0x2020)
742 & 0x3F3F);
743 }
744 }
745 bcm43xx_phy_write(bcm, 0x0035,
746 (bcm43xx_phy_read(bcm, 0x0035) & 0xF0FF)
747 | 0x0700);
748 if (radio->version == 0x2050)
749 bcm43xx_phy_write(bcm, 0x0038, 0x0667);
750
751 if (phy->connected) {
752 if (radio->version == 0x2050) {
753 bcm43xx_radio_write16(bcm, 0x007A,
754 bcm43xx_radio_read16(bcm, 0x007A)
755 | 0x0020);
756 bcm43xx_radio_write16(bcm, 0x0051,
757 bcm43xx_radio_read16(bcm, 0x0051)
758 | 0x0004);
759 }
760 bcm43xx_write16(bcm, BCM43xx_MMIO_PHY_RADIO, 0x0000);
761
762 bcm43xx_phy_write(bcm, 0x0802, bcm43xx_phy_read(bcm, 0x0802) | 0x0100);
763 bcm43xx_phy_write(bcm, 0x042B, bcm43xx_phy_read(bcm, 0x042B) | 0x2000);
764
765 bcm43xx_phy_write(bcm, 0x001C, 0x186A);
766
767 bcm43xx_phy_write(bcm, 0x0013, (bcm43xx_phy_read(bcm, 0x0013) & 0x00FF) | 0x1900);
768 bcm43xx_phy_write(bcm, 0x0035, (bcm43xx_phy_read(bcm, 0x0035) & 0xFFC0) | 0x0064);
769 bcm43xx_phy_write(bcm, 0x005D, (bcm43xx_phy_read(bcm, 0x005D) & 0xFF80) | 0x000A);
770 }
771
772 if (bcm->bad_frames_preempt) {
773 bcm43xx_phy_write(bcm, BCM43xx_PHY_RADIO_BITFIELD,
774 bcm43xx_phy_read(bcm, BCM43xx_PHY_RADIO_BITFIELD) | (1 << 11));
775 }
776
777 if (phy->version == 1 && radio->version == 0x2050) {
778 bcm43xx_phy_write(bcm, 0x0026, 0xCE00);
779 bcm43xx_phy_write(bcm, 0x0021, 0x3763);
780 bcm43xx_phy_write(bcm, 0x0022, 0x1BC3);
781 bcm43xx_phy_write(bcm, 0x0023, 0x06F9);
782 bcm43xx_phy_write(bcm, 0x0024, 0x037E);
783 } else
784 bcm43xx_phy_write(bcm, 0x0026, 0xCC00);
785 bcm43xx_phy_write(bcm, 0x0030, 0x00C6);
786 bcm43xx_write16(bcm, 0x03EC, 0x3F22);
787
788 if (phy->version == 1 && radio->version == 0x2050)
789 bcm43xx_phy_write(bcm, 0x0020, 0x3E1C);
790 else
791 bcm43xx_phy_write(bcm, 0x0020, 0x301C);
792
793 if (phy->version == 0)
794 bcm43xx_write16(bcm, 0x03E4, 0x3000);
795
796 /* Force to channel 7, even if not supported. */
797 bcm43xx_radio_selectchannel(bcm, 7, 0);
798
799 if (radio->version != 0x2050) {
800 bcm43xx_radio_write16(bcm, 0x0075, 0x0080);
801 bcm43xx_radio_write16(bcm, 0x0079, 0x0081);
802 }
803
804 bcm43xx_radio_write16(bcm, 0x0050, 0x0020);
805 bcm43xx_radio_write16(bcm, 0x0050, 0x0023);
806
807 if (radio->version == 0x2050) {
808 bcm43xx_radio_write16(bcm, 0x0050, 0x0020);
809 bcm43xx_radio_write16(bcm, 0x005A, 0x0070);
810 }
811
812 bcm43xx_radio_write16(bcm, 0x005B, 0x007B);
813 bcm43xx_radio_write16(bcm, 0x005C, 0x00B0);
814
815 bcm43xx_radio_write16(bcm, 0x007A, bcm43xx_radio_read16(bcm, 0x007A) | 0x0007);
816
817 bcm43xx_radio_selectchannel(bcm, BCM43xx_RADIO_DEFAULT_CHANNEL_BG, 0);
818
819 bcm43xx_phy_write(bcm, 0x0014, 0x0080);
820 bcm43xx_phy_write(bcm, 0x0032, 0x00CA);
821 bcm43xx_phy_write(bcm, 0x88A3, 0x002A);
822
823 bcm43xx_radio_set_txpower_bg(bcm, 0xFFFF, 0xFFFF, 0xFFFF);
824
825 if (radio->version == 0x2050)
826 bcm43xx_radio_write16(bcm, 0x005D, 0x000D);
827
828 bcm43xx_write16(bcm, 0x03E4, (bcm43xx_read16(bcm, 0x03E4) & 0xFFC0) | 0x0004);
829}
830
831static void bcm43xx_phy_initb6(struct bcm43xx_private *bcm)
832{
833 struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
834 struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm);
835 u16 offset, val;
836
837 bcm43xx_phy_write(bcm, 0x003E, 0x817A);
838 bcm43xx_radio_write16(bcm, 0x007A,
839 (bcm43xx_radio_read16(bcm, 0x007A) | 0x0058));
840 if ((radio->manufact == 0x17F) &&
841 (radio->version == 0x2050) &&
842 (radio->revision == 3 ||
843 radio->revision == 4 ||
844 radio->revision == 5)) {
845 bcm43xx_radio_write16(bcm, 0x0051, 0x001F);
846 bcm43xx_radio_write16(bcm, 0x0052, 0x0040);
847 bcm43xx_radio_write16(bcm, 0x0053, 0x005B);
848 bcm43xx_radio_write16(bcm, 0x0054, 0x0098);
849 bcm43xx_radio_write16(bcm, 0x005A, 0x0088);
850 bcm43xx_radio_write16(bcm, 0x005B, 0x0088);
851 bcm43xx_radio_write16(bcm, 0x005D, 0x0088);
852 bcm43xx_radio_write16(bcm, 0x005E, 0x0088);
853 bcm43xx_radio_write16(bcm, 0x007D, 0x0088);
854 }
855 if ((radio->manufact == 0x17F) &&
856 (radio->version == 0x2050) &&
857 (radio->revision == 6)) {
858 bcm43xx_radio_write16(bcm, 0x0051, 0x0000);
859 bcm43xx_radio_write16(bcm, 0x0052, 0x0040);
860 bcm43xx_radio_write16(bcm, 0x0053, 0x00B7);
861 bcm43xx_radio_write16(bcm, 0x0054, 0x0098);
862 bcm43xx_radio_write16(bcm, 0x005A, 0x0088);
863 bcm43xx_radio_write16(bcm, 0x005B, 0x008B);
864 bcm43xx_radio_write16(bcm, 0x005C, 0x00B5);
865 bcm43xx_radio_write16(bcm, 0x005D, 0x0088);
866 bcm43xx_radio_write16(bcm, 0x005E, 0x0088);
867 bcm43xx_radio_write16(bcm, 0x007D, 0x0088);
868 bcm43xx_radio_write16(bcm, 0x007C, 0x0001);
869 bcm43xx_radio_write16(bcm, 0x007E, 0x0008);
870 }
871 if ((radio->manufact == 0x17F) &&
872 (radio->version == 0x2050) &&
873 (radio->revision == 7)) {
874 bcm43xx_radio_write16(bcm, 0x0051, 0x0000);
875 bcm43xx_radio_write16(bcm, 0x0052, 0x0040);
876 bcm43xx_radio_write16(bcm, 0x0053, 0x00B7);
877 bcm43xx_radio_write16(bcm, 0x0054, 0x0098);
878 bcm43xx_radio_write16(bcm, 0x005A, 0x0088);
879 bcm43xx_radio_write16(bcm, 0x005B, 0x00A8);
880 bcm43xx_radio_write16(bcm, 0x005C, 0x0075);
881 bcm43xx_radio_write16(bcm, 0x005D, 0x00F5);
882 bcm43xx_radio_write16(bcm, 0x005E, 0x00B8);
883 bcm43xx_radio_write16(bcm, 0x007D, 0x00E8);
884 bcm43xx_radio_write16(bcm, 0x007C, 0x0001);
885 bcm43xx_radio_write16(bcm, 0x007E, 0x0008);
886 bcm43xx_radio_write16(bcm, 0x007B, 0x0000);
887 }
888 if ((radio->manufact == 0x17F) &&
889 (radio->version == 0x2050) &&
890 (radio->revision == 8)) {
891 bcm43xx_radio_write16(bcm, 0x0051, 0x0000);
892 bcm43xx_radio_write16(bcm, 0x0052, 0x0040);
893 bcm43xx_radio_write16(bcm, 0x0053, 0x00B7);
894 bcm43xx_radio_write16(bcm, 0x0054, 0x0098);
895 bcm43xx_radio_write16(bcm, 0x005A, 0x0088);
896 bcm43xx_radio_write16(bcm, 0x005B, 0x006B);
897 bcm43xx_radio_write16(bcm, 0x005C, 0x000F);
898 if (bcm->sprom.boardflags & 0x8000) {
899 bcm43xx_radio_write16(bcm, 0x005D, 0x00FA);
900 bcm43xx_radio_write16(bcm, 0x005E, 0x00D8);
901 } else {
902 bcm43xx_radio_write16(bcm, 0x005D, 0x00F5);
903 bcm43xx_radio_write16(bcm, 0x005E, 0x00B8);
904 }
905 bcm43xx_radio_write16(bcm, 0x0073, 0x0003);
906 bcm43xx_radio_write16(bcm, 0x007D, 0x00A8);
907 bcm43xx_radio_write16(bcm, 0x007C, 0x0001);
908 bcm43xx_radio_write16(bcm, 0x007E, 0x0008);
909 }
910 val = 0x1E1F;
911 for (offset = 0x0088; offset < 0x0098; offset++) {
912 bcm43xx_phy_write(bcm, offset, val);
913 val -= 0x0202;
914 }
915 val = 0x3E3F;
916 for (offset = 0x0098; offset < 0x00A8; offset++) {
917 bcm43xx_phy_write(bcm, offset, val);
918 val -= 0x0202;
919 }
920 val = 0x2120;
921 for (offset = 0x00A8; offset < 0x00C8; offset++) {
922 bcm43xx_phy_write(bcm, offset, (val & 0x3F3F));
923 val += 0x0202;
924 }
925 if (phy->type == BCM43xx_PHYTYPE_G) {
926 bcm43xx_radio_write16(bcm, 0x007A,
927 bcm43xx_radio_read16(bcm, 0x007A) | 0x0020);
928 bcm43xx_radio_write16(bcm, 0x0051,
929 bcm43xx_radio_read16(bcm, 0x0051) | 0x0004);
930 bcm43xx_phy_write(bcm, 0x0802,
931 bcm43xx_phy_read(bcm, 0x0802) | 0x0100);
932 bcm43xx_phy_write(bcm, 0x042B,
933 bcm43xx_phy_read(bcm, 0x042B) | 0x2000);
934 }
935
936 /* Force to channel 7, even if not supported. */
937 bcm43xx_radio_selectchannel(bcm, 7, 0);
938
939 bcm43xx_radio_write16(bcm, 0x0050, 0x0020);
940 bcm43xx_radio_write16(bcm, 0x0050, 0x0023);
941 udelay(40);
942 bcm43xx_radio_write16(bcm, 0x007C, (bcm43xx_radio_read16(bcm, 0x007C) | 0x0002));
943 bcm43xx_radio_write16(bcm, 0x0050, 0x0020);
944 if (radio->manufact == 0x17F &&
945 radio->version == 0x2050 &&
946 radio->revision <= 2) {
947 bcm43xx_radio_write16(bcm, 0x0050, 0x0020);
948 bcm43xx_radio_write16(bcm, 0x005A, 0x0070);
949 bcm43xx_radio_write16(bcm, 0x005B, 0x007B);
950 bcm43xx_radio_write16(bcm, 0x005C, 0x00B0);
951 }
952 bcm43xx_radio_write16(bcm, 0x007A,
953 (bcm43xx_radio_read16(bcm, 0x007A) & 0x00F8) | 0x0007);
954
955 bcm43xx_radio_selectchannel(bcm, BCM43xx_RADIO_DEFAULT_CHANNEL_BG, 0);
956
957 bcm43xx_phy_write(bcm, 0x0014, 0x0200);
958 if (radio->version == 0x2050){
959 if (radio->revision == 3 ||
960 radio->revision == 4 ||
961 radio->revision == 5)
962 bcm43xx_phy_write(bcm, 0x002A, 0x8AC0);
963 else
964 bcm43xx_phy_write(bcm, 0x002A, 0x88C2);
965 }
966 bcm43xx_phy_write(bcm, 0x0038, 0x0668);
967 bcm43xx_radio_set_txpower_bg(bcm, 0xFFFF, 0xFFFF, 0xFFFF);
968 if (radio->version == 0x2050) {
969 if (radio->revision == 3 ||
970 radio->revision == 4 ||
971 radio->revision == 5)
972 bcm43xx_phy_write(bcm, 0x005D, bcm43xx_phy_read(bcm, 0x005D) | 0x0003);
973 else if (radio->revision <= 2)
974 bcm43xx_radio_write16(bcm, 0x005D, 0x000D);
975 }
976
977 if (phy->rev == 4)
978 bcm43xx_phy_write(bcm, 0x0002, (bcm43xx_phy_read(bcm, 0x0002) & 0xFFC0) | 0x0004);
979 else
980 bcm43xx_write16(bcm, 0x03E4, 0x0009);
981 if (phy->type == BCM43xx_PHYTYPE_B) {
982 bcm43xx_write16(bcm, 0x03E6, 0x8140);
983 bcm43xx_phy_write(bcm, 0x0016, 0x0410);
984 bcm43xx_phy_write(bcm, 0x0017, 0x0820);
985 bcm43xx_phy_write(bcm, 0x0062, 0x0007);
986 (void) bcm43xx_radio_calibrationvalue(bcm);
987 bcm43xx_phy_lo_b_measure(bcm);
988 if (bcm->sprom.boardflags & BCM43xx_BFL_RSSI) {
989 bcm43xx_calc_nrssi_slope(bcm);
990 bcm43xx_calc_nrssi_threshold(bcm);
991 }
992 bcm43xx_phy_init_pctl(bcm);
993 } else
994 bcm43xx_write16(bcm, 0x03E6, 0x0);
995}
996
997static void bcm43xx_calc_loopback_gain(struct bcm43xx_private *bcm)
998{
999 struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
1000 struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm);
1001 u16 backup_phy[15];
1002 u16 backup_radio[3];
1003 u16 backup_bband;
1004 u16 i;
1005 u16 loop1_cnt, loop1_done, loop1_omitted;
1006 u16 loop2_done;
1007
1008 backup_phy[0] = bcm43xx_phy_read(bcm, 0x0429);
1009 backup_phy[1] = bcm43xx_phy_read(bcm, 0x0001);
1010 backup_phy[2] = bcm43xx_phy_read(bcm, 0x0811);
1011 backup_phy[3] = bcm43xx_phy_read(bcm, 0x0812);
1012 backup_phy[4] = bcm43xx_phy_read(bcm, 0x0814);
1013 backup_phy[5] = bcm43xx_phy_read(bcm, 0x0815);
1014 backup_phy[6] = bcm43xx_phy_read(bcm, 0x005A);
1015 backup_phy[7] = bcm43xx_phy_read(bcm, 0x0059);
1016 backup_phy[8] = bcm43xx_phy_read(bcm, 0x0058);
1017 backup_phy[9] = bcm43xx_phy_read(bcm, 0x000A);
1018 backup_phy[10] = bcm43xx_phy_read(bcm, 0x0003);
1019 backup_phy[11] = bcm43xx_phy_read(bcm, 0x080F);
1020 backup_phy[12] = bcm43xx_phy_read(bcm, 0x0810);
1021 backup_phy[13] = bcm43xx_phy_read(bcm, 0x002B);
1022 backup_phy[14] = bcm43xx_phy_read(bcm, 0x0015);
1023 bcm43xx_phy_read(bcm, 0x002D); /* dummy read */
1024 backup_bband = radio->baseband_atten;
1025 backup_radio[0] = bcm43xx_radio_read16(bcm, 0x0052);
1026 backup_radio[1] = bcm43xx_radio_read16(bcm, 0x0043);
1027 backup_radio[2] = bcm43xx_radio_read16(bcm, 0x007A);
1028
1029 bcm43xx_phy_write(bcm, 0x0429,
1030 bcm43xx_phy_read(bcm, 0x0429) & 0x3FFF);
1031 bcm43xx_phy_write(bcm, 0x0001,
1032 bcm43xx_phy_read(bcm, 0x0001) & 0x8000);
1033 bcm43xx_phy_write(bcm, 0x0811,
1034 bcm43xx_phy_read(bcm, 0x0811) | 0x0002);
1035 bcm43xx_phy_write(bcm, 0x0812,
1036 bcm43xx_phy_read(bcm, 0x0812) & 0xFFFD);
1037 bcm43xx_phy_write(bcm, 0x0811,
1038 bcm43xx_phy_read(bcm, 0x0811) | 0x0001);
1039 bcm43xx_phy_write(bcm, 0x0812,
1040 bcm43xx_phy_read(bcm, 0x0812) & 0xFFFE);
1041 bcm43xx_phy_write(bcm, 0x0814,
1042 bcm43xx_phy_read(bcm, 0x0814) | 0x0001);
1043 bcm43xx_phy_write(bcm, 0x0815,
1044 bcm43xx_phy_read(bcm, 0x0815) & 0xFFFE);
1045 bcm43xx_phy_write(bcm, 0x0814,
1046 bcm43xx_phy_read(bcm, 0x0814) | 0x0002);
1047 bcm43xx_phy_write(bcm, 0x0815,
1048 bcm43xx_phy_read(bcm, 0x0815) & 0xFFFD);
1049 bcm43xx_phy_write(bcm, 0x0811,
1050 bcm43xx_phy_read(bcm, 0x0811) | 0x000C);
1051 bcm43xx_phy_write(bcm, 0x0812,
1052 bcm43xx_phy_read(bcm, 0x0812) | 0x000C);
1053
1054 bcm43xx_phy_write(bcm, 0x0811,
1055 (bcm43xx_phy_read(bcm, 0x0811)
1056 & 0xFFCF) | 0x0030);
1057 bcm43xx_phy_write(bcm, 0x0812,
1058 (bcm43xx_phy_read(bcm, 0x0812)
1059 & 0xFFCF) | 0x0010);
1060
1061 bcm43xx_phy_write(bcm, 0x005A, 0x0780);
1062 bcm43xx_phy_write(bcm, 0x0059, 0xC810);
1063 bcm43xx_phy_write(bcm, 0x0058, 0x000D);
1064 if (phy->version == 0) {
1065 bcm43xx_phy_write(bcm, 0x0003, 0x0122);
1066 } else {
1067 bcm43xx_phy_write(bcm, 0x000A,
1068 bcm43xx_phy_read(bcm, 0x000A)
1069 | 0x2000);
1070 }
1071 bcm43xx_phy_write(bcm, 0x0814,
1072 bcm43xx_phy_read(bcm, 0x0814) | 0x0004);
1073 bcm43xx_phy_write(bcm, 0x0815,
1074 bcm43xx_phy_read(bcm, 0x0815) & 0xFFFB);
1075 bcm43xx_phy_write(bcm, 0x0003,
1076 (bcm43xx_phy_read(bcm, 0x0003)
1077 & 0xFF9F) | 0x0040);
1078 if (radio->version == 0x2050 && radio->revision == 2) {
1079 bcm43xx_radio_write16(bcm, 0x0052, 0x0000);
1080 bcm43xx_radio_write16(bcm, 0x0043,
1081 (bcm43xx_radio_read16(bcm, 0x0043)
1082 & 0xFFF0) | 0x0009);
1083 loop1_cnt = 9;
1084 } else if (radio->revision == 8) {
1085 bcm43xx_radio_write16(bcm, 0x0043, 0x000F);
1086 loop1_cnt = 15;
1087 } else
1088 loop1_cnt = 0;
1089
1090 bcm43xx_phy_set_baseband_attenuation(bcm, 11);
1091
1092 if (phy->rev >= 3)
1093 bcm43xx_phy_write(bcm, 0x080F, 0xC020);
1094 else
1095 bcm43xx_phy_write(bcm, 0x080F, 0x8020);
1096 bcm43xx_phy_write(bcm, 0x0810, 0x0000);
1097
1098 bcm43xx_phy_write(bcm, 0x002B,
1099 (bcm43xx_phy_read(bcm, 0x002B)
1100 & 0xFFC0) | 0x0001);
1101 bcm43xx_phy_write(bcm, 0x002B,
1102 (bcm43xx_phy_read(bcm, 0x002B)
1103 & 0xC0FF) | 0x0800);
1104 bcm43xx_phy_write(bcm, 0x0811,
1105 bcm43xx_phy_read(bcm, 0x0811) | 0x0100);
1106 bcm43xx_phy_write(bcm, 0x0812,
1107 bcm43xx_phy_read(bcm, 0x0812) & 0xCFFF);
1108 if (bcm->sprom.boardflags & BCM43xx_BFL_EXTLNA) {
1109 if (phy->rev >= 7) {
1110 bcm43xx_phy_write(bcm, 0x0811,
1111 bcm43xx_phy_read(bcm, 0x0811)
1112 | 0x0800);
1113 bcm43xx_phy_write(bcm, 0x0812,
1114 bcm43xx_phy_read(bcm, 0x0812)
1115 | 0x8000);
1116 }
1117 }
1118 bcm43xx_radio_write16(bcm, 0x007A,
1119 bcm43xx_radio_read16(bcm, 0x007A)
1120 & 0x00F7);
1121
1122 for (i = 0; i < loop1_cnt; i++) {
1123 bcm43xx_radio_write16(bcm, 0x0043, loop1_cnt);
1124 bcm43xx_phy_write(bcm, 0x0812,
1125 (bcm43xx_phy_read(bcm, 0x0812)
1126 & 0xF0FF) | (i << 8));
1127 bcm43xx_phy_write(bcm, 0x0015,
1128 (bcm43xx_phy_read(bcm, 0x0015)
1129 & 0x0FFF) | 0xA000);
1130 bcm43xx_phy_write(bcm, 0x0015,
1131 (bcm43xx_phy_read(bcm, 0x0015)
1132 & 0x0FFF) | 0xF000);
1133 udelay(20);
1134 if (bcm43xx_phy_read(bcm, 0x002D) >= 0x0DFC)
1135 break;
1136 }
1137 loop1_done = i;
1138 loop1_omitted = loop1_cnt - loop1_done;
1139
1140 loop2_done = 0;
1141 if (loop1_done >= 8) {
1142 bcm43xx_phy_write(bcm, 0x0812,
1143 bcm43xx_phy_read(bcm, 0x0812)
1144 | 0x0030);
1145 for (i = loop1_done - 8; i < 16; i++) {
1146 bcm43xx_phy_write(bcm, 0x0812,
1147 (bcm43xx_phy_read(bcm, 0x0812)
1148 & 0xF0FF) | (i << 8));
1149 bcm43xx_phy_write(bcm, 0x0015,
1150 (bcm43xx_phy_read(bcm, 0x0015)
1151 & 0x0FFF) | 0xA000);
1152 bcm43xx_phy_write(bcm, 0x0015,
1153 (bcm43xx_phy_read(bcm, 0x0015)
1154 & 0x0FFF) | 0xF000);
1155 udelay(20);
1156 if (bcm43xx_phy_read(bcm, 0x002D) >= 0x0DFC)
1157 break;
1158 }
1159 }
1160
1161 bcm43xx_phy_write(bcm, 0x0814, backup_phy[4]);
1162 bcm43xx_phy_write(bcm, 0x0815, backup_phy[5]);
1163 bcm43xx_phy_write(bcm, 0x005A, backup_phy[6]);
1164 bcm43xx_phy_write(bcm, 0x0059, backup_phy[7]);
1165 bcm43xx_phy_write(bcm, 0x0058, backup_phy[8]);
1166 bcm43xx_phy_write(bcm, 0x000A, backup_phy[9]);
1167 bcm43xx_phy_write(bcm, 0x0003, backup_phy[10]);
1168 bcm43xx_phy_write(bcm, 0x080F, backup_phy[11]);
1169 bcm43xx_phy_write(bcm, 0x0810, backup_phy[12]);
1170 bcm43xx_phy_write(bcm, 0x002B, backup_phy[13]);
1171 bcm43xx_phy_write(bcm, 0x0015, backup_phy[14]);
1172
1173 bcm43xx_phy_set_baseband_attenuation(bcm, backup_bband);
1174
1175 bcm43xx_radio_write16(bcm, 0x0052, backup_radio[0]);
1176 bcm43xx_radio_write16(bcm, 0x0043, backup_radio[1]);
1177 bcm43xx_radio_write16(bcm, 0x007A, backup_radio[2]);
1178
1179 bcm43xx_phy_write(bcm, 0x0811, backup_phy[2] | 0x0003);
1180 udelay(10);
1181 bcm43xx_phy_write(bcm, 0x0811, backup_phy[2]);
1182 bcm43xx_phy_write(bcm, 0x0812, backup_phy[3]);
1183 bcm43xx_phy_write(bcm, 0x0429, backup_phy[0]);
1184 bcm43xx_phy_write(bcm, 0x0001, backup_phy[1]);
1185
1186 phy->loopback_gain[0] = ((loop1_done * 6) - (loop1_omitted * 4)) - 11;
1187 phy->loopback_gain[1] = (24 - (3 * loop2_done)) * 2;
1188}
1189
1190static void bcm43xx_phy_initg(struct bcm43xx_private *bcm)
1191{
1192 struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
1193 struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm);
1194 u16 tmp;
1195
1196 if (phy->rev == 1)
1197 bcm43xx_phy_initb5(bcm);
1198 else if (phy->rev >= 2 && phy->rev <= 7)
1199 bcm43xx_phy_initb6(bcm);
1200 if (phy->rev >= 2 || phy->connected)
1201 bcm43xx_phy_inita(bcm);
1202
1203 if (phy->rev >= 2) {
1204 bcm43xx_phy_write(bcm, 0x0814, 0x0000);
1205 bcm43xx_phy_write(bcm, 0x0815, 0x0000);
1206 if (phy->rev == 2)
1207 bcm43xx_phy_write(bcm, 0x0811, 0x0000);
1208 else if (phy->rev >= 3)
1209 bcm43xx_phy_write(bcm, 0x0811, 0x0400);
1210 bcm43xx_phy_write(bcm, 0x0015, 0x00C0);
1211 if (phy->connected) {
1212 tmp = bcm43xx_phy_read(bcm, 0x0400) & 0xFF;
1213 if (tmp < 6) {
1214 bcm43xx_phy_write(bcm, 0x04C2, 0x1816);
1215 bcm43xx_phy_write(bcm, 0x04C3, 0x8006);
1216 if (tmp != 3) {
1217 bcm43xx_phy_write(bcm, 0x04CC,
1218 (bcm43xx_phy_read(bcm, 0x04CC)
1219 & 0x00FF) | 0x1F00);
1220 }
1221 }
1222 }
1223 }
1224 if (phy->rev < 3 && phy->connected)
1225 bcm43xx_phy_write(bcm, 0x047E, 0x0078);
1226 if (phy->rev >= 6 && phy->rev <= 8) {
1227 bcm43xx_phy_write(bcm, 0x0801, bcm43xx_phy_read(bcm, 0x0801) | 0x0080);
1228 bcm43xx_phy_write(bcm, 0x043E, bcm43xx_phy_read(bcm, 0x043E) | 0x0004);
1229 }
1230 if (phy->rev >= 2 && phy->connected)
1231 bcm43xx_calc_loopback_gain(bcm);
1232 if (radio->revision != 8) {
1233 if (radio->initval == 0xFFFF)
1234 radio->initval = bcm43xx_radio_init2050(bcm);
1235 else
1236 bcm43xx_radio_write16(bcm, 0x0078, radio->initval);
1237 }
1238 if (radio->txctl2 == 0xFFFF) {
1239 bcm43xx_phy_lo_g_measure(bcm);
1240 } else {
1241 if (radio->version == 0x2050 && radio->revision == 8) {
1242 //FIXME
1243 } else {
1244 bcm43xx_radio_write16(bcm, 0x0052,
1245 (bcm43xx_radio_read16(bcm, 0x0052)
1246 & 0xFFF0) | radio->txctl1);
1247 }
1248 if (phy->rev >= 6) {
1249 /*
1250 bcm43xx_phy_write(bcm, 0x0036,
1251 (bcm43xx_phy_read(bcm, 0x0036)
1252 & 0xF000) | (FIXME << 12));
1253 */
1254 }
1255 if (bcm->sprom.boardflags & BCM43xx_BFL_PACTRL)
1256 bcm43xx_phy_write(bcm, 0x002E, 0x8075);
1257 else
1258 bcm43xx_phy_write(bcm, 0x003E, 0x807F);
1259 if (phy->rev < 2)
1260 bcm43xx_phy_write(bcm, 0x002F, 0x0101);
1261 else
1262 bcm43xx_phy_write(bcm, 0x002F, 0x0202);
1263 }
1264 if (phy->connected) {
1265 bcm43xx_phy_lo_adjust(bcm, 0);
1266 bcm43xx_phy_write(bcm, 0x080F, 0x8078);
1267 }
1268
1269 if (!(bcm->sprom.boardflags & BCM43xx_BFL_RSSI)) {
1270 /* The specs state to update the NRSSI LT with
1271 * the value 0x7FFFFFFF here. I think that is some weird
1272 * compiler optimization in the original driver.
1273 * Essentially, what we do here is resetting all NRSSI LT
1274 * entries to -32 (see the limit_value() in nrssi_hw_update())
1275 */
1276 bcm43xx_nrssi_hw_update(bcm, 0xFFFF);
1277 bcm43xx_calc_nrssi_threshold(bcm);
1278 } else if (phy->connected) {
1279 if (radio->nrssi[0] == -1000) {
1280 assert(radio->nrssi[1] == -1000);
1281 bcm43xx_calc_nrssi_slope(bcm);
1282 } else {
1283 assert(radio->nrssi[1] != -1000);
1284 bcm43xx_calc_nrssi_threshold(bcm);
1285 }
1286 }
1287 if (radio->revision == 8)
1288 bcm43xx_phy_write(bcm, 0x0805, 0x3230);
1289 bcm43xx_phy_init_pctl(bcm);
1290 if (bcm->chip_id == 0x4306 && bcm->chip_package != 2) {
1291 bcm43xx_phy_write(bcm, 0x0429,
1292 bcm43xx_phy_read(bcm, 0x0429) & 0xBFFF);
1293 bcm43xx_phy_write(bcm, 0x04C3,
1294 bcm43xx_phy_read(bcm, 0x04C3) & 0x7FFF);
1295 }
1296}
1297
1298static u16 bcm43xx_phy_lo_b_r15_loop(struct bcm43xx_private *bcm)
1299{
1300 int i;
1301 u16 ret = 0;
1302
1303 for (i = 0; i < 10; i++){
1304 bcm43xx_phy_write(bcm, 0x0015, 0xAFA0);
1305 udelay(1);
1306 bcm43xx_phy_write(bcm, 0x0015, 0xEFA0);
1307 udelay(10);
1308 bcm43xx_phy_write(bcm, 0x0015, 0xFFA0);
1309 udelay(40);
1310 ret += bcm43xx_phy_read(bcm, 0x002C);
1311 }
1312
1313 return ret;
1314}
1315
1316void bcm43xx_phy_lo_b_measure(struct bcm43xx_private *bcm)
1317{
1318 struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm);
1319 struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
1320 u16 regstack[12] = { 0 };
1321 u16 mls;
1322 u16 fval;
1323 int i, j;
1324
1325 regstack[0] = bcm43xx_phy_read(bcm, 0x0015);
1326 regstack[1] = bcm43xx_radio_read16(bcm, 0x0052) & 0xFFF0;
1327
1328 if (radio->version == 0x2053) {
1329 regstack[2] = bcm43xx_phy_read(bcm, 0x000A);
1330 regstack[3] = bcm43xx_phy_read(bcm, 0x002A);
1331 regstack[4] = bcm43xx_phy_read(bcm, 0x0035);
1332 regstack[5] = bcm43xx_phy_read(bcm, 0x0003);
1333 regstack[6] = bcm43xx_phy_read(bcm, 0x0001);
1334 regstack[7] = bcm43xx_phy_read(bcm, 0x0030);
1335
1336 regstack[8] = bcm43xx_radio_read16(bcm, 0x0043);
1337 regstack[9] = bcm43xx_radio_read16(bcm, 0x007A);
1338 regstack[10] = bcm43xx_read16(bcm, 0x03EC);
1339 regstack[11] = bcm43xx_radio_read16(bcm, 0x0052) & 0x00F0;
1340
1341 bcm43xx_phy_write(bcm, 0x0030, 0x00FF);
1342 bcm43xx_write16(bcm, 0x03EC, 0x3F3F);
1343 bcm43xx_phy_write(bcm, 0x0035, regstack[4] & 0xFF7F);
1344 bcm43xx_radio_write16(bcm, 0x007A, regstack[9] & 0xFFF0);
1345 }
1346 bcm43xx_phy_write(bcm, 0x0015, 0xB000);
1347 bcm43xx_phy_write(bcm, 0x002B, 0x0004);
1348
1349 if (radio->version == 0x2053) {
1350 bcm43xx_phy_write(bcm, 0x002B, 0x0203);
1351 bcm43xx_phy_write(bcm, 0x002A, 0x08A3);
1352 }
1353
1354 phy->minlowsig[0] = 0xFFFF;
1355
1356 for (i = 0; i < 4; i++) {
1357 bcm43xx_radio_write16(bcm, 0x0052, regstack[1] | i);
1358 bcm43xx_phy_lo_b_r15_loop(bcm);
1359 }
1360 for (i = 0; i < 10; i++) {
1361 bcm43xx_radio_write16(bcm, 0x0052, regstack[1] | i);
1362 mls = bcm43xx_phy_lo_b_r15_loop(bcm) / 10;
1363 if (mls < phy->minlowsig[0]) {
1364 phy->minlowsig[0] = mls;
1365 phy->minlowsigpos[0] = i;
1366 }
1367 }
1368 bcm43xx_radio_write16(bcm, 0x0052, regstack[1] | phy->minlowsigpos[0]);
1369
1370 phy->minlowsig[1] = 0xFFFF;
1371
1372 for (i = -4; i < 5; i += 2) {
1373 for (j = -4; j < 5; j += 2) {
1374 if (j < 0)
1375 fval = (0x0100 * i) + j + 0x0100;
1376 else
1377 fval = (0x0100 * i) + j;
1378 bcm43xx_phy_write(bcm, 0x002F, fval);
1379 mls = bcm43xx_phy_lo_b_r15_loop(bcm) / 10;
1380 if (mls < phy->minlowsig[1]) {
1381 phy->minlowsig[1] = mls;
1382 phy->minlowsigpos[1] = fval;
1383 }
1384 }
1385 }
1386 phy->minlowsigpos[1] += 0x0101;
1387
1388 bcm43xx_phy_write(bcm, 0x002F, phy->minlowsigpos[1]);
1389 if (radio->version == 0x2053) {
1390 bcm43xx_phy_write(bcm, 0x000A, regstack[2]);
1391 bcm43xx_phy_write(bcm, 0x002A, regstack[3]);
1392 bcm43xx_phy_write(bcm, 0x0035, regstack[4]);
1393 bcm43xx_phy_write(bcm, 0x0003, regstack[5]);
1394 bcm43xx_phy_write(bcm, 0x0001, regstack[6]);
1395 bcm43xx_phy_write(bcm, 0x0030, regstack[7]);
1396
1397 bcm43xx_radio_write16(bcm, 0x0043, regstack[8]);
1398 bcm43xx_radio_write16(bcm, 0x007A, regstack[9]);
1399
1400 bcm43xx_radio_write16(bcm, 0x0052,
1401 (bcm43xx_radio_read16(bcm, 0x0052) & 0x000F)
1402 | regstack[11]);
1403
1404 bcm43xx_write16(bcm, 0x03EC, regstack[10]);
1405 }
1406 bcm43xx_phy_write(bcm, 0x0015, regstack[0]);
1407}
1408
1409static inline
1410u16 bcm43xx_phy_lo_g_deviation_subval(struct bcm43xx_private *bcm, u16 control)
1411{
1412 struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
1413
1414 if (phy->connected) {
1415 bcm43xx_phy_write(bcm, 0x15, 0xE300);
1416 control <<= 8;
1417 bcm43xx_phy_write(bcm, 0x0812, control | 0x00B0);
1418 udelay(5);
1419 bcm43xx_phy_write(bcm, 0x0812, control | 0x00B2);
1420 udelay(2);
1421 bcm43xx_phy_write(bcm, 0x0812, control | 0x00B3);
1422 udelay(4);
1423 bcm43xx_phy_write(bcm, 0x0015, 0xF300);
1424 udelay(8);
1425 } else {
1426 bcm43xx_phy_write(bcm, 0x0015, control | 0xEFA0);
1427 udelay(2);
1428 bcm43xx_phy_write(bcm, 0x0015, control | 0xEFE0);
1429 udelay(4);
1430 bcm43xx_phy_write(bcm, 0x0015, control | 0xFFE0);
1431 udelay(8);
1432 }
1433
1434 return bcm43xx_phy_read(bcm, 0x002D);
1435}
1436
1437static u32 bcm43xx_phy_lo_g_singledeviation(struct bcm43xx_private *bcm, u16 control)
1438{
1439 int i;
1440 u32 ret = 0;
1441
1442 for (i = 0; i < 8; i++)
1443 ret += bcm43xx_phy_lo_g_deviation_subval(bcm, control);
1444
1445 return ret;
1446}
1447
1448/* Write the LocalOscillator CONTROL */
1449static inline
1450void bcm43xx_lo_write(struct bcm43xx_private *bcm,
1451 struct bcm43xx_lopair *pair)
1452{
1453 u16 value;
1454
1455 value = (u8)(pair->low);
1456 value |= ((u8)(pair->high)) << 8;
1457
1458#ifdef CONFIG_BCM43XX_DEBUG
1459 /* Sanity check. */
1460 if (pair->low < -8 || pair->low > 8 ||
1461 pair->high < -8 || pair->high > 8) {
1462 printk(KERN_WARNING PFX
1463 "WARNING: Writing invalid LOpair "
1464 "(low: %d, high: %d, index: %lu)\n",
1465 pair->low, pair->high,
1466 (unsigned long)(pair - bcm43xx_current_phy(bcm)->_lo_pairs));
1467 dump_stack();
1468 }
1469#endif
1470
1471 bcm43xx_phy_write(bcm, BCM43xx_PHY_G_LO_CONTROL, value);
1472}
1473
1474static inline
1475struct bcm43xx_lopair * bcm43xx_find_lopair(struct bcm43xx_private *bcm,
1476 u16 baseband_attenuation,
1477 u16 radio_attenuation,
1478 u16 tx)
1479{
1480 static const u8 dict[10] = { 11, 10, 11, 12, 13, 12, 13, 12, 13, 12 };
1481 struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
1482
1483 if (baseband_attenuation > 6)
1484 baseband_attenuation = 6;
1485 assert(radio_attenuation < 10);
1486
1487 if (tx == 3) {
1488 return bcm43xx_get_lopair(phy,
1489 radio_attenuation,
1490 baseband_attenuation);
1491 }
1492 return bcm43xx_get_lopair(phy, dict[radio_attenuation], baseband_attenuation);
1493}
1494
1495static inline
1496struct bcm43xx_lopair * bcm43xx_current_lopair(struct bcm43xx_private *bcm)
1497{
1498 struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm);
1499
1500 return bcm43xx_find_lopair(bcm,
1501 radio->baseband_atten,
1502 radio->radio_atten,
1503 radio->txctl1);
1504}
1505
1506/* Adjust B/G LO */
1507void bcm43xx_phy_lo_adjust(struct bcm43xx_private *bcm, int fixed)
1508{
1509 struct bcm43xx_lopair *pair;
1510
1511 if (fixed) {
1512 /* Use fixed values. Only for initialization. */
1513 pair = bcm43xx_find_lopair(bcm, 2, 3, 0);
1514 } else
1515 pair = bcm43xx_current_lopair(bcm);
1516 bcm43xx_lo_write(bcm, pair);
1517}
1518
1519static void bcm43xx_phy_lo_g_measure_txctl2(struct bcm43xx_private *bcm)
1520{
1521 struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm);
1522 u16 txctl2 = 0, i;
1523 u32 smallest, tmp;
1524
1525 bcm43xx_radio_write16(bcm, 0x0052, 0x0000);
1526 udelay(10);
1527 smallest = bcm43xx_phy_lo_g_singledeviation(bcm, 0);
1528 for (i = 0; i < 16; i++) {
1529 bcm43xx_radio_write16(bcm, 0x0052, i);
1530 udelay(10);
1531 tmp = bcm43xx_phy_lo_g_singledeviation(bcm, 0);
1532 if (tmp < smallest) {
1533 smallest = tmp;
1534 txctl2 = i;
1535 }
1536 }
1537 radio->txctl2 = txctl2;
1538}
1539
1540static
1541void bcm43xx_phy_lo_g_state(struct bcm43xx_private *bcm,
1542 const struct bcm43xx_lopair *in_pair,
1543 struct bcm43xx_lopair *out_pair,
1544 u16 r27)
1545{
1546 static const struct bcm43xx_lopair transitions[8] = {
1547 { .high = 1, .low = 1, },
1548 { .high = 1, .low = 0, },
1549 { .high = 1, .low = -1, },
1550 { .high = 0, .low = -1, },
1551 { .high = -1, .low = -1, },
1552 { .high = -1, .low = 0, },
1553 { .high = -1, .low = 1, },
1554 { .high = 0, .low = 1, },
1555 };
1556 struct bcm43xx_lopair lowest_transition = {
1557 .high = in_pair->high,
1558 .low = in_pair->low,
1559 };
1560 struct bcm43xx_lopair tmp_pair;
1561 struct bcm43xx_lopair transition;
1562 int i = 12;
1563 int state = 0;
1564 int found_lower;
1565 int j, begin, end;
1566 u32 lowest_deviation;
1567 u32 tmp;
1568
1569 /* Note that in_pair and out_pair can point to the same pair. Be careful. */
1570
1571 bcm43xx_lo_write(bcm, &lowest_transition);
1572 lowest_deviation = bcm43xx_phy_lo_g_singledeviation(bcm, r27);
1573 do {
1574 found_lower = 0;
1575 assert(state >= 0 && state <= 8);
1576 if (state == 0) {
1577 begin = 1;
1578 end = 8;
1579 } else if (state % 2 == 0) {
1580 begin = state - 1;
1581 end = state + 1;
1582 } else {
1583 begin = state - 2;
1584 end = state + 2;
1585 }
1586 if (begin < 1)
1587 begin += 8;
1588 if (end > 8)
1589 end -= 8;
1590
1591 j = begin;
1592 tmp_pair.high = lowest_transition.high;
1593 tmp_pair.low = lowest_transition.low;
1594 while (1) {
1595 assert(j >= 1 && j <= 8);
1596 transition.high = tmp_pair.high + transitions[j - 1].high;
1597 transition.low = tmp_pair.low + transitions[j - 1].low;
1598 if ((abs(transition.low) < 9) && (abs(transition.high) < 9)) {
1599 bcm43xx_lo_write(bcm, &transition);
1600 tmp = bcm43xx_phy_lo_g_singledeviation(bcm, r27);
1601 if (tmp < lowest_deviation) {
1602 lowest_deviation = tmp;
1603 state = j;
1604 found_lower = 1;
1605
1606 lowest_transition.high = transition.high;
1607 lowest_transition.low = transition.low;
1608 }
1609 }
1610 if (j == end)
1611 break;
1612 if (j == 8)
1613 j = 1;
1614 else
1615 j++;
1616 }
1617 } while (i-- && found_lower);
1618
1619 out_pair->high = lowest_transition.high;
1620 out_pair->low = lowest_transition.low;
1621}
1622
1623/* Set the baseband attenuation value on chip. */
1624void bcm43xx_phy_set_baseband_attenuation(struct bcm43xx_private *bcm,
1625 u16 baseband_attenuation)
1626{
1627 struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
1628 u16 value;
1629
1630 if (phy->version == 0) {
1631 value = (bcm43xx_read16(bcm, 0x03E6) & 0xFFF0);
1632 value |= (baseband_attenuation & 0x000F);
1633 bcm43xx_write16(bcm, 0x03E6, value);
1634 return;
1635 }
1636
1637 if (phy->version > 1) {
1638 value = bcm43xx_phy_read(bcm, 0x0060) & ~0x003C;
1639 value |= (baseband_attenuation << 2) & 0x003C;
1640 } else {
1641 value = bcm43xx_phy_read(bcm, 0x0060) & ~0x0078;
1642 value |= (baseband_attenuation << 3) & 0x0078;
1643 }
1644 bcm43xx_phy_write(bcm, 0x0060, value);
1645}
1646
1647/* http://bcm-specs.sipsolutions.net/LocalOscillator/Measure */
1648void bcm43xx_phy_lo_g_measure(struct bcm43xx_private *bcm)
1649{
1650 static const u8 pairorder[10] = { 3, 1, 5, 7, 9, 2, 0, 4, 6, 8 };
1651 const int is_initializing = bcm43xx_is_initializing(bcm);
1652 struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
1653 struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm);
1654 u16 h, i, oldi = 0, j;
1655 struct bcm43xx_lopair control;
1656 struct bcm43xx_lopair *tmp_control;
1657 u16 tmp;
1658 u16 regstack[16] = { 0 };
1659 u8 oldchannel;
1660
1661 //XXX: What are these?
1662 u8 r27 = 0, r31;
1663
1664 oldchannel = radio->channel;
1665 /* Setup */
1666 if (phy->connected) {
1667 regstack[0] = bcm43xx_phy_read(bcm, BCM43xx_PHY_G_CRS);
1668 regstack[1] = bcm43xx_phy_read(bcm, 0x0802);
1669 bcm43xx_phy_write(bcm, BCM43xx_PHY_G_CRS, regstack[0] & 0x7FFF);
1670 bcm43xx_phy_write(bcm, 0x0802, regstack[1] & 0xFFFC);
1671 }
1672 regstack[3] = bcm43xx_read16(bcm, 0x03E2);
1673 bcm43xx_write16(bcm, 0x03E2, regstack[3] | 0x8000);
1674 regstack[4] = bcm43xx_read16(bcm, BCM43xx_MMIO_CHANNEL_EXT);
1675 regstack[5] = bcm43xx_phy_read(bcm, 0x15);
1676 regstack[6] = bcm43xx_phy_read(bcm, 0x2A);
1677 regstack[7] = bcm43xx_phy_read(bcm, 0x35);
1678 regstack[8] = bcm43xx_phy_read(bcm, 0x60);
1679 regstack[9] = bcm43xx_radio_read16(bcm, 0x43);
1680 regstack[10] = bcm43xx_radio_read16(bcm, 0x7A);
1681 regstack[11] = bcm43xx_radio_read16(bcm, 0x52);
1682 if (phy->connected) {
1683 regstack[12] = bcm43xx_phy_read(bcm, 0x0811);
1684 regstack[13] = bcm43xx_phy_read(bcm, 0x0812);
1685 regstack[14] = bcm43xx_phy_read(bcm, 0x0814);
1686 regstack[15] = bcm43xx_phy_read(bcm, 0x0815);
1687 }
1688 bcm43xx_radio_selectchannel(bcm, 6, 0);
1689 if (phy->connected) {
1690 bcm43xx_phy_write(bcm, BCM43xx_PHY_G_CRS, regstack[0] & 0x7FFF);
1691 bcm43xx_phy_write(bcm, 0x0802, regstack[1] & 0xFFFC);
1692 bcm43xx_dummy_transmission(bcm);
1693 }
1694 bcm43xx_radio_write16(bcm, 0x0043, 0x0006);
1695
1696 bcm43xx_phy_set_baseband_attenuation(bcm, 2);
1697
1698 bcm43xx_write16(bcm, BCM43xx_MMIO_CHANNEL_EXT, 0x0000);
1699 bcm43xx_phy_write(bcm, 0x002E, 0x007F);
1700 bcm43xx_phy_write(bcm, 0x080F, 0x0078);
1701 bcm43xx_phy_write(bcm, 0x0035, regstack[7] & ~(1 << 7));
1702 bcm43xx_radio_write16(bcm, 0x007A, regstack[10] & 0xFFF0);
1703 bcm43xx_phy_write(bcm, 0x002B, 0x0203);
1704 bcm43xx_phy_write(bcm, 0x002A, 0x08A3);
1705 if (phy->connected) {
1706 bcm43xx_phy_write(bcm, 0x0814, regstack[14] | 0x0003);
1707 bcm43xx_phy_write(bcm, 0x0815, regstack[15] & 0xFFFC);
1708 bcm43xx_phy_write(bcm, 0x0811, 0x01B3);
1709 bcm43xx_phy_write(bcm, 0x0812, 0x00B2);
1710 }
1711 if (is_initializing)
1712 bcm43xx_phy_lo_g_measure_txctl2(bcm);
1713 bcm43xx_phy_write(bcm, 0x080F, 0x8078);
1714
1715 /* Measure */
1716 control.low = 0;
1717 control.high = 0;
1718 for (h = 0; h < 10; h++) {
1719 /* Loop over each possible RadioAttenuation (0-9) */
1720 i = pairorder[h];
1721 if (is_initializing) {
1722 if (i == 3) {
1723 control.low = 0;
1724 control.high = 0;
1725 } else if (((i % 2 == 1) && (oldi % 2 == 1)) ||
1726 ((i % 2 == 0) && (oldi % 2 == 0))) {
1727 tmp_control = bcm43xx_get_lopair(phy, oldi, 0);
1728 memcpy(&control, tmp_control, sizeof(control));
1729 } else {
1730 tmp_control = bcm43xx_get_lopair(phy, 3, 0);
1731 memcpy(&control, tmp_control, sizeof(control));
1732 }
1733 }
1734 /* Loop over each possible BasebandAttenuation/2 */
1735 for (j = 0; j < 4; j++) {
1736 if (is_initializing) {
1737 tmp = i * 2 + j;
1738 r27 = 0;
1739 r31 = 0;
1740 if (tmp > 14) {
1741 r31 = 1;
1742 if (tmp > 17)
1743 r27 = 1;
1744 if (tmp > 19)
1745 r27 = 2;
1746 }
1747 } else {
1748 tmp_control = bcm43xx_get_lopair(phy, i, j * 2);
1749 if (!tmp_control->used)
1750 continue;
1751 memcpy(&control, tmp_control, sizeof(control));
1752 r27 = 3;
1753 r31 = 0;
1754 }
1755 bcm43xx_radio_write16(bcm, 0x43, i);
1756 bcm43xx_radio_write16(bcm, 0x52, radio->txctl2);
1757 udelay(10);
1758
1759 bcm43xx_phy_set_baseband_attenuation(bcm, j * 2);
1760
1761 tmp = (regstack[10] & 0xFFF0);
1762 if (r31)
1763 tmp |= 0x0008;
1764 bcm43xx_radio_write16(bcm, 0x007A, tmp);
1765
1766 tmp_control = bcm43xx_get_lopair(phy, i, j * 2);
1767 bcm43xx_phy_lo_g_state(bcm, &control, tmp_control, r27);
1768 }
1769 oldi = i;
1770 }
1771 /* Loop over each possible RadioAttenuation (10-13) */
1772 for (i = 10; i < 14; i++) {
1773 /* Loop over each possible BasebandAttenuation/2 */
1774 for (j = 0; j < 4; j++) {
1775 if (is_initializing) {
1776 tmp_control = bcm43xx_get_lopair(phy, i - 9, j * 2);
1777 memcpy(&control, tmp_control, sizeof(control));
1778 tmp = (i - 9) * 2 + j - 5;//FIXME: This is wrong, as the following if statement can never trigger.
1779 r27 = 0;
1780 r31 = 0;
1781 if (tmp > 14) {
1782 r31 = 1;
1783 if (tmp > 17)
1784 r27 = 1;
1785 if (tmp > 19)
1786 r27 = 2;
1787 }
1788 } else {
1789 tmp_control = bcm43xx_get_lopair(phy, i - 9, j * 2);
1790 if (!tmp_control->used)
1791 continue;
1792 memcpy(&control, tmp_control, sizeof(control));
1793 r27 = 3;
1794 r31 = 0;
1795 }
1796 bcm43xx_radio_write16(bcm, 0x43, i - 9);
1797 bcm43xx_radio_write16(bcm, 0x52,
1798 radio->txctl2
1799 | (3/*txctl1*/ << 4));//FIXME: shouldn't txctl1 be zero here and 3 in the loop above?
1800 udelay(10);
1801
1802 bcm43xx_phy_set_baseband_attenuation(bcm, j * 2);
1803
1804 tmp = (regstack[10] & 0xFFF0);
1805 if (r31)
1806 tmp |= 0x0008;
1807 bcm43xx_radio_write16(bcm, 0x7A, tmp);
1808
1809 tmp_control = bcm43xx_get_lopair(phy, i, j * 2);
1810 bcm43xx_phy_lo_g_state(bcm, &control, tmp_control, r27);
1811 }
1812 }
1813
1814 /* Restoration */
1815 if (phy->connected) {
1816 bcm43xx_phy_write(bcm, 0x0015, 0xE300);
1817 bcm43xx_phy_write(bcm, 0x0812, (r27 << 8) | 0xA0);
1818 udelay(5);
1819 bcm43xx_phy_write(bcm, 0x0812, (r27 << 8) | 0xA2);
1820 udelay(2);
1821 bcm43xx_phy_write(bcm, 0x0812, (r27 << 8) | 0xA3);
1822 } else
1823 bcm43xx_phy_write(bcm, 0x0015, r27 | 0xEFA0);
1824 bcm43xx_phy_lo_adjust(bcm, is_initializing);
1825 bcm43xx_phy_write(bcm, 0x002E, 0x807F);
1826 if (phy->connected)
1827 bcm43xx_phy_write(bcm, 0x002F, 0x0202);
1828 else
1829 bcm43xx_phy_write(bcm, 0x002F, 0x0101);
1830 bcm43xx_write16(bcm, BCM43xx_MMIO_CHANNEL_EXT, regstack[4]);
1831 bcm43xx_phy_write(bcm, 0x0015, regstack[5]);
1832 bcm43xx_phy_write(bcm, 0x002A, regstack[6]);
1833 bcm43xx_phy_write(bcm, 0x0035, regstack[7]);
1834 bcm43xx_phy_write(bcm, 0x0060, regstack[8]);
1835 bcm43xx_radio_write16(bcm, 0x0043, regstack[9]);
1836 bcm43xx_radio_write16(bcm, 0x007A, regstack[10]);
1837 regstack[11] &= 0x00F0;
1838 regstack[11] |= (bcm43xx_radio_read16(bcm, 0x52) & 0x000F);
1839 bcm43xx_radio_write16(bcm, 0x52, regstack[11]);
1840 bcm43xx_write16(bcm, 0x03E2, regstack[3]);
1841 if (phy->connected) {
1842 bcm43xx_phy_write(bcm, 0x0811, regstack[12]);
1843 bcm43xx_phy_write(bcm, 0x0812, regstack[13]);
1844 bcm43xx_phy_write(bcm, 0x0814, regstack[14]);
1845 bcm43xx_phy_write(bcm, 0x0815, regstack[15]);
1846 bcm43xx_phy_write(bcm, BCM43xx_PHY_G_CRS, regstack[0]);
1847 bcm43xx_phy_write(bcm, 0x0802, regstack[1]);
1848 }
1849 bcm43xx_radio_selectchannel(bcm, oldchannel, 1);
1850
1851#ifdef CONFIG_BCM43XX_DEBUG
1852 {
1853 /* Sanity check for all lopairs. */
1854 for (i = 0; i < BCM43xx_LO_COUNT; i++) {
1855 tmp_control = phy->_lo_pairs + i;
1856 if (tmp_control->low < -8 || tmp_control->low > 8 ||
1857 tmp_control->high < -8 || tmp_control->high > 8) {
1858 printk(KERN_WARNING PFX
1859 "WARNING: Invalid LOpair (low: %d, high: %d, index: %d)\n",
1860 tmp_control->low, tmp_control->high, i);
1861 }
1862 }
1863 }
1864#endif /* CONFIG_BCM43XX_DEBUG */
1865}
1866
1867static
1868void bcm43xx_phy_lo_mark_current_used(struct bcm43xx_private *bcm)
1869{
1870 struct bcm43xx_lopair *pair;
1871
1872 pair = bcm43xx_current_lopair(bcm);
1873 pair->used = 1;
1874}
1875
1876void bcm43xx_phy_lo_mark_all_unused(struct bcm43xx_private *bcm)
1877{
1878 struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
1879 struct bcm43xx_lopair *pair;
1880 int i;
1881
1882 for (i = 0; i < BCM43xx_LO_COUNT; i++) {
1883 pair = phy->_lo_pairs + i;
1884 pair->used = 0;
1885 }
1886}
1887
1888/* http://bcm-specs.sipsolutions.net/EstimatePowerOut
1889 * This function converts a TSSI value to dBm in Q5.2
1890 */
1891static s8 bcm43xx_phy_estimate_power_out(struct bcm43xx_private *bcm, s8 tssi)
1892{
1893 struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
1894 s8 dbm = 0;
1895 s32 tmp;
1896
1897 tmp = phy->idle_tssi;
1898 tmp += tssi;
1899 tmp -= phy->savedpctlreg;
1900
1901 switch (phy->type) {
1902 case BCM43xx_PHYTYPE_A:
1903 tmp += 0x80;
1904 tmp = limit_value(tmp, 0x00, 0xFF);
1905 dbm = phy->tssi2dbm[tmp];
1906 TODO(); //TODO: There's a FIXME on the specs
1907 break;
1908 case BCM43xx_PHYTYPE_B:
1909 case BCM43xx_PHYTYPE_G:
1910 tmp = limit_value(tmp, 0x00, 0x3F);
1911 dbm = phy->tssi2dbm[tmp];
1912 break;
1913 default:
1914 assert(0);
1915 }
1916
1917 return dbm;
1918}
1919
1920/* http://bcm-specs.sipsolutions.net/RecalculateTransmissionPower */
1921void bcm43xx_phy_xmitpower(struct bcm43xx_private *bcm)
1922{
1923 struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm);
1924 struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
1925
1926 if (phy->savedpctlreg == 0xFFFF)
1927 return;
1928 if ((bcm->board_type == 0x0416) &&
1929 (bcm->board_vendor == PCI_VENDOR_ID_BROADCOM))
1930 return;
1931
1932 switch (phy->type) {
1933 case BCM43xx_PHYTYPE_A: {
1934
1935 TODO(); //TODO: Nothing for A PHYs yet :-/
1936
1937 break;
1938 }
1939 case BCM43xx_PHYTYPE_B:
1940 case BCM43xx_PHYTYPE_G: {
1941 u16 tmp;
1942 u16 txpower;
1943 s8 v0, v1, v2, v3;
1944 s8 average;
1945 u8 max_pwr;
1946 s16 desired_pwr, estimated_pwr, pwr_adjust;
1947 s16 radio_att_delta, baseband_att_delta;
1948 s16 radio_attenuation, baseband_attenuation;
1949 unsigned long phylock_flags;
1950
1951 tmp = bcm43xx_shm_read16(bcm, BCM43xx_SHM_SHARED, 0x0058);
1952 v0 = (s8)(tmp & 0x00FF);
1953 v1 = (s8)((tmp & 0xFF00) >> 8);
1954 tmp = bcm43xx_shm_read16(bcm, BCM43xx_SHM_SHARED, 0x005A);
1955 v2 = (s8)(tmp & 0x00FF);
1956 v3 = (s8)((tmp & 0xFF00) >> 8);
1957 tmp = 0;
1958
1959 if (v0 == 0x7F || v1 == 0x7F || v2 == 0x7F || v3 == 0x7F) {
1960 tmp = bcm43xx_shm_read16(bcm, BCM43xx_SHM_SHARED, 0x0070);
1961 v0 = (s8)(tmp & 0x00FF);
1962 v1 = (s8)((tmp & 0xFF00) >> 8);
1963 tmp = bcm43xx_shm_read16(bcm, BCM43xx_SHM_SHARED, 0x0072);
1964 v2 = (s8)(tmp & 0x00FF);
1965 v3 = (s8)((tmp & 0xFF00) >> 8);
1966 if (v0 == 0x7F || v1 == 0x7F || v2 == 0x7F || v3 == 0x7F)
1967 return;
1968 v0 = (v0 + 0x20) & 0x3F;
1969 v1 = (v1 + 0x20) & 0x3F;
1970 v2 = (v2 + 0x20) & 0x3F;
1971 v3 = (v3 + 0x20) & 0x3F;
1972 tmp = 1;
1973 }
1974 bcm43xx_radio_clear_tssi(bcm);
1975
1976 average = (v0 + v1 + v2 + v3 + 2) / 4;
1977
1978 if (tmp && (bcm43xx_shm_read16(bcm, BCM43xx_SHM_SHARED, 0x005E) & 0x8))
1979 average -= 13;
1980
1981 estimated_pwr = bcm43xx_phy_estimate_power_out(bcm, average);
1982
1983 max_pwr = bcm->sprom.maxpower_bgphy;
1984
1985 if ((bcm->sprom.boardflags & BCM43xx_BFL_PACTRL) &&
1986 (phy->type == BCM43xx_PHYTYPE_G))
1987 max_pwr -= 0x3;
1988
1989 /*TODO:
1990 max_pwr = min(REG - bcm->sprom.antennagain_bgphy - 0x6, max_pwr)
1991 where REG is the max power as per the regulatory domain
1992 */
1993
1994 desired_pwr = limit_value(radio->txpower_desired, 0, max_pwr);
1995 /* Check if we need to adjust the current power. */
1996 pwr_adjust = desired_pwr - estimated_pwr;
1997 radio_att_delta = -(pwr_adjust + 7) >> 3;
1998 baseband_att_delta = -(pwr_adjust >> 1) - (4 * radio_att_delta);
1999 if ((radio_att_delta == 0) && (baseband_att_delta == 0)) {
2000 bcm43xx_phy_lo_mark_current_used(bcm);
2001 return;
2002 }
2003
2004 /* Calculate the new attenuation values. */
2005 baseband_attenuation = radio->baseband_atten;
2006 baseband_attenuation += baseband_att_delta;
2007 radio_attenuation = radio->radio_atten;
2008 radio_attenuation += radio_att_delta;
2009
2010 /* Get baseband and radio attenuation values into their permitted ranges.
2011 * baseband 0-11, radio 0-9.
2012 * Radio attenuation affects power level 4 times as much as baseband.
2013 */
2014 if (radio_attenuation < 0) {
2015 baseband_attenuation -= (4 * -radio_attenuation);
2016 radio_attenuation = 0;
2017 } else if (radio_attenuation > 9) {
2018 baseband_attenuation += (4 * (radio_attenuation - 9));
2019 radio_attenuation = 9;
2020 } else {
2021 while (baseband_attenuation < 0 && radio_attenuation > 0) {
2022 baseband_attenuation += 4;
2023 radio_attenuation--;
2024 }
2025 while (baseband_attenuation > 11 && radio_attenuation < 9) {
2026 baseband_attenuation -= 4;
2027 radio_attenuation++;
2028 }
2029 }
2030 baseband_attenuation = limit_value(baseband_attenuation, 0, 11);
2031
2032 txpower = radio->txctl1;
2033 if ((radio->version == 0x2050) && (radio->revision == 2)) {
2034 if (radio_attenuation <= 1) {
2035 if (txpower == 0) {
2036 txpower = 3;
2037 radio_attenuation += 2;
2038 baseband_attenuation += 2;
2039 } else if (bcm->sprom.boardflags & BCM43xx_BFL_PACTRL) {
2040 baseband_attenuation += 4 * (radio_attenuation - 2);
2041 radio_attenuation = 2;
2042 }
2043 } else if (radio_attenuation > 4 && txpower != 0) {
2044 txpower = 0;
2045 if (baseband_attenuation < 3) {
2046 radio_attenuation -= 3;
2047 baseband_attenuation += 2;
2048 } else {
2049 radio_attenuation -= 2;
2050 baseband_attenuation -= 2;
2051 }
2052 }
2053 }
2054 radio->txctl1 = txpower;
2055 baseband_attenuation = limit_value(baseband_attenuation, 0, 11);
2056 radio_attenuation = limit_value(radio_attenuation, 0, 9);
2057
2058 bcm43xx_phy_lock(bcm, phylock_flags);
2059 bcm43xx_radio_lock(bcm);
2060 bcm43xx_radio_set_txpower_bg(bcm, baseband_attenuation,
2061 radio_attenuation, txpower);
2062 bcm43xx_phy_lo_mark_current_used(bcm);
2063 bcm43xx_radio_unlock(bcm);
2064 bcm43xx_phy_unlock(bcm, phylock_flags);
2065 break;
2066 }
2067 default:
2068 assert(0);
2069 }
2070}
2071
2072static inline
2073s32 bcm43xx_tssi2dbm_ad(s32 num, s32 den)
2074{
2075 if (num < 0)
2076 return num/den;
2077 else
2078 return (num+den/2)/den;
2079}
2080
2081static inline
2082s8 bcm43xx_tssi2dbm_entry(s8 entry [], u8 index, s16 pab0, s16 pab1, s16 pab2)
2083{
2084 s32 m1, m2, f = 256, q, delta;
2085 s8 i = 0;
2086
2087 m1 = bcm43xx_tssi2dbm_ad(16 * pab0 + index * pab1, 32);
2088 m2 = max(bcm43xx_tssi2dbm_ad(32768 + index * pab2, 256), 1);
2089 do {
2090 if (i > 15)
2091 return -EINVAL;
2092 q = bcm43xx_tssi2dbm_ad(f * 4096 -
2093 bcm43xx_tssi2dbm_ad(m2 * f, 16) * f, 2048);
2094 delta = abs(q - f);
2095 f = q;
2096 i++;
2097 } while (delta >= 2);
2098 entry[index] = limit_value(bcm43xx_tssi2dbm_ad(m1 * f, 8192), -127, 128);
2099 return 0;
2100}
2101
2102/* http://bcm-specs.sipsolutions.net/TSSI_to_DBM_Table */
2103int bcm43xx_phy_init_tssi2dbm_table(struct bcm43xx_private *bcm)
2104{
2105 struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
2106 struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm);
2107 s16 pab0, pab1, pab2;
2108 u8 idx;
2109 s8 *dyn_tssi2dbm;
2110
2111 if (phy->type == BCM43xx_PHYTYPE_A) {
2112 pab0 = (s16)(bcm->sprom.pa1b0);
2113 pab1 = (s16)(bcm->sprom.pa1b1);
2114 pab2 = (s16)(bcm->sprom.pa1b2);
2115 } else {
2116 pab0 = (s16)(bcm->sprom.pa0b0);
2117 pab1 = (s16)(bcm->sprom.pa0b1);
2118 pab2 = (s16)(bcm->sprom.pa0b2);
2119 }
2120
2121 if ((bcm->chip_id == 0x4301) && (radio->version != 0x2050)) {
2122 phy->idle_tssi = 0x34;
2123 phy->tssi2dbm = bcm43xx_tssi2dbm_b_table;
2124 return 0;
2125 }
2126
2127 if (pab0 != 0 && pab1 != 0 && pab2 != 0 &&
2128 pab0 != -1 && pab1 != -1 && pab2 != -1) {
2129 /* The pabX values are set in SPROM. Use them. */
2130 if (phy->type == BCM43xx_PHYTYPE_A) {
2131 if ((s8)bcm->sprom.idle_tssi_tgt_aphy != 0 &&
2132 (s8)bcm->sprom.idle_tssi_tgt_aphy != -1)
2133 phy->idle_tssi = (s8)(bcm->sprom.idle_tssi_tgt_aphy);
2134 else
2135 phy->idle_tssi = 62;
2136 } else {
2137 if ((s8)bcm->sprom.idle_tssi_tgt_bgphy != 0 &&
2138 (s8)bcm->sprom.idle_tssi_tgt_bgphy != -1)
2139 phy->idle_tssi = (s8)(bcm->sprom.idle_tssi_tgt_bgphy);
2140 else
2141 phy->idle_tssi = 62;
2142 }
2143 dyn_tssi2dbm = kmalloc(64, GFP_KERNEL);
2144 if (dyn_tssi2dbm == NULL) {
2145 printk(KERN_ERR PFX "Could not allocate memory"
2146 "for tssi2dbm table\n");
2147 return -ENOMEM;
2148 }
2149 for (idx = 0; idx < 64; idx++)
2150 if (bcm43xx_tssi2dbm_entry(dyn_tssi2dbm, idx, pab0, pab1, pab2)) {
2151 phy->tssi2dbm = NULL;
2152 printk(KERN_ERR PFX "Could not generate "
2153 "tssi2dBm table\n");
2154 return -ENODEV;
2155 }
2156 phy->tssi2dbm = dyn_tssi2dbm;
2157 phy->dyn_tssi_tbl = 1;
2158 } else {
2159 /* pabX values not set in SPROM. */
2160 switch (phy->type) {
2161 case BCM43xx_PHYTYPE_A:
2162 /* APHY needs a generated table. */
2163 phy->tssi2dbm = NULL;
2164 printk(KERN_ERR PFX "Could not generate tssi2dBm "
2165 "table (wrong SPROM info)!\n");
2166 return -ENODEV;
2167 case BCM43xx_PHYTYPE_B:
2168 phy->idle_tssi = 0x34;
2169 phy->tssi2dbm = bcm43xx_tssi2dbm_b_table;
2170 break;
2171 case BCM43xx_PHYTYPE_G:
2172 phy->idle_tssi = 0x34;
2173 phy->tssi2dbm = bcm43xx_tssi2dbm_g_table;
2174 break;
2175 }
2176 }
2177
2178 return 0;
2179}
2180
2181int bcm43xx_phy_init(struct bcm43xx_private *bcm)
2182{
2183 struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
2184 int err = -ENODEV;
2185 unsigned long flags;
2186
2187 /* We do not want to be preempted while calibrating
2188 * the hardware.
2189 */
2190 local_irq_save(flags);
2191
2192 switch (phy->type) {
2193 case BCM43xx_PHYTYPE_A:
2194 if (phy->rev == 2 || phy->rev == 3) {
2195 bcm43xx_phy_inita(bcm);
2196 err = 0;
2197 }
2198 break;
2199 case BCM43xx_PHYTYPE_B:
2200 switch (phy->rev) {
2201 case 2:
2202 bcm43xx_phy_initb2(bcm);
2203 err = 0;
2204 break;
2205 case 4:
2206 bcm43xx_phy_initb4(bcm);
2207 err = 0;
2208 break;
2209 case 5:
2210 bcm43xx_phy_initb5(bcm);
2211 err = 0;
2212 break;
2213 case 6:
2214 bcm43xx_phy_initb6(bcm);
2215 err = 0;
2216 break;
2217 }
2218 break;
2219 case BCM43xx_PHYTYPE_G:
2220 bcm43xx_phy_initg(bcm);
2221 err = 0;
2222 break;
2223 }
2224 local_irq_restore(flags);
2225 if (err)
2226 printk(KERN_WARNING PFX "Unknown PHYTYPE found!\n");
2227
2228 return err;
2229}
2230
2231void bcm43xx_phy_set_antenna_diversity(struct bcm43xx_private *bcm)
2232{
2233 struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
2234 u16 antennadiv;
2235 u16 offset;
2236 u16 value;
2237 u32 ucodeflags;
2238
2239 antennadiv = phy->antenna_diversity;
2240
2241 if (antennadiv == 0xFFFF)
2242 antennadiv = 3;
2243 assert(antennadiv <= 3);
2244
2245 ucodeflags = bcm43xx_shm_read32(bcm, BCM43xx_SHM_SHARED,
2246 BCM43xx_UCODEFLAGS_OFFSET);
2247 bcm43xx_shm_write32(bcm, BCM43xx_SHM_SHARED,
2248 BCM43xx_UCODEFLAGS_OFFSET,
2249 ucodeflags & ~BCM43xx_UCODEFLAG_AUTODIV);
2250
2251 switch (phy->type) {
2252 case BCM43xx_PHYTYPE_A:
2253 case BCM43xx_PHYTYPE_G:
2254 if (phy->type == BCM43xx_PHYTYPE_A)
2255 offset = 0x0000;
2256 else
2257 offset = 0x0400;
2258
2259 if (antennadiv == 2)
2260 value = (3/*automatic*/ << 7);
2261 else
2262 value = (antennadiv << 7);
2263 bcm43xx_phy_write(bcm, offset + 1,
2264 (bcm43xx_phy_read(bcm, offset + 1)
2265 & 0x7E7F) | value);
2266
2267 if (antennadiv >= 2) {
2268 if (antennadiv == 2)
2269 value = (antennadiv << 7);
2270 else
2271 value = (0/*force0*/ << 7);
2272 bcm43xx_phy_write(bcm, offset + 0x2B,
2273 (bcm43xx_phy_read(bcm, offset + 0x2B)
2274 & 0xFEFF) | value);
2275 }
2276
2277 if (phy->type == BCM43xx_PHYTYPE_G) {
2278 if (antennadiv >= 2)
2279 bcm43xx_phy_write(bcm, 0x048C,
2280 bcm43xx_phy_read(bcm, 0x048C)
2281 | 0x2000);
2282 else
2283 bcm43xx_phy_write(bcm, 0x048C,
2284 bcm43xx_phy_read(bcm, 0x048C)
2285 & ~0x2000);
2286 if (phy->rev >= 2) {
2287 bcm43xx_phy_write(bcm, 0x0461,
2288 bcm43xx_phy_read(bcm, 0x0461)
2289 | 0x0010);
2290 bcm43xx_phy_write(bcm, 0x04AD,
2291 (bcm43xx_phy_read(bcm, 0x04AD)
2292 & 0x00FF) | 0x0015);
2293 if (phy->rev == 2)
2294 bcm43xx_phy_write(bcm, 0x0427, 0x0008);
2295 else
2296 bcm43xx_phy_write(bcm, 0x0427,
2297 (bcm43xx_phy_read(bcm, 0x0427)
2298 & 0x00FF) | 0x0008);
2299 }
2300 else if (phy->rev >= 6)
2301 bcm43xx_phy_write(bcm, 0x049B, 0x00DC);
2302 } else {
2303 if (phy->rev < 3)
2304 bcm43xx_phy_write(bcm, 0x002B,
2305 (bcm43xx_phy_read(bcm, 0x002B)
2306 & 0x00FF) | 0x0024);
2307 else {
2308 bcm43xx_phy_write(bcm, 0x0061,
2309 bcm43xx_phy_read(bcm, 0x0061)
2310 | 0x0010);
2311 if (phy->rev == 3) {
2312 bcm43xx_phy_write(bcm, 0x0093, 0x001D);
2313 bcm43xx_phy_write(bcm, 0x0027, 0x0008);
2314 } else {
2315 bcm43xx_phy_write(bcm, 0x0093, 0x003A);
2316 bcm43xx_phy_write(bcm, 0x0027,
2317 (bcm43xx_phy_read(bcm, 0x0027)
2318 & 0x00FF) | 0x0008);
2319 }
2320 }
2321 }
2322 break;
2323 case BCM43xx_PHYTYPE_B:
2324 if (bcm->current_core->rev == 2)
2325 value = (3/*automatic*/ << 7);
2326 else
2327 value = (antennadiv << 7);
2328 bcm43xx_phy_write(bcm, 0x03E2,
2329 (bcm43xx_phy_read(bcm, 0x03E2)
2330 & 0xFE7F) | value);
2331 break;
2332 default:
2333 assert(0);
2334 }
2335
2336 if (antennadiv >= 2) {
2337 ucodeflags = bcm43xx_shm_read32(bcm, BCM43xx_SHM_SHARED,
2338 BCM43xx_UCODEFLAGS_OFFSET);
2339 bcm43xx_shm_write32(bcm, BCM43xx_SHM_SHARED,
2340 BCM43xx_UCODEFLAGS_OFFSET,
2341 ucodeflags | BCM43xx_UCODEFLAG_AUTODIV);
2342 }
2343
2344 phy->antenna_diversity = antennadiv;
2345}
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_phy.h b/drivers/net/wireless/bcm43xx/bcm43xx_phy.h
new file mode 100644
index 000000000000..1f321ef42be8
--- /dev/null
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_phy.h
@@ -0,0 +1,74 @@
1/*
2
3 Broadcom BCM43xx wireless driver
4
5 Copyright (c) 2005 Martin Langer <martin-langer@gmx.de>,
6 Stefano Brivio <st3@riseup.net>
7 Michael Buesch <mbuesch@freenet.de>
8 Danny van Dyk <kugelfang@gentoo.org>
9 Andreas Jaggi <andreas.jaggi@waterwave.ch>
10
11 Some parts of the code in this file are derived from the ipw2200
12 driver Copyright(c) 2003 - 2004 Intel Corporation.
13
14 This program is free software; you can redistribute it and/or modify
15 it under the terms of the GNU General Public License as published by
16 the Free Software Foundation; either version 2 of the License, or
17 (at your option) any later version.
18
19 This program is distributed in the hope that it will be useful,
20 but WITHOUT ANY WARRANTY; without even the implied warranty of
21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 GNU General Public License for more details.
23
24 You should have received a copy of the GNU General Public License
25 along with this program; see the file COPYING. If not, write to
26 the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,
27 Boston, MA 02110-1301, USA.
28
29*/
30
31#ifndef BCM43xx_PHY_H_
32#define BCM43xx_PHY_H_
33
34#include <linux/types.h>
35
36struct bcm43xx_private;
37
38void bcm43xx_raw_phy_lock(struct bcm43xx_private *bcm);
39#define bcm43xx_phy_lock(bcm, flags) \
40 do { \
41 local_irq_save(flags); \
42 bcm43xx_raw_phy_lock(bcm); \
43 } while (0)
44void bcm43xx_raw_phy_unlock(struct bcm43xx_private *bcm);
45#define bcm43xx_phy_unlock(bcm, flags) \
46 do { \
47 bcm43xx_raw_phy_unlock(bcm); \
48 local_irq_restore(flags); \
49 } while (0)
50
51u16 bcm43xx_phy_read(struct bcm43xx_private *bcm, u16 offset);
52void bcm43xx_phy_write(struct bcm43xx_private *bcm, u16 offset, u16 val);
53
54int bcm43xx_phy_init_tssi2dbm_table(struct bcm43xx_private *bcm);
55int bcm43xx_phy_init(struct bcm43xx_private *bcm);
56
57void bcm43xx_phy_set_antenna_diversity(struct bcm43xx_private *bcm);
58void bcm43xx_phy_calibrate(struct bcm43xx_private *bcm);
59int bcm43xx_phy_connect(struct bcm43xx_private *bcm, int connect);
60
61void bcm43xx_phy_lo_b_measure(struct bcm43xx_private *bcm);
62void bcm43xx_phy_lo_g_measure(struct bcm43xx_private *bcm);
63void bcm43xx_phy_xmitpower(struct bcm43xx_private *bcm);
64
65/* Adjust the LocalOscillator to the saved values.
66 * "fixed" is only set to 1 once in initialization. Set to 0 otherwise.
67 */
68void bcm43xx_phy_lo_adjust(struct bcm43xx_private *bcm, int fixed);
69void bcm43xx_phy_lo_mark_all_unused(struct bcm43xx_private *bcm);
70
71void bcm43xx_phy_set_baseband_attenuation(struct bcm43xx_private *bcm,
72 u16 baseband_attenuation);
73
74#endif /* BCM43xx_PHY_H_ */
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_pio.c b/drivers/net/wireless/bcm43xx/bcm43xx_pio.c
new file mode 100644
index 000000000000..c59ddd40680d
--- /dev/null
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_pio.c
@@ -0,0 +1,606 @@
1/*
2
3 Broadcom BCM43xx wireless driver
4
5 PIO Transmission
6
7 Copyright (c) 2005 Michael Buesch <mbuesch@freenet.de>
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; see the file COPYING. If not, write to
21 the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,
22 Boston, MA 02110-1301, USA.
23
24*/
25
26#include "bcm43xx.h"
27#include "bcm43xx_pio.h"
28#include "bcm43xx_main.h"
29#include "bcm43xx_xmit.h"
30
31#include <linux/delay.h>
32
33
34static void tx_start(struct bcm43xx_pioqueue *queue)
35{
36 bcm43xx_pio_write(queue, BCM43xx_PIO_TXCTL,
37 BCM43xx_PIO_TXCTL_INIT);
38}
39
40static void tx_octet(struct bcm43xx_pioqueue *queue,
41 u8 octet)
42{
43 if (queue->need_workarounds) {
44 bcm43xx_pio_write(queue, BCM43xx_PIO_TXDATA,
45 octet);
46 bcm43xx_pio_write(queue, BCM43xx_PIO_TXCTL,
47 BCM43xx_PIO_TXCTL_WRITEHI);
48 } else {
49 bcm43xx_pio_write(queue, BCM43xx_PIO_TXCTL,
50 BCM43xx_PIO_TXCTL_WRITEHI);
51 bcm43xx_pio_write(queue, BCM43xx_PIO_TXDATA,
52 octet);
53 }
54}
55
56static u16 tx_get_next_word(struct bcm43xx_txhdr *txhdr,
57 const u8 *packet,
58 unsigned int *pos)
59{
60 const u8 *source;
61 unsigned int i = *pos;
62 u16 ret;
63
64 if (i < sizeof(*txhdr)) {
65 source = (const u8 *)txhdr;
66 } else {
67 source = packet;
68 i -= sizeof(*txhdr);
69 }
70 ret = le16_to_cpu( *((u16 *)(source + i)) );
71 *pos += 2;
72
73 return ret;
74}
75
76static void tx_data(struct bcm43xx_pioqueue *queue,
77 struct bcm43xx_txhdr *txhdr,
78 const u8 *packet,
79 unsigned int octets)
80{
81 u16 data;
82 unsigned int i = 0;
83
84 if (queue->need_workarounds) {
85 data = tx_get_next_word(txhdr, packet, &i);
86 bcm43xx_pio_write(queue, BCM43xx_PIO_TXDATA, data);
87 }
88 bcm43xx_pio_write(queue, BCM43xx_PIO_TXCTL,
89 BCM43xx_PIO_TXCTL_WRITELO |
90 BCM43xx_PIO_TXCTL_WRITEHI);
91 while (i < octets - 1) {
92 data = tx_get_next_word(txhdr, packet, &i);
93 bcm43xx_pio_write(queue, BCM43xx_PIO_TXDATA, data);
94 }
95 if (octets % 2)
96 tx_octet(queue, packet[octets - sizeof(*txhdr) - 1]);
97}
98
99static void tx_complete(struct bcm43xx_pioqueue *queue,
100 struct sk_buff *skb)
101{
102 if (queue->need_workarounds) {
103 bcm43xx_pio_write(queue, BCM43xx_PIO_TXDATA,
104 skb->data[skb->len - 1]);
105 bcm43xx_pio_write(queue, BCM43xx_PIO_TXCTL,
106 BCM43xx_PIO_TXCTL_WRITEHI |
107 BCM43xx_PIO_TXCTL_COMPLETE);
108 } else {
109 bcm43xx_pio_write(queue, BCM43xx_PIO_TXCTL,
110 BCM43xx_PIO_TXCTL_COMPLETE);
111 }
112}
113
114static u16 generate_cookie(struct bcm43xx_pioqueue *queue,
115 int packetindex)
116{
117 u16 cookie = 0x0000;
118
119 /* We use the upper 4 bits for the PIO
120 * controller ID and the lower 12 bits
121 * for the packet index (in the cache).
122 */
123 switch (queue->mmio_base) {
124 case BCM43xx_MMIO_PIO1_BASE:
125 break;
126 case BCM43xx_MMIO_PIO2_BASE:
127 cookie = 0x1000;
128 break;
129 case BCM43xx_MMIO_PIO3_BASE:
130 cookie = 0x2000;
131 break;
132 case BCM43xx_MMIO_PIO4_BASE:
133 cookie = 0x3000;
134 break;
135 default:
136 assert(0);
137 }
138 assert(((u16)packetindex & 0xF000) == 0x0000);
139 cookie |= (u16)packetindex;
140
141 return cookie;
142}
143
144static
145struct bcm43xx_pioqueue * parse_cookie(struct bcm43xx_private *bcm,
146 u16 cookie,
147 struct bcm43xx_pio_txpacket **packet)
148{
149 struct bcm43xx_pio *pio = bcm43xx_current_pio(bcm);
150 struct bcm43xx_pioqueue *queue = NULL;
151 int packetindex;
152
153 switch (cookie & 0xF000) {
154 case 0x0000:
155 queue = pio->queue0;
156 break;
157 case 0x1000:
158 queue = pio->queue1;
159 break;
160 case 0x2000:
161 queue = pio->queue2;
162 break;
163 case 0x3000:
164 queue = pio->queue3;
165 break;
166 default:
167 assert(0);
168 }
169 packetindex = (cookie & 0x0FFF);
170 assert(packetindex >= 0 && packetindex < BCM43xx_PIO_MAXTXPACKETS);
171 *packet = &(queue->tx_packets_cache[packetindex]);
172
173 return queue;
174}
175
176static void pio_tx_write_fragment(struct bcm43xx_pioqueue *queue,
177 struct sk_buff *skb,
178 struct bcm43xx_pio_txpacket *packet)
179{
180 struct bcm43xx_txhdr txhdr;
181 unsigned int octets;
182
183 assert(skb_shinfo(skb)->nr_frags == 0);
184 bcm43xx_generate_txhdr(queue->bcm,
185 &txhdr, skb->data, skb->len,
186 (packet->xmitted_frags == 0),
187 generate_cookie(queue, pio_txpacket_getindex(packet)));
188
189 tx_start(queue);
190 octets = skb->len + sizeof(txhdr);
191 if (queue->need_workarounds)
192 octets--;
193 tx_data(queue, &txhdr, (u8 *)skb->data, octets);
194 tx_complete(queue, skb);
195}
196
197static void free_txpacket(struct bcm43xx_pio_txpacket *packet,
198 int irq_context)
199{
200 struct bcm43xx_pioqueue *queue = packet->queue;
201
202 ieee80211_txb_free(packet->txb);
203 list_move(&packet->list, &queue->txfree);
204 queue->nr_txfree++;
205
206 assert(queue->tx_devq_used >= packet->xmitted_octets);
207 assert(queue->tx_devq_packets >= packet->xmitted_frags);
208 queue->tx_devq_used -= packet->xmitted_octets;
209 queue->tx_devq_packets -= packet->xmitted_frags;
210}
211
212static int pio_tx_packet(struct bcm43xx_pio_txpacket *packet)
213{
214 struct bcm43xx_pioqueue *queue = packet->queue;
215 struct ieee80211_txb *txb = packet->txb;
216 struct sk_buff *skb;
217 u16 octets;
218 int i;
219
220 for (i = packet->xmitted_frags; i < txb->nr_frags; i++) {
221 skb = txb->fragments[i];
222
223 octets = (u16)skb->len + sizeof(struct bcm43xx_txhdr);
224 assert(queue->tx_devq_size >= octets);
225 assert(queue->tx_devq_packets <= BCM43xx_PIO_MAXTXDEVQPACKETS);
226 assert(queue->tx_devq_used <= queue->tx_devq_size);
227 /* Check if there is sufficient free space on the device
228 * TX queue. If not, return and let the TX tasklet
229 * retry later.
230 */
231 if (queue->tx_devq_packets == BCM43xx_PIO_MAXTXDEVQPACKETS)
232 return -EBUSY;
233 if (queue->tx_devq_used + octets > queue->tx_devq_size)
234 return -EBUSY;
235 /* Now poke the device. */
236 pio_tx_write_fragment(queue, skb, packet);
237
238 /* Account for the packet size.
239 * (We must not overflow the device TX queue)
240 */
241 queue->tx_devq_packets++;
242 queue->tx_devq_used += octets;
243
244 assert(packet->xmitted_frags <= packet->txb->nr_frags);
245 packet->xmitted_frags++;
246 packet->xmitted_octets += octets;
247 }
248 list_move_tail(&packet->list, &queue->txrunning);
249
250 return 0;
251}
252
253static void tx_tasklet(unsigned long d)
254{
255 struct bcm43xx_pioqueue *queue = (struct bcm43xx_pioqueue *)d;
256 struct bcm43xx_private *bcm = queue->bcm;
257 unsigned long flags;
258 struct bcm43xx_pio_txpacket *packet, *tmp_packet;
259 int err;
260
261 bcm43xx_lock_mmio(bcm, flags);
262 list_for_each_entry_safe(packet, tmp_packet, &queue->txqueue, list) {
263 assert(packet->xmitted_frags < packet->txb->nr_frags);
264 if (packet->xmitted_frags == 0) {
265 int i;
266 struct sk_buff *skb;
267
268 /* Check if the device queue is big
269 * enough for every fragment. If not, drop the
270 * whole packet.
271 */
272 for (i = 0; i < packet->txb->nr_frags; i++) {
273 skb = packet->txb->fragments[i];
274 if (unlikely(skb->len > queue->tx_devq_size)) {
275 dprintkl(KERN_ERR PFX "PIO TX device queue too small. "
276 "Dropping packet.\n");
277 free_txpacket(packet, 1);
278 goto next_packet;
279 }
280 }
281 }
282 /* Try to transmit the packet.
283 * This may not completely succeed.
284 */
285 err = pio_tx_packet(packet);
286 if (err)
287 break;
288 next_packet:
289 continue;
290 }
291 bcm43xx_unlock_mmio(bcm, flags);
292}
293
294static void setup_txqueues(struct bcm43xx_pioqueue *queue)
295{
296 struct bcm43xx_pio_txpacket *packet;
297 int i;
298
299 queue->nr_txfree = BCM43xx_PIO_MAXTXPACKETS;
300 for (i = 0; i < BCM43xx_PIO_MAXTXPACKETS; i++) {
301 packet = &(queue->tx_packets_cache[i]);
302
303 packet->queue = queue;
304 INIT_LIST_HEAD(&packet->list);
305
306 list_add(&packet->list, &queue->txfree);
307 }
308}
309
310static
311struct bcm43xx_pioqueue * bcm43xx_setup_pioqueue(struct bcm43xx_private *bcm,
312 u16 pio_mmio_base)
313{
314 struct bcm43xx_pioqueue *queue;
315 u32 value;
316 u16 qsize;
317
318 queue = kzalloc(sizeof(*queue), GFP_KERNEL);
319 if (!queue)
320 goto out;
321
322 queue->bcm = bcm;
323 queue->mmio_base = pio_mmio_base;
324 queue->need_workarounds = (bcm->current_core->rev < 3);
325
326 INIT_LIST_HEAD(&queue->txfree);
327 INIT_LIST_HEAD(&queue->txqueue);
328 INIT_LIST_HEAD(&queue->txrunning);
329 tasklet_init(&queue->txtask, tx_tasklet,
330 (unsigned long)queue);
331
332 value = bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD);
333 value |= BCM43xx_SBF_XFER_REG_BYTESWAP;
334 bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD, value);
335
336 qsize = bcm43xx_read16(bcm, queue->mmio_base + BCM43xx_PIO_TXQBUFSIZE);
337 if (qsize <= BCM43xx_PIO_TXQADJUST) {
338 printk(KERN_ERR PFX "PIO tx device-queue too small (%u)\n", qsize);
339 goto err_freequeue;
340 }
341 qsize -= BCM43xx_PIO_TXQADJUST;
342 queue->tx_devq_size = qsize;
343
344 setup_txqueues(queue);
345
346out:
347 return queue;
348
349err_freequeue:
350 kfree(queue);
351 queue = NULL;
352 goto out;
353}
354
355static void cancel_transfers(struct bcm43xx_pioqueue *queue)
356{
357 struct bcm43xx_pio_txpacket *packet, *tmp_packet;
358
359 netif_tx_disable(queue->bcm->net_dev);
360 assert(queue->bcm->shutting_down);
361 tasklet_disable(&queue->txtask);
362
363 list_for_each_entry_safe(packet, tmp_packet, &queue->txrunning, list)
364 free_txpacket(packet, 0);
365 list_for_each_entry_safe(packet, tmp_packet, &queue->txqueue, list)
366 free_txpacket(packet, 0);
367}
368
369static void bcm43xx_destroy_pioqueue(struct bcm43xx_pioqueue *queue)
370{
371 if (!queue)
372 return;
373
374 cancel_transfers(queue);
375 kfree(queue);
376}
377
378void bcm43xx_pio_free(struct bcm43xx_private *bcm)
379{
380 struct bcm43xx_pio *pio;
381
382 if (!bcm43xx_using_pio(bcm))
383 return;
384 pio = bcm43xx_current_pio(bcm);
385
386 bcm43xx_destroy_pioqueue(pio->queue3);
387 pio->queue3 = NULL;
388 bcm43xx_destroy_pioqueue(pio->queue2);
389 pio->queue2 = NULL;
390 bcm43xx_destroy_pioqueue(pio->queue1);
391 pio->queue1 = NULL;
392 bcm43xx_destroy_pioqueue(pio->queue0);
393 pio->queue0 = NULL;
394}
395
396int bcm43xx_pio_init(struct bcm43xx_private *bcm)
397{
398 struct bcm43xx_pio *pio = bcm43xx_current_pio(bcm);
399 struct bcm43xx_pioqueue *queue;
400 int err = -ENOMEM;
401
402 queue = bcm43xx_setup_pioqueue(bcm, BCM43xx_MMIO_PIO1_BASE);
403 if (!queue)
404 goto out;
405 pio->queue0 = queue;
406
407 queue = bcm43xx_setup_pioqueue(bcm, BCM43xx_MMIO_PIO2_BASE);
408 if (!queue)
409 goto err_destroy0;
410 pio->queue1 = queue;
411
412 queue = bcm43xx_setup_pioqueue(bcm, BCM43xx_MMIO_PIO3_BASE);
413 if (!queue)
414 goto err_destroy1;
415 pio->queue2 = queue;
416
417 queue = bcm43xx_setup_pioqueue(bcm, BCM43xx_MMIO_PIO4_BASE);
418 if (!queue)
419 goto err_destroy2;
420 pio->queue3 = queue;
421
422 if (bcm->current_core->rev < 3)
423 bcm->irq_savedstate |= BCM43xx_IRQ_PIO_WORKAROUND;
424
425 dprintk(KERN_INFO PFX "PIO initialized\n");
426 err = 0;
427out:
428 return err;
429
430err_destroy2:
431 bcm43xx_destroy_pioqueue(pio->queue2);
432 pio->queue2 = NULL;
433err_destroy1:
434 bcm43xx_destroy_pioqueue(pio->queue1);
435 pio->queue1 = NULL;
436err_destroy0:
437 bcm43xx_destroy_pioqueue(pio->queue0);
438 pio->queue0 = NULL;
439 goto out;
440}
441
442int bcm43xx_pio_tx(struct bcm43xx_private *bcm,
443 struct ieee80211_txb *txb)
444{
445 struct bcm43xx_pioqueue *queue = bcm43xx_current_pio(bcm)->queue1;
446 struct bcm43xx_pio_txpacket *packet;
447 u16 tmp;
448
449 assert(!queue->tx_suspended);
450 assert(!list_empty(&queue->txfree));
451
452 tmp = bcm43xx_pio_read(queue, BCM43xx_PIO_TXCTL);
453 if (tmp & BCM43xx_PIO_TXCTL_SUSPEND)
454 return -EBUSY;
455
456 packet = list_entry(queue->txfree.next, struct bcm43xx_pio_txpacket, list);
457 packet->txb = txb;
458 packet->xmitted_frags = 0;
459 packet->xmitted_octets = 0;
460 list_move_tail(&packet->list, &queue->txqueue);
461 queue->nr_txfree--;
462 assert(queue->nr_txfree < BCM43xx_PIO_MAXTXPACKETS);
463
464 /* Suspend TX, if we are out of packets in the "free" queue. */
465 if (unlikely(list_empty(&queue->txfree))) {
466 netif_stop_queue(queue->bcm->net_dev);
467 queue->tx_suspended = 1;
468 }
469
470 tasklet_schedule(&queue->txtask);
471
472 return 0;
473}
474
475void bcm43xx_pio_handle_xmitstatus(struct bcm43xx_private *bcm,
476 struct bcm43xx_xmitstatus *status)
477{
478 struct bcm43xx_pioqueue *queue;
479 struct bcm43xx_pio_txpacket *packet;
480
481 queue = parse_cookie(bcm, status->cookie, &packet);
482 assert(queue);
483//TODO
484if (!queue)
485return;
486 free_txpacket(packet, 1);
487 if (unlikely(queue->tx_suspended)) {
488 queue->tx_suspended = 0;
489 netif_wake_queue(queue->bcm->net_dev);
490 }
491 /* If there are packets on the txqueue, poke the tasklet. */
492 if (!list_empty(&queue->txqueue))
493 tasklet_schedule(&queue->txtask);
494}
495
496static void pio_rx_error(struct bcm43xx_pioqueue *queue,
497 int clear_buffers,
498 const char *error)
499{
500 int i;
501
502 printkl("PIO RX error: %s\n", error);
503 bcm43xx_pio_write(queue, BCM43xx_PIO_RXCTL,
504 BCM43xx_PIO_RXCTL_READY);
505 if (clear_buffers) {
506 assert(queue->mmio_base == BCM43xx_MMIO_PIO1_BASE);
507 for (i = 0; i < 15; i++) {
508 /* Dummy read. */
509 bcm43xx_pio_read(queue, BCM43xx_PIO_RXDATA);
510 }
511 }
512}
513
514void bcm43xx_pio_rx(struct bcm43xx_pioqueue *queue)
515{
516 u16 preamble[21] = { 0 };
517 struct bcm43xx_rxhdr *rxhdr;
518 u16 tmp, len, rxflags2;
519 int i, preamble_readwords;
520 struct sk_buff *skb;
521
522return;
523 tmp = bcm43xx_pio_read(queue, BCM43xx_PIO_RXCTL);
524 if (!(tmp & BCM43xx_PIO_RXCTL_DATAAVAILABLE)) {
525 dprintkl(KERN_ERR PFX "PIO RX: No data available\n");//TODO: remove this printk.
526 return;
527 }
528 bcm43xx_pio_write(queue, BCM43xx_PIO_RXCTL,
529 BCM43xx_PIO_RXCTL_DATAAVAILABLE);
530
531 for (i = 0; i < 10; i++) {
532 tmp = bcm43xx_pio_read(queue, BCM43xx_PIO_RXCTL);
533 if (tmp & BCM43xx_PIO_RXCTL_READY)
534 goto data_ready;
535 udelay(10);
536 }
537 dprintkl(KERN_ERR PFX "PIO RX timed out\n");
538 return;
539data_ready:
540
541//FIXME: endianess in this function.
542 len = le16_to_cpu(bcm43xx_pio_read(queue, BCM43xx_PIO_RXDATA));
543 if (unlikely(len > 0x700)) {
544 pio_rx_error(queue, 0, "len > 0x700");
545 return;
546 }
547 if (unlikely(len == 0 && queue->mmio_base != BCM43xx_MMIO_PIO4_BASE)) {
548 pio_rx_error(queue, 0, "len == 0");
549 return;
550 }
551 preamble[0] = cpu_to_le16(len);
552 if (queue->mmio_base == BCM43xx_MMIO_PIO4_BASE)
553 preamble_readwords = 14 / sizeof(u16);
554 else
555 preamble_readwords = 18 / sizeof(u16);
556 for (i = 0; i < preamble_readwords; i++) {
557 tmp = bcm43xx_pio_read(queue, BCM43xx_PIO_RXDATA);
558 preamble[i + 1] = cpu_to_be16(tmp);//FIXME?
559 }
560 rxhdr = (struct bcm43xx_rxhdr *)preamble;
561 rxflags2 = le16_to_cpu(rxhdr->flags2);
562 if (unlikely(rxflags2 & BCM43xx_RXHDR_FLAGS2_INVALIDFRAME)) {
563 pio_rx_error(queue,
564 (queue->mmio_base == BCM43xx_MMIO_PIO1_BASE),
565 "invalid frame");
566 return;
567 }
568 if (queue->mmio_base == BCM43xx_MMIO_PIO4_BASE) {
569 /* We received an xmit status. */
570 struct bcm43xx_hwxmitstatus *hw;
571 struct bcm43xx_xmitstatus stat;
572
573 hw = (struct bcm43xx_hwxmitstatus *)(preamble + 1);
574 stat.cookie = le16_to_cpu(hw->cookie);
575 stat.flags = hw->flags;
576 stat.cnt1 = hw->cnt1;
577 stat.cnt2 = hw->cnt2;
578 stat.seq = le16_to_cpu(hw->seq);
579 stat.unknown = le16_to_cpu(hw->unknown);
580
581 bcm43xx_debugfs_log_txstat(queue->bcm, &stat);
582 bcm43xx_pio_handle_xmitstatus(queue->bcm, &stat);
583
584 return;
585 }
586
587 skb = dev_alloc_skb(len);
588 if (unlikely(!skb)) {
589 pio_rx_error(queue, 1, "OOM");
590 return;
591 }
592 skb_put(skb, len);
593 for (i = 0; i < len - 1; i += 2) {
594 tmp = cpu_to_be16(bcm43xx_pio_read(queue, BCM43xx_PIO_RXDATA));
595 *((u16 *)(skb->data + i)) = tmp;
596 }
597 if (len % 2) {
598 tmp = bcm43xx_pio_read(queue, BCM43xx_PIO_RXDATA);
599 skb->data[len - 1] = (tmp & 0x00FF);
600 if (rxflags2 & BCM43xx_RXHDR_FLAGS2_TYPE2FRAME)
601 skb->data[0x20] = (tmp & 0xFF00) >> 8;
602 else
603 skb->data[0x1E] = (tmp & 0xFF00) >> 8;
604 }
605 bcm43xx_rx(queue->bcm, skb, rxhdr);
606}
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_pio.h b/drivers/net/wireless/bcm43xx/bcm43xx_pio.h
new file mode 100644
index 000000000000..970627bc1769
--- /dev/null
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_pio.h
@@ -0,0 +1,138 @@
1#ifndef BCM43xx_PIO_H_
2#define BCM43xx_PIO_H_
3
4#include "bcm43xx.h"
5
6#include <linux/interrupt.h>
7#include <linux/list.h>
8#include <linux/skbuff.h>
9
10
11#define BCM43xx_PIO_TXCTL 0x00
12#define BCM43xx_PIO_TXDATA 0x02
13#define BCM43xx_PIO_TXQBUFSIZE 0x04
14#define BCM43xx_PIO_RXCTL 0x08
15#define BCM43xx_PIO_RXDATA 0x0A
16
17#define BCM43xx_PIO_TXCTL_WRITEHI (1 << 0)
18#define BCM43xx_PIO_TXCTL_WRITELO (1 << 1)
19#define BCM43xx_PIO_TXCTL_COMPLETE (1 << 2)
20#define BCM43xx_PIO_TXCTL_INIT (1 << 3)
21#define BCM43xx_PIO_TXCTL_SUSPEND (1 << 7)
22
23#define BCM43xx_PIO_RXCTL_DATAAVAILABLE (1 << 0)
24#define BCM43xx_PIO_RXCTL_READY (1 << 1)
25
26/* PIO constants */
27#define BCM43xx_PIO_MAXTXDEVQPACKETS 31
28#define BCM43xx_PIO_TXQADJUST 80
29
30/* PIO tuning knobs */
31#define BCM43xx_PIO_MAXTXPACKETS 256
32
33
34
35#ifdef CONFIG_BCM43XX_PIO
36
37
38struct bcm43xx_pioqueue;
39struct bcm43xx_xmitstatus;
40
41struct bcm43xx_pio_txpacket {
42 struct bcm43xx_pioqueue *queue;
43 struct ieee80211_txb *txb;
44 struct list_head list;
45
46 u8 xmitted_frags;
47 u16 xmitted_octets;
48};
49
50#define pio_txpacket_getindex(packet) ((int)((packet) - (packet)->queue->tx_packets_cache))
51
52struct bcm43xx_pioqueue {
53 struct bcm43xx_private *bcm;
54 u16 mmio_base;
55
56 u8 tx_suspended:1,
57 need_workarounds:1; /* Workarounds needed for core.rev < 3 */
58
59 /* Adjusted size of the device internal TX buffer. */
60 u16 tx_devq_size;
61 /* Used octets of the device internal TX buffer. */
62 u16 tx_devq_used;
63 /* Used packet slots in the device internal TX buffer. */
64 u8 tx_devq_packets;
65 /* Packets from the txfree list can
66 * be taken on incoming TX requests.
67 */
68 struct list_head txfree;
69 unsigned int nr_txfree;
70 /* Packets on the txqueue are queued,
71 * but not completely written to the chip, yet.
72 */
73 struct list_head txqueue;
74 /* Packets on the txrunning queue are completely
75 * posted to the device. We are waiting for the txstatus.
76 */
77 struct list_head txrunning;
78 /* Total number or packets sent.
79 * (This counter can obviously wrap).
80 */
81 unsigned int nr_tx_packets;
82 struct tasklet_struct txtask;
83 struct bcm43xx_pio_txpacket tx_packets_cache[BCM43xx_PIO_MAXTXPACKETS];
84};
85
86static inline
87u16 bcm43xx_pio_read(struct bcm43xx_pioqueue *queue,
88 u16 offset)
89{
90 return bcm43xx_read16(queue->bcm, queue->mmio_base + offset);
91}
92
93static inline
94void bcm43xx_pio_write(struct bcm43xx_pioqueue *queue,
95 u16 offset, u16 value)
96{
97 bcm43xx_write16(queue->bcm, queue->mmio_base + offset, value);
98}
99
100
101int bcm43xx_pio_init(struct bcm43xx_private *bcm);
102void bcm43xx_pio_free(struct bcm43xx_private *bcm);
103
104int bcm43xx_pio_tx(struct bcm43xx_private *bcm,
105 struct ieee80211_txb *txb);
106void bcm43xx_pio_handle_xmitstatus(struct bcm43xx_private *bcm,
107 struct bcm43xx_xmitstatus *status);
108void bcm43xx_pio_rx(struct bcm43xx_pioqueue *queue);
109
110#else /* CONFIG_BCM43XX_PIO */
111
112static inline
113int bcm43xx_pio_init(struct bcm43xx_private *bcm)
114{
115 return 0;
116}
117static inline
118void bcm43xx_pio_free(struct bcm43xx_private *bcm)
119{
120}
121static inline
122int bcm43xx_pio_tx(struct bcm43xx_private *bcm,
123 struct ieee80211_txb *txb)
124{
125 return 0;
126}
127static inline
128void bcm43xx_pio_handle_xmitstatus(struct bcm43xx_private *bcm,
129 struct bcm43xx_xmitstatus *status)
130{
131}
132static inline
133void bcm43xx_pio_rx(struct bcm43xx_pioqueue *queue)
134{
135}
136
137#endif /* CONFIG_BCM43XX_PIO */
138#endif /* BCM43xx_PIO_H_ */
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_power.c b/drivers/net/wireless/bcm43xx/bcm43xx_power.c
new file mode 100644
index 000000000000..3c92b62807c5
--- /dev/null
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_power.c
@@ -0,0 +1,358 @@
1/*
2
3 Broadcom BCM43xx wireless driver
4
5 Copyright (c) 2005 Martin Langer <martin-langer@gmx.de>,
6 Stefano Brivio <st3@riseup.net>
7 Michael Buesch <mbuesch@freenet.de>
8 Danny van Dyk <kugelfang@gentoo.org>
9 Andreas Jaggi <andreas.jaggi@waterwave.ch>
10
11 Some parts of the code in this file are derived from the ipw2200
12 driver Copyright(c) 2003 - 2004 Intel Corporation.
13
14 This program is free software; you can redistribute it and/or modify
15 it under the terms of the GNU General Public License as published by
16 the Free Software Foundation; either version 2 of the License, or
17 (at your option) any later version.
18
19 This program is distributed in the hope that it will be useful,
20 but WITHOUT ANY WARRANTY; without even the implied warranty of
21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 GNU General Public License for more details.
23
24 You should have received a copy of the GNU General Public License
25 along with this program; see the file COPYING. If not, write to
26 the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,
27 Boston, MA 02110-1301, USA.
28
29*/
30
31#include <linux/delay.h>
32
33#include "bcm43xx.h"
34#include "bcm43xx_power.h"
35#include "bcm43xx_main.h"
36
37
38/* Get max/min slowclock frequency
39 * as described in http://bcm-specs.sipsolutions.net/PowerControl
40 */
41static int bcm43xx_pctl_clockfreqlimit(struct bcm43xx_private *bcm,
42 int get_max)
43{
44 int limit = 0;
45 int divisor;
46 int selection;
47 int err;
48 u32 tmp;
49 struct bcm43xx_coreinfo *old_core;
50
51 if (!(bcm->chipcommon_capabilities & BCM43xx_CAPABILITIES_PCTL))
52 goto out;
53 old_core = bcm->current_core;
54 err = bcm43xx_switch_core(bcm, &bcm->core_chipcommon);
55 if (err)
56 goto out;
57
58 if (bcm->current_core->rev < 6) {
59 if ((bcm->bustype == BCM43xx_BUSTYPE_PCMCIA) ||
60 (bcm->bustype == BCM43xx_BUSTYPE_SB)) {
61 selection = 1;
62 divisor = 32;
63 } else {
64 err = bcm43xx_pci_read_config32(bcm, BCM43xx_PCTL_OUT, &tmp);
65 if (err) {
66 printk(KERN_ERR PFX "clockfreqlimit pcicfg read failure\n");
67 goto out_switchback;
68 }
69 if (tmp & 0x10) {
70 /* PCI */
71 selection = 2;
72 divisor = 64;
73 } else {
74 /* XTAL */
75 selection = 1;
76 divisor = 32;
77 }
78 }
79 } else if (bcm->current_core->rev < 10) {
80 selection = (tmp & 0x07);
81 if (selection) {
82 tmp = bcm43xx_read32(bcm, BCM43xx_CHIPCOMMON_SLOWCLKCTL);
83 divisor = 4 * (1 + ((tmp & 0xFFFF0000) >> 16));
84 } else
85 divisor = 1;
86 } else {
87 tmp = bcm43xx_read32(bcm, BCM43xx_CHIPCOMMON_SYSCLKCTL);
88 divisor = 4 * (1 + ((tmp & 0xFFFF0000) >> 16));
89 selection = 1;
90 }
91
92 switch (selection) {
93 case 0:
94 /* LPO */
95 if (get_max)
96 limit = 43000;
97 else
98 limit = 25000;
99 break;
100 case 1:
101 /* XTAL */
102 if (get_max)
103 limit = 20200000;
104 else
105 limit = 19800000;
106 break;
107 case 2:
108 /* PCI */
109 if (get_max)
110 limit = 34000000;
111 else
112 limit = 25000000;
113 break;
114 default:
115 assert(0);
116 }
117 limit /= divisor;
118
119out_switchback:
120 err = bcm43xx_switch_core(bcm, old_core);
121 assert(err == 0);
122
123out:
124 return limit;
125}
126
127/* init power control
128 * as described in http://bcm-specs.sipsolutions.net/PowerControl
129 */
130int bcm43xx_pctl_init(struct bcm43xx_private *bcm)
131{
132 int err, maxfreq;
133 struct bcm43xx_coreinfo *old_core;
134
135 if (!(bcm->chipcommon_capabilities & BCM43xx_CAPABILITIES_PCTL))
136 return 0;
137 old_core = bcm->current_core;
138 err = bcm43xx_switch_core(bcm, &bcm->core_chipcommon);
139 if (err == -ENODEV)
140 return 0;
141 if (err)
142 goto out;
143
144 maxfreq = bcm43xx_pctl_clockfreqlimit(bcm, 1);
145 bcm43xx_write32(bcm, BCM43xx_CHIPCOMMON_PLLONDELAY,
146 (maxfreq * 150 + 999999) / 1000000);
147 bcm43xx_write32(bcm, BCM43xx_CHIPCOMMON_FREFSELDELAY,
148 (maxfreq * 15 + 999999) / 1000000);
149
150 err = bcm43xx_switch_core(bcm, old_core);
151 assert(err == 0);
152
153out:
154 return err;
155}
156
157u16 bcm43xx_pctl_powerup_delay(struct bcm43xx_private *bcm)
158{
159 u16 delay = 0;
160 int err;
161 u32 pll_on_delay;
162 struct bcm43xx_coreinfo *old_core;
163 int minfreq;
164
165 if (bcm->bustype != BCM43xx_BUSTYPE_PCI)
166 goto out;
167 if (!(bcm->chipcommon_capabilities & BCM43xx_CAPABILITIES_PCTL))
168 goto out;
169 old_core = bcm->current_core;
170 err = bcm43xx_switch_core(bcm, &bcm->core_chipcommon);
171 if (err == -ENODEV)
172 goto out;
173
174 minfreq = bcm43xx_pctl_clockfreqlimit(bcm, 0);
175 pll_on_delay = bcm43xx_read32(bcm, BCM43xx_CHIPCOMMON_PLLONDELAY);
176 delay = (((pll_on_delay + 2) * 1000000) + (minfreq - 1)) / minfreq;
177
178 err = bcm43xx_switch_core(bcm, old_core);
179 assert(err == 0);
180
181out:
182 return delay;
183}
184
185/* set the powercontrol clock
186 * as described in http://bcm-specs.sipsolutions.net/PowerControl
187 */
188int bcm43xx_pctl_set_clock(struct bcm43xx_private *bcm, u16 mode)
189{
190 int err;
191 struct bcm43xx_coreinfo *old_core;
192 u32 tmp;
193
194 old_core = bcm->current_core;
195 err = bcm43xx_switch_core(bcm, &bcm->core_chipcommon);
196 if (err == -ENODEV)
197 return 0;
198 if (err)
199 goto out;
200
201 if (bcm->core_chipcommon.rev < 6) {
202 if (mode == BCM43xx_PCTL_CLK_FAST) {
203 err = bcm43xx_pctl_set_crystal(bcm, 1);
204 if (err)
205 goto out;
206 }
207 } else {
208 if ((bcm->chipcommon_capabilities & BCM43xx_CAPABILITIES_PCTL) &&
209 (bcm->core_chipcommon.rev < 10)) {
210 switch (mode) {
211 case BCM43xx_PCTL_CLK_FAST:
212 tmp = bcm43xx_read32(bcm, BCM43xx_CHIPCOMMON_SLOWCLKCTL);
213 tmp = (tmp & ~BCM43xx_PCTL_FORCE_SLOW) | BCM43xx_PCTL_FORCE_PLL;
214 bcm43xx_write32(bcm, BCM43xx_CHIPCOMMON_SLOWCLKCTL, tmp);
215 break;
216 case BCM43xx_PCTL_CLK_SLOW:
217 tmp = bcm43xx_read32(bcm, BCM43xx_CHIPCOMMON_SLOWCLKCTL);
218 tmp |= BCM43xx_PCTL_FORCE_SLOW;
219 bcm43xx_write32(bcm, BCM43xx_CHIPCOMMON_SLOWCLKCTL, tmp);
220 break;
221 case BCM43xx_PCTL_CLK_DYNAMIC:
222 tmp = bcm43xx_read32(bcm, BCM43xx_CHIPCOMMON_SLOWCLKCTL);
223 tmp &= ~BCM43xx_PCTL_FORCE_SLOW;
224 tmp |= BCM43xx_PCTL_FORCE_PLL;
225 tmp &= ~BCM43xx_PCTL_DYN_XTAL;
226 bcm43xx_write32(bcm, BCM43xx_CHIPCOMMON_SLOWCLKCTL, tmp);
227 }
228 }
229 }
230
231 err = bcm43xx_switch_core(bcm, old_core);
232 assert(err == 0);
233
234out:
235 return err;
236}
237
238int bcm43xx_pctl_set_crystal(struct bcm43xx_private *bcm, int on)
239{
240 int err;
241 u32 in, out, outenable;
242
243 err = bcm43xx_pci_read_config32(bcm, BCM43xx_PCTL_IN, &in);
244 if (err)
245 goto err_pci;
246 err = bcm43xx_pci_read_config32(bcm, BCM43xx_PCTL_OUT, &out);
247 if (err)
248 goto err_pci;
249 err = bcm43xx_pci_read_config32(bcm, BCM43xx_PCTL_OUTENABLE, &outenable);
250 if (err)
251 goto err_pci;
252
253 outenable |= (BCM43xx_PCTL_XTAL_POWERUP | BCM43xx_PCTL_PLL_POWERDOWN);
254
255 if (on) {
256 if (in & 0x40)
257 return 0;
258
259 out |= (BCM43xx_PCTL_XTAL_POWERUP | BCM43xx_PCTL_PLL_POWERDOWN);
260
261 err = bcm43xx_pci_write_config32(bcm, BCM43xx_PCTL_OUT, out);
262 if (err)
263 goto err_pci;
264 err = bcm43xx_pci_write_config32(bcm, BCM43xx_PCTL_OUTENABLE, outenable);
265 if (err)
266 goto err_pci;
267 udelay(1000);
268
269 out &= ~BCM43xx_PCTL_PLL_POWERDOWN;
270 err = bcm43xx_pci_write_config32(bcm, BCM43xx_PCTL_OUT, out);
271 if (err)
272 goto err_pci;
273 udelay(5000);
274 } else {
275 if (bcm->current_core->rev < 5)
276 return 0;
277 if (bcm->sprom.boardflags & BCM43xx_BFL_XTAL_NOSLOW)
278 return 0;
279
280/* XXX: Why BCM43xx_MMIO_RADIO_HWENABLED_xx can't be read at this time?
281 * err = bcm43xx_switch_core(bcm, bcm->active_80211_core);
282 * if (err)
283 * return err;
284 * if (((bcm->current_core->rev >= 3) &&
285 * (bcm43xx_read32(bcm, BCM43xx_MMIO_RADIO_HWENABLED_HI) & (1 << 16))) ||
286 * ((bcm->current_core->rev < 3) &&
287 * !(bcm43xx_read16(bcm, BCM43xx_MMIO_RADIO_HWENABLED_LO) & (1 << 4))))
288 * return 0;
289 * err = bcm43xx_switch_core(bcm, &bcm->core_chipcommon);
290 * if (err)
291 * return err;
292 */
293
294 err = bcm43xx_pctl_set_clock(bcm, BCM43xx_PCTL_CLK_SLOW);
295 if (err)
296 goto out;
297 out &= ~BCM43xx_PCTL_XTAL_POWERUP;
298 out |= BCM43xx_PCTL_PLL_POWERDOWN;
299 err = bcm43xx_pci_write_config32(bcm, BCM43xx_PCTL_OUT, out);
300 if (err)
301 goto err_pci;
302 err = bcm43xx_pci_write_config32(bcm, BCM43xx_PCTL_OUTENABLE, outenable);
303 if (err)
304 goto err_pci;
305 }
306
307out:
308 return err;
309
310err_pci:
311 printk(KERN_ERR PFX "Error: pctl_set_clock() could not access PCI config space!\n");
312 err = -EBUSY;
313 goto out;
314}
315
316/* Set the PowerSavingControlBits.
317 * Bitvalues:
318 * 0 => unset the bit
319 * 1 => set the bit
320 * -1 => calculate the bit
321 */
322void bcm43xx_power_saving_ctl_bits(struct bcm43xx_private *bcm,
323 int bit25, int bit26)
324{
325 int i;
326 u32 status;
327
328//FIXME: Force 25 to off and 26 to on for now:
329bit25 = 0;
330bit26 = 1;
331
332 if (bit25 == -1) {
333 //TODO: If powersave is not off and FIXME is not set and we are not in adhoc
334 // and thus is not an AP and we are associated, set bit 25
335 }
336 if (bit26 == -1) {
337 //TODO: If the device is awake or this is an AP, or we are scanning, or FIXME,
338 // or we are associated, or FIXME, or the latest PS-Poll packet sent was
339 // successful, set bit26
340 }
341 status = bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD);
342 if (bit25)
343 status |= BCM43xx_SBF_PS1;
344 else
345 status &= ~BCM43xx_SBF_PS1;
346 if (bit26)
347 status |= BCM43xx_SBF_PS2;
348 else
349 status &= ~BCM43xx_SBF_PS2;
350 bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD, status);
351 if (bit26 && bcm->current_core->rev >= 5) {
352 for (i = 0; i < 100; i++) {
353 if (bcm43xx_shm_read32(bcm, BCM43xx_SHM_SHARED, 0x0040) != 4)
354 break;
355 udelay(10);
356 }
357 }
358}
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_power.h b/drivers/net/wireless/bcm43xx/bcm43xx_power.h
new file mode 100644
index 000000000000..5f63640810bd
--- /dev/null
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_power.h
@@ -0,0 +1,47 @@
1/*
2
3 Broadcom BCM43xx wireless driver
4
5 Copyright (c) 2005 Martin Langer <martin-langer@gmx.de>,
6 Stefano Brivio <st3@riseup.net>
7 Michael Buesch <mbuesch@freenet.de>
8 Danny van Dyk <kugelfang@gentoo.org>
9 Andreas Jaggi <andreas.jaggi@waterwave.ch>
10
11 Some parts of the code in this file are derived from the ipw2200
12 driver Copyright(c) 2003 - 2004 Intel Corporation.
13
14 This program is free software; you can redistribute it and/or modify
15 it under the terms of the GNU General Public License as published by
16 the Free Software Foundation; either version 2 of the License, or
17 (at your option) any later version.
18
19 This program is distributed in the hope that it will be useful,
20 but WITHOUT ANY WARRANTY; without even the implied warranty of
21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 GNU General Public License for more details.
23
24 You should have received a copy of the GNU General Public License
25 along with this program; see the file COPYING. If not, write to
26 the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,
27 Boston, MA 02110-1301, USA.
28
29*/
30
31#ifndef BCM43xx_POWER_H_
32#define BCM43xx_POWER_H_
33
34#include <linux/types.h>
35
36
37struct bcm43xx_private;
38
39int bcm43xx_pctl_init(struct bcm43xx_private *bcm);
40int bcm43xx_pctl_set_clock(struct bcm43xx_private *bcm, u16 mode);
41int bcm43xx_pctl_set_crystal(struct bcm43xx_private *bcm, int on);
42u16 bcm43xx_pctl_powerup_delay(struct bcm43xx_private *bcm);
43
44void bcm43xx_power_saving_ctl_bits(struct bcm43xx_private *bcm,
45 int bit25, int bit26);
46
47#endif /* BCM43xx_POWER_H_ */
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_radio.c b/drivers/net/wireless/bcm43xx/bcm43xx_radio.c
new file mode 100644
index 000000000000..af5c0bff1696
--- /dev/null
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_radio.c
@@ -0,0 +1,2026 @@
1/*
2
3 Broadcom BCM43xx wireless driver
4
5 Copyright (c) 2005 Martin Langer <martin-langer@gmx.de>,
6 Stefano Brivio <st3@riseup.net>
7 Michael Buesch <mbuesch@freenet.de>
8 Danny van Dyk <kugelfang@gentoo.org>
9 Andreas Jaggi <andreas.jaggi@waterwave.ch>
10
11 Some parts of the code in this file are derived from the ipw2200
12 driver Copyright(c) 2003 - 2004 Intel Corporation.
13
14 This program is free software; you can redistribute it and/or modify
15 it under the terms of the GNU General Public License as published by
16 the Free Software Foundation; either version 2 of the License, or
17 (at your option) any later version.
18
19 This program is distributed in the hope that it will be useful,
20 but WITHOUT ANY WARRANTY; without even the implied warranty of
21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 GNU General Public License for more details.
23
24 You should have received a copy of the GNU General Public License
25 along with this program; see the file COPYING. If not, write to
26 the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,
27 Boston, MA 02110-1301, USA.
28
29*/
30
31#include <linux/delay.h>
32
33#include "bcm43xx.h"
34#include "bcm43xx_main.h"
35#include "bcm43xx_phy.h"
36#include "bcm43xx_radio.h"
37#include "bcm43xx_ilt.h"
38
39
40/* Table for bcm43xx_radio_calibrationvalue() */
41static const u16 rcc_table[16] = {
42 0x0002, 0x0003, 0x0001, 0x000F,
43 0x0006, 0x0007, 0x0005, 0x000F,
44 0x000A, 0x000B, 0x0009, 0x000F,
45 0x000E, 0x000F, 0x000D, 0x000F,
46};
47
48/* Reverse the bits of a 4bit value.
49 * Example: 1101 is flipped 1011
50 */
51static u16 flip_4bit(u16 value)
52{
53 u16 flipped = 0x0000;
54
55 assert((value & ~0x000F) == 0x0000);
56
57 flipped |= (value & 0x0001) << 3;
58 flipped |= (value & 0x0002) << 1;
59 flipped |= (value & 0x0004) >> 1;
60 flipped |= (value & 0x0008) >> 3;
61
62 return flipped;
63}
64
65/* Get the freq, as it has to be written to the device. */
66static inline
67u16 channel2freq_bg(u8 channel)
68{
69 /* Frequencies are given as frequencies_bg[index] + 2.4GHz
70 * Starting with channel 1
71 */
72 static const u16 frequencies_bg[14] = {
73 12, 17, 22, 27,
74 32, 37, 42, 47,
75 52, 57, 62, 67,
76 72, 84,
77 };
78
79 assert(channel >= 1 && channel <= 14);
80
81 return frequencies_bg[channel - 1];
82}
83
84/* Get the freq, as it has to be written to the device. */
85static inline
86u16 channel2freq_a(u8 channel)
87{
88 assert(channel <= 200);
89
90 return (5000 + 5 * channel);
91}
92
93void bcm43xx_radio_lock(struct bcm43xx_private *bcm)
94{
95 u32 status;
96
97 status = bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD);
98 status |= BCM43xx_SBF_RADIOREG_LOCK;
99 bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD, status);
100 mmiowb();
101 udelay(10);
102}
103
104void bcm43xx_radio_unlock(struct bcm43xx_private *bcm)
105{
106 u32 status;
107
108 bcm43xx_read16(bcm, BCM43xx_MMIO_PHY_VER); /* dummy read */
109 status = bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD);
110 status &= ~BCM43xx_SBF_RADIOREG_LOCK;
111 bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD, status);
112 mmiowb();
113}
114
115u16 bcm43xx_radio_read16(struct bcm43xx_private *bcm, u16 offset)
116{
117 struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
118 struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm);
119
120 switch (phy->type) {
121 case BCM43xx_PHYTYPE_A:
122 offset |= 0x0040;
123 break;
124 case BCM43xx_PHYTYPE_B:
125 if (radio->version == 0x2053) {
126 if (offset < 0x70)
127 offset += 0x80;
128 else if (offset < 0x80)
129 offset += 0x70;
130 } else if (radio->version == 0x2050) {
131 offset |= 0x80;
132 } else
133 assert(0);
134 break;
135 case BCM43xx_PHYTYPE_G:
136 offset |= 0x80;
137 break;
138 }
139
140 bcm43xx_write16(bcm, BCM43xx_MMIO_RADIO_CONTROL, offset);
141 return bcm43xx_read16(bcm, BCM43xx_MMIO_RADIO_DATA_LOW);
142}
143
144void bcm43xx_radio_write16(struct bcm43xx_private *bcm, u16 offset, u16 val)
145{
146 bcm43xx_write16(bcm, BCM43xx_MMIO_RADIO_CONTROL, offset);
147 mmiowb();
148 bcm43xx_write16(bcm, BCM43xx_MMIO_RADIO_DATA_LOW, val);
149}
150
151static void bcm43xx_set_all_gains(struct bcm43xx_private *bcm,
152 s16 first, s16 second, s16 third)
153{
154 struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
155 u16 i;
156 u16 start = 0x08, end = 0x18;
157 u16 offset = 0x0400;
158 u16 tmp;
159
160 if (phy->rev <= 1) {
161 offset = 0x5000;
162 start = 0x10;
163 end = 0x20;
164 }
165
166 for (i = 0; i < 4; i++)
167 bcm43xx_ilt_write(bcm, offset + i, first);
168
169 for (i = start; i < end; i++)
170 bcm43xx_ilt_write(bcm, offset + i, second);
171
172 if (third != -1) {
173 tmp = ((u16)third << 14) | ((u16)third << 6);
174 bcm43xx_phy_write(bcm, 0x04A0,
175 (bcm43xx_phy_read(bcm, 0x04A0) & 0xBFBF) | tmp);
176 bcm43xx_phy_write(bcm, 0x04A1,
177 (bcm43xx_phy_read(bcm, 0x04A1) & 0xBFBF) | tmp);
178 bcm43xx_phy_write(bcm, 0x04A2,
179 (bcm43xx_phy_read(bcm, 0x04A2) & 0xBFBF) | tmp);
180 }
181 bcm43xx_dummy_transmission(bcm);
182}
183
184static void bcm43xx_set_original_gains(struct bcm43xx_private *bcm)
185{
186 struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
187 u16 i, tmp;
188 u16 offset = 0x0400;
189 u16 start = 0x0008, end = 0x0018;
190
191 if (phy->rev <= 1) {
192 offset = 0x5000;
193 start = 0x0010;
194 end = 0x0020;
195 }
196
197 for (i = 0; i < 4; i++) {
198 tmp = (i & 0xFFFC);
199 tmp |= (i & 0x0001) << 1;
200 tmp |= (i & 0x0002) >> 1;
201
202 bcm43xx_ilt_write(bcm, offset + i, tmp);
203 }
204
205 for (i = start; i < end; i++)
206 bcm43xx_ilt_write(bcm, offset + i, i - start);
207
208 bcm43xx_phy_write(bcm, 0x04A0,
209 (bcm43xx_phy_read(bcm, 0x04A0) & 0xBFBF) | 0x4040);
210 bcm43xx_phy_write(bcm, 0x04A1,
211 (bcm43xx_phy_read(bcm, 0x04A1) & 0xBFBF) | 0x4040);
212 bcm43xx_phy_write(bcm, 0x04A2,
213 (bcm43xx_phy_read(bcm, 0x04A2) & 0xBFBF) | 0x4000);
214 bcm43xx_dummy_transmission(bcm);
215}
216
217/* Synthetic PU workaround */
218static void bcm43xx_synth_pu_workaround(struct bcm43xx_private *bcm, u8 channel)
219{
220 struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm);
221
222 if (radio->version != 0x2050 || radio->revision >= 6) {
223 /* We do not need the workaround. */
224 return;
225 }
226
227 if (channel <= 10) {
228 bcm43xx_write16(bcm, BCM43xx_MMIO_CHANNEL,
229 channel2freq_bg(channel + 4));
230 } else {
231 bcm43xx_write16(bcm, BCM43xx_MMIO_CHANNEL,
232 channel2freq_bg(1));
233 }
234 udelay(100);
235 bcm43xx_write16(bcm, BCM43xx_MMIO_CHANNEL,
236 channel2freq_bg(channel));
237}
238
239u8 bcm43xx_radio_aci_detect(struct bcm43xx_private *bcm, u8 channel)
240{
241 struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm);
242 u8 ret = 0;
243 u16 saved, rssi, temp;
244 int i, j = 0;
245
246 saved = bcm43xx_phy_read(bcm, 0x0403);
247 bcm43xx_radio_selectchannel(bcm, channel, 0);
248 bcm43xx_phy_write(bcm, 0x0403, (saved & 0xFFF8) | 5);
249 if (radio->aci_hw_rssi)
250 rssi = bcm43xx_phy_read(bcm, 0x048A) & 0x3F;
251 else
252 rssi = saved & 0x3F;
253 /* clamp temp to signed 5bit */
254 if (rssi > 32)
255 rssi -= 64;
256 for (i = 0;i < 100; i++) {
257 temp = (bcm43xx_phy_read(bcm, 0x047F) >> 8) & 0x3F;
258 if (temp > 32)
259 temp -= 64;
260 if (temp < rssi)
261 j++;
262 if (j >= 20)
263 ret = 1;
264 }
265 bcm43xx_phy_write(bcm, 0x0403, saved);
266
267 return ret;
268}
269
270u8 bcm43xx_radio_aci_scan(struct bcm43xx_private *bcm)
271{
272 struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
273 struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm);
274 u8 ret[13];
275 unsigned int channel = radio->channel;
276 unsigned int i, j, start, end;
277 unsigned long phylock_flags;
278
279 if (!((phy->type == BCM43xx_PHYTYPE_G) && (phy->rev > 0)))
280 return 0;
281
282 bcm43xx_phy_lock(bcm, phylock_flags);
283 bcm43xx_radio_lock(bcm);
284 bcm43xx_phy_write(bcm, 0x0802,
285 bcm43xx_phy_read(bcm, 0x0802) & 0xFFFC);
286 bcm43xx_phy_write(bcm, BCM43xx_PHY_G_CRS,
287 bcm43xx_phy_read(bcm, BCM43xx_PHY_G_CRS) & 0x7FFF);
288 bcm43xx_set_all_gains(bcm, 3, 8, 1);
289
290 start = (channel - 5 > 0) ? channel - 5 : 1;
291 end = (channel + 5 < 14) ? channel + 5 : 13;
292
293 for (i = start; i <= end; i++) {
294 if (abs(channel - i) > 2)
295 ret[i-1] = bcm43xx_radio_aci_detect(bcm, i);
296 }
297 bcm43xx_radio_selectchannel(bcm, channel, 0);
298 bcm43xx_phy_write(bcm, 0x0802,
299 (bcm43xx_phy_read(bcm, 0x0802) & 0xFFFC) | 0x0003);
300 bcm43xx_phy_write(bcm, 0x0403,
301 bcm43xx_phy_read(bcm, 0x0403) & 0xFFF8);
302 bcm43xx_phy_write(bcm, BCM43xx_PHY_G_CRS,
303 bcm43xx_phy_read(bcm, BCM43xx_PHY_G_CRS) | 0x8000);
304 bcm43xx_set_original_gains(bcm);
305 for (i = 0; i < 13; i++) {
306 if (!ret[i])
307 continue;
308 end = (i + 5 < 13) ? i + 5 : 13;
309 for (j = i; j < end; j++)
310 ret[j] = 1;
311 }
312 bcm43xx_radio_unlock(bcm);
313 bcm43xx_phy_unlock(bcm, phylock_flags);
314
315 return ret[channel - 1];
316}
317
318/* http://bcm-specs.sipsolutions.net/NRSSILookupTable */
319void bcm43xx_nrssi_hw_write(struct bcm43xx_private *bcm, u16 offset, s16 val)
320{
321 bcm43xx_phy_write(bcm, BCM43xx_PHY_NRSSILT_CTRL, offset);
322 mmiowb();
323 bcm43xx_phy_write(bcm, BCM43xx_PHY_NRSSILT_DATA, (u16)val);
324}
325
326/* http://bcm-specs.sipsolutions.net/NRSSILookupTable */
327s16 bcm43xx_nrssi_hw_read(struct bcm43xx_private *bcm, u16 offset)
328{
329 u16 val;
330
331 bcm43xx_phy_write(bcm, BCM43xx_PHY_NRSSILT_CTRL, offset);
332 val = bcm43xx_phy_read(bcm, BCM43xx_PHY_NRSSILT_DATA);
333
334 return (s16)val;
335}
336
337/* http://bcm-specs.sipsolutions.net/NRSSILookupTable */
338void bcm43xx_nrssi_hw_update(struct bcm43xx_private *bcm, u16 val)
339{
340 u16 i;
341 s16 tmp;
342
343 for (i = 0; i < 64; i++) {
344 tmp = bcm43xx_nrssi_hw_read(bcm, i);
345 tmp -= val;
346 tmp = limit_value(tmp, -32, 31);
347 bcm43xx_nrssi_hw_write(bcm, i, tmp);
348 }
349}
350
351/* http://bcm-specs.sipsolutions.net/NRSSILookupTable */
352void bcm43xx_nrssi_mem_update(struct bcm43xx_private *bcm)
353{
354 struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm);
355 s16 i, delta;
356 s32 tmp;
357
358 delta = 0x1F - radio->nrssi[0];
359 for (i = 0; i < 64; i++) {
360 tmp = (i - delta) * radio->nrssislope;
361 tmp /= 0x10000;
362 tmp += 0x3A;
363 tmp = limit_value(tmp, 0, 0x3F);
364 radio->nrssi_lt[i] = tmp;
365 }
366}
367
368static void bcm43xx_calc_nrssi_offset(struct bcm43xx_private *bcm)
369{
370 struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
371 u16 backup[20] = { 0 };
372 s16 v47F;
373 u16 i;
374 u16 saved = 0xFFFF;
375
376 backup[0] = bcm43xx_phy_read(bcm, 0x0001);
377 backup[1] = bcm43xx_phy_read(bcm, 0x0811);
378 backup[2] = bcm43xx_phy_read(bcm, 0x0812);
379 backup[3] = bcm43xx_phy_read(bcm, 0x0814);
380 backup[4] = bcm43xx_phy_read(bcm, 0x0815);
381 backup[5] = bcm43xx_phy_read(bcm, 0x005A);
382 backup[6] = bcm43xx_phy_read(bcm, 0x0059);
383 backup[7] = bcm43xx_phy_read(bcm, 0x0058);
384 backup[8] = bcm43xx_phy_read(bcm, 0x000A);
385 backup[9] = bcm43xx_phy_read(bcm, 0x0003);
386 backup[10] = bcm43xx_radio_read16(bcm, 0x007A);
387 backup[11] = bcm43xx_radio_read16(bcm, 0x0043);
388
389 bcm43xx_phy_write(bcm, 0x0429,
390 bcm43xx_phy_read(bcm, 0x0429) & 0x7FFF);
391 bcm43xx_phy_write(bcm, 0x0001,
392 (bcm43xx_phy_read(bcm, 0x0001) & 0x3FFF) | 0x4000);
393 bcm43xx_phy_write(bcm, 0x0811,
394 bcm43xx_phy_read(bcm, 0x0811) | 0x000C);
395 bcm43xx_phy_write(bcm, 0x0812,
396 (bcm43xx_phy_read(bcm, 0x0812) & 0xFFF3) | 0x0004);
397 bcm43xx_phy_write(bcm, 0x0802,
398 bcm43xx_phy_read(bcm, 0x0802) & ~(0x1 | 0x2));
399 if (phy->rev >= 6) {
400 backup[12] = bcm43xx_phy_read(bcm, 0x002E);
401 backup[13] = bcm43xx_phy_read(bcm, 0x002F);
402 backup[14] = bcm43xx_phy_read(bcm, 0x080F);
403 backup[15] = bcm43xx_phy_read(bcm, 0x0810);
404 backup[16] = bcm43xx_phy_read(bcm, 0x0801);
405 backup[17] = bcm43xx_phy_read(bcm, 0x0060);
406 backup[18] = bcm43xx_phy_read(bcm, 0x0014);
407 backup[19] = bcm43xx_phy_read(bcm, 0x0478);
408
409 bcm43xx_phy_write(bcm, 0x002E, 0);
410 bcm43xx_phy_write(bcm, 0x002F, 0);
411 bcm43xx_phy_write(bcm, 0x080F, 0);
412 bcm43xx_phy_write(bcm, 0x0810, 0);
413 bcm43xx_phy_write(bcm, 0x0478,
414 bcm43xx_phy_read(bcm, 0x0478) | 0x0100);
415 bcm43xx_phy_write(bcm, 0x0801,
416 bcm43xx_phy_read(bcm, 0x0801) | 0x0040);
417 bcm43xx_phy_write(bcm, 0x0060,
418 bcm43xx_phy_read(bcm, 0x0060) | 0x0040);
419 bcm43xx_phy_write(bcm, 0x0014,
420 bcm43xx_phy_read(bcm, 0x0014) | 0x0200);
421 }
422 bcm43xx_radio_write16(bcm, 0x007A,
423 bcm43xx_radio_read16(bcm, 0x007A) | 0x0070);
424 bcm43xx_radio_write16(bcm, 0x007A,
425 bcm43xx_radio_read16(bcm, 0x007A) | 0x0080);
426 udelay(30);
427
428 v47F = (s16)((bcm43xx_phy_read(bcm, 0x047F) >> 8) & 0x003F);
429 if (v47F >= 0x20)
430 v47F -= 0x40;
431 if (v47F == 31) {
432 for (i = 7; i >= 4; i--) {
433 bcm43xx_radio_write16(bcm, 0x007B, i);
434 udelay(20);
435 v47F = (s16)((bcm43xx_phy_read(bcm, 0x047F) >> 8) & 0x003F);
436 if (v47F >= 0x20)
437 v47F -= 0x40;
438 if (v47F < 31 && saved == 0xFFFF)
439 saved = i;
440 }
441 if (saved == 0xFFFF)
442 saved = 4;
443 } else {
444 bcm43xx_radio_write16(bcm, 0x007A,
445 bcm43xx_radio_read16(bcm, 0x007A) & 0x007F);
446 bcm43xx_phy_write(bcm, 0x0814,
447 bcm43xx_phy_read(bcm, 0x0814) | 0x0001);
448 bcm43xx_phy_write(bcm, 0x0815,
449 bcm43xx_phy_read(bcm, 0x0815) & 0xFFFE);
450 bcm43xx_phy_write(bcm, 0x0811,
451 bcm43xx_phy_read(bcm, 0x0811) | 0x000C);
452 bcm43xx_phy_write(bcm, 0x0812,
453 bcm43xx_phy_read(bcm, 0x0812) | 0x000C);
454 bcm43xx_phy_write(bcm, 0x0811,
455 bcm43xx_phy_read(bcm, 0x0811) | 0x0030);
456 bcm43xx_phy_write(bcm, 0x0812,
457 bcm43xx_phy_read(bcm, 0x0812) | 0x0030);
458 bcm43xx_phy_write(bcm, 0x005A, 0x0480);
459 bcm43xx_phy_write(bcm, 0x0059, 0x0810);
460 bcm43xx_phy_write(bcm, 0x0058, 0x000D);
461 if (phy->rev == 0) {
462 bcm43xx_phy_write(bcm, 0x0003, 0x0122);
463 } else {
464 bcm43xx_phy_write(bcm, 0x000A,
465 bcm43xx_phy_read(bcm, 0x000A)
466 | 0x2000);
467 }
468 bcm43xx_phy_write(bcm, 0x0814,
469 bcm43xx_phy_read(bcm, 0x0814) | 0x0004);
470 bcm43xx_phy_write(bcm, 0x0815,
471 bcm43xx_phy_read(bcm, 0x0815) & 0xFFFB);
472 bcm43xx_phy_write(bcm, 0x0003,
473 (bcm43xx_phy_read(bcm, 0x0003) & 0xFF9F)
474 | 0x0040);
475 bcm43xx_radio_write16(bcm, 0x007A,
476 bcm43xx_radio_read16(bcm, 0x007A) | 0x000F);
477 bcm43xx_set_all_gains(bcm, 3, 0, 1);
478 bcm43xx_radio_write16(bcm, 0x0043,
479 (bcm43xx_radio_read16(bcm, 0x0043)
480 & 0x00F0) | 0x000F);
481 udelay(30);
482 v47F = (s16)((bcm43xx_phy_read(bcm, 0x047F) >> 8) & 0x003F);
483 if (v47F >= 0x20)
484 v47F -= 0x40;
485 if (v47F == -32) {
486 for (i = 0; i < 4; i++) {
487 bcm43xx_radio_write16(bcm, 0x007B, i);
488 udelay(20);
489 v47F = (s16)((bcm43xx_phy_read(bcm, 0x047F) >> 8) & 0x003F);
490 if (v47F >= 0x20)
491 v47F -= 0x40;
492 if (v47F > -31 && saved == 0xFFFF)
493 saved = i;
494 }
495 if (saved == 0xFFFF)
496 saved = 3;
497 } else
498 saved = 0;
499 }
500 bcm43xx_radio_write16(bcm, 0x007B, saved);
501
502 if (phy->rev >= 6) {
503 bcm43xx_phy_write(bcm, 0x002E, backup[12]);
504 bcm43xx_phy_write(bcm, 0x002F, backup[13]);
505 bcm43xx_phy_write(bcm, 0x080F, backup[14]);
506 bcm43xx_phy_write(bcm, 0x0810, backup[15]);
507 }
508 bcm43xx_phy_write(bcm, 0x0814, backup[3]);
509 bcm43xx_phy_write(bcm, 0x0815, backup[4]);
510 bcm43xx_phy_write(bcm, 0x005A, backup[5]);
511 bcm43xx_phy_write(bcm, 0x0059, backup[6]);
512 bcm43xx_phy_write(bcm, 0x0058, backup[7]);
513 bcm43xx_phy_write(bcm, 0x000A, backup[8]);
514 bcm43xx_phy_write(bcm, 0x0003, backup[9]);
515 bcm43xx_radio_write16(bcm, 0x0043, backup[11]);
516 bcm43xx_radio_write16(bcm, 0x007A, backup[10]);
517 bcm43xx_phy_write(bcm, 0x0802,
518 bcm43xx_phy_read(bcm, 0x0802) | 0x1 | 0x2);
519 bcm43xx_phy_write(bcm, 0x0429,
520 bcm43xx_phy_read(bcm, 0x0429) | 0x8000);
521 bcm43xx_set_original_gains(bcm);
522 if (phy->rev >= 6) {
523 bcm43xx_phy_write(bcm, 0x0801, backup[16]);
524 bcm43xx_phy_write(bcm, 0x0060, backup[17]);
525 bcm43xx_phy_write(bcm, 0x0014, backup[18]);
526 bcm43xx_phy_write(bcm, 0x0478, backup[19]);
527 }
528 bcm43xx_phy_write(bcm, 0x0001, backup[0]);
529 bcm43xx_phy_write(bcm, 0x0812, backup[2]);
530 bcm43xx_phy_write(bcm, 0x0811, backup[1]);
531}
532
533void bcm43xx_calc_nrssi_slope(struct bcm43xx_private *bcm)
534{
535 struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
536 struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm);
537 u16 backup[18] = { 0 };
538 u16 tmp;
539 s16 nrssi0, nrssi1;
540
541 switch (phy->type) {
542 case BCM43xx_PHYTYPE_B:
543 backup[0] = bcm43xx_radio_read16(bcm, 0x007A);
544 backup[1] = bcm43xx_radio_read16(bcm, 0x0052);
545 backup[2] = bcm43xx_radio_read16(bcm, 0x0043);
546 backup[3] = bcm43xx_phy_read(bcm, 0x0030);
547 backup[4] = bcm43xx_phy_read(bcm, 0x0026);
548 backup[5] = bcm43xx_phy_read(bcm, 0x0015);
549 backup[6] = bcm43xx_phy_read(bcm, 0x002A);
550 backup[7] = bcm43xx_phy_read(bcm, 0x0020);
551 backup[8] = bcm43xx_phy_read(bcm, 0x005A);
552 backup[9] = bcm43xx_phy_read(bcm, 0x0059);
553 backup[10] = bcm43xx_phy_read(bcm, 0x0058);
554 backup[11] = bcm43xx_read16(bcm, 0x03E2);
555 backup[12] = bcm43xx_read16(bcm, 0x03E6);
556 backup[13] = bcm43xx_read16(bcm, BCM43xx_MMIO_CHANNEL_EXT);
557
558 tmp = bcm43xx_radio_read16(bcm, 0x007A);
559 tmp &= (phy->rev >= 5) ? 0x007F : 0x000F;
560 bcm43xx_radio_write16(bcm, 0x007A, tmp);
561 bcm43xx_phy_write(bcm, 0x0030, 0x00FF);
562 bcm43xx_write16(bcm, 0x03EC, 0x7F7F);
563 bcm43xx_phy_write(bcm, 0x0026, 0x0000);
564 bcm43xx_phy_write(bcm, 0x0015,
565 bcm43xx_phy_read(bcm, 0x0015) | 0x0020);
566 bcm43xx_phy_write(bcm, 0x002A, 0x08A3);
567 bcm43xx_radio_write16(bcm, 0x007A,
568 bcm43xx_radio_read16(bcm, 0x007A) | 0x0080);
569
570 nrssi0 = (s16)bcm43xx_phy_read(bcm, 0x0027);
571 bcm43xx_radio_write16(bcm, 0x007A,
572 bcm43xx_radio_read16(bcm, 0x007A) & 0x007F);
573 if (phy->rev >= 2) {
574 bcm43xx_write16(bcm, 0x03E6, 0x0040);
575 } else if (phy->rev == 0) {
576 bcm43xx_write16(bcm, 0x03E6, 0x0122);
577 } else {
578 bcm43xx_write16(bcm, BCM43xx_MMIO_CHANNEL_EXT,
579 bcm43xx_read16(bcm, BCM43xx_MMIO_CHANNEL_EXT) & 0x2000);
580 }
581 bcm43xx_phy_write(bcm, 0x0020, 0x3F3F);
582 bcm43xx_phy_write(bcm, 0x0015, 0xF330);
583 bcm43xx_radio_write16(bcm, 0x005A, 0x0060);
584 bcm43xx_radio_write16(bcm, 0x0043,
585 bcm43xx_radio_read16(bcm, 0x0043) & 0x00F0);
586 bcm43xx_phy_write(bcm, 0x005A, 0x0480);
587 bcm43xx_phy_write(bcm, 0x0059, 0x0810);
588 bcm43xx_phy_write(bcm, 0x0058, 0x000D);
589 udelay(20);
590
591 nrssi1 = (s16)bcm43xx_phy_read(bcm, 0x0027);
592 bcm43xx_phy_write(bcm, 0x0030, backup[3]);
593 bcm43xx_radio_write16(bcm, 0x007A, backup[0]);
594 bcm43xx_write16(bcm, 0x03E2, backup[11]);
595 bcm43xx_phy_write(bcm, 0x0026, backup[4]);
596 bcm43xx_phy_write(bcm, 0x0015, backup[5]);
597 bcm43xx_phy_write(bcm, 0x002A, backup[6]);
598 bcm43xx_synth_pu_workaround(bcm, radio->channel);
599 if (phy->rev != 0)
600 bcm43xx_write16(bcm, 0x03F4, backup[13]);
601
602 bcm43xx_phy_write(bcm, 0x0020, backup[7]);
603 bcm43xx_phy_write(bcm, 0x005A, backup[8]);
604 bcm43xx_phy_write(bcm, 0x0059, backup[9]);
605 bcm43xx_phy_write(bcm, 0x0058, backup[10]);
606 bcm43xx_radio_write16(bcm, 0x0052, backup[1]);
607 bcm43xx_radio_write16(bcm, 0x0043, backup[2]);
608
609 if (nrssi0 == nrssi1)
610 radio->nrssislope = 0x00010000;
611 else
612 radio->nrssislope = 0x00400000 / (nrssi0 - nrssi1);
613
614 if (nrssi0 <= -4) {
615 radio->nrssi[0] = nrssi0;
616 radio->nrssi[1] = nrssi1;
617 }
618 break;
619 case BCM43xx_PHYTYPE_G:
620 if (radio->revision >= 9)
621 return;
622 if (radio->revision == 8)
623 bcm43xx_calc_nrssi_offset(bcm);
624
625 bcm43xx_phy_write(bcm, BCM43xx_PHY_G_CRS,
626 bcm43xx_phy_read(bcm, BCM43xx_PHY_G_CRS) & 0x7FFF);
627 bcm43xx_phy_write(bcm, 0x0802,
628 bcm43xx_phy_read(bcm, 0x0802) & 0xFFFC);
629 backup[7] = bcm43xx_read16(bcm, 0x03E2);
630 bcm43xx_write16(bcm, 0x03E2,
631 bcm43xx_read16(bcm, 0x03E2) | 0x8000);
632 backup[0] = bcm43xx_radio_read16(bcm, 0x007A);
633 backup[1] = bcm43xx_radio_read16(bcm, 0x0052);
634 backup[2] = bcm43xx_radio_read16(bcm, 0x0043);
635 backup[3] = bcm43xx_phy_read(bcm, 0x0015);
636 backup[4] = bcm43xx_phy_read(bcm, 0x005A);
637 backup[5] = bcm43xx_phy_read(bcm, 0x0059);
638 backup[6] = bcm43xx_phy_read(bcm, 0x0058);
639 backup[8] = bcm43xx_read16(bcm, 0x03E6);
640 backup[9] = bcm43xx_read16(bcm, BCM43xx_MMIO_CHANNEL_EXT);
641 if (phy->rev >= 3) {
642 backup[10] = bcm43xx_phy_read(bcm, 0x002E);
643 backup[11] = bcm43xx_phy_read(bcm, 0x002F);
644 backup[12] = bcm43xx_phy_read(bcm, 0x080F);
645 backup[13] = bcm43xx_phy_read(bcm, BCM43xx_PHY_G_LO_CONTROL);
646 backup[14] = bcm43xx_phy_read(bcm, 0x0801);
647 backup[15] = bcm43xx_phy_read(bcm, 0x0060);
648 backup[16] = bcm43xx_phy_read(bcm, 0x0014);
649 backup[17] = bcm43xx_phy_read(bcm, 0x0478);
650 bcm43xx_phy_write(bcm, 0x002E, 0);
651 bcm43xx_phy_write(bcm, BCM43xx_PHY_G_LO_CONTROL, 0);
652 switch (phy->rev) {
653 case 4: case 6: case 7:
654 bcm43xx_phy_write(bcm, 0x0478,
655 bcm43xx_phy_read(bcm, 0x0478)
656 | 0x0100);
657 bcm43xx_phy_write(bcm, 0x0801,
658 bcm43xx_phy_read(bcm, 0x0801)
659 | 0x0040);
660 break;
661 case 3: case 5:
662 bcm43xx_phy_write(bcm, 0x0801,
663 bcm43xx_phy_read(bcm, 0x0801)
664 & 0xFFBF);
665 break;
666 }
667 bcm43xx_phy_write(bcm, 0x0060,
668 bcm43xx_phy_read(bcm, 0x0060)
669 | 0x0040);
670 bcm43xx_phy_write(bcm, 0x0014,
671 bcm43xx_phy_read(bcm, 0x0014)
672 | 0x0200);
673 }
674 bcm43xx_radio_write16(bcm, 0x007A,
675 bcm43xx_radio_read16(bcm, 0x007A) | 0x0070);
676 bcm43xx_set_all_gains(bcm, 0, 8, 0);
677 bcm43xx_radio_write16(bcm, 0x007A,
678 bcm43xx_radio_read16(bcm, 0x007A) & 0x00F7);
679 if (phy->rev >= 2) {
680 bcm43xx_phy_write(bcm, 0x0811,
681 (bcm43xx_phy_read(bcm, 0x0811) & 0xFFCF) | 0x0030);
682 bcm43xx_phy_write(bcm, 0x0812,
683 (bcm43xx_phy_read(bcm, 0x0812) & 0xFFCF) | 0x0010);
684 }
685 bcm43xx_radio_write16(bcm, 0x007A,
686 bcm43xx_radio_read16(bcm, 0x007A) | 0x0080);
687 udelay(20);
688
689 nrssi0 = (s16)((bcm43xx_phy_read(bcm, 0x047F) >> 8) & 0x003F);
690 if (nrssi0 >= 0x0020)
691 nrssi0 -= 0x0040;
692
693 bcm43xx_radio_write16(bcm, 0x007A,
694 bcm43xx_radio_read16(bcm, 0x007A) & 0x007F);
695 if (phy->rev >= 2) {
696 bcm43xx_phy_write(bcm, 0x0003,
697 (bcm43xx_phy_read(bcm, 0x0003)
698 & 0xFF9F) | 0x0040);
699 }
700
701 bcm43xx_write16(bcm, BCM43xx_MMIO_CHANNEL_EXT,
702 bcm43xx_read16(bcm, BCM43xx_MMIO_CHANNEL_EXT)
703 | 0x2000);
704 bcm43xx_radio_write16(bcm, 0x007A,
705 bcm43xx_radio_read16(bcm, 0x007A) | 0x000F);
706 bcm43xx_phy_write(bcm, 0x0015, 0xF330);
707 if (phy->rev >= 2) {
708 bcm43xx_phy_write(bcm, 0x0812,
709 (bcm43xx_phy_read(bcm, 0x0812) & 0xFFCF) | 0x0020);
710 bcm43xx_phy_write(bcm, 0x0811,
711 (bcm43xx_phy_read(bcm, 0x0811) & 0xFFCF) | 0x0020);
712 }
713
714 bcm43xx_set_all_gains(bcm, 3, 0, 1);
715 if (radio->revision == 8) {
716 bcm43xx_radio_write16(bcm, 0x0043, 0x001F);
717 } else {
718 tmp = bcm43xx_radio_read16(bcm, 0x0052) & 0xFF0F;
719 bcm43xx_radio_write16(bcm, 0x0052, tmp | 0x0060);
720 tmp = bcm43xx_radio_read16(bcm, 0x0043) & 0xFFF0;
721 bcm43xx_radio_write16(bcm, 0x0043, tmp | 0x0009);
722 }
723 bcm43xx_phy_write(bcm, 0x005A, 0x0480);
724 bcm43xx_phy_write(bcm, 0x0059, 0x0810);
725 bcm43xx_phy_write(bcm, 0x0058, 0x000D);
726 udelay(20);
727 nrssi1 = (s16)((bcm43xx_phy_read(bcm, 0x047F) >> 8) & 0x003F);
728 if (nrssi1 >= 0x0020)
729 nrssi1 -= 0x0040;
730 if (nrssi0 == nrssi1)
731 radio->nrssislope = 0x00010000;
732 else
733 radio->nrssislope = 0x00400000 / (nrssi0 - nrssi1);
734 if (nrssi0 >= -4) {
735 radio->nrssi[0] = nrssi1;
736 radio->nrssi[1] = nrssi0;
737 }
738 if (phy->rev >= 3) {
739 bcm43xx_phy_write(bcm, 0x002E, backup[10]);
740 bcm43xx_phy_write(bcm, 0x002F, backup[11]);
741 bcm43xx_phy_write(bcm, 0x080F, backup[12]);
742 bcm43xx_phy_write(bcm, BCM43xx_PHY_G_LO_CONTROL, backup[13]);
743 }
744 if (phy->rev >= 2) {
745 bcm43xx_phy_write(bcm, 0x0812,
746 bcm43xx_phy_read(bcm, 0x0812) & 0xFFCF);
747 bcm43xx_phy_write(bcm, 0x0811,
748 bcm43xx_phy_read(bcm, 0x0811) & 0xFFCF);
749 }
750
751 bcm43xx_radio_write16(bcm, 0x007A, backup[0]);
752 bcm43xx_radio_write16(bcm, 0x0052, backup[1]);
753 bcm43xx_radio_write16(bcm, 0x0043, backup[2]);
754 bcm43xx_write16(bcm, 0x03E2, backup[7]);
755 bcm43xx_write16(bcm, 0x03E6, backup[8]);
756 bcm43xx_write16(bcm, BCM43xx_MMIO_CHANNEL_EXT, backup[9]);
757 bcm43xx_phy_write(bcm, 0x0015, backup[3]);
758 bcm43xx_phy_write(bcm, 0x005A, backup[4]);
759 bcm43xx_phy_write(bcm, 0x0059, backup[5]);
760 bcm43xx_phy_write(bcm, 0x0058, backup[6]);
761 bcm43xx_synth_pu_workaround(bcm, radio->channel);
762 bcm43xx_phy_write(bcm, 0x0802,
763 bcm43xx_phy_read(bcm, 0x0802) | (0x0001 | 0x0002));
764 bcm43xx_set_original_gains(bcm);
765 bcm43xx_phy_write(bcm, BCM43xx_PHY_G_CRS,
766 bcm43xx_phy_read(bcm, BCM43xx_PHY_G_CRS) | 0x8000);
767 if (phy->rev >= 3) {
768 bcm43xx_phy_write(bcm, 0x0801, backup[14]);
769 bcm43xx_phy_write(bcm, 0x0060, backup[15]);
770 bcm43xx_phy_write(bcm, 0x0014, backup[16]);
771 bcm43xx_phy_write(bcm, 0x0478, backup[17]);
772 }
773 bcm43xx_nrssi_mem_update(bcm);
774 bcm43xx_calc_nrssi_threshold(bcm);
775 break;
776 default:
777 assert(0);
778 }
779}
780
781void bcm43xx_calc_nrssi_threshold(struct bcm43xx_private *bcm)
782{
783 struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
784 struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm);
785 s32 threshold;
786 s32 a, b;
787 s16 tmp16;
788 u16 tmp_u16;
789
790 switch (phy->type) {
791 case BCM43xx_PHYTYPE_B: {
792 if (radio->version != 0x2050)
793 return;
794 if (!(bcm->sprom.boardflags & BCM43xx_BFL_RSSI))
795 return;
796
797 if (radio->revision >= 6) {
798 threshold = (radio->nrssi[1] - radio->nrssi[0]) * 32;
799 threshold += 20 * (radio->nrssi[0] + 1);
800 threshold /= 40;
801 } else
802 threshold = radio->nrssi[1] - 5;
803
804 threshold = limit_value(threshold, 0, 0x3E);
805 bcm43xx_phy_read(bcm, 0x0020); /* dummy read */
806 bcm43xx_phy_write(bcm, 0x0020, (((u16)threshold) << 8) | 0x001C);
807
808 if (radio->revision >= 6) {
809 bcm43xx_phy_write(bcm, 0x0087, 0x0E0D);
810 bcm43xx_phy_write(bcm, 0x0086, 0x0C0B);
811 bcm43xx_phy_write(bcm, 0x0085, 0x0A09);
812 bcm43xx_phy_write(bcm, 0x0084, 0x0808);
813 bcm43xx_phy_write(bcm, 0x0083, 0x0808);
814 bcm43xx_phy_write(bcm, 0x0082, 0x0604);
815 bcm43xx_phy_write(bcm, 0x0081, 0x0302);
816 bcm43xx_phy_write(bcm, 0x0080, 0x0100);
817 }
818 break;
819 }
820 case BCM43xx_PHYTYPE_G:
821 if (!phy->connected ||
822 !(bcm->sprom.boardflags & BCM43xx_BFL_RSSI)) {
823 tmp16 = bcm43xx_nrssi_hw_read(bcm, 0x20);
824 if (tmp16 >= 0x20)
825 tmp16 -= 0x40;
826 if (tmp16 < 3) {
827 bcm43xx_phy_write(bcm, 0x048A,
828 (bcm43xx_phy_read(bcm, 0x048A)
829 & 0xF000) | 0x09EB);
830 } else {
831 bcm43xx_phy_write(bcm, 0x048A,
832 (bcm43xx_phy_read(bcm, 0x048A)
833 & 0xF000) | 0x0AED);
834 }
835 } else {
836 if (radio->interfmode == BCM43xx_RADIO_INTERFMODE_NONWLAN) {
837 a = 0xE;
838 b = 0xA;
839 } else if (!radio->aci_wlan_automatic && radio->aci_enable) {
840 a = 0x13;
841 b = 0x12;
842 } else {
843 a = 0xE;
844 b = 0x11;
845 }
846
847 a = a * (radio->nrssi[1] - radio->nrssi[0]);
848 a += (radio->nrssi[0] << 6);
849 if (a < 32)
850 a += 31;
851 else
852 a += 32;
853 a = a >> 6;
854 a = limit_value(a, -31, 31);
855
856 b = b * (radio->nrssi[1] - radio->nrssi[0]);
857 b += (radio->nrssi[0] << 6);
858 if (b < 32)
859 b += 31;
860 else
861 b += 32;
862 b = b >> 6;
863 b = limit_value(b, -31, 31);
864
865 tmp_u16 = bcm43xx_phy_read(bcm, 0x048A) & 0xF000;
866 tmp_u16 |= ((u32)b & 0x0000003F);
867 tmp_u16 |= (((u32)a & 0x0000003F) << 6);
868 bcm43xx_phy_write(bcm, 0x048A, tmp_u16);
869 }
870 break;
871 default:
872 assert(0);
873 }
874}
875
876/* Stack implementation to save/restore values from the
877 * interference mitigation code.
878 * It is save to restore values in random order.
879 */
880static void _stack_save(u32 *_stackptr, size_t *stackidx,
881 u8 id, u16 offset, u16 value)
882{
883 u32 *stackptr = &(_stackptr[*stackidx]);
884
885 assert((offset & 0xF000) == 0x0000);
886 assert((id & 0xF0) == 0x00);
887 *stackptr = offset;
888 *stackptr |= ((u32)id) << 12;
889 *stackptr |= ((u32)value) << 16;
890 (*stackidx)++;
891 assert(*stackidx < BCM43xx_INTERFSTACK_SIZE);
892}
893
894static u16 _stack_restore(u32 *stackptr,
895 u8 id, u16 offset)
896{
897 size_t i;
898
899 assert((offset & 0xF000) == 0x0000);
900 assert((id & 0xF0) == 0x00);
901 for (i = 0; i < BCM43xx_INTERFSTACK_SIZE; i++, stackptr++) {
902 if ((*stackptr & 0x00000FFF) != offset)
903 continue;
904 if (((*stackptr & 0x0000F000) >> 12) != id)
905 continue;
906 return ((*stackptr & 0xFFFF0000) >> 16);
907 }
908 assert(0);
909
910 return 0;
911}
912
913#define phy_stacksave(offset) \
914 do { \
915 _stack_save(stack, &stackidx, 0x1, (offset), \
916 bcm43xx_phy_read(bcm, (offset))); \
917 } while (0)
918#define phy_stackrestore(offset) \
919 do { \
920 bcm43xx_phy_write(bcm, (offset), \
921 _stack_restore(stack, 0x1, \
922 (offset))); \
923 } while (0)
924#define radio_stacksave(offset) \
925 do { \
926 _stack_save(stack, &stackidx, 0x2, (offset), \
927 bcm43xx_radio_read16(bcm, (offset))); \
928 } while (0)
929#define radio_stackrestore(offset) \
930 do { \
931 bcm43xx_radio_write16(bcm, (offset), \
932 _stack_restore(stack, 0x2, \
933 (offset))); \
934 } while (0)
935#define ilt_stacksave(offset) \
936 do { \
937 _stack_save(stack, &stackidx, 0x3, (offset), \
938 bcm43xx_ilt_read(bcm, (offset))); \
939 } while (0)
940#define ilt_stackrestore(offset) \
941 do { \
942 bcm43xx_ilt_write(bcm, (offset), \
943 _stack_restore(stack, 0x3, \
944 (offset))); \
945 } while (0)
946
947static void
948bcm43xx_radio_interference_mitigation_enable(struct bcm43xx_private *bcm,
949 int mode)
950{
951 struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
952 struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm);
953 u16 tmp, flipped;
954 u32 tmp32;
955 size_t stackidx = 0;
956 u32 *stack = radio->interfstack;
957
958 switch (mode) {
959 case BCM43xx_RADIO_INTERFMODE_NONWLAN:
960 if (phy->rev != 1) {
961 bcm43xx_phy_write(bcm, 0x042B,
962 bcm43xx_phy_read(bcm, 0x042B) | 0x0800);
963 bcm43xx_phy_write(bcm, BCM43xx_PHY_G_CRS,
964 bcm43xx_phy_read(bcm, BCM43xx_PHY_G_CRS) & ~0x4000);
965 break;
966 }
967 radio_stacksave(0x0078);
968 tmp = (bcm43xx_radio_read16(bcm, 0x0078) & 0x001E);
969 flipped = flip_4bit(tmp);
970 if (flipped < 10 && flipped >= 8)
971 flipped = 7;
972 else if (flipped >= 10)
973 flipped -= 3;
974 flipped = flip_4bit(flipped);
975 flipped = (flipped << 1) | 0x0020;
976 bcm43xx_radio_write16(bcm, 0x0078, flipped);
977
978 bcm43xx_calc_nrssi_threshold(bcm);
979
980 phy_stacksave(0x0406);
981 bcm43xx_phy_write(bcm, 0x0406, 0x7E28);
982
983 bcm43xx_phy_write(bcm, 0x042B,
984 bcm43xx_phy_read(bcm, 0x042B) | 0x0800);
985 bcm43xx_phy_write(bcm, BCM43xx_PHY_RADIO_BITFIELD,
986 bcm43xx_phy_read(bcm, BCM43xx_PHY_RADIO_BITFIELD) | 0x1000);
987
988 phy_stacksave(0x04A0);
989 bcm43xx_phy_write(bcm, 0x04A0,
990 (bcm43xx_phy_read(bcm, 0x04A0) & 0xC0C0) | 0x0008);
991 phy_stacksave(0x04A1);
992 bcm43xx_phy_write(bcm, 0x04A1,
993 (bcm43xx_phy_read(bcm, 0x04A1) & 0xC0C0) | 0x0605);
994 phy_stacksave(0x04A2);
995 bcm43xx_phy_write(bcm, 0x04A2,
996 (bcm43xx_phy_read(bcm, 0x04A2) & 0xC0C0) | 0x0204);
997 phy_stacksave(0x04A8);
998 bcm43xx_phy_write(bcm, 0x04A8,
999 (bcm43xx_phy_read(bcm, 0x04A8) & 0xC0C0) | 0x0803);
1000 phy_stacksave(0x04AB);
1001 bcm43xx_phy_write(bcm, 0x04AB,
1002 (bcm43xx_phy_read(bcm, 0x04AB) & 0xC0C0) | 0x0605);
1003
1004 phy_stacksave(0x04A7);
1005 bcm43xx_phy_write(bcm, 0x04A7, 0x0002);
1006 phy_stacksave(0x04A3);
1007 bcm43xx_phy_write(bcm, 0x04A3, 0x287A);
1008 phy_stacksave(0x04A9);
1009 bcm43xx_phy_write(bcm, 0x04A9, 0x2027);
1010 phy_stacksave(0x0493);
1011 bcm43xx_phy_write(bcm, 0x0493, 0x32F5);
1012 phy_stacksave(0x04AA);
1013 bcm43xx_phy_write(bcm, 0x04AA, 0x2027);
1014 phy_stacksave(0x04AC);
1015 bcm43xx_phy_write(bcm, 0x04AC, 0x32F5);
1016 break;
1017 case BCM43xx_RADIO_INTERFMODE_MANUALWLAN:
1018 if (bcm43xx_phy_read(bcm, 0x0033) & 0x0800)
1019 break;
1020
1021 radio->aci_enable = 1;
1022
1023 phy_stacksave(BCM43xx_PHY_RADIO_BITFIELD);
1024 phy_stacksave(BCM43xx_PHY_G_CRS);
1025 if (phy->rev < 2) {
1026 phy_stacksave(0x0406);
1027 } else {
1028 phy_stacksave(0x04C0);
1029 phy_stacksave(0x04C1);
1030 }
1031 phy_stacksave(0x0033);
1032 phy_stacksave(0x04A7);
1033 phy_stacksave(0x04A3);
1034 phy_stacksave(0x04A9);
1035 phy_stacksave(0x04AA);
1036 phy_stacksave(0x04AC);
1037 phy_stacksave(0x0493);
1038 phy_stacksave(0x04A1);
1039 phy_stacksave(0x04A0);
1040 phy_stacksave(0x04A2);
1041 phy_stacksave(0x048A);
1042 phy_stacksave(0x04A8);
1043 phy_stacksave(0x04AB);
1044 if (phy->rev == 2) {
1045 phy_stacksave(0x04AD);
1046 phy_stacksave(0x04AE);
1047 } else if (phy->rev >= 3) {
1048 phy_stacksave(0x04AD);
1049 phy_stacksave(0x0415);
1050 phy_stacksave(0x0416);
1051 phy_stacksave(0x0417);
1052 ilt_stacksave(0x1A00 + 0x2);
1053 ilt_stacksave(0x1A00 + 0x3);
1054 }
1055 phy_stacksave(0x042B);
1056 phy_stacksave(0x048C);
1057
1058 bcm43xx_phy_write(bcm, BCM43xx_PHY_RADIO_BITFIELD,
1059 bcm43xx_phy_read(bcm, BCM43xx_PHY_RADIO_BITFIELD)
1060 & ~0x1000);
1061 bcm43xx_phy_write(bcm, BCM43xx_PHY_G_CRS,
1062 (bcm43xx_phy_read(bcm, BCM43xx_PHY_G_CRS)
1063 & 0xFFFC) | 0x0002);
1064
1065 bcm43xx_phy_write(bcm, 0x0033, 0x0800);
1066 bcm43xx_phy_write(bcm, 0x04A3, 0x2027);
1067 bcm43xx_phy_write(bcm, 0x04A9, 0x1CA8);
1068 bcm43xx_phy_write(bcm, 0x0493, 0x287A);
1069 bcm43xx_phy_write(bcm, 0x04AA, 0x1CA8);
1070 bcm43xx_phy_write(bcm, 0x04AC, 0x287A);
1071
1072 bcm43xx_phy_write(bcm, 0x04A0,
1073 (bcm43xx_phy_read(bcm, 0x04A0)
1074 & 0xFFC0) | 0x001A);
1075 bcm43xx_phy_write(bcm, 0x04A7, 0x000D);
1076
1077 if (phy->rev < 2) {
1078 bcm43xx_phy_write(bcm, 0x0406, 0xFF0D);
1079 } else if (phy->rev == 2) {
1080 bcm43xx_phy_write(bcm, 0x04C0, 0xFFFF);
1081 bcm43xx_phy_write(bcm, 0x04C1, 0x00A9);
1082 } else {
1083 bcm43xx_phy_write(bcm, 0x04C0, 0x00C1);
1084 bcm43xx_phy_write(bcm, 0x04C1, 0x0059);
1085 }
1086
1087 bcm43xx_phy_write(bcm, 0x04A1,
1088 (bcm43xx_phy_read(bcm, 0x04A1)
1089 & 0xC0FF) | 0x1800);
1090 bcm43xx_phy_write(bcm, 0x04A1,
1091 (bcm43xx_phy_read(bcm, 0x04A1)
1092 & 0xFFC0) | 0x0015);
1093 bcm43xx_phy_write(bcm, 0x04A8,
1094 (bcm43xx_phy_read(bcm, 0x04A8)
1095 & 0xCFFF) | 0x1000);
1096 bcm43xx_phy_write(bcm, 0x04A8,
1097 (bcm43xx_phy_read(bcm, 0x04A8)
1098 & 0xF0FF) | 0x0A00);
1099 bcm43xx_phy_write(bcm, 0x04AB,
1100 (bcm43xx_phy_read(bcm, 0x04AB)
1101 & 0xCFFF) | 0x1000);
1102 bcm43xx_phy_write(bcm, 0x04AB,
1103 (bcm43xx_phy_read(bcm, 0x04AB)
1104 & 0xF0FF) | 0x0800);
1105 bcm43xx_phy_write(bcm, 0x04AB,
1106 (bcm43xx_phy_read(bcm, 0x04AB)
1107 & 0xFFCF) | 0x0010);
1108 bcm43xx_phy_write(bcm, 0x04AB,
1109 (bcm43xx_phy_read(bcm, 0x04AB)
1110 & 0xFFF0) | 0x0005);
1111 bcm43xx_phy_write(bcm, 0x04A8,
1112 (bcm43xx_phy_read(bcm, 0x04A8)
1113 & 0xFFCF) | 0x0010);
1114 bcm43xx_phy_write(bcm, 0x04A8,
1115 (bcm43xx_phy_read(bcm, 0x04A8)
1116 & 0xFFF0) | 0x0006);
1117 bcm43xx_phy_write(bcm, 0x04A2,
1118 (bcm43xx_phy_read(bcm, 0x04A2)
1119 & 0xF0FF) | 0x0800);
1120 bcm43xx_phy_write(bcm, 0x04A0,
1121 (bcm43xx_phy_read(bcm, 0x04A0)
1122 & 0xF0FF) | 0x0500);
1123 bcm43xx_phy_write(bcm, 0x04A2,
1124 (bcm43xx_phy_read(bcm, 0x04A2)
1125 & 0xFFF0) | 0x000B);
1126
1127 if (phy->rev >= 3) {
1128 bcm43xx_phy_write(bcm, 0x048A,
1129 bcm43xx_phy_read(bcm, 0x048A)
1130 & ~0x8000);
1131 bcm43xx_phy_write(bcm, 0x0415,
1132 (bcm43xx_phy_read(bcm, 0x0415)
1133 & 0x8000) | 0x36D8);
1134 bcm43xx_phy_write(bcm, 0x0416,
1135 (bcm43xx_phy_read(bcm, 0x0416)
1136 & 0x8000) | 0x36D8);
1137 bcm43xx_phy_write(bcm, 0x0417,
1138 (bcm43xx_phy_read(bcm, 0x0417)
1139 & 0xFE00) | 0x016D);
1140 } else {
1141 bcm43xx_phy_write(bcm, 0x048A,
1142 bcm43xx_phy_read(bcm, 0x048A)
1143 | 0x1000);
1144 bcm43xx_phy_write(bcm, 0x048A,
1145 (bcm43xx_phy_read(bcm, 0x048A)
1146 & 0x9FFF) | 0x2000);
1147 tmp32 = bcm43xx_shm_read32(bcm, BCM43xx_SHM_SHARED,
1148 BCM43xx_UCODEFLAGS_OFFSET);
1149 if (!(tmp32 & 0x800)) {
1150 tmp32 |= 0x800;
1151 bcm43xx_shm_write32(bcm, BCM43xx_SHM_SHARED,
1152 BCM43xx_UCODEFLAGS_OFFSET,
1153 tmp32);
1154 }
1155 }
1156 if (phy->rev >= 2) {
1157 bcm43xx_phy_write(bcm, 0x042B,
1158 bcm43xx_phy_read(bcm, 0x042B)
1159 | 0x0800);
1160 }
1161 bcm43xx_phy_write(bcm, 0x048C,
1162 (bcm43xx_phy_read(bcm, 0x048C)
1163 & 0xF0FF) | 0x0200);
1164 if (phy->rev == 2) {
1165 bcm43xx_phy_write(bcm, 0x04AE,
1166 (bcm43xx_phy_read(bcm, 0x04AE)
1167 & 0xFF00) | 0x007F);
1168 bcm43xx_phy_write(bcm, 0x04AD,
1169 (bcm43xx_phy_read(bcm, 0x04AD)
1170 & 0x00FF) | 0x1300);
1171 } else if (phy->rev >= 6) {
1172 bcm43xx_ilt_write(bcm, 0x1A00 + 0x3, 0x007F);
1173 bcm43xx_ilt_write(bcm, 0x1A00 + 0x2, 0x007F);
1174 bcm43xx_phy_write(bcm, 0x04AD,
1175 bcm43xx_phy_read(bcm, 0x04AD)
1176 & 0x00FF);
1177 }
1178 bcm43xx_calc_nrssi_slope(bcm);
1179 break;
1180 default:
1181 assert(0);
1182 }
1183}
1184
1185static void
1186bcm43xx_radio_interference_mitigation_disable(struct bcm43xx_private *bcm,
1187 int mode)
1188{
1189 struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
1190 struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm);
1191 u32 tmp32;
1192 u32 *stack = radio->interfstack;
1193
1194 switch (mode) {
1195 case BCM43xx_RADIO_INTERFMODE_NONWLAN:
1196 if (phy->rev != 1) {
1197 bcm43xx_phy_write(bcm, 0x042B,
1198 bcm43xx_phy_read(bcm, 0x042B) & ~0x0800);
1199 bcm43xx_phy_write(bcm, BCM43xx_PHY_G_CRS,
1200 bcm43xx_phy_read(bcm, BCM43xx_PHY_G_CRS) | 0x4000);
1201 break;
1202 }
1203 phy_stackrestore(0x0078);
1204 bcm43xx_calc_nrssi_threshold(bcm);
1205 phy_stackrestore(0x0406);
1206 bcm43xx_phy_write(bcm, 0x042B,
1207 bcm43xx_phy_read(bcm, 0x042B) & ~0x0800);
1208 if (!bcm->bad_frames_preempt) {
1209 bcm43xx_phy_write(bcm, BCM43xx_PHY_RADIO_BITFIELD,
1210 bcm43xx_phy_read(bcm, BCM43xx_PHY_RADIO_BITFIELD)
1211 & ~(1 << 11));
1212 }
1213 bcm43xx_phy_write(bcm, BCM43xx_PHY_G_CRS,
1214 bcm43xx_phy_read(bcm, BCM43xx_PHY_G_CRS) | 0x4000);
1215 phy_stackrestore(0x04A0);
1216 phy_stackrestore(0x04A1);
1217 phy_stackrestore(0x04A2);
1218 phy_stackrestore(0x04A8);
1219 phy_stackrestore(0x04AB);
1220 phy_stackrestore(0x04A7);
1221 phy_stackrestore(0x04A3);
1222 phy_stackrestore(0x04A9);
1223 phy_stackrestore(0x0493);
1224 phy_stackrestore(0x04AA);
1225 phy_stackrestore(0x04AC);
1226 break;
1227 case BCM43xx_RADIO_INTERFMODE_MANUALWLAN:
1228 if (!(bcm43xx_phy_read(bcm, 0x0033) & 0x0800))
1229 break;
1230
1231 radio->aci_enable = 0;
1232
1233 phy_stackrestore(BCM43xx_PHY_RADIO_BITFIELD);
1234 phy_stackrestore(BCM43xx_PHY_G_CRS);
1235 phy_stackrestore(0x0033);
1236 phy_stackrestore(0x04A3);
1237 phy_stackrestore(0x04A9);
1238 phy_stackrestore(0x0493);
1239 phy_stackrestore(0x04AA);
1240 phy_stackrestore(0x04AC);
1241 phy_stackrestore(0x04A0);
1242 phy_stackrestore(0x04A7);
1243 if (phy->rev >= 2) {
1244 phy_stackrestore(0x04C0);
1245 phy_stackrestore(0x04C1);
1246 } else
1247 phy_stackrestore(0x0406);
1248 phy_stackrestore(0x04A1);
1249 phy_stackrestore(0x04AB);
1250 phy_stackrestore(0x04A8);
1251 if (phy->rev == 2) {
1252 phy_stackrestore(0x04AD);
1253 phy_stackrestore(0x04AE);
1254 } else if (phy->rev >= 3) {
1255 phy_stackrestore(0x04AD);
1256 phy_stackrestore(0x0415);
1257 phy_stackrestore(0x0416);
1258 phy_stackrestore(0x0417);
1259 ilt_stackrestore(0x1A00 + 0x2);
1260 ilt_stackrestore(0x1A00 + 0x3);
1261 }
1262 phy_stackrestore(0x04A2);
1263 phy_stackrestore(0x04A8);
1264 phy_stackrestore(0x042B);
1265 phy_stackrestore(0x048C);
1266 tmp32 = bcm43xx_shm_read32(bcm, BCM43xx_SHM_SHARED,
1267 BCM43xx_UCODEFLAGS_OFFSET);
1268 if (tmp32 & 0x800) {
1269 tmp32 &= ~0x800;
1270 bcm43xx_shm_write32(bcm, BCM43xx_SHM_SHARED,
1271 BCM43xx_UCODEFLAGS_OFFSET,
1272 tmp32);
1273 }
1274 bcm43xx_calc_nrssi_slope(bcm);
1275 break;
1276 default:
1277 assert(0);
1278 }
1279}
1280
1281#undef phy_stacksave
1282#undef phy_stackrestore
1283#undef radio_stacksave
1284#undef radio_stackrestore
1285#undef ilt_stacksave
1286#undef ilt_stackrestore
1287
1288int bcm43xx_radio_set_interference_mitigation(struct bcm43xx_private *bcm,
1289 int mode)
1290{
1291 struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
1292 struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm);
1293 int currentmode;
1294
1295 if ((phy->type != BCM43xx_PHYTYPE_G) ||
1296 (phy->rev == 0) ||
1297 (!phy->connected))
1298 return -ENODEV;
1299
1300 radio->aci_wlan_automatic = 0;
1301 switch (mode) {
1302 case BCM43xx_RADIO_INTERFMODE_AUTOWLAN:
1303 radio->aci_wlan_automatic = 1;
1304 if (radio->aci_enable)
1305 mode = BCM43xx_RADIO_INTERFMODE_MANUALWLAN;
1306 else
1307 mode = BCM43xx_RADIO_INTERFMODE_NONE;
1308 break;
1309 case BCM43xx_RADIO_INTERFMODE_NONE:
1310 case BCM43xx_RADIO_INTERFMODE_NONWLAN:
1311 case BCM43xx_RADIO_INTERFMODE_MANUALWLAN:
1312 break;
1313 default:
1314 return -EINVAL;
1315 }
1316
1317 currentmode = radio->interfmode;
1318 if (currentmode == mode)
1319 return 0;
1320 if (currentmode != BCM43xx_RADIO_INTERFMODE_NONE)
1321 bcm43xx_radio_interference_mitigation_disable(bcm, currentmode);
1322
1323 if (mode == BCM43xx_RADIO_INTERFMODE_NONE) {
1324 radio->aci_enable = 0;
1325 radio->aci_hw_rssi = 0;
1326 } else
1327 bcm43xx_radio_interference_mitigation_enable(bcm, mode);
1328 radio->interfmode = mode;
1329
1330 return 0;
1331}
1332
1333u16 bcm43xx_radio_calibrationvalue(struct bcm43xx_private *bcm)
1334{
1335 u16 reg, index, ret;
1336
1337 reg = bcm43xx_radio_read16(bcm, 0x0060);
1338 index = (reg & 0x001E) >> 1;
1339 ret = rcc_table[index] << 1;
1340 ret |= (reg & 0x0001);
1341 ret |= 0x0020;
1342
1343 return ret;
1344}
1345
1346u16 bcm43xx_radio_init2050(struct bcm43xx_private *bcm)
1347{
1348 struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
1349 struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm);
1350 u16 backup[19] = { 0 };
1351 u16 ret;
1352 u16 i, j;
1353 u32 tmp1 = 0, tmp2 = 0;
1354
1355 backup[0] = bcm43xx_radio_read16(bcm, 0x0043);
1356 backup[14] = bcm43xx_radio_read16(bcm, 0x0051);
1357 backup[15] = bcm43xx_radio_read16(bcm, 0x0052);
1358 backup[1] = bcm43xx_phy_read(bcm, 0x0015);
1359 backup[16] = bcm43xx_phy_read(bcm, 0x005A);
1360 backup[17] = bcm43xx_phy_read(bcm, 0x0059);
1361 backup[18] = bcm43xx_phy_read(bcm, 0x0058);
1362 if (phy->type == BCM43xx_PHYTYPE_B) {
1363 backup[2] = bcm43xx_phy_read(bcm, 0x0030);
1364 backup[3] = bcm43xx_read16(bcm, 0x03EC);
1365 bcm43xx_phy_write(bcm, 0x0030, 0x00FF);
1366 bcm43xx_write16(bcm, 0x03EC, 0x3F3F);
1367 } else {
1368 if (phy->connected) {
1369 backup[4] = bcm43xx_phy_read(bcm, 0x0811);
1370 backup[5] = bcm43xx_phy_read(bcm, 0x0812);
1371 backup[6] = bcm43xx_phy_read(bcm, 0x0814);
1372 backup[7] = bcm43xx_phy_read(bcm, 0x0815);
1373 backup[8] = bcm43xx_phy_read(bcm, BCM43xx_PHY_G_CRS);
1374 backup[9] = bcm43xx_phy_read(bcm, 0x0802);
1375 bcm43xx_phy_write(bcm, 0x0814,
1376 (bcm43xx_phy_read(bcm, 0x0814) | 0x0003));
1377 bcm43xx_phy_write(bcm, 0x0815,
1378 (bcm43xx_phy_read(bcm, 0x0815) & 0xFFFC));
1379 bcm43xx_phy_write(bcm, BCM43xx_PHY_G_CRS,
1380 (bcm43xx_phy_read(bcm, BCM43xx_PHY_G_CRS) & 0x7FFF));
1381 bcm43xx_phy_write(bcm, 0x0802,
1382 (bcm43xx_phy_read(bcm, 0x0802) & 0xFFFC));
1383 bcm43xx_phy_write(bcm, 0x0811, 0x01B3);
1384 bcm43xx_phy_write(bcm, 0x0812, 0x0FB2);
1385 }
1386 bcm43xx_write16(bcm, BCM43xx_MMIO_PHY_RADIO,
1387 (bcm43xx_read16(bcm, BCM43xx_MMIO_PHY_RADIO) | 0x8000));
1388 }
1389 backup[10] = bcm43xx_phy_read(bcm, 0x0035);
1390 bcm43xx_phy_write(bcm, 0x0035,
1391 (bcm43xx_phy_read(bcm, 0x0035) & 0xFF7F));
1392 backup[11] = bcm43xx_read16(bcm, 0x03E6);
1393 backup[12] = bcm43xx_read16(bcm, BCM43xx_MMIO_CHANNEL_EXT);
1394
1395 // Initialization
1396 if (phy->version == 0) {
1397 bcm43xx_write16(bcm, 0x03E6, 0x0122);
1398 } else {
1399 if (phy->version >= 2)
1400 bcm43xx_write16(bcm, 0x03E6, 0x0040);
1401 bcm43xx_write16(bcm, BCM43xx_MMIO_CHANNEL_EXT,
1402 (bcm43xx_read16(bcm, BCM43xx_MMIO_CHANNEL_EXT) | 0x2000));
1403 }
1404
1405 ret = bcm43xx_radio_calibrationvalue(bcm);
1406
1407 if (phy->type == BCM43xx_PHYTYPE_B)
1408 bcm43xx_radio_write16(bcm, 0x0078, 0x0003);
1409
1410 bcm43xx_phy_write(bcm, 0x0015, 0xBFAF);
1411 bcm43xx_phy_write(bcm, 0x002B, 0x1403);
1412 if (phy->connected)
1413 bcm43xx_phy_write(bcm, 0x0812, 0x00B2);
1414 bcm43xx_phy_write(bcm, 0x0015, 0xBFA0);
1415 bcm43xx_radio_write16(bcm, 0x0051,
1416 (bcm43xx_radio_read16(bcm, 0x0051) | 0x0004));
1417 bcm43xx_radio_write16(bcm, 0x0052, 0x0000);
1418 bcm43xx_radio_write16(bcm, 0x0043,
1419 bcm43xx_radio_read16(bcm, 0x0043) | 0x0009);
1420 bcm43xx_phy_write(bcm, 0x0058, 0x0000);
1421
1422 for (i = 0; i < 16; i++) {
1423 bcm43xx_phy_write(bcm, 0x005A, 0x0480);
1424 bcm43xx_phy_write(bcm, 0x0059, 0xC810);
1425 bcm43xx_phy_write(bcm, 0x0058, 0x000D);
1426 if (phy->connected)
1427 bcm43xx_phy_write(bcm, 0x0812, 0x30B2);
1428 bcm43xx_phy_write(bcm, 0x0015, 0xAFB0);
1429 udelay(10);
1430 if (phy->connected)
1431 bcm43xx_phy_write(bcm, 0x0812, 0x30B2);
1432 bcm43xx_phy_write(bcm, 0x0015, 0xEFB0);
1433 udelay(10);
1434 if (phy->connected)
1435 bcm43xx_phy_write(bcm, 0x0812, 0x30B2);
1436 bcm43xx_phy_write(bcm, 0x0015, 0xFFF0);
1437 udelay(10);
1438 tmp1 += bcm43xx_phy_read(bcm, 0x002D);
1439 bcm43xx_phy_write(bcm, 0x0058, 0x0000);
1440 if (phy->connected)
1441 bcm43xx_phy_write(bcm, 0x0812, 0x30B2);
1442 bcm43xx_phy_write(bcm, 0x0015, 0xAFB0);
1443 }
1444
1445 tmp1++;
1446 tmp1 >>= 9;
1447 udelay(10);
1448 bcm43xx_phy_write(bcm, 0x0058, 0x0000);
1449
1450 for (i = 0; i < 16; i++) {
1451 bcm43xx_radio_write16(bcm, 0x0078, (flip_4bit(i) << 1) | 0x0020);
1452 backup[13] = bcm43xx_radio_read16(bcm, 0x0078);
1453 udelay(10);
1454 for (j = 0; j < 16; j++) {
1455 bcm43xx_phy_write(bcm, 0x005A, 0x0D80);
1456 bcm43xx_phy_write(bcm, 0x0059, 0xC810);
1457 bcm43xx_phy_write(bcm, 0x0058, 0x000D);
1458 if (phy->connected)
1459 bcm43xx_phy_write(bcm, 0x0812, 0x30B2);
1460 bcm43xx_phy_write(bcm, 0x0015, 0xAFB0);
1461 udelay(10);
1462 if (phy->connected)
1463 bcm43xx_phy_write(bcm, 0x0812, 0x30B2);
1464 bcm43xx_phy_write(bcm, 0x0015, 0xEFB0);
1465 udelay(10);
1466 if (phy->connected)
1467 bcm43xx_phy_write(bcm, 0x0812, 0x30B3); /* 0x30B3 is not a typo */
1468 bcm43xx_phy_write(bcm, 0x0015, 0xFFF0);
1469 udelay(10);
1470 tmp2 += bcm43xx_phy_read(bcm, 0x002D);
1471 bcm43xx_phy_write(bcm, 0x0058, 0x0000);
1472 if (phy->connected)
1473 bcm43xx_phy_write(bcm, 0x0812, 0x30B2);
1474 bcm43xx_phy_write(bcm, 0x0015, 0xAFB0);
1475 }
1476 tmp2++;
1477 tmp2 >>= 8;
1478 if (tmp1 < tmp2)
1479 break;
1480 }
1481
1482 /* Restore the registers */
1483 bcm43xx_phy_write(bcm, 0x0015, backup[1]);
1484 bcm43xx_radio_write16(bcm, 0x0051, backup[14]);
1485 bcm43xx_radio_write16(bcm, 0x0052, backup[15]);
1486 bcm43xx_radio_write16(bcm, 0x0043, backup[0]);
1487 bcm43xx_phy_write(bcm, 0x005A, backup[16]);
1488 bcm43xx_phy_write(bcm, 0x0059, backup[17]);
1489 bcm43xx_phy_write(bcm, 0x0058, backup[18]);
1490 bcm43xx_write16(bcm, 0x03E6, backup[11]);
1491 if (phy->version != 0)
1492 bcm43xx_write16(bcm, BCM43xx_MMIO_CHANNEL_EXT, backup[12]);
1493 bcm43xx_phy_write(bcm, 0x0035, backup[10]);
1494 bcm43xx_radio_selectchannel(bcm, radio->channel, 1);
1495 if (phy->type == BCM43xx_PHYTYPE_B) {
1496 bcm43xx_phy_write(bcm, 0x0030, backup[2]);
1497 bcm43xx_write16(bcm, 0x03EC, backup[3]);
1498 } else {
1499 bcm43xx_write16(bcm, BCM43xx_MMIO_PHY_RADIO,
1500 (bcm43xx_read16(bcm, BCM43xx_MMIO_PHY_RADIO) & 0x7FFF));
1501 if (phy->connected) {
1502 bcm43xx_phy_write(bcm, 0x0811, backup[4]);
1503 bcm43xx_phy_write(bcm, 0x0812, backup[5]);
1504 bcm43xx_phy_write(bcm, 0x0814, backup[6]);
1505 bcm43xx_phy_write(bcm, 0x0815, backup[7]);
1506 bcm43xx_phy_write(bcm, BCM43xx_PHY_G_CRS, backup[8]);
1507 bcm43xx_phy_write(bcm, 0x0802, backup[9]);
1508 }
1509 }
1510 if (i >= 15)
1511 ret = backup[13];
1512
1513 return ret;
1514}
1515
1516void bcm43xx_radio_init2060(struct bcm43xx_private *bcm)
1517{
1518 int err;
1519
1520 bcm43xx_radio_write16(bcm, 0x0004, 0x00C0);
1521 bcm43xx_radio_write16(bcm, 0x0005, 0x0008);
1522 bcm43xx_radio_write16(bcm, 0x0009, 0x0040);
1523 bcm43xx_radio_write16(bcm, 0x0005, 0x00AA);
1524 bcm43xx_radio_write16(bcm, 0x0032, 0x008F);
1525 bcm43xx_radio_write16(bcm, 0x0006, 0x008F);
1526 bcm43xx_radio_write16(bcm, 0x0034, 0x008F);
1527 bcm43xx_radio_write16(bcm, 0x002C, 0x0007);
1528 bcm43xx_radio_write16(bcm, 0x0082, 0x0080);
1529 bcm43xx_radio_write16(bcm, 0x0080, 0x0000);
1530 bcm43xx_radio_write16(bcm, 0x003F, 0x00DA);
1531 bcm43xx_radio_write16(bcm, 0x0005, bcm43xx_radio_read16(bcm, 0x0005) & ~0x0008);
1532 bcm43xx_radio_write16(bcm, 0x0081, bcm43xx_radio_read16(bcm, 0x0081) & ~0x0010);
1533 bcm43xx_radio_write16(bcm, 0x0081, bcm43xx_radio_read16(bcm, 0x0081) & ~0x0020);
1534 bcm43xx_radio_write16(bcm, 0x0081, bcm43xx_radio_read16(bcm, 0x0081) & ~0x0020);
1535 udelay(400);
1536
1537 bcm43xx_radio_write16(bcm, 0x0081, (bcm43xx_radio_read16(bcm, 0x0081) & ~0x0020) | 0x0010);
1538 udelay(400);
1539
1540 bcm43xx_radio_write16(bcm, 0x0005, (bcm43xx_radio_read16(bcm, 0x0005) & ~0x0008) | 0x0008);
1541 bcm43xx_radio_write16(bcm, 0x0085, bcm43xx_radio_read16(bcm, 0x0085) & ~0x0010);
1542 bcm43xx_radio_write16(bcm, 0x0005, bcm43xx_radio_read16(bcm, 0x0005) & ~0x0008);
1543 bcm43xx_radio_write16(bcm, 0x0081, bcm43xx_radio_read16(bcm, 0x0081) & ~0x0040);
1544 bcm43xx_radio_write16(bcm, 0x0081, (bcm43xx_radio_read16(bcm, 0x0081) & ~0x0040) | 0x0040);
1545 bcm43xx_radio_write16(bcm, 0x0005, (bcm43xx_radio_read16(bcm, 0x0081) & ~0x0008) | 0x0008);
1546 bcm43xx_phy_write(bcm, 0x0063, 0xDDC6);
1547 bcm43xx_phy_write(bcm, 0x0069, 0x07BE);
1548 bcm43xx_phy_write(bcm, 0x006A, 0x0000);
1549
1550 err = bcm43xx_radio_selectchannel(bcm, BCM43xx_RADIO_DEFAULT_CHANNEL_A, 0);
1551 assert(err == 0);
1552 udelay(1000);
1553}
1554
1555static inline
1556u16 freq_r3A_value(u16 frequency)
1557{
1558 u16 value;
1559
1560 if (frequency < 5091)
1561 value = 0x0040;
1562 else if (frequency < 5321)
1563 value = 0x0000;
1564 else if (frequency < 5806)
1565 value = 0x0080;
1566 else
1567 value = 0x0040;
1568
1569 return value;
1570}
1571
1572void bcm43xx_radio_set_tx_iq(struct bcm43xx_private *bcm)
1573{
1574 static const u8 data_high[5] = { 0x00, 0x40, 0x80, 0x90, 0xD0 };
1575 static const u8 data_low[5] = { 0x00, 0x01, 0x05, 0x06, 0x0A };
1576 u16 tmp = bcm43xx_radio_read16(bcm, 0x001E);
1577 int i, j;
1578
1579 for (i = 0; i < 5; i++) {
1580 for (j = 0; j < 5; j++) {
1581 if (tmp == (data_high[i] << 4 | data_low[j])) {
1582 bcm43xx_phy_write(bcm, 0x0069, (i - j) << 8 | 0x00C0);
1583 return;
1584 }
1585 }
1586 }
1587}
1588
1589int bcm43xx_radio_selectchannel(struct bcm43xx_private *bcm,
1590 u8 channel,
1591 int synthetic_pu_workaround)
1592{
1593 struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm);
1594 u16 r8, tmp;
1595 u16 freq;
1596
1597 if ((radio->manufact == 0x17F) &&
1598 (radio->version == 0x2060) &&
1599 (radio->revision == 1)) {
1600 if (channel > 200)
1601 return -EINVAL;
1602 freq = channel2freq_a(channel);
1603
1604 r8 = bcm43xx_radio_read16(bcm, 0x0008);
1605 bcm43xx_write16(bcm, 0x03F0, freq);
1606 bcm43xx_radio_write16(bcm, 0x0008, r8);
1607
1608 TODO();//TODO: write max channel TX power? to Radio 0x2D
1609 tmp = bcm43xx_radio_read16(bcm, 0x002E);
1610 tmp &= 0x0080;
1611 TODO();//TODO: OR tmp with the Power out estimation for this channel?
1612 bcm43xx_radio_write16(bcm, 0x002E, tmp);
1613
1614 if (freq >= 4920 && freq <= 5500) {
1615 /*
1616 * r8 = (((freq * 15 * 0xE1FC780F) >> 32) / 29) & 0x0F;
1617 * = (freq * 0.025862069
1618 */
1619 r8 = 3 * freq / 116; /* is equal to r8 = freq * 0.025862 */
1620 }
1621 bcm43xx_radio_write16(bcm, 0x0007, (r8 << 4) | r8);
1622 bcm43xx_radio_write16(bcm, 0x0020, (r8 << 4) | r8);
1623 bcm43xx_radio_write16(bcm, 0x0021, (r8 << 4) | r8);
1624 bcm43xx_radio_write16(bcm, 0x0022,
1625 (bcm43xx_radio_read16(bcm, 0x0022)
1626 & 0x000F) | (r8 << 4));
1627 bcm43xx_radio_write16(bcm, 0x002A, (r8 << 4));
1628 bcm43xx_radio_write16(bcm, 0x002B, (r8 << 4));
1629 bcm43xx_radio_write16(bcm, 0x0008,
1630 (bcm43xx_radio_read16(bcm, 0x0008)
1631 & 0x00F0) | (r8 << 4));
1632 bcm43xx_radio_write16(bcm, 0x0029,
1633 (bcm43xx_radio_read16(bcm, 0x0029)
1634 & 0xFF0F) | 0x00B0);
1635 bcm43xx_radio_write16(bcm, 0x0035, 0x00AA);
1636 bcm43xx_radio_write16(bcm, 0x0036, 0x0085);
1637 bcm43xx_radio_write16(bcm, 0x003A,
1638 (bcm43xx_radio_read16(bcm, 0x003A)
1639 & 0xFF20) | freq_r3A_value(freq));
1640 bcm43xx_radio_write16(bcm, 0x003D,
1641 bcm43xx_radio_read16(bcm, 0x003D) & 0x00FF);
1642 bcm43xx_radio_write16(bcm, 0x0081,
1643 (bcm43xx_radio_read16(bcm, 0x0081)
1644 & 0xFF7F) | 0x0080);
1645 bcm43xx_radio_write16(bcm, 0x0035,
1646 bcm43xx_radio_read16(bcm, 0x0035) & 0xFFEF);
1647 bcm43xx_radio_write16(bcm, 0x0035,
1648 (bcm43xx_radio_read16(bcm, 0x0035)
1649 & 0xFFEF) | 0x0010);
1650 bcm43xx_radio_set_tx_iq(bcm);
1651 TODO(); //TODO: TSSI2dbm workaround
1652 bcm43xx_phy_xmitpower(bcm);//FIXME correct?
1653 } else {
1654 if ((channel < 1) || (channel > 14))
1655 return -EINVAL;
1656
1657 if (synthetic_pu_workaround)
1658 bcm43xx_synth_pu_workaround(bcm, channel);
1659
1660 bcm43xx_write16(bcm, BCM43xx_MMIO_CHANNEL,
1661 channel2freq_bg(channel));
1662
1663 if (channel == 14) {
1664 if (bcm->sprom.locale == BCM43xx_LOCALE_JAPAN) {
1665 bcm43xx_shm_write32(bcm, BCM43xx_SHM_SHARED,
1666 BCM43xx_UCODEFLAGS_OFFSET,
1667 bcm43xx_shm_read32(bcm, BCM43xx_SHM_SHARED,
1668 BCM43xx_UCODEFLAGS_OFFSET)
1669 & ~(1 << 7));
1670 } else {
1671 bcm43xx_shm_write32(bcm, BCM43xx_SHM_SHARED,
1672 BCM43xx_UCODEFLAGS_OFFSET,
1673 bcm43xx_shm_read32(bcm, BCM43xx_SHM_SHARED,
1674 BCM43xx_UCODEFLAGS_OFFSET)
1675 | (1 << 7));
1676 }
1677 bcm43xx_write16(bcm, BCM43xx_MMIO_CHANNEL_EXT,
1678 bcm43xx_read16(bcm, BCM43xx_MMIO_CHANNEL_EXT)
1679 | (1 << 11));
1680 } else {
1681 bcm43xx_write16(bcm, BCM43xx_MMIO_CHANNEL_EXT,
1682 bcm43xx_read16(bcm, BCM43xx_MMIO_CHANNEL_EXT)
1683 & 0xF7BF);
1684 }
1685 }
1686
1687 radio->channel = channel;
1688 //XXX: Using the longer of 2 timeouts (8000 vs 2000 usecs). Specs states
1689 // that 2000 usecs might suffice.
1690 udelay(8000);
1691
1692 return 0;
1693}
1694
1695void bcm43xx_radio_set_txantenna(struct bcm43xx_private *bcm, u32 val)
1696{
1697 u16 tmp;
1698
1699 val <<= 8;
1700 tmp = bcm43xx_shm_read16(bcm, BCM43xx_SHM_SHARED, 0x0022) & 0xFCFF;
1701 bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, 0x0022, tmp | val);
1702 tmp = bcm43xx_shm_read16(bcm, BCM43xx_SHM_SHARED, 0x03A8) & 0xFCFF;
1703 bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, 0x03A8, tmp | val);
1704 tmp = bcm43xx_shm_read16(bcm, BCM43xx_SHM_SHARED, 0x0054) & 0xFCFF;
1705 bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, 0x0054, tmp | val);
1706}
1707
1708/* http://bcm-specs.sipsolutions.net/TX_Gain_Base_Band */
1709static u16 bcm43xx_get_txgain_base_band(u16 txpower)
1710{
1711 u16 ret;
1712
1713 assert(txpower <= 63);
1714
1715 if (txpower >= 54)
1716 ret = 2;
1717 else if (txpower >= 49)
1718 ret = 4;
1719 else if (txpower >= 44)
1720 ret = 5;
1721 else
1722 ret = 6;
1723
1724 return ret;
1725}
1726
1727/* http://bcm-specs.sipsolutions.net/TX_Gain_Radio_Frequency_Power_Amplifier */
1728static u16 bcm43xx_get_txgain_freq_power_amp(u16 txpower)
1729{
1730 u16 ret;
1731
1732 assert(txpower <= 63);
1733
1734 if (txpower >= 32)
1735 ret = 0;
1736 else if (txpower >= 25)
1737 ret = 1;
1738 else if (txpower >= 20)
1739 ret = 2;
1740 else if (txpower >= 12)
1741 ret = 3;
1742 else
1743 ret = 4;
1744
1745 return ret;
1746}
1747
1748/* http://bcm-specs.sipsolutions.net/TX_Gain_Digital_Analog_Converter */
1749static u16 bcm43xx_get_txgain_dac(u16 txpower)
1750{
1751 u16 ret;
1752
1753 assert(txpower <= 63);
1754
1755 if (txpower >= 54)
1756 ret = txpower - 53;
1757 else if (txpower >= 49)
1758 ret = txpower - 42;
1759 else if (txpower >= 44)
1760 ret = txpower - 37;
1761 else if (txpower >= 32)
1762 ret = txpower - 32;
1763 else if (txpower >= 25)
1764 ret = txpower - 20;
1765 else if (txpower >= 20)
1766 ret = txpower - 13;
1767 else if (txpower >= 12)
1768 ret = txpower - 8;
1769 else
1770 ret = txpower;
1771
1772 return ret;
1773}
1774
1775void bcm43xx_radio_set_txpower_a(struct bcm43xx_private *bcm, u16 txpower)
1776{
1777 struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm);
1778 u16 pamp, base, dac, ilt;
1779
1780 txpower = limit_value(txpower, 0, 63);
1781
1782 pamp = bcm43xx_get_txgain_freq_power_amp(txpower);
1783 pamp <<= 5;
1784 pamp &= 0x00E0;
1785 bcm43xx_phy_write(bcm, 0x0019, pamp);
1786
1787 base = bcm43xx_get_txgain_base_band(txpower);
1788 base &= 0x000F;
1789 bcm43xx_phy_write(bcm, 0x0017, base | 0x0020);
1790
1791 ilt = bcm43xx_ilt_read(bcm, 0x3001);
1792 ilt &= 0x0007;
1793
1794 dac = bcm43xx_get_txgain_dac(txpower);
1795 dac <<= 3;
1796 dac |= ilt;
1797
1798 bcm43xx_ilt_write(bcm, 0x3001, dac);
1799
1800 radio->txpwr_offset = txpower;
1801
1802 TODO();
1803 //TODO: FuncPlaceholder (Adjust BB loft cancel)
1804}
1805
1806void bcm43xx_radio_set_txpower_bg(struct bcm43xx_private *bcm,
1807 u16 baseband_attenuation, u16 radio_attenuation,
1808 u16 txpower)
1809{
1810 struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm);
1811 struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
1812
1813 if (baseband_attenuation == 0xFFFF)
1814 baseband_attenuation = radio->baseband_atten;
1815 if (radio_attenuation == 0xFFFF)
1816 radio_attenuation = radio->radio_atten;
1817 if (txpower == 0xFFFF)
1818 txpower = radio->txctl1;
1819 radio->baseband_atten = baseband_attenuation;
1820 radio->radio_atten = radio_attenuation;
1821 radio->txctl1 = txpower;
1822
1823 assert(/*baseband_attenuation >= 0 &&*/ baseband_attenuation <= 11);
1824 if (radio->revision < 6)
1825 assert(/*radio_attenuation >= 0 &&*/ radio_attenuation <= 9);
1826 else
1827 assert(/* radio_attenuation >= 0 &&*/ radio_attenuation <= 31);
1828 assert(/*txpower >= 0 &&*/ txpower <= 7);
1829
1830 bcm43xx_phy_set_baseband_attenuation(bcm, baseband_attenuation);
1831 bcm43xx_radio_write16(bcm, 0x0043, radio_attenuation);
1832 bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, 0x0064, radio_attenuation);
1833 if (radio->version == 0x2050) {
1834 bcm43xx_radio_write16(bcm, 0x0052,
1835 (bcm43xx_radio_read16(bcm, 0x0052) & ~0x0070)
1836 | ((txpower << 4) & 0x0070));
1837 }
1838 //FIXME: The spec is very weird and unclear here.
1839 if (phy->type == BCM43xx_PHYTYPE_G)
1840 bcm43xx_phy_lo_adjust(bcm, 0);
1841}
1842
1843u16 bcm43xx_default_baseband_attenuation(struct bcm43xx_private *bcm)
1844{
1845 struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm);
1846
1847 if (radio->version == 0x2050 && radio->revision < 6)
1848 return 0;
1849 return 2;
1850}
1851
1852u16 bcm43xx_default_radio_attenuation(struct bcm43xx_private *bcm)
1853{
1854 struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
1855 struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm);
1856 u16 att = 0xFFFF;
1857
1858 if (phy->type == BCM43xx_PHYTYPE_A)
1859 return 0x60;
1860
1861 switch (radio->version) {
1862 case 0x2053:
1863 switch (radio->revision) {
1864 case 1:
1865 att = 6;
1866 break;
1867 }
1868 break;
1869 case 0x2050:
1870 switch (radio->revision) {
1871 case 0:
1872 att = 5;
1873 break;
1874 case 1:
1875 if (phy->type == BCM43xx_PHYTYPE_G) {
1876 if (bcm->board_vendor == PCI_VENDOR_ID_BROADCOM &&
1877 bcm->board_type == 0x421 &&
1878 bcm->board_revision >= 30)
1879 att = 3;
1880 else if (bcm->board_vendor == PCI_VENDOR_ID_BROADCOM &&
1881 bcm->board_type == 0x416)
1882 att = 3;
1883 else
1884 att = 1;
1885 } else {
1886 if (bcm->board_vendor == PCI_VENDOR_ID_BROADCOM &&
1887 bcm->board_type == 0x421 &&
1888 bcm->board_revision >= 30)
1889 att = 7;
1890 else
1891 att = 6;
1892 }
1893 break;
1894 case 2:
1895 if (phy->type == BCM43xx_PHYTYPE_G) {
1896 if (bcm->board_vendor == PCI_VENDOR_ID_BROADCOM &&
1897 bcm->board_type == 0x421 &&
1898 bcm->board_revision >= 30)
1899 att = 3;
1900 else if (bcm->board_vendor == PCI_VENDOR_ID_BROADCOM &&
1901 bcm->board_type == 0x416)
1902 att = 5;
1903 else if (bcm->chip_id == 0x4320)
1904 att = 4;
1905 else
1906 att = 3;
1907 } else
1908 att = 6;
1909 break;
1910 case 3:
1911 att = 5;
1912 break;
1913 case 4:
1914 case 5:
1915 att = 1;
1916 break;
1917 case 6:
1918 case 7:
1919 att = 5;
1920 break;
1921 case 8:
1922 att = 0x1A;
1923 break;
1924 case 9:
1925 default:
1926 att = 5;
1927 }
1928 }
1929 if (bcm->board_vendor == PCI_VENDOR_ID_BROADCOM &&
1930 bcm->board_type == 0x421) {
1931 if (bcm->board_revision < 0x43)
1932 att = 2;
1933 else if (bcm->board_revision < 0x51)
1934 att = 3;
1935 }
1936 if (att == 0xFFFF)
1937 att = 5;
1938
1939 return att;
1940}
1941
1942u16 bcm43xx_default_txctl1(struct bcm43xx_private *bcm)
1943{
1944 struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm);
1945
1946 if (radio->version != 0x2050)
1947 return 0;
1948 if (radio->revision == 1)
1949 return 3;
1950 if (radio->revision < 6)
1951 return 2;
1952 if (radio->revision == 8)
1953 return 1;
1954 return 0;
1955}
1956
1957void bcm43xx_radio_turn_on(struct bcm43xx_private *bcm)
1958{
1959 struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
1960 struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm);
1961 int err;
1962
1963 if (radio->enabled)
1964 return;
1965
1966 switch (phy->type) {
1967 case BCM43xx_PHYTYPE_A:
1968 bcm43xx_radio_write16(bcm, 0x0004, 0x00C0);
1969 bcm43xx_radio_write16(bcm, 0x0005, 0x0008);
1970 bcm43xx_phy_write(bcm, 0x0010, bcm43xx_phy_read(bcm, 0x0010) & 0xFFF7);
1971 bcm43xx_phy_write(bcm, 0x0011, bcm43xx_phy_read(bcm, 0x0011) & 0xFFF7);
1972 bcm43xx_radio_init2060(bcm);
1973 break;
1974 case BCM43xx_PHYTYPE_B:
1975 case BCM43xx_PHYTYPE_G:
1976 bcm43xx_phy_write(bcm, 0x0015, 0x8000);
1977 bcm43xx_phy_write(bcm, 0x0015, 0xCC00);
1978 bcm43xx_phy_write(bcm, 0x0015, (phy->connected ? 0x00C0 : 0x0000));
1979 err = bcm43xx_radio_selectchannel(bcm, BCM43xx_RADIO_DEFAULT_CHANNEL_BG, 1);
1980 assert(err == 0);
1981 break;
1982 default:
1983 assert(0);
1984 }
1985 radio->enabled = 1;
1986 dprintk(KERN_INFO PFX "Radio turned on\n");
1987}
1988
1989void bcm43xx_radio_turn_off(struct bcm43xx_private *bcm)
1990{
1991 struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
1992 struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm);
1993
1994 if (phy->type == BCM43xx_PHYTYPE_A) {
1995 bcm43xx_radio_write16(bcm, 0x0004, 0x00FF);
1996 bcm43xx_radio_write16(bcm, 0x0005, 0x00FB);
1997 bcm43xx_phy_write(bcm, 0x0010, bcm43xx_phy_read(bcm, 0x0010) | 0x0008);
1998 bcm43xx_phy_write(bcm, 0x0011, bcm43xx_phy_read(bcm, 0x0011) | 0x0008);
1999 }
2000 if (phy->type == BCM43xx_PHYTYPE_G && bcm->current_core->rev >= 5) {
2001 bcm43xx_phy_write(bcm, 0x0811, bcm43xx_phy_read(bcm, 0x0811) | 0x008C);
2002 bcm43xx_phy_write(bcm, 0x0812, bcm43xx_phy_read(bcm, 0x0812) & 0xFF73);
2003 } else
2004 bcm43xx_phy_write(bcm, 0x0015, 0xAA00);
2005 radio->enabled = 0;
2006 dprintk(KERN_INFO PFX "Radio turned off\n");
2007}
2008
2009void bcm43xx_radio_clear_tssi(struct bcm43xx_private *bcm)
2010{
2011 struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
2012
2013 switch (phy->type) {
2014 case BCM43xx_PHYTYPE_A:
2015 bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, 0x0068, 0x7F7F);
2016 bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, 0x006a, 0x7F7F);
2017 break;
2018 case BCM43xx_PHYTYPE_B:
2019 case BCM43xx_PHYTYPE_G:
2020 bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, 0x0058, 0x7F7F);
2021 bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, 0x005a, 0x7F7F);
2022 bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, 0x0070, 0x7F7F);
2023 bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, 0x0072, 0x7F7F);
2024 break;
2025 }
2026}
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_radio.h b/drivers/net/wireless/bcm43xx/bcm43xx_radio.h
new file mode 100644
index 000000000000..9ed18039fa3e
--- /dev/null
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_radio.h
@@ -0,0 +1,99 @@
1/*
2
3 Broadcom BCM43xx wireless driver
4
5 Copyright (c) 2005 Martin Langer <martin-langer@gmx.de>,
6 Stefano Brivio <st3@riseup.net>
7 Michael Buesch <mbuesch@freenet.de>
8 Danny van Dyk <kugelfang@gentoo.org>
9 Andreas Jaggi <andreas.jaggi@waterwave.ch>
10
11 Some parts of the code in this file are derived from the ipw2200
12 driver Copyright(c) 2003 - 2004 Intel Corporation.
13
14 This program is free software; you can redistribute it and/or modify
15 it under the terms of the GNU General Public License as published by
16 the Free Software Foundation; either version 2 of the License, or
17 (at your option) any later version.
18
19 This program is distributed in the hope that it will be useful,
20 but WITHOUT ANY WARRANTY; without even the implied warranty of
21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 GNU General Public License for more details.
23
24 You should have received a copy of the GNU General Public License
25 along with this program; see the file COPYING. If not, write to
26 the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,
27 Boston, MA 02110-1301, USA.
28
29*/
30
31#ifndef BCM43xx_RADIO_H_
32#define BCM43xx_RADIO_H_
33
34#include "bcm43xx.h"
35
36
37#define BCM43xx_RADIO_DEFAULT_CHANNEL_A 36
38#define BCM43xx_RADIO_DEFAULT_CHANNEL_BG 6
39
40/* Force antenna 0. */
41#define BCM43xx_RADIO_TXANTENNA_0 0
42/* Force antenna 1. */
43#define BCM43xx_RADIO_TXANTENNA_1 1
44/* Use the RX antenna, that was selected for the most recently
45 * received good PLCP header.
46 */
47#define BCM43xx_RADIO_TXANTENNA_LASTPLCP 3
48#define BCM43xx_RADIO_TXANTENNA_DEFAULT BCM43xx_RADIO_TXANTENNA_LASTPLCP
49
50#define BCM43xx_RADIO_INTERFMODE_NONE 0
51#define BCM43xx_RADIO_INTERFMODE_NONWLAN 1
52#define BCM43xx_RADIO_INTERFMODE_MANUALWLAN 2
53#define BCM43xx_RADIO_INTERFMODE_AUTOWLAN 3
54
55
56void bcm43xx_radio_lock(struct bcm43xx_private *bcm);
57void bcm43xx_radio_unlock(struct bcm43xx_private *bcm);
58
59u16 bcm43xx_radio_read16(struct bcm43xx_private *bcm, u16 offset);
60void bcm43xx_radio_write16(struct bcm43xx_private *bcm, u16 offset, u16 val);
61
62u16 bcm43xx_radio_init2050(struct bcm43xx_private *bcm);
63void bcm43xx_radio_init2060(struct bcm43xx_private *bcm);
64
65void bcm43xx_radio_turn_on(struct bcm43xx_private *bcm);
66void bcm43xx_radio_turn_off(struct bcm43xx_private *bcm);
67
68int bcm43xx_radio_selectchannel(struct bcm43xx_private *bcm, u8 channel,
69 int synthetic_pu_workaround);
70
71void bcm43xx_radio_set_txpower_a(struct bcm43xx_private *bcm, u16 txpower);
72void bcm43xx_radio_set_txpower_bg(struct bcm43xx_private *bcm,
73 u16 baseband_attenuation, u16 attenuation,
74 u16 txpower);
75
76u16 bcm43xx_default_baseband_attenuation(struct bcm43xx_private *bcm);
77u16 bcm43xx_default_radio_attenuation(struct bcm43xx_private *bcm);
78u16 bcm43xx_default_txctl1(struct bcm43xx_private *bcm);
79
80void bcm43xx_radio_set_txantenna(struct bcm43xx_private *bcm, u32 val);
81
82void bcm43xx_radio_clear_tssi(struct bcm43xx_private *bcm);
83
84u8 bcm43xx_radio_aci_detect(struct bcm43xx_private *bcm, u8 channel);
85u8 bcm43xx_radio_aci_scan(struct bcm43xx_private *bcm);
86
87int bcm43xx_radio_set_interference_mitigation(struct bcm43xx_private *bcm, int mode);
88
89void bcm43xx_calc_nrssi_slope(struct bcm43xx_private *bcm);
90void bcm43xx_calc_nrssi_threshold(struct bcm43xx_private *bcm);
91s16 bcm43xx_nrssi_hw_read(struct bcm43xx_private *bcm, u16 offset);
92void bcm43xx_nrssi_hw_write(struct bcm43xx_private *bcm, u16 offset, s16 val);
93void bcm43xx_nrssi_hw_update(struct bcm43xx_private *bcm, u16 val);
94void bcm43xx_nrssi_mem_update(struct bcm43xx_private *bcm);
95
96void bcm43xx_radio_set_tx_iq(struct bcm43xx_private *bcm);
97u16 bcm43xx_radio_calibrationvalue(struct bcm43xx_private *bcm);
98
99#endif /* BCM43xx_RADIO_H_ */
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_sysfs.c b/drivers/net/wireless/bcm43xx/bcm43xx_sysfs.c
new file mode 100644
index 000000000000..c44d890b949b
--- /dev/null
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_sysfs.c
@@ -0,0 +1,322 @@
1/*
2
3 Broadcom BCM43xx wireless driver
4
5 SYSFS support routines
6
7 Copyright (c) 2006 Michael Buesch <mbuesch@freenet.de>
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; see the file COPYING. If not, write to
21 the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,
22 Boston, MA 02110-1301, USA.
23
24*/
25
26#include "bcm43xx_sysfs.h"
27#include "bcm43xx.h"
28#include "bcm43xx_main.h"
29#include "bcm43xx_radio.h"
30
31#include <linux/capability.h>
32
33
34#define GENERIC_FILESIZE 64
35
36
37static int get_integer(const char *buf, size_t count)
38{
39 char tmp[10 + 1] = { 0 };
40 int ret = -EINVAL;
41
42 if (count == 0)
43 goto out;
44 count = min(count, (size_t)10);
45 memcpy(tmp, buf, count);
46 ret = simple_strtol(tmp, NULL, 10);
47out:
48 return ret;
49}
50
51static int get_boolean(const char *buf, size_t count)
52{
53 if (count != 0) {
54 if (buf[0] == '1')
55 return 1;
56 if (buf[0] == '0')
57 return 0;
58 if (count >= 4 && memcmp(buf, "true", 4) == 0)
59 return 1;
60 if (count >= 5 && memcmp(buf, "false", 5) == 0)
61 return 0;
62 if (count >= 3 && memcmp(buf, "yes", 3) == 0)
63 return 1;
64 if (count >= 2 && memcmp(buf, "no", 2) == 0)
65 return 0;
66 if (count >= 2 && memcmp(buf, "on", 2) == 0)
67 return 1;
68 if (count >= 3 && memcmp(buf, "off", 3) == 0)
69 return 0;
70 }
71 return -EINVAL;
72}
73
74static ssize_t bcm43xx_attr_sprom_show(struct device *dev,
75 struct device_attribute *attr,
76 char *buf)
77{
78 struct bcm43xx_private *bcm = devattr_to_bcm(attr, attr_sprom);
79 u16 *sprom;
80 unsigned long flags;
81 int i, err;
82
83 if (!capable(CAP_NET_ADMIN))
84 return -EPERM;
85
86 assert(BCM43xx_SPROM_SIZE * sizeof(u16) <= PAGE_SIZE);
87 sprom = kmalloc(BCM43xx_SPROM_SIZE * sizeof(*sprom),
88 GFP_KERNEL);
89 if (!sprom)
90 return -ENOMEM;
91 bcm43xx_lock_mmio(bcm, flags);
92 assert(bcm->initialized);
93 err = bcm43xx_sprom_read(bcm, sprom);
94 if (!err) {
95 for (i = 0; i < BCM43xx_SPROM_SIZE; i++) {
96 buf[i * 2] = sprom[i] & 0x00FF;
97 buf[i * 2 + 1] = (sprom[i] & 0xFF00) >> 8;
98 }
99 }
100 bcm43xx_unlock_mmio(bcm, flags);
101 kfree(sprom);
102
103 return err ? err : BCM43xx_SPROM_SIZE * sizeof(u16);
104}
105
106static ssize_t bcm43xx_attr_sprom_store(struct device *dev,
107 struct device_attribute *attr,
108 const char *buf, size_t count)
109{
110 struct bcm43xx_private *bcm = devattr_to_bcm(attr, attr_sprom);
111 u16 *sprom;
112 unsigned long flags;
113 int i, err;
114
115 if (!capable(CAP_NET_ADMIN))
116 return -EPERM;
117
118 if (count != BCM43xx_SPROM_SIZE * sizeof(u16))
119 return -EINVAL;
120 sprom = kmalloc(BCM43xx_SPROM_SIZE * sizeof(*sprom),
121 GFP_KERNEL);
122 if (!sprom)
123 return -ENOMEM;
124 for (i = 0; i < BCM43xx_SPROM_SIZE; i++) {
125 sprom[i] = buf[i * 2] & 0xFF;
126 sprom[i] |= ((u16)(buf[i * 2 + 1] & 0xFF)) << 8;
127 }
128 bcm43xx_lock_mmio(bcm, flags);
129 assert(bcm->initialized);
130 err = bcm43xx_sprom_write(bcm, sprom);
131 bcm43xx_unlock_mmio(bcm, flags);
132 kfree(sprom);
133
134 return err ? err : count;
135
136}
137
138static ssize_t bcm43xx_attr_interfmode_show(struct device *dev,
139 struct device_attribute *attr,
140 char *buf)
141{
142 struct bcm43xx_private *bcm = devattr_to_bcm(attr, attr_interfmode);
143 unsigned long flags;
144 int err;
145 ssize_t count = 0;
146
147 if (!capable(CAP_NET_ADMIN))
148 return -EPERM;
149
150 bcm43xx_lock(bcm, flags);
151 assert(bcm->initialized);
152
153 switch (bcm43xx_current_radio(bcm)->interfmode) {
154 case BCM43xx_RADIO_INTERFMODE_NONE:
155 count = snprintf(buf, PAGE_SIZE, "0 (No Interference Mitigation)\n");
156 break;
157 case BCM43xx_RADIO_INTERFMODE_NONWLAN:
158 count = snprintf(buf, PAGE_SIZE, "1 (Non-WLAN Interference Mitigation)\n");
159 break;
160 case BCM43xx_RADIO_INTERFMODE_MANUALWLAN:
161 count = snprintf(buf, PAGE_SIZE, "2 (WLAN Interference Mitigation)\n");
162 break;
163 default:
164 assert(0);
165 }
166 err = 0;
167
168 bcm43xx_unlock(bcm, flags);
169
170 return err ? err : count;
171
172}
173
174static ssize_t bcm43xx_attr_interfmode_store(struct device *dev,
175 struct device_attribute *attr,
176 const char *buf, size_t count)
177{
178 struct bcm43xx_private *bcm = devattr_to_bcm(attr, attr_interfmode);
179 unsigned long flags;
180 int err;
181 int mode;
182
183 if (!capable(CAP_NET_ADMIN))
184 return -EPERM;
185
186 mode = get_integer(buf, count);
187 switch (mode) {
188 case 0:
189 mode = BCM43xx_RADIO_INTERFMODE_NONE;
190 break;
191 case 1:
192 mode = BCM43xx_RADIO_INTERFMODE_NONWLAN;
193 break;
194 case 2:
195 mode = BCM43xx_RADIO_INTERFMODE_MANUALWLAN;
196 break;
197 case 3:
198 mode = BCM43xx_RADIO_INTERFMODE_AUTOWLAN;
199 break;
200 default:
201 return -EINVAL;
202 }
203
204 bcm43xx_lock_mmio(bcm, flags);
205 assert(bcm->initialized);
206
207 err = bcm43xx_radio_set_interference_mitigation(bcm, mode);
208 if (err) {
209 printk(KERN_ERR PFX "Interference Mitigation not "
210 "supported by device\n");
211 }
212
213 bcm43xx_unlock_mmio(bcm, flags);
214
215 return err ? err : count;
216}
217
218static ssize_t bcm43xx_attr_preamble_show(struct device *dev,
219 struct device_attribute *attr,
220 char *buf)
221{
222 struct bcm43xx_private *bcm = devattr_to_bcm(attr, attr_preamble);
223 unsigned long flags;
224 int err;
225 ssize_t count;
226
227 if (!capable(CAP_NET_ADMIN))
228 return -EPERM;
229
230 bcm43xx_lock(bcm, flags);
231 assert(bcm->initialized);
232
233 if (bcm->short_preamble)
234 count = snprintf(buf, PAGE_SIZE, "1 (Short Preamble enabled)\n");
235 else
236 count = snprintf(buf, PAGE_SIZE, "0 (Short Preamble disabled)\n");
237
238 err = 0;
239 bcm43xx_unlock(bcm, flags);
240
241 return err ? err : count;
242}
243
244static ssize_t bcm43xx_attr_preamble_store(struct device *dev,
245 struct device_attribute *attr,
246 const char *buf, size_t count)
247{
248 struct bcm43xx_private *bcm = devattr_to_bcm(attr, attr_preamble);
249 unsigned long flags;
250 int err;
251 int value;
252
253 if (!capable(CAP_NET_ADMIN))
254 return -EPERM;
255
256 value = get_boolean(buf, count);
257 if (value < 0)
258 return value;
259 bcm43xx_lock(bcm, flags);
260 assert(bcm->initialized);
261
262 bcm->short_preamble = !!value;
263
264 err = 0;
265 bcm43xx_unlock(bcm, flags);
266
267 return err ? err : count;
268}
269
270int bcm43xx_sysfs_register(struct bcm43xx_private *bcm)
271{
272 struct device *dev = &bcm->pci_dev->dev;
273 struct bcm43xx_sysfs *sysfs = &bcm->sysfs;
274 int err;
275
276 assert(bcm->initialized);
277
278 sysfs->attr_sprom.attr.name = "sprom";
279 sysfs->attr_sprom.attr.owner = THIS_MODULE;
280 sysfs->attr_sprom.attr.mode = 0600;
281 sysfs->attr_sprom.show = bcm43xx_attr_sprom_show;
282 sysfs->attr_sprom.store = bcm43xx_attr_sprom_store;
283 err = device_create_file(dev, &sysfs->attr_sprom);
284 if (err)
285 goto out;
286
287 sysfs->attr_interfmode.attr.name = "interference";
288 sysfs->attr_interfmode.attr.owner = THIS_MODULE;
289 sysfs->attr_interfmode.attr.mode = 0600;
290 sysfs->attr_interfmode.show = bcm43xx_attr_interfmode_show;
291 sysfs->attr_interfmode.store = bcm43xx_attr_interfmode_store;
292 err = device_create_file(dev, &sysfs->attr_interfmode);
293 if (err)
294 goto err_remove_sprom;
295
296 sysfs->attr_preamble.attr.name = "shortpreamble";
297 sysfs->attr_preamble.attr.owner = THIS_MODULE;
298 sysfs->attr_preamble.attr.mode = 0600;
299 sysfs->attr_preamble.show = bcm43xx_attr_preamble_show;
300 sysfs->attr_preamble.store = bcm43xx_attr_preamble_store;
301 err = device_create_file(dev, &sysfs->attr_preamble);
302 if (err)
303 goto err_remove_interfmode;
304
305out:
306 return err;
307err_remove_interfmode:
308 device_remove_file(dev, &sysfs->attr_interfmode);
309err_remove_sprom:
310 device_remove_file(dev, &sysfs->attr_sprom);
311 goto out;
312}
313
314void bcm43xx_sysfs_unregister(struct bcm43xx_private *bcm)
315{
316 struct device *dev = &bcm->pci_dev->dev;
317 struct bcm43xx_sysfs *sysfs = &bcm->sysfs;
318
319 device_remove_file(dev, &sysfs->attr_preamble);
320 device_remove_file(dev, &sysfs->attr_interfmode);
321 device_remove_file(dev, &sysfs->attr_sprom);
322}
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_sysfs.h b/drivers/net/wireless/bcm43xx/bcm43xx_sysfs.h
new file mode 100644
index 000000000000..57f14514e3e0
--- /dev/null
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_sysfs.h
@@ -0,0 +1,25 @@
1#ifndef BCM43xx_SYSFS_H_
2#define BCM43xx_SYSFS_H_
3
4#include <linux/device.h>
5
6
7struct bcm43xx_sysfs {
8 struct device_attribute attr_sprom;
9 struct device_attribute attr_interfmode;
10 struct device_attribute attr_preamble;
11};
12
13#define devattr_to_bcm(attr, attr_name) ({ \
14 struct bcm43xx_sysfs *__s; struct bcm43xx_private *__p; \
15 __s = container_of((attr), struct bcm43xx_sysfs, attr_name); \
16 __p = container_of(__s, struct bcm43xx_private, sysfs); \
17 __p; \
18 })
19
20struct bcm43xx_private;
21
22int bcm43xx_sysfs_register(struct bcm43xx_private *bcm);
23void bcm43xx_sysfs_unregister(struct bcm43xx_private *bcm);
24
25#endif /* BCM43xx_SYSFS_H_ */
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_wx.c b/drivers/net/wireless/bcm43xx/bcm43xx_wx.c
new file mode 100644
index 000000000000..3daee828ef4b
--- /dev/null
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_wx.c
@@ -0,0 +1,1002 @@
1/*
2
3 Broadcom BCM43xx wireless driver
4
5 Copyright (c) 2005 Martin Langer <martin-langer@gmx.de>,
6 Stefano Brivio <st3@riseup.net>
7 Michael Buesch <mbuesch@freenet.de>
8 Danny van Dyk <kugelfang@gentoo.org>
9 Andreas Jaggi <andreas.jaggi@waterwave.ch>
10
11 Some parts of the code in this file are derived from the ipw2200
12 driver Copyright(c) 2003 - 2004 Intel Corporation.
13
14 This program is free software; you can redistribute it and/or modify
15 it under the terms of the GNU General Public License as published by
16 the Free Software Foundation; either version 2 of the License, or
17 (at your option) any later version.
18
19 This program is distributed in the hope that it will be useful,
20 but WITHOUT ANY WARRANTY; without even the implied warranty of
21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 GNU General Public License for more details.
23
24 You should have received a copy of the GNU General Public License
25 along with this program; see the file COPYING. If not, write to
26 the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,
27 Boston, MA 02110-1301, USA.
28
29*/
30
31#include <linux/wireless.h>
32#include <net/iw_handler.h>
33#include <net/ieee80211softmac.h>
34#include <net/ieee80211softmac_wx.h>
35#include <linux/capability.h>
36#include <linux/sched.h> /* for capable() */
37#include <linux/delay.h>
38
39#include "bcm43xx.h"
40#include "bcm43xx_wx.h"
41#include "bcm43xx_main.h"
42#include "bcm43xx_radio.h"
43#include "bcm43xx_phy.h"
44
45
46/* The WIRELESS_EXT version, which is implemented by this driver. */
47#define BCM43xx_WX_VERSION 18
48
49#define MAX_WX_STRING 80
50
51
52static int bcm43xx_wx_get_name(struct net_device *net_dev,
53 struct iw_request_info *info,
54 union iwreq_data *data,
55 char *extra)
56{
57 struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
58 unsigned long flags;
59 int i;
60 struct bcm43xx_phyinfo *phy;
61 char suffix[7] = { 0 };
62 int have_a = 0, have_b = 0, have_g = 0;
63
64 bcm43xx_lock(bcm, flags);
65 for (i = 0; i < bcm->nr_80211_available; i++) {
66 phy = &(bcm->core_80211_ext[i].phy);
67 switch (phy->type) {
68 case BCM43xx_PHYTYPE_A:
69 have_a = 1;
70 break;
71 case BCM43xx_PHYTYPE_G:
72 have_g = 1;
73 case BCM43xx_PHYTYPE_B:
74 have_b = 1;
75 break;
76 default:
77 assert(0);
78 }
79 }
80 bcm43xx_unlock(bcm, flags);
81
82 i = 0;
83 if (have_a) {
84 suffix[i++] = 'a';
85 suffix[i++] = '/';
86 }
87 if (have_b) {
88 suffix[i++] = 'b';
89 suffix[i++] = '/';
90 }
91 if (have_g) {
92 suffix[i++] = 'g';
93 suffix[i++] = '/';
94 }
95 if (i != 0)
96 suffix[i - 1] = '\0';
97
98 snprintf(data->name, IFNAMSIZ, "IEEE 802.11%s", suffix);
99
100 return 0;
101}
102
103static int bcm43xx_wx_set_channelfreq(struct net_device *net_dev,
104 struct iw_request_info *info,
105 union iwreq_data *data,
106 char *extra)
107{
108 struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
109 unsigned long flags;
110 u8 channel;
111 int freq;
112 int err = -EINVAL;
113
114 bcm43xx_lock_mmio(bcm, flags);
115 if ((data->freq.m >= 0) && (data->freq.m <= 1000)) {
116 channel = data->freq.m;
117 freq = bcm43xx_channel_to_freq(bcm, channel);
118 } else {
119 channel = bcm43xx_freq_to_channel(bcm, data->freq.m);
120 freq = data->freq.m;
121 }
122 if (!bcm43xx_is_valid_channel(bcm, channel))
123 goto out_unlock;
124 if (bcm->initialized) {
125 //ieee80211softmac_disassoc(softmac, $REASON);
126 bcm43xx_mac_suspend(bcm);
127 err = bcm43xx_radio_selectchannel(bcm, channel, 0);
128 bcm43xx_mac_enable(bcm);
129 } else {
130 bcm43xx_current_radio(bcm)->initial_channel = channel;
131 err = 0;
132 }
133out_unlock:
134 bcm43xx_unlock_mmio(bcm, flags);
135
136 return err;
137}
138
139static int bcm43xx_wx_get_channelfreq(struct net_device *net_dev,
140 struct iw_request_info *info,
141 union iwreq_data *data,
142 char *extra)
143{
144 struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
145 struct bcm43xx_radioinfo *radio;
146 unsigned long flags;
147 int err = -ENODEV;
148 u16 channel;
149
150 bcm43xx_lock(bcm, flags);
151 radio = bcm43xx_current_radio(bcm);
152 channel = radio->channel;
153 if (channel == 0xFF) {
154 assert(!bcm->initialized);
155 channel = radio->initial_channel;
156 if (channel == 0xFF)
157 goto out_unlock;
158 }
159 assert(channel > 0 && channel <= 1000);
160 data->freq.e = 1;
161 data->freq.m = bcm43xx_channel_to_freq(bcm, channel) * 100000;
162 data->freq.flags = 1;
163
164 err = 0;
165out_unlock:
166 bcm43xx_unlock(bcm, flags);
167
168 return err;
169}
170
171static int bcm43xx_wx_set_mode(struct net_device *net_dev,
172 struct iw_request_info *info,
173 union iwreq_data *data,
174 char *extra)
175{
176 struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
177 unsigned long flags;
178 int mode;
179
180 mode = data->mode;
181 if (mode == IW_MODE_AUTO)
182 mode = BCM43xx_INITIAL_IWMODE;
183
184 bcm43xx_lock_mmio(bcm, flags);
185 if (bcm->ieee->iw_mode != mode)
186 bcm43xx_set_iwmode(bcm, mode);
187 bcm43xx_unlock_mmio(bcm, flags);
188
189 return 0;
190}
191
192static int bcm43xx_wx_get_mode(struct net_device *net_dev,
193 struct iw_request_info *info,
194 union iwreq_data *data,
195 char *extra)
196{
197 struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
198 unsigned long flags;
199
200 bcm43xx_lock(bcm, flags);
201 data->mode = bcm->ieee->iw_mode;
202 bcm43xx_unlock(bcm, flags);
203
204 return 0;
205}
206
207static int bcm43xx_wx_get_rangeparams(struct net_device *net_dev,
208 struct iw_request_info *info,
209 union iwreq_data *data,
210 char *extra)
211{
212 struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
213 struct iw_range *range = (struct iw_range *)extra;
214 const struct ieee80211_geo *geo;
215 unsigned long flags;
216 int i, j;
217 struct bcm43xx_phyinfo *phy;
218
219 data->data.length = sizeof(*range);
220 memset(range, 0, sizeof(*range));
221
222 //TODO: What about 802.11b?
223 /* 54Mb/s == ~27Mb/s payload throughput (802.11g) */
224 range->throughput = 27 * 1000 * 1000;
225
226 range->max_qual.qual = 100;
227 /* TODO: Real max RSSI */
228 range->max_qual.level = 3;
229 range->max_qual.noise = 100;
230 range->max_qual.updated = 7;
231
232 range->avg_qual.qual = 70;
233 range->avg_qual.level = 2;
234 range->avg_qual.noise = 40;
235 range->avg_qual.updated = 7;
236
237 range->min_rts = BCM43xx_MIN_RTS_THRESHOLD;
238 range->max_rts = BCM43xx_MAX_RTS_THRESHOLD;
239 range->min_frag = MIN_FRAG_THRESHOLD;
240 range->max_frag = MAX_FRAG_THRESHOLD;
241
242 range->encoding_size[0] = 5;
243 range->encoding_size[1] = 13;
244 range->num_encoding_sizes = 2;
245 range->max_encoding_tokens = WEP_KEYS;
246
247 range->we_version_compiled = WIRELESS_EXT;
248 range->we_version_source = BCM43xx_WX_VERSION;
249
250 range->enc_capa = IW_ENC_CAPA_WPA |
251 IW_ENC_CAPA_WPA2 |
252 IW_ENC_CAPA_CIPHER_TKIP |
253 IW_ENC_CAPA_CIPHER_CCMP;
254
255 bcm43xx_lock(bcm, flags);
256 phy = bcm43xx_current_phy(bcm);
257
258 range->num_bitrates = 0;
259 i = 0;
260 if (phy->type == BCM43xx_PHYTYPE_A ||
261 phy->type == BCM43xx_PHYTYPE_G) {
262 range->num_bitrates = 8;
263 range->bitrate[i++] = IEEE80211_OFDM_RATE_6MB;
264 range->bitrate[i++] = IEEE80211_OFDM_RATE_9MB;
265 range->bitrate[i++] = IEEE80211_OFDM_RATE_12MB;
266 range->bitrate[i++] = IEEE80211_OFDM_RATE_18MB;
267 range->bitrate[i++] = IEEE80211_OFDM_RATE_24MB;
268 range->bitrate[i++] = IEEE80211_OFDM_RATE_36MB;
269 range->bitrate[i++] = IEEE80211_OFDM_RATE_48MB;
270 range->bitrate[i++] = IEEE80211_OFDM_RATE_54MB;
271 }
272 if (phy->type == BCM43xx_PHYTYPE_B ||
273 phy->type == BCM43xx_PHYTYPE_G) {
274 range->num_bitrates += 4;
275 range->bitrate[i++] = IEEE80211_CCK_RATE_1MB;
276 range->bitrate[i++] = IEEE80211_CCK_RATE_2MB;
277 range->bitrate[i++] = IEEE80211_CCK_RATE_5MB;
278 range->bitrate[i++] = IEEE80211_CCK_RATE_11MB;
279 }
280
281 geo = ieee80211_get_geo(bcm->ieee);
282 range->num_channels = geo->a_channels + geo->bg_channels;
283 j = 0;
284 for (i = 0; i < geo->a_channels; i++) {
285 if (j == IW_MAX_FREQUENCIES)
286 break;
287 range->freq[j].i = j + 1;
288 range->freq[j].m = geo->a[i].freq;//FIXME?
289 range->freq[j].e = 1;
290 j++;
291 }
292 for (i = 0; i < geo->bg_channels; i++) {
293 if (j == IW_MAX_FREQUENCIES)
294 break;
295 range->freq[j].i = j + 1;
296 range->freq[j].m = geo->bg[i].freq;//FIXME?
297 range->freq[j].e = 1;
298 j++;
299 }
300 range->num_frequency = j;
301
302 bcm43xx_unlock(bcm, flags);
303
304 return 0;
305}
306
307static int bcm43xx_wx_set_nick(struct net_device *net_dev,
308 struct iw_request_info *info,
309 union iwreq_data *data,
310 char *extra)
311{
312 struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
313 unsigned long flags;
314 size_t len;
315
316 bcm43xx_lock(bcm, flags);
317 len = min((size_t)data->data.length, (size_t)IW_ESSID_MAX_SIZE);
318 memcpy(bcm->nick, extra, len);
319 bcm->nick[len] = '\0';
320 bcm43xx_unlock(bcm, flags);
321
322 return 0;
323}
324
325static int bcm43xx_wx_get_nick(struct net_device *net_dev,
326 struct iw_request_info *info,
327 union iwreq_data *data,
328 char *extra)
329{
330 struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
331 unsigned long flags;
332 size_t len;
333
334 bcm43xx_lock(bcm, flags);
335 len = strlen(bcm->nick) + 1;
336 memcpy(extra, bcm->nick, len);
337 data->data.length = (__u16)len;
338 data->data.flags = 1;
339 bcm43xx_unlock(bcm, flags);
340
341 return 0;
342}
343
344static int bcm43xx_wx_set_rts(struct net_device *net_dev,
345 struct iw_request_info *info,
346 union iwreq_data *data,
347 char *extra)
348{
349 struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
350 unsigned long flags;
351 int err = -EINVAL;
352
353 bcm43xx_lock(bcm, flags);
354 if (data->rts.disabled) {
355 bcm->rts_threshold = BCM43xx_MAX_RTS_THRESHOLD;
356 err = 0;
357 } else {
358 if (data->rts.value >= BCM43xx_MIN_RTS_THRESHOLD &&
359 data->rts.value <= BCM43xx_MAX_RTS_THRESHOLD) {
360 bcm->rts_threshold = data->rts.value;
361 err = 0;
362 }
363 }
364 bcm43xx_unlock(bcm, flags);
365
366 return err;
367}
368
369static int bcm43xx_wx_get_rts(struct net_device *net_dev,
370 struct iw_request_info *info,
371 union iwreq_data *data,
372 char *extra)
373{
374 struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
375 unsigned long flags;
376
377 bcm43xx_lock(bcm, flags);
378 data->rts.value = bcm->rts_threshold;
379 data->rts.fixed = 0;
380 data->rts.disabled = (bcm->rts_threshold == BCM43xx_MAX_RTS_THRESHOLD);
381 bcm43xx_unlock(bcm, flags);
382
383 return 0;
384}
385
386static int bcm43xx_wx_set_frag(struct net_device *net_dev,
387 struct iw_request_info *info,
388 union iwreq_data *data,
389 char *extra)
390{
391 struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
392 unsigned long flags;
393 int err = -EINVAL;
394
395 bcm43xx_lock(bcm, flags);
396 if (data->frag.disabled) {
397 bcm->ieee->fts = MAX_FRAG_THRESHOLD;
398 err = 0;
399 } else {
400 if (data->frag.value >= MIN_FRAG_THRESHOLD &&
401 data->frag.value <= MAX_FRAG_THRESHOLD) {
402 bcm->ieee->fts = data->frag.value & ~0x1;
403 err = 0;
404 }
405 }
406 bcm43xx_unlock(bcm, flags);
407
408 return err;
409}
410
411static int bcm43xx_wx_get_frag(struct net_device *net_dev,
412 struct iw_request_info *info,
413 union iwreq_data *data,
414 char *extra)
415{
416 struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
417 unsigned long flags;
418
419 bcm43xx_lock(bcm, flags);
420 data->frag.value = bcm->ieee->fts;
421 data->frag.fixed = 0;
422 data->frag.disabled = (bcm->ieee->fts == MAX_FRAG_THRESHOLD);
423 bcm43xx_unlock(bcm, flags);
424
425 return 0;
426}
427
428static int bcm43xx_wx_set_xmitpower(struct net_device *net_dev,
429 struct iw_request_info *info,
430 union iwreq_data *data,
431 char *extra)
432{
433 struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
434 struct bcm43xx_radioinfo *radio;
435 struct bcm43xx_phyinfo *phy;
436 unsigned long flags;
437 int err = -ENODEV;
438 u16 maxpower;
439
440 if ((data->txpower.flags & IW_TXPOW_TYPE) != IW_TXPOW_DBM) {
441 printk(PFX KERN_ERR "TX power not in dBm.\n");
442 return -EOPNOTSUPP;
443 }
444
445 bcm43xx_lock_mmio(bcm, flags);
446 if (!bcm->initialized)
447 goto out_unlock;
448 radio = bcm43xx_current_radio(bcm);
449 phy = bcm43xx_current_phy(bcm);
450 if (data->txpower.disabled != (!(radio->enabled))) {
451 if (data->txpower.disabled)
452 bcm43xx_radio_turn_off(bcm);
453 else
454 bcm43xx_radio_turn_on(bcm);
455 }
456 if (data->txpower.value > 0) {
457 /* desired and maxpower dBm values are in Q5.2 */
458 if (phy->type == BCM43xx_PHYTYPE_A)
459 maxpower = bcm->sprom.maxpower_aphy;
460 else
461 maxpower = bcm->sprom.maxpower_bgphy;
462 radio->txpower_desired = limit_value(data->txpower.value << 2,
463 0, maxpower);
464 bcm43xx_phy_xmitpower(bcm);
465 }
466 err = 0;
467
468out_unlock:
469 bcm43xx_unlock_mmio(bcm, flags);
470
471 return err;
472}
473
474static int bcm43xx_wx_get_xmitpower(struct net_device *net_dev,
475 struct iw_request_info *info,
476 union iwreq_data *data,
477 char *extra)
478{
479 struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
480 struct bcm43xx_radioinfo *radio;
481 unsigned long flags;
482 int err = -ENODEV;
483
484 bcm43xx_lock(bcm, flags);
485 if (!bcm->initialized)
486 goto out_unlock;
487 radio = bcm43xx_current_radio(bcm);
488 /* desired dBm value is in Q5.2 */
489 data->txpower.value = radio->txpower_desired >> 2;
490 data->txpower.fixed = 1;
491 data->txpower.flags = IW_TXPOW_DBM;
492 data->txpower.disabled = !(radio->enabled);
493
494 err = 0;
495out_unlock:
496 bcm43xx_unlock(bcm, flags);
497
498 return err;
499}
500
501static int bcm43xx_wx_set_encoding(struct net_device *net_dev,
502 struct iw_request_info *info,
503 union iwreq_data *data,
504 char *extra)
505{
506 struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
507 int err;
508
509 err = ieee80211_wx_set_encode(bcm->ieee, info, data, extra);
510
511 return err;
512}
513
514static int bcm43xx_wx_set_encodingext(struct net_device *net_dev,
515 struct iw_request_info *info,
516 union iwreq_data *data,
517 char *extra)
518{
519 struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
520 int err;
521
522 err = ieee80211_wx_set_encodeext(bcm->ieee, info, data, extra);
523
524 return err;
525}
526
527static int bcm43xx_wx_get_encoding(struct net_device *net_dev,
528 struct iw_request_info *info,
529 union iwreq_data *data,
530 char *extra)
531{
532 struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
533 int err;
534
535 err = ieee80211_wx_get_encode(bcm->ieee, info, data, extra);
536
537 return err;
538}
539
540static int bcm43xx_wx_get_encodingext(struct net_device *net_dev,
541 struct iw_request_info *info,
542 union iwreq_data *data,
543 char *extra)
544{
545 struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
546 int err;
547
548 err = ieee80211_wx_get_encodeext(bcm->ieee, info, data, extra);
549
550 return err;
551}
552
553static int bcm43xx_wx_set_interfmode(struct net_device *net_dev,
554 struct iw_request_info *info,
555 union iwreq_data *data,
556 char *extra)
557{
558 struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
559 unsigned long flags;
560 int mode, err = 0;
561
562 mode = *((int *)extra);
563 switch (mode) {
564 case 0:
565 mode = BCM43xx_RADIO_INTERFMODE_NONE;
566 break;
567 case 1:
568 mode = BCM43xx_RADIO_INTERFMODE_NONWLAN;
569 break;
570 case 2:
571 mode = BCM43xx_RADIO_INTERFMODE_MANUALWLAN;
572 break;
573 case 3:
574 mode = BCM43xx_RADIO_INTERFMODE_AUTOWLAN;
575 break;
576 default:
577 printk(KERN_ERR PFX "set_interfmode allowed parameters are: "
578 "0 => None, 1 => Non-WLAN, 2 => WLAN, "
579 "3 => Auto-WLAN\n");
580 return -EINVAL;
581 }
582
583 bcm43xx_lock_mmio(bcm, flags);
584 if (bcm->initialized) {
585 err = bcm43xx_radio_set_interference_mitigation(bcm, mode);
586 if (err) {
587 printk(KERN_ERR PFX "Interference Mitigation not "
588 "supported by device\n");
589 }
590 } else {
591 if (mode == BCM43xx_RADIO_INTERFMODE_AUTOWLAN) {
592 printk(KERN_ERR PFX "Interference Mitigation mode Auto-WLAN "
593 "not supported while the interface is down.\n");
594 err = -ENODEV;
595 } else
596 bcm43xx_current_radio(bcm)->interfmode = mode;
597 }
598 bcm43xx_unlock_mmio(bcm, flags);
599
600 return err;
601}
602
603static int bcm43xx_wx_get_interfmode(struct net_device *net_dev,
604 struct iw_request_info *info,
605 union iwreq_data *data,
606 char *extra)
607{
608 struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
609 unsigned long flags;
610 int mode;
611
612 bcm43xx_lock(bcm, flags);
613 mode = bcm43xx_current_radio(bcm)->interfmode;
614 bcm43xx_unlock(bcm, flags);
615
616 switch (mode) {
617 case BCM43xx_RADIO_INTERFMODE_NONE:
618 strncpy(extra, "0 (No Interference Mitigation)", MAX_WX_STRING);
619 break;
620 case BCM43xx_RADIO_INTERFMODE_NONWLAN:
621 strncpy(extra, "1 (Non-WLAN Interference Mitigation)", MAX_WX_STRING);
622 break;
623 case BCM43xx_RADIO_INTERFMODE_MANUALWLAN:
624 strncpy(extra, "2 (WLAN Interference Mitigation)", MAX_WX_STRING);
625 break;
626 default:
627 assert(0);
628 }
629 data->data.length = strlen(extra) + 1;
630
631 return 0;
632}
633
634static int bcm43xx_wx_set_shortpreamble(struct net_device *net_dev,
635 struct iw_request_info *info,
636 union iwreq_data *data,
637 char *extra)
638{
639 struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
640 unsigned long flags;
641 int on;
642
643 on = *((int *)extra);
644 bcm43xx_lock(bcm, flags);
645 bcm->short_preamble = !!on;
646 bcm43xx_unlock(bcm, flags);
647
648 return 0;
649}
650
651static int bcm43xx_wx_get_shortpreamble(struct net_device *net_dev,
652 struct iw_request_info *info,
653 union iwreq_data *data,
654 char *extra)
655{
656 struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
657 unsigned long flags;
658 int on;
659
660 bcm43xx_lock(bcm, flags);
661 on = bcm->short_preamble;
662 bcm43xx_unlock(bcm, flags);
663
664 if (on)
665 strncpy(extra, "1 (Short Preamble enabled)", MAX_WX_STRING);
666 else
667 strncpy(extra, "0 (Short Preamble disabled)", MAX_WX_STRING);
668 data->data.length = strlen(extra) + 1;
669
670 return 0;
671}
672
673static int bcm43xx_wx_set_swencryption(struct net_device *net_dev,
674 struct iw_request_info *info,
675 union iwreq_data *data,
676 char *extra)
677{
678 struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
679 unsigned long flags;
680 int on;
681
682 on = *((int *)extra);
683
684 bcm43xx_lock(bcm, flags);
685 bcm->ieee->host_encrypt = !!on;
686 bcm->ieee->host_decrypt = !!on;
687 bcm->ieee->host_build_iv = !on;
688 bcm43xx_unlock(bcm, flags);
689
690 return 0;
691}
692
693static int bcm43xx_wx_get_swencryption(struct net_device *net_dev,
694 struct iw_request_info *info,
695 union iwreq_data *data,
696 char *extra)
697{
698 struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
699 unsigned long flags;
700 int on;
701
702 bcm43xx_lock(bcm, flags);
703 on = bcm->ieee->host_encrypt;
704 bcm43xx_unlock(bcm, flags);
705
706 if (on)
707 strncpy(extra, "1 (SW encryption enabled) ", MAX_WX_STRING);
708 else
709 strncpy(extra, "0 (SW encryption disabled) ", MAX_WX_STRING);
710 data->data.length = strlen(extra + 1);
711
712 return 0;
713}
714
715/* Enough buffer to hold a hexdump of the sprom data. */
716#define SPROM_BUFFERSIZE 512
717
718static int sprom2hex(const u16 *sprom, char *dump)
719{
720 int i, pos = 0;
721
722 for (i = 0; i < BCM43xx_SPROM_SIZE; i++) {
723 pos += snprintf(dump + pos, SPROM_BUFFERSIZE - pos - 1,
724 "%04X", swab16(sprom[i]) & 0xFFFF);
725 }
726
727 return pos + 1;
728}
729
730static int hex2sprom(u16 *sprom, const char *dump, unsigned int len)
731{
732 char tmp[5] = { 0 };
733 int cnt = 0;
734 unsigned long parsed;
735
736 if (len < BCM43xx_SPROM_SIZE * sizeof(u16) * 2)
737 return -EINVAL;
738 while (cnt < BCM43xx_SPROM_SIZE) {
739 memcpy(tmp, dump, 4);
740 dump += 4;
741 parsed = simple_strtoul(tmp, NULL, 16);
742 sprom[cnt++] = swab16((u16)parsed);
743 }
744
745 return 0;
746}
747
748static int bcm43xx_wx_sprom_read(struct net_device *net_dev,
749 struct iw_request_info *info,
750 union iwreq_data *data,
751 char *extra)
752{
753 struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
754 int err = -EPERM;
755 u16 *sprom;
756 unsigned long flags;
757
758 if (!capable(CAP_SYS_RAWIO))
759 goto out;
760
761 err = -ENOMEM;
762 sprom = kmalloc(BCM43xx_SPROM_SIZE * sizeof(*sprom),
763 GFP_KERNEL);
764 if (!sprom)
765 goto out;
766
767 bcm43xx_lock_mmio(bcm, flags);
768 err = -ENODEV;
769 if (bcm->initialized)
770 err = bcm43xx_sprom_read(bcm, sprom);
771 bcm43xx_unlock_mmio(bcm, flags);
772 if (!err)
773 data->data.length = sprom2hex(sprom, extra);
774 kfree(sprom);
775out:
776 return err;
777}
778
779static int bcm43xx_wx_sprom_write(struct net_device *net_dev,
780 struct iw_request_info *info,
781 union iwreq_data *data,
782 char *extra)
783{
784 struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
785 int err = -EPERM;
786 u16 *sprom;
787 unsigned long flags;
788 char *input;
789 unsigned int len;
790
791 if (!capable(CAP_SYS_RAWIO))
792 goto out;
793
794 err = -ENOMEM;
795 sprom = kmalloc(BCM43xx_SPROM_SIZE * sizeof(*sprom),
796 GFP_KERNEL);
797 if (!sprom)
798 goto out;
799
800 len = data->data.length;
801 extra[len - 1] = '\0';
802 input = strchr(extra, ':');
803 if (input) {
804 input++;
805 len -= input - extra;
806 } else
807 input = extra;
808 err = hex2sprom(sprom, input, len);
809 if (err)
810 goto out_kfree;
811
812 bcm43xx_lock_mmio(bcm, flags);
813 err = -ENODEV;
814 if (bcm->initialized)
815 err = bcm43xx_sprom_write(bcm, sprom);
816 bcm43xx_unlock_mmio(bcm, flags);
817out_kfree:
818 kfree(sprom);
819out:
820 return err;
821}
822
823/* Get wireless statistics. Called by /proc/net/wireless and by SIOCGIWSTATS */
824
825static struct iw_statistics *bcm43xx_get_wireless_stats(struct net_device *net_dev)
826{
827 struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
828 struct ieee80211softmac_device *mac = ieee80211_priv(net_dev);
829 struct iw_statistics *wstats;
830
831 wstats = &bcm->stats.wstats;
832 if (!mac->associated) {
833 wstats->miss.beacon = 0;
834// bcm->ieee->ieee_stats.tx_retry_limit_exceeded = 0; // FIXME: should this be cleared here?
835 wstats->discard.retries = 0;
836// bcm->ieee->ieee_stats.tx_discards_wrong_sa = 0; // FIXME: same question
837 wstats->discard.nwid = 0;
838// bcm->ieee->ieee_stats.rx_discards_undecryptable = 0; // FIXME: ditto
839 wstats->discard.code = 0;
840// bcm->ieee->ieee_stats.rx_fragments = 0; // FIXME: same here
841 wstats->discard.fragment = 0;
842 wstats->discard.misc = 0;
843 wstats->qual.qual = 0;
844 wstats->qual.level = 0;
845 wstats->qual.noise = 0;
846 wstats->qual.updated = 7;
847 wstats->qual.updated |= IW_QUAL_NOISE_INVALID |
848 IW_QUAL_QUAL_INVALID | IW_QUAL_LEVEL_INVALID;
849 return wstats;
850 }
851 /* fill in the real statistics when iface associated */
852 wstats->qual.qual = 100; // TODO: get the real signal quality
853 wstats->qual.level = 3 - bcm->stats.link_quality;
854 wstats->qual.noise = bcm->stats.noise;
855 wstats->qual.updated = IW_QUAL_QUAL_UPDATED | IW_QUAL_LEVEL_UPDATED |
856 IW_QUAL_NOISE_UPDATED;
857 wstats->discard.code = bcm->ieee->ieee_stats.rx_discards_undecryptable;
858 wstats->discard.retries = bcm->ieee->ieee_stats.tx_retry_limit_exceeded;
859 wstats->discard.nwid = bcm->ieee->ieee_stats.tx_discards_wrong_sa;
860 wstats->discard.fragment = bcm->ieee->ieee_stats.rx_fragments;
861 wstats->discard.misc = 0; // FIXME
862 wstats->miss.beacon = 0; // FIXME
863 return wstats;
864}
865
866
867#ifdef WX
868# undef WX
869#endif
870#define WX(ioctl) [(ioctl) - SIOCSIWCOMMIT]
871static const iw_handler bcm43xx_wx_handlers[] = {
872 /* Wireless Identification */
873 WX(SIOCGIWNAME) = bcm43xx_wx_get_name,
874 /* Basic operations */
875 WX(SIOCSIWFREQ) = bcm43xx_wx_set_channelfreq,
876 WX(SIOCGIWFREQ) = bcm43xx_wx_get_channelfreq,
877 WX(SIOCSIWMODE) = bcm43xx_wx_set_mode,
878 WX(SIOCGIWMODE) = bcm43xx_wx_get_mode,
879 /* Informative stuff */
880 WX(SIOCGIWRANGE) = bcm43xx_wx_get_rangeparams,
881 /* Access Point manipulation */
882 WX(SIOCSIWAP) = ieee80211softmac_wx_set_wap,
883 WX(SIOCGIWAP) = ieee80211softmac_wx_get_wap,
884 WX(SIOCSIWSCAN) = ieee80211softmac_wx_trigger_scan,
885 WX(SIOCGIWSCAN) = ieee80211softmac_wx_get_scan_results,
886 /* 802.11 specific support */
887 WX(SIOCSIWESSID) = ieee80211softmac_wx_set_essid,
888 WX(SIOCGIWESSID) = ieee80211softmac_wx_get_essid,
889 WX(SIOCSIWNICKN) = bcm43xx_wx_set_nick,
890 WX(SIOCGIWNICKN) = bcm43xx_wx_get_nick,
891 /* Other parameters */
892 WX(SIOCSIWRATE) = ieee80211softmac_wx_set_rate,
893 WX(SIOCGIWRATE) = ieee80211softmac_wx_get_rate,
894 WX(SIOCSIWRTS) = bcm43xx_wx_set_rts,
895 WX(SIOCGIWRTS) = bcm43xx_wx_get_rts,
896 WX(SIOCSIWFRAG) = bcm43xx_wx_set_frag,
897 WX(SIOCGIWFRAG) = bcm43xx_wx_get_frag,
898 WX(SIOCSIWTXPOW) = bcm43xx_wx_set_xmitpower,
899 WX(SIOCGIWTXPOW) = bcm43xx_wx_get_xmitpower,
900//TODO WX(SIOCSIWRETRY) = bcm43xx_wx_set_retry,
901//TODO WX(SIOCGIWRETRY) = bcm43xx_wx_get_retry,
902 /* Encoding */
903 WX(SIOCSIWENCODE) = bcm43xx_wx_set_encoding,
904 WX(SIOCGIWENCODE) = bcm43xx_wx_get_encoding,
905 WX(SIOCSIWENCODEEXT) = bcm43xx_wx_set_encodingext,
906 WX(SIOCGIWENCODEEXT) = bcm43xx_wx_get_encodingext,
907 /* Power saving */
908//TODO WX(SIOCSIWPOWER) = bcm43xx_wx_set_power,
909//TODO WX(SIOCGIWPOWER) = bcm43xx_wx_get_power,
910 WX(SIOCSIWGENIE) = ieee80211softmac_wx_set_genie,
911 WX(SIOCGIWGENIE) = ieee80211softmac_wx_get_genie,
912 WX(SIOCSIWAUTH) = ieee80211_wx_set_auth,
913 WX(SIOCGIWAUTH) = ieee80211_wx_get_auth,
914};
915#undef WX
916
917static const iw_handler bcm43xx_priv_wx_handlers[] = {
918 /* Set Interference Mitigation Mode. */
919 bcm43xx_wx_set_interfmode,
920 /* Get Interference Mitigation Mode. */
921 bcm43xx_wx_get_interfmode,
922 /* Enable/Disable Short Preamble mode. */
923 bcm43xx_wx_set_shortpreamble,
924 /* Get Short Preamble mode. */
925 bcm43xx_wx_get_shortpreamble,
926 /* Enable/Disable Software Encryption mode */
927 bcm43xx_wx_set_swencryption,
928 /* Get Software Encryption mode */
929 bcm43xx_wx_get_swencryption,
930 /* Write SRPROM data. */
931 bcm43xx_wx_sprom_write,
932 /* Read SPROM data. */
933 bcm43xx_wx_sprom_read,
934};
935
936#define PRIV_WX_SET_INTERFMODE (SIOCIWFIRSTPRIV + 0)
937#define PRIV_WX_GET_INTERFMODE (SIOCIWFIRSTPRIV + 1)
938#define PRIV_WX_SET_SHORTPREAMBLE (SIOCIWFIRSTPRIV + 2)
939#define PRIV_WX_GET_SHORTPREAMBLE (SIOCIWFIRSTPRIV + 3)
940#define PRIV_WX_SET_SWENCRYPTION (SIOCIWFIRSTPRIV + 4)
941#define PRIV_WX_GET_SWENCRYPTION (SIOCIWFIRSTPRIV + 5)
942#define PRIV_WX_SPROM_WRITE (SIOCIWFIRSTPRIV + 6)
943#define PRIV_WX_SPROM_READ (SIOCIWFIRSTPRIV + 7)
944
945#define PRIV_WX_DUMMY(ioctl) \
946 { \
947 .cmd = (ioctl), \
948 .name = "__unused" \
949 }
950
951static const struct iw_priv_args bcm43xx_priv_wx_args[] = {
952 {
953 .cmd = PRIV_WX_SET_INTERFMODE,
954 .set_args = IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
955 .name = "set_interfmode",
956 },
957 {
958 .cmd = PRIV_WX_GET_INTERFMODE,
959 .get_args = IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | MAX_WX_STRING,
960 .name = "get_interfmode",
961 },
962 {
963 .cmd = PRIV_WX_SET_SHORTPREAMBLE,
964 .set_args = IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
965 .name = "set_shortpreambl",
966 },
967 {
968 .cmd = PRIV_WX_GET_SHORTPREAMBLE,
969 .get_args = IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | MAX_WX_STRING,
970 .name = "get_shortpreambl",
971 },
972 {
973 .cmd = PRIV_WX_SET_SWENCRYPTION,
974 .set_args = IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
975 .name = "set_swencryption",
976 },
977 {
978 .cmd = PRIV_WX_GET_SWENCRYPTION,
979 .get_args = IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | MAX_WX_STRING,
980 .name = "get_swencryption",
981 },
982 {
983 .cmd = PRIV_WX_SPROM_WRITE,
984 .set_args = IW_PRIV_TYPE_CHAR | SPROM_BUFFERSIZE,
985 .name = "write_sprom",
986 },
987 {
988 .cmd = PRIV_WX_SPROM_READ,
989 .get_args = IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | SPROM_BUFFERSIZE,
990 .name = "read_sprom",
991 },
992};
993
994const struct iw_handler_def bcm43xx_wx_handlers_def = {
995 .standard = bcm43xx_wx_handlers,
996 .num_standard = ARRAY_SIZE(bcm43xx_wx_handlers),
997 .num_private = ARRAY_SIZE(bcm43xx_priv_wx_handlers),
998 .num_private_args = ARRAY_SIZE(bcm43xx_priv_wx_args),
999 .private = bcm43xx_priv_wx_handlers,
1000 .private_args = bcm43xx_priv_wx_args,
1001 .get_wireless_stats = bcm43xx_get_wireless_stats,
1002};
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_wx.h b/drivers/net/wireless/bcm43xx/bcm43xx_wx.h
new file mode 100644
index 000000000000..1f29ff3aa4c3
--- /dev/null
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_wx.h
@@ -0,0 +1,36 @@
1/*
2
3 Broadcom BCM43xx wireless driver
4
5 Copyright (c) 2005 Martin Langer <martin-langer@gmx.de>,
6 Stefano Brivio <st3@riseup.net>
7 Michael Buesch <mbuesch@freenet.de>
8 Danny van Dyk <kugelfang@gentoo.org>
9 Andreas Jaggi <andreas.jaggi@waterwave.ch>
10
11 Some parts of the code in this file are derived from the ipw2200
12 driver Copyright(c) 2003 - 2004 Intel Corporation.
13
14 This program is free software; you can redistribute it and/or modify
15 it under the terms of the GNU General Public License as published by
16 the Free Software Foundation; either version 2 of the License, or
17 (at your option) any later version.
18
19 This program is distributed in the hope that it will be useful,
20 but WITHOUT ANY WARRANTY; without even the implied warranty of
21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 GNU General Public License for more details.
23
24 You should have received a copy of the GNU General Public License
25 along with this program; see the file COPYING. If not, write to
26 the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,
27 Boston, MA 02110-1301, USA.
28
29*/
30
31#ifndef BCM43xx_WX_H_
32#define BCM43xx_WX_H_
33
34extern const struct iw_handler_def bcm43xx_wx_handlers_def;
35
36#endif /* BCM43xx_WX_H_ */
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_xmit.c b/drivers/net/wireless/bcm43xx/bcm43xx_xmit.c
new file mode 100644
index 000000000000..d8ece28c079f
--- /dev/null
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_xmit.c
@@ -0,0 +1,582 @@
1/*
2
3 Broadcom BCM43xx wireless driver
4
5 Transmission (TX/RX) related functions.
6
7 Copyright (c) 2005 Martin Langer <martin-langer@gmx.de>,
8 Stefano Brivio <st3@riseup.net>
9 Michael Buesch <mbuesch@freenet.de>
10 Danny van Dyk <kugelfang@gentoo.org>
11 Andreas Jaggi <andreas.jaggi@waterwave.ch>
12
13 This program is free software; you can redistribute it and/or modify
14 it under the terms of the GNU General Public License as published by
15 the Free Software Foundation; either version 2 of the License, or
16 (at your option) any later version.
17
18 This program is distributed in the hope that it will be useful,
19 but WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 GNU General Public License for more details.
22
23 You should have received a copy of the GNU General Public License
24 along with this program; see the file COPYING. If not, write to
25 the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,
26 Boston, MA 02110-1301, USA.
27
28*/
29
30#include "bcm43xx_xmit.h"
31
32#include <linux/etherdevice.h>
33
34
35/* Extract the bitrate out of a CCK PLCP header. */
36static u8 bcm43xx_plcp_get_bitrate_cck(struct bcm43xx_plcp_hdr4 *plcp)
37{
38 switch (plcp->raw[0]) {
39 case 0x0A:
40 return IEEE80211_CCK_RATE_1MB;
41 case 0x14:
42 return IEEE80211_CCK_RATE_2MB;
43 case 0x37:
44 return IEEE80211_CCK_RATE_5MB;
45 case 0x6E:
46 return IEEE80211_CCK_RATE_11MB;
47 }
48 assert(0);
49 return 0;
50}
51
52/* Extract the bitrate out of an OFDM PLCP header. */
53static u8 bcm43xx_plcp_get_bitrate_ofdm(struct bcm43xx_plcp_hdr4 *plcp)
54{
55 switch (plcp->raw[0] & 0xF) {
56 case 0xB:
57 return IEEE80211_OFDM_RATE_6MB;
58 case 0xF:
59 return IEEE80211_OFDM_RATE_9MB;
60 case 0xA:
61 return IEEE80211_OFDM_RATE_12MB;
62 case 0xE:
63 return IEEE80211_OFDM_RATE_18MB;
64 case 0x9:
65 return IEEE80211_OFDM_RATE_24MB;
66 case 0xD:
67 return IEEE80211_OFDM_RATE_36MB;
68 case 0x8:
69 return IEEE80211_OFDM_RATE_48MB;
70 case 0xC:
71 return IEEE80211_OFDM_RATE_54MB;
72 }
73 assert(0);
74 return 0;
75}
76
77u8 bcm43xx_plcp_get_ratecode_cck(const u8 bitrate)
78{
79 switch (bitrate) {
80 case IEEE80211_CCK_RATE_1MB:
81 return 0x0A;
82 case IEEE80211_CCK_RATE_2MB:
83 return 0x14;
84 case IEEE80211_CCK_RATE_5MB:
85 return 0x37;
86 case IEEE80211_CCK_RATE_11MB:
87 return 0x6E;
88 }
89 assert(0);
90 return 0;
91}
92
93u8 bcm43xx_plcp_get_ratecode_ofdm(const u8 bitrate)
94{
95 switch (bitrate) {
96 case IEEE80211_OFDM_RATE_6MB:
97 return 0xB;
98 case IEEE80211_OFDM_RATE_9MB:
99 return 0xF;
100 case IEEE80211_OFDM_RATE_12MB:
101 return 0xA;
102 case IEEE80211_OFDM_RATE_18MB:
103 return 0xE;
104 case IEEE80211_OFDM_RATE_24MB:
105 return 0x9;
106 case IEEE80211_OFDM_RATE_36MB:
107 return 0xD;
108 case IEEE80211_OFDM_RATE_48MB:
109 return 0x8;
110 case IEEE80211_OFDM_RATE_54MB:
111 return 0xC;
112 }
113 assert(0);
114 return 0;
115}
116
117static void bcm43xx_generate_plcp_hdr(struct bcm43xx_plcp_hdr4 *plcp,
118 const u16 octets, const u8 bitrate,
119 const int ofdm_modulation)
120{
121 __le32 *data = &(plcp->data);
122 __u8 *raw = plcp->raw;
123
124 if (ofdm_modulation) {
125 *data = bcm43xx_plcp_get_ratecode_ofdm(bitrate);
126 assert(!(octets & 0xF000));
127 *data |= (octets << 5);
128 *data = cpu_to_le32(*data);
129 } else {
130 u32 plen;
131
132 plen = octets * 16 / bitrate;
133 if ((octets * 16 % bitrate) > 0) {
134 plen++;
135 if ((bitrate == IEEE80211_CCK_RATE_11MB)
136 && ((octets * 8 % 11) < 4)) {
137 raw[1] = 0x84;
138 } else
139 raw[1] = 0x04;
140 } else
141 raw[1] = 0x04;
142 *data |= cpu_to_le32(plen << 16);
143 raw[0] = bcm43xx_plcp_get_ratecode_cck(bitrate);
144 }
145}
146
147static u8 bcm43xx_calc_fallback_rate(u8 bitrate)
148{
149 switch (bitrate) {
150 case IEEE80211_CCK_RATE_1MB:
151 return IEEE80211_CCK_RATE_1MB;
152 case IEEE80211_CCK_RATE_2MB:
153 return IEEE80211_CCK_RATE_1MB;
154 case IEEE80211_CCK_RATE_5MB:
155 return IEEE80211_CCK_RATE_2MB;
156 case IEEE80211_CCK_RATE_11MB:
157 return IEEE80211_CCK_RATE_5MB;
158 case IEEE80211_OFDM_RATE_6MB:
159 return IEEE80211_CCK_RATE_5MB;
160 case IEEE80211_OFDM_RATE_9MB:
161 return IEEE80211_OFDM_RATE_6MB;
162 case IEEE80211_OFDM_RATE_12MB:
163 return IEEE80211_OFDM_RATE_9MB;
164 case IEEE80211_OFDM_RATE_18MB:
165 return IEEE80211_OFDM_RATE_12MB;
166 case IEEE80211_OFDM_RATE_24MB:
167 return IEEE80211_OFDM_RATE_18MB;
168 case IEEE80211_OFDM_RATE_36MB:
169 return IEEE80211_OFDM_RATE_24MB;
170 case IEEE80211_OFDM_RATE_48MB:
171 return IEEE80211_OFDM_RATE_36MB;
172 case IEEE80211_OFDM_RATE_54MB:
173 return IEEE80211_OFDM_RATE_48MB;
174 }
175 assert(0);
176 return 0;
177}
178
179static
180__le16 bcm43xx_calc_duration_id(const struct ieee80211_hdr *wireless_header,
181 u8 bitrate)
182{
183 const u16 frame_ctl = le16_to_cpu(wireless_header->frame_ctl);
184 __le16 duration_id = wireless_header->duration_id;
185
186 switch (WLAN_FC_GET_TYPE(frame_ctl)) {
187 case IEEE80211_FTYPE_DATA:
188 case IEEE80211_FTYPE_MGMT:
189 //TODO: Steal the code from ieee80211, once it is completed there.
190 break;
191 case IEEE80211_FTYPE_CTL:
192 /* Use the original duration/id. */
193 break;
194 default:
195 assert(0);
196 }
197
198 return duration_id;
199}
200
201static inline
202u16 ceiling_div(u16 dividend, u16 divisor)
203{
204 return ((dividend + divisor - 1) / divisor);
205}
206
207static void bcm43xx_generate_rts(const struct bcm43xx_phyinfo *phy,
208 struct bcm43xx_txhdr *txhdr,
209 u16 *flags,
210 u8 bitrate,
211 const struct ieee80211_hdr_4addr *wlhdr)
212{
213 u16 fctl;
214 u16 dur;
215 u8 fallback_bitrate;
216 int ofdm_modulation;
217 int fallback_ofdm_modulation;
218// u8 *sa, *da;
219 u16 flen;
220
221//FIXME sa = ieee80211_get_SA((struct ieee80211_hdr *)wlhdr);
222//FIXME da = ieee80211_get_DA((struct ieee80211_hdr *)wlhdr);
223 fallback_bitrate = bcm43xx_calc_fallback_rate(bitrate);
224 ofdm_modulation = !(ieee80211_is_cck_rate(bitrate));
225 fallback_ofdm_modulation = !(ieee80211_is_cck_rate(fallback_bitrate));
226
227 flen = sizeof(u16) + sizeof(u16) + ETH_ALEN + ETH_ALEN + IEEE80211_FCS_LEN,
228 bcm43xx_generate_plcp_hdr((struct bcm43xx_plcp_hdr4 *)(&txhdr->rts_cts_plcp),
229 flen, bitrate,
230 !ieee80211_is_cck_rate(bitrate));
231 bcm43xx_generate_plcp_hdr((struct bcm43xx_plcp_hdr4 *)(&txhdr->rts_cts_fallback_plcp),
232 flen, fallback_bitrate,
233 !ieee80211_is_cck_rate(fallback_bitrate));
234 fctl = IEEE80211_FTYPE_CTL;
235 fctl |= IEEE80211_STYPE_RTS;
236 dur = le16_to_cpu(wlhdr->duration_id);
237/*FIXME: should we test for dur==0 here and let it unmodified in this case?
238 * The following assert checks for this case...
239 */
240assert(dur);
241/*FIXME: The duration calculation is not really correct.
242 * I am not 100% sure which bitrate to use. We use the RTS rate here,
243 * but this is likely to be wrong.
244 */
245 if (phy->type == BCM43xx_PHYTYPE_A) {
246 /* Three times SIFS */
247 dur += 16 * 3;
248 /* Add ACK duration. */
249 dur += ceiling_div((16 + 8 * (14 /*bytes*/) + 6) * 10,
250 bitrate * 4);
251 /* Add CTS duration. */
252 dur += ceiling_div((16 + 8 * (14 /*bytes*/) + 6) * 10,
253 bitrate * 4);
254 } else {
255 /* Three times SIFS */
256 dur += 10 * 3;
257 /* Add ACK duration. */
258 dur += ceiling_div(8 * (14 /*bytes*/) * 10,
259 bitrate);
260 /* Add CTS duration. */
261 dur += ceiling_div(8 * (14 /*bytes*/) * 10,
262 bitrate);
263 }
264
265 txhdr->rts_cts_frame_control = cpu_to_le16(fctl);
266 txhdr->rts_cts_dur = cpu_to_le16(dur);
267//printk(BCM43xx_MACFMT " " BCM43xx_MACFMT " " BCM43xx_MACFMT "\n", BCM43xx_MACARG(wlhdr->addr1), BCM43xx_MACARG(wlhdr->addr2), BCM43xx_MACARG(wlhdr->addr3));
268//printk(BCM43xx_MACFMT " " BCM43xx_MACFMT "\n", BCM43xx_MACARG(sa), BCM43xx_MACARG(da));
269 memcpy(txhdr->rts_cts_mac1, wlhdr->addr1, ETH_ALEN);//FIXME!
270// memcpy(txhdr->rts_cts_mac2, sa, ETH_ALEN);
271
272 *flags |= BCM43xx_TXHDRFLAG_RTSCTS;
273 *flags |= BCM43xx_TXHDRFLAG_RTS;
274 if (ofdm_modulation)
275 *flags |= BCM43xx_TXHDRFLAG_RTSCTS_OFDM;
276 if (fallback_ofdm_modulation)
277 *flags |= BCM43xx_TXHDRFLAG_RTSCTSFALLBACK_OFDM;
278}
279
280void bcm43xx_generate_txhdr(struct bcm43xx_private *bcm,
281 struct bcm43xx_txhdr *txhdr,
282 const unsigned char *fragment_data,
283 const unsigned int fragment_len,
284 const int is_first_fragment,
285 const u16 cookie)
286{
287 const struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
288 const struct ieee80211_hdr_4addr *wireless_header = (const struct ieee80211_hdr_4addr *)fragment_data;
289 const struct ieee80211_security *secinfo = &bcm->ieee->sec;
290 u8 bitrate;
291 u8 fallback_bitrate;
292 int ofdm_modulation;
293 int fallback_ofdm_modulation;
294 u16 plcp_fragment_len = fragment_len;
295 u16 flags = 0;
296 u16 control = 0;
297 u16 wsec_rate = 0;
298 u16 encrypt_frame;
299
300 /* Now construct the TX header. */
301 memset(txhdr, 0, sizeof(*txhdr));
302
303 bitrate = bcm->softmac->txrates.default_rate;
304 ofdm_modulation = !(ieee80211_is_cck_rate(bitrate));
305 fallback_bitrate = bcm43xx_calc_fallback_rate(bitrate);
306 fallback_ofdm_modulation = !(ieee80211_is_cck_rate(fallback_bitrate));
307
308 /* Set Frame Control from 80211 header. */
309 txhdr->frame_control = wireless_header->frame_ctl;
310 /* Copy address1 from 80211 header. */
311 memcpy(txhdr->mac1, wireless_header->addr1, 6);
312 /* Set the fallback duration ID. */
313 txhdr->fallback_dur_id = bcm43xx_calc_duration_id((const struct ieee80211_hdr *)wireless_header,
314 fallback_bitrate);
315 /* Set the cookie (used as driver internal ID for the frame) */
316 txhdr->cookie = cpu_to_le16(cookie);
317
318 /* Hardware appends FCS. */
319 plcp_fragment_len += IEEE80211_FCS_LEN;
320
321 /* Hardware encryption. */
322 encrypt_frame = le16_to_cpup(&wireless_header->frame_ctl) & IEEE80211_FCTL_PROTECTED;
323 if (encrypt_frame && !bcm->ieee->host_encrypt) {
324 const struct ieee80211_hdr_3addr *hdr = (struct ieee80211_hdr_3addr *)wireless_header;
325 memcpy(txhdr->wep_iv, hdr->payload, 4);
326 /* Hardware appends ICV. */
327 plcp_fragment_len += 4;
328
329 wsec_rate |= (bcm->key[secinfo->active_key].algorithm << BCM43xx_TXHDR_WSEC_ALGO_SHIFT)
330 & BCM43xx_TXHDR_WSEC_ALGO_MASK;
331 wsec_rate |= (secinfo->active_key << BCM43xx_TXHDR_WSEC_KEYINDEX_SHIFT)
332 & BCM43xx_TXHDR_WSEC_KEYINDEX_MASK;
333 }
334
335 /* Generate the PLCP header and the fallback PLCP header. */
336 bcm43xx_generate_plcp_hdr((struct bcm43xx_plcp_hdr4 *)(&txhdr->plcp),
337 plcp_fragment_len,
338 bitrate, ofdm_modulation);
339 bcm43xx_generate_plcp_hdr(&txhdr->fallback_plcp, plcp_fragment_len,
340 fallback_bitrate, fallback_ofdm_modulation);
341
342 /* Set the CONTROL field */
343 if (ofdm_modulation)
344 control |= BCM43xx_TXHDRCTL_OFDM;
345 if (bcm->short_preamble) //FIXME: could be the other way around, please test
346 control |= BCM43xx_TXHDRCTL_SHORT_PREAMBLE;
347 control |= (phy->antenna_diversity << BCM43xx_TXHDRCTL_ANTENNADIV_SHIFT)
348 & BCM43xx_TXHDRCTL_ANTENNADIV_MASK;
349
350 /* Set the FLAGS field */
351 if (!is_multicast_ether_addr(wireless_header->addr1) &&
352 !is_broadcast_ether_addr(wireless_header->addr1))
353 flags |= BCM43xx_TXHDRFLAG_EXPECTACK;
354 if (1 /* FIXME: PS poll?? */)
355 flags |= 0x10; // FIXME: unknown meaning.
356 if (fallback_ofdm_modulation)
357 flags |= BCM43xx_TXHDRFLAG_FALLBACKOFDM;
358 if (is_first_fragment)
359 flags |= BCM43xx_TXHDRFLAG_FIRSTFRAGMENT;
360
361 /* Set WSEC/RATE field */
362 wsec_rate |= (txhdr->plcp.raw[0] << BCM43xx_TXHDR_RATE_SHIFT)
363 & BCM43xx_TXHDR_RATE_MASK;
364
365 /* Generate the RTS/CTS packet, if required. */
366 /* FIXME: We should first try with CTS-to-self,
367 * if we are on 80211g. If we get too many
368 * failures (hidden nodes), we should switch back to RTS/CTS.
369 */
370 if (0/*FIXME txctl->use_rts_cts*/) {
371 bcm43xx_generate_rts(phy, txhdr, &flags,
372 0/*FIXME txctl->rts_cts_rate*/,
373 wireless_header);
374 }
375
376 txhdr->flags = cpu_to_le16(flags);
377 txhdr->control = cpu_to_le16(control);
378 txhdr->wsec_rate = cpu_to_le16(wsec_rate);
379}
380
381static s8 bcm43xx_rssi_postprocess(struct bcm43xx_private *bcm,
382 u8 in_rssi, int ofdm,
383 int adjust_2053, int adjust_2050)
384{
385 struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm);
386 struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
387 s32 tmp;
388
389 switch (radio->version) {
390 case 0x2050:
391 if (ofdm) {
392 tmp = in_rssi;
393 if (tmp > 127)
394 tmp -= 256;
395 tmp *= 73;
396 tmp /= 64;
397 if (adjust_2050)
398 tmp += 25;
399 else
400 tmp -= 3;
401 } else {
402 if (bcm->sprom.boardflags & BCM43xx_BFL_RSSI) {
403 if (in_rssi > 63)
404 in_rssi = 63;
405 tmp = radio->nrssi_lt[in_rssi];
406 tmp = 31 - tmp;
407 tmp *= -131;
408 tmp /= 128;
409 tmp -= 57;
410 } else {
411 tmp = in_rssi;
412 tmp = 31 - tmp;
413 tmp *= -149;
414 tmp /= 128;
415 tmp -= 68;
416 }
417 if (phy->type == BCM43xx_PHYTYPE_G &&
418 adjust_2050)
419 tmp += 25;
420 }
421 break;
422 case 0x2060:
423 if (in_rssi > 127)
424 tmp = in_rssi - 256;
425 else
426 tmp = in_rssi;
427 break;
428 default:
429 tmp = in_rssi;
430 tmp -= 11;
431 tmp *= 103;
432 tmp /= 64;
433 if (adjust_2053)
434 tmp -= 109;
435 else
436 tmp -= 83;
437 }
438
439 return (s8)tmp;
440}
441
442//TODO
443#if 0
444static s8 bcm43xx_rssinoise_postprocess(struct bcm43xx_private *bcm,
445 u8 in_rssi)
446{
447 struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
448 s8 ret;
449
450 if (phy->type == BCM43xx_PHYTYPE_A) {
451 //TODO: Incomplete specs.
452 ret = 0;
453 } else
454 ret = bcm43xx_rssi_postprocess(bcm, in_rssi, 0, 1, 1);
455
456 return ret;
457}
458#endif
459
460int bcm43xx_rx(struct bcm43xx_private *bcm,
461 struct sk_buff *skb,
462 struct bcm43xx_rxhdr *rxhdr)
463{
464 struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm);
465 struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
466 struct bcm43xx_plcp_hdr4 *plcp;
467 struct ieee80211_rx_stats stats;
468 struct ieee80211_hdr_4addr *wlhdr;
469 u16 frame_ctl;
470 int is_packet_for_us = 0;
471 int err = -EINVAL;
472 const u16 rxflags1 = le16_to_cpu(rxhdr->flags1);
473 const u16 rxflags2 = le16_to_cpu(rxhdr->flags2);
474 const u16 rxflags3 = le16_to_cpu(rxhdr->flags3);
475 const int is_ofdm = !!(rxflags1 & BCM43xx_RXHDR_FLAGS1_OFDM);
476
477 if (rxflags2 & BCM43xx_RXHDR_FLAGS2_TYPE2FRAME) {
478 plcp = (struct bcm43xx_plcp_hdr4 *)(skb->data + 2);
479 /* Skip two unknown bytes and the PLCP header. */
480 skb_pull(skb, 2 + sizeof(struct bcm43xx_plcp_hdr6));
481 } else {
482 plcp = (struct bcm43xx_plcp_hdr4 *)(skb->data);
483 /* Skip the PLCP header. */
484 skb_pull(skb, sizeof(struct bcm43xx_plcp_hdr6));
485 }
486 /* The SKB contains the PAYLOAD (wireless header + data)
487 * at this point. The FCS at the end is stripped.
488 */
489
490 memset(&stats, 0, sizeof(stats));
491 stats.mac_time = le16_to_cpu(rxhdr->mactime);
492 stats.rssi = bcm43xx_rssi_postprocess(bcm, rxhdr->rssi, is_ofdm,
493 !!(rxflags1 & BCM43xx_RXHDR_FLAGS1_2053RSSIADJ),
494 !!(rxflags3 & BCM43xx_RXHDR_FLAGS3_2050RSSIADJ));
495 stats.signal = rxhdr->signal_quality; //FIXME
496//TODO stats.noise =
497 if (is_ofdm)
498 stats.rate = bcm43xx_plcp_get_bitrate_ofdm(plcp);
499 else
500 stats.rate = bcm43xx_plcp_get_bitrate_cck(plcp);
501//printk("RX ofdm %d, rate == %u\n", is_ofdm, stats.rate);
502 stats.received_channel = radio->channel;
503//TODO stats.control =
504 stats.mask = IEEE80211_STATMASK_SIGNAL |
505//TODO IEEE80211_STATMASK_NOISE |
506 IEEE80211_STATMASK_RATE |
507 IEEE80211_STATMASK_RSSI;
508 if (phy->type == BCM43xx_PHYTYPE_A)
509 stats.freq = IEEE80211_52GHZ_BAND;
510 else
511 stats.freq = IEEE80211_24GHZ_BAND;
512 stats.len = skb->len;
513
514 bcm->stats.last_rx = jiffies;
515 if (bcm->ieee->iw_mode == IW_MODE_MONITOR) {
516 err = ieee80211_rx(bcm->ieee, skb, &stats);
517 return (err == 0) ? -EINVAL : 0;
518 }
519
520 wlhdr = (struct ieee80211_hdr_4addr *)(skb->data);
521
522 switch (bcm->ieee->iw_mode) {
523 case IW_MODE_ADHOC:
524 if (memcmp(wlhdr->addr1, bcm->net_dev->dev_addr, ETH_ALEN) == 0 ||
525 memcmp(wlhdr->addr3, bcm->ieee->bssid, ETH_ALEN) == 0 ||
526 is_broadcast_ether_addr(wlhdr->addr1) ||
527 is_multicast_ether_addr(wlhdr->addr1) ||
528 bcm->net_dev->flags & IFF_PROMISC)
529 is_packet_for_us = 1;
530 break;
531 case IW_MODE_INFRA:
532 default:
533 /* When receiving multicast or broadcast packets, filter out
534 the packets we send ourself; we shouldn't see those */
535 if (memcmp(wlhdr->addr3, bcm->ieee->bssid, ETH_ALEN) == 0 ||
536 memcmp(wlhdr->addr1, bcm->net_dev->dev_addr, ETH_ALEN) == 0 ||
537 (memcmp(wlhdr->addr3, bcm->net_dev->dev_addr, ETH_ALEN) &&
538 (is_broadcast_ether_addr(wlhdr->addr1) ||
539 is_multicast_ether_addr(wlhdr->addr1) ||
540 bcm->net_dev->flags & IFF_PROMISC)))
541 is_packet_for_us = 1;
542 break;
543 }
544
545 frame_ctl = le16_to_cpu(wlhdr->frame_ctl);
546 if ((frame_ctl & IEEE80211_FCTL_PROTECTED) && !bcm->ieee->host_decrypt) {
547 frame_ctl &= ~IEEE80211_FCTL_PROTECTED;
548 wlhdr->frame_ctl = cpu_to_le16(frame_ctl);
549 /* trim IV and ICV */
550 /* FIXME: this must be done only for WEP encrypted packets */
551 if (skb->len < 32) {
552 dprintkl(KERN_ERR PFX "RX packet dropped (PROTECTED flag "
553 "set and length < 32)\n");
554 return -EINVAL;
555 } else {
556 memmove(skb->data + 4, skb->data, 24);
557 skb_pull(skb, 4);
558 skb_trim(skb, skb->len - 4);
559 stats.len -= 8;
560 }
561 wlhdr = (struct ieee80211_hdr_4addr *)(skb->data);
562 }
563
564 switch (WLAN_FC_GET_TYPE(frame_ctl)) {
565 case IEEE80211_FTYPE_MGMT:
566 ieee80211_rx_mgt(bcm->ieee, wlhdr, &stats);
567 break;
568 case IEEE80211_FTYPE_DATA:
569 if (is_packet_for_us) {
570 err = ieee80211_rx(bcm->ieee, skb, &stats);
571 err = (err == 0) ? -EINVAL : 0;
572 }
573 break;
574 case IEEE80211_FTYPE_CTL:
575 break;
576 default:
577 assert(0);
578 return -EINVAL;
579 }
580
581 return err;
582}
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_xmit.h b/drivers/net/wireless/bcm43xx/bcm43xx_xmit.h
new file mode 100644
index 000000000000..2aed19e35c77
--- /dev/null
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_xmit.h
@@ -0,0 +1,156 @@
1#ifndef BCM43xx_XMIT_H_
2#define BCM43xx_XMIT_H_
3
4#include "bcm43xx_main.h"
5
6
7#define _bcm43xx_declare_plcp_hdr(size) \
8 struct bcm43xx_plcp_hdr##size { \
9 union { \
10 __le32 data; \
11 __u8 raw[size]; \
12 } __attribute__((__packed__)); \
13 } __attribute__((__packed__))
14
15/* struct bcm43xx_plcp_hdr4 */
16_bcm43xx_declare_plcp_hdr(4);
17/* struct bcm43xx_plcp_hdr6 */
18_bcm43xx_declare_plcp_hdr(6);
19
20#undef _bcm43xx_declare_plcp_hdr
21
22/* Device specific TX header. To be prepended to TX frames. */
23struct bcm43xx_txhdr {
24 union {
25 struct {
26 __le16 flags;
27 __le16 wsec_rate;
28 __le16 frame_control;
29 u16 unknown_zeroed_0;
30 __le16 control;
31 u8 wep_iv[10];
32 u8 unknown_wsec_tkip_data[3]; //FIXME
33 PAD_BYTES(3);
34 u8 mac1[6];
35 u16 unknown_zeroed_1;
36 struct bcm43xx_plcp_hdr4 rts_cts_fallback_plcp;
37 __le16 rts_cts_dur_fallback;
38 struct bcm43xx_plcp_hdr4 fallback_plcp;
39 __le16 fallback_dur_id;
40 PAD_BYTES(2);
41 __le16 cookie;
42 __le16 unknown_scb_stuff; //FIXME
43 struct bcm43xx_plcp_hdr6 rts_cts_plcp;
44 __le16 rts_cts_frame_control;
45 __le16 rts_cts_dur;
46 u8 rts_cts_mac1[6];
47 u8 rts_cts_mac2[6];
48 PAD_BYTES(2);
49 struct bcm43xx_plcp_hdr6 plcp;
50 } __attribute__((__packed__));
51 u8 raw[82];
52 } __attribute__((__packed__));
53} __attribute__((__packed__));
54
55/* Values/Masks for the device TX header */
56#define BCM43xx_TXHDRFLAG_EXPECTACK 0x0001
57#define BCM43xx_TXHDRFLAG_RTSCTS 0x0002
58#define BCM43xx_TXHDRFLAG_RTS 0x0004
59#define BCM43xx_TXHDRFLAG_FIRSTFRAGMENT 0x0008
60#define BCM43xx_TXHDRFLAG_DESTPSMODE 0x0020
61#define BCM43xx_TXHDRFLAG_RTSCTS_OFDM 0x0080
62#define BCM43xx_TXHDRFLAG_FALLBACKOFDM 0x0100
63#define BCM43xx_TXHDRFLAG_RTSCTSFALLBACK_OFDM 0x0200
64#define BCM43xx_TXHDRFLAG_CTS 0x0400
65#define BCM43xx_TXHDRFLAG_FRAMEBURST 0x0800
66
67#define BCM43xx_TXHDRCTL_OFDM 0x0001
68#define BCM43xx_TXHDRCTL_SHORT_PREAMBLE 0x0010
69#define BCM43xx_TXHDRCTL_ANTENNADIV_MASK 0x0030
70#define BCM43xx_TXHDRCTL_ANTENNADIV_SHIFT 8
71
72#define BCM43xx_TXHDR_RATE_MASK 0x0F00
73#define BCM43xx_TXHDR_RATE_SHIFT 8
74#define BCM43xx_TXHDR_RTSRATE_MASK 0xF000
75#define BCM43xx_TXHDR_RTSRATE_SHIFT 12
76#define BCM43xx_TXHDR_WSEC_KEYINDEX_MASK 0x00F0
77#define BCM43xx_TXHDR_WSEC_KEYINDEX_SHIFT 4
78#define BCM43xx_TXHDR_WSEC_ALGO_MASK 0x0003
79#define BCM43xx_TXHDR_WSEC_ALGO_SHIFT 0
80
81void bcm43xx_generate_txhdr(struct bcm43xx_private *bcm,
82 struct bcm43xx_txhdr *txhdr,
83 const unsigned char *fragment_data,
84 const unsigned int fragment_len,
85 const int is_first_fragment,
86 const u16 cookie);
87
88/* RX header as received from the hardware. */
89struct bcm43xx_rxhdr {
90 /* Frame Length. Must be generated explicitely in PIO mode. */
91 __le16 frame_length;
92 PAD_BYTES(2);
93 /* Flags field 1 */
94 __le16 flags1;
95 u8 rssi;
96 u8 signal_quality;
97 PAD_BYTES(2);
98 /* Flags field 3 */
99 __le16 flags3;
100 /* Flags field 2 */
101 __le16 flags2;
102 /* Lower 16bits of the TSF at the time the frame started. */
103 __le16 mactime;
104 PAD_BYTES(14);
105} __attribute__((__packed__));
106
107#define BCM43xx_RXHDR_FLAGS1_OFDM (1 << 0)
108/*#define BCM43xx_RXHDR_FLAGS1_SIGNAL??? (1 << 3) FIXME */
109#define BCM43xx_RXHDR_FLAGS1_SHORTPREAMBLE (1 << 7)
110#define BCM43xx_RXHDR_FLAGS1_2053RSSIADJ (1 << 14)
111
112#define BCM43xx_RXHDR_FLAGS2_INVALIDFRAME (1 << 0)
113#define BCM43xx_RXHDR_FLAGS2_TYPE2FRAME (1 << 2)
114/*FIXME: WEP related flags */
115
116#define BCM43xx_RXHDR_FLAGS3_2050RSSIADJ (1 << 10)
117
118/* Transmit Status as received from the hardware. */
119struct bcm43xx_hwxmitstatus {
120 PAD_BYTES(4);
121 __le16 cookie;
122 u8 flags;
123 u8 cnt1:4,
124 cnt2:4;
125 PAD_BYTES(2);
126 __le16 seq;
127 __le16 unknown; //FIXME
128} __attribute__((__packed__));
129
130/* Transmit Status in CPU byteorder. */
131struct bcm43xx_xmitstatus {
132 u16 cookie;
133 u8 flags;
134 u8 cnt1:4,
135 cnt2:4;
136 u16 seq;
137 u16 unknown; //FIXME
138};
139
140#define BCM43xx_TXSTAT_FLAG_ACK 0x01
141//TODO #define BCM43xx_TXSTAT_FLAG_??? 0x02
142//TODO #define BCM43xx_TXSTAT_FLAG_??? 0x04
143//TODO #define BCM43xx_TXSTAT_FLAG_??? 0x08
144//TODO #define BCM43xx_TXSTAT_FLAG_??? 0x10
145#define BCM43xx_TXSTAT_FLAG_IGNORE 0x20
146//TODO #define BCM43xx_TXSTAT_FLAG_??? 0x40
147//TODO #define BCM43xx_TXSTAT_FLAG_??? 0x80
148
149u8 bcm43xx_plcp_get_ratecode_cck(const u8 bitrate);
150u8 bcm43xx_plcp_get_ratecode_ofdm(const u8 bitrate);
151
152int bcm43xx_rx(struct bcm43xx_private *bcm,
153 struct sk_buff *skb,
154 struct bcm43xx_rxhdr *rxhdr);
155
156#endif /* BCM43xx_XMIT_H_ */
diff --git a/drivers/net/wireless/hostap/hostap_80211.h b/drivers/net/wireless/hostap/hostap_80211.h
index 1fc72fe511e9..cc1ee7f4f5f8 100644
--- a/drivers/net/wireless/hostap/hostap_80211.h
+++ b/drivers/net/wireless/hostap/hostap_80211.h
@@ -92,8 +92,6 @@ void hostap_dump_rx_80211(const char *name, struct sk_buff *skb,
92void hostap_dump_tx_80211(const char *name, struct sk_buff *skb); 92void hostap_dump_tx_80211(const char *name, struct sk_buff *skb);
93int hostap_data_start_xmit(struct sk_buff *skb, struct net_device *dev); 93int hostap_data_start_xmit(struct sk_buff *skb, struct net_device *dev);
94int hostap_mgmt_start_xmit(struct sk_buff *skb, struct net_device *dev); 94int hostap_mgmt_start_xmit(struct sk_buff *skb, struct net_device *dev);
95struct sk_buff * hostap_tx_encrypt(struct sk_buff *skb,
96 struct ieee80211_crypt_data *crypt);
97int hostap_master_start_xmit(struct sk_buff *skb, struct net_device *dev); 95int hostap_master_start_xmit(struct sk_buff *skb, struct net_device *dev);
98 96
99#endif /* HOSTAP_80211_H */ 97#endif /* HOSTAP_80211_H */
diff --git a/drivers/net/wireless/hostap/hostap_80211_tx.c b/drivers/net/wireless/hostap/hostap_80211_tx.c
index 4a85e63906f1..06a5214145e3 100644
--- a/drivers/net/wireless/hostap/hostap_80211_tx.c
+++ b/drivers/net/wireless/hostap/hostap_80211_tx.c
@@ -299,8 +299,8 @@ int hostap_mgmt_start_xmit(struct sk_buff *skb, struct net_device *dev)
299 299
300 300
301/* Called only from software IRQ */ 301/* Called only from software IRQ */
302struct sk_buff * hostap_tx_encrypt(struct sk_buff *skb, 302static struct sk_buff * hostap_tx_encrypt(struct sk_buff *skb,
303 struct ieee80211_crypt_data *crypt) 303 struct ieee80211_crypt_data *crypt)
304{ 304{
305 struct hostap_interface *iface; 305 struct hostap_interface *iface;
306 local_info_t *local; 306 local_info_t *local;
@@ -317,7 +317,7 @@ struct sk_buff * hostap_tx_encrypt(struct sk_buff *skb,
317 } 317 }
318 318
319 if (local->tkip_countermeasures && 319 if (local->tkip_countermeasures &&
320 crypt && crypt->ops && strcmp(crypt->ops->name, "TKIP") == 0) { 320 strcmp(crypt->ops->name, "TKIP") == 0) {
321 hdr = (struct ieee80211_hdr_4addr *) skb->data; 321 hdr = (struct ieee80211_hdr_4addr *) skb->data;
322 if (net_ratelimit()) { 322 if (net_ratelimit()) {
323 printk(KERN_DEBUG "%s: TKIP countermeasures: dropped " 323 printk(KERN_DEBUG "%s: TKIP countermeasures: dropped "
@@ -469,7 +469,7 @@ int hostap_master_start_xmit(struct sk_buff *skb, struct net_device *dev)
469 } 469 }
470 470
471 if (local->ieee_802_1x && meta->ethertype == ETH_P_PAE && tx.crypt && 471 if (local->ieee_802_1x && meta->ethertype == ETH_P_PAE && tx.crypt &&
472 !(fc & IEEE80211_FCTL_VERS)) { 472 !(fc & IEEE80211_FCTL_PROTECTED)) {
473 no_encrypt = 1; 473 no_encrypt = 1;
474 PDEBUG(DEBUG_EXTRA2, "%s: TX: IEEE 802.1X - passing " 474 PDEBUG(DEBUG_EXTRA2, "%s: TX: IEEE 802.1X - passing "
475 "unencrypted EAPOL frame\n", dev->name); 475 "unencrypted EAPOL frame\n", dev->name);
@@ -535,5 +535,4 @@ int hostap_master_start_xmit(struct sk_buff *skb, struct net_device *dev)
535 535
536 536
537EXPORT_SYMBOL(hostap_dump_tx_80211); 537EXPORT_SYMBOL(hostap_dump_tx_80211);
538EXPORT_SYMBOL(hostap_tx_encrypt);
539EXPORT_SYMBOL(hostap_master_start_xmit); 538EXPORT_SYMBOL(hostap_master_start_xmit);
diff --git a/drivers/parisc/ccio-dma.c b/drivers/parisc/ccio-dma.c
index 93f8a8fa8890..a5d826237b26 100644
--- a/drivers/parisc/ccio-dma.c
+++ b/drivers/parisc/ccio-dma.c
@@ -1560,7 +1560,7 @@ static int ccio_probe(struct parisc_device *dev)
1560 *ioc_p = ioc; 1560 *ioc_p = ioc;
1561 1561
1562 ioc->hw_path = dev->hw_path; 1562 ioc->hw_path = dev->hw_path;
1563 ioc->ioc_regs = ioremap(dev->hpa.start, 4096); 1563 ioc->ioc_regs = ioremap_nocache(dev->hpa.start, 4096);
1564 ccio_ioc_init(ioc); 1564 ccio_ioc_init(ioc);
1565 ccio_init_resources(ioc); 1565 ccio_init_resources(ioc);
1566 hppa_dma_ops = &ccio_ops; 1566 hppa_dma_ops = &ccio_ops;
diff --git a/drivers/parisc/dino.c b/drivers/parisc/dino.c
index 3d1a7f98c676..6e8ed0c81a6c 100644
--- a/drivers/parisc/dino.c
+++ b/drivers/parisc/dino.c
@@ -5,6 +5,7 @@
5** (c) Copyright 1999 SuSE GmbH 5** (c) Copyright 1999 SuSE GmbH
6** (c) Copyright 1999,2000 Hewlett-Packard Company 6** (c) Copyright 1999,2000 Hewlett-Packard Company
7** (c) Copyright 2000 Grant Grundler 7** (c) Copyright 2000 Grant Grundler
8** (c) Copyright 2006 Helge Deller
8** 9**
9** This program is free software; you can redistribute it and/or modify 10** This program is free software; you can redistribute it and/or modify
10** it under the terms of the GNU General Public License as published by 11** it under the terms of the GNU General Public License as published by
@@ -785,7 +786,7 @@ dino_bridge_init(struct dino_device *dino_dev, const char *name)
785 if((io_addr & (1 << i)) == 0) 786 if((io_addr & (1 << i)) == 0)
786 continue; 787 continue;
787 788
788 start = (unsigned long)(signed int)(0xf0000000 | (i << 23)); 789 start = F_EXTEND(0xf0000000UL) | (i << 23);
789 end = start + 8 * 1024 * 1024 - 1; 790 end = start + 8 * 1024 * 1024 - 1;
790 791
791 DBG("DINO RANGE %d is at 0x%lx-0x%lx\n", count, 792 DBG("DINO RANGE %d is at 0x%lx-0x%lx\n", count,
@@ -996,7 +997,7 @@ static int __init dino_probe(struct parisc_device *dev)
996 } 997 }
997 998
998 dino_dev->hba.dev = dev; 999 dino_dev->hba.dev = dev;
999 dino_dev->hba.base_addr = ioremap(hpa, 4096); 1000 dino_dev->hba.base_addr = ioremap_nocache(hpa, 4096);
1000 dino_dev->hba.lmmio_space_offset = 0; /* CPU addrs == bus addrs */ 1001 dino_dev->hba.lmmio_space_offset = 0; /* CPU addrs == bus addrs */
1001 spin_lock_init(&dino_dev->dinosaur_pen); 1002 spin_lock_init(&dino_dev->dinosaur_pen);
1002 dino_dev->hba.iommu = ccio_get_iommu(dev); 1003 dino_dev->hba.iommu = ccio_get_iommu(dev);
diff --git a/drivers/parisc/eisa.c b/drivers/parisc/eisa.c
index 3d94d86c1c9f..9d3bd15bf53b 100644
--- a/drivers/parisc/eisa.c
+++ b/drivers/parisc/eisa.c
@@ -366,7 +366,7 @@ static int __devinit eisa_probe(struct parisc_device *dev)
366 eisa_dev.eeprom_addr = MIRAGE_EEPROM_BASE_ADDR; 366 eisa_dev.eeprom_addr = MIRAGE_EEPROM_BASE_ADDR;
367 } 367 }
368 } 368 }
369 eisa_eeprom_addr = ioremap(eisa_dev.eeprom_addr, HPEE_MAX_LENGTH); 369 eisa_eeprom_addr = ioremap_nocache(eisa_dev.eeprom_addr, HPEE_MAX_LENGTH);
370 result = eisa_enumerator(eisa_dev.eeprom_addr, &eisa_dev.hba.io_space, 370 result = eisa_enumerator(eisa_dev.eeprom_addr, &eisa_dev.hba.io_space,
371 &eisa_dev.hba.lmmio_space); 371 &eisa_dev.hba.lmmio_space);
372 init_eisa_pic(); 372 init_eisa_pic();
diff --git a/drivers/parisc/iosapic.c b/drivers/parisc/iosapic.c
index 8d7a36392eb8..7a458d5bc751 100644
--- a/drivers/parisc/iosapic.c
+++ b/drivers/parisc/iosapic.c
@@ -879,7 +879,7 @@ void *iosapic_register(unsigned long hpa)
879 return NULL; 879 return NULL;
880 } 880 }
881 881
882 isi->addr = ioremap(hpa, 4096); 882 isi->addr = ioremap_nocache(hpa, 4096);
883 isi->isi_hpa = hpa; 883 isi->isi_hpa = hpa;
884 isi->isi_version = iosapic_rd_version(isi); 884 isi->isi_version = iosapic_rd_version(isi);
885 isi->isi_num_vectors = IOSAPIC_IRDT_MAX_ENTRY(isi->isi_version) + 1; 885 isi->isi_num_vectors = IOSAPIC_IRDT_MAX_ENTRY(isi->isi_version) + 1;
diff --git a/drivers/parisc/lba_pci.c b/drivers/parisc/lba_pci.c
index e8a2a4a852f5..3fe4a77fa16a 100644
--- a/drivers/parisc/lba_pci.c
+++ b/drivers/parisc/lba_pci.c
@@ -1213,7 +1213,7 @@ lba_pat_resources(struct parisc_device *pa_dev, struct lba_device *lba_dev)
1213 ** Postable I/O port space is per PCI host adapter. 1213 ** Postable I/O port space is per PCI host adapter.
1214 ** base of 64MB PIOP region 1214 ** base of 64MB PIOP region
1215 */ 1215 */
1216 lba_dev->iop_base = ioremap(p->start, 64 * 1024 * 1024); 1216 lba_dev->iop_base = ioremap_nocache(p->start, 64 * 1024 * 1024);
1217 1217
1218 sprintf(lba_dev->hba.io_name, "PCI%02lx Ports", 1218 sprintf(lba_dev->hba.io_name, "PCI%02lx Ports",
1219 lba_dev->hba.bus_num.start); 1219 lba_dev->hba.bus_num.start);
@@ -1525,7 +1525,7 @@ lba_driver_probe(struct parisc_device *dev)
1525 u32 func_class; 1525 u32 func_class;
1526 void *tmp_obj; 1526 void *tmp_obj;
1527 char *version; 1527 char *version;
1528 void __iomem *addr = ioremap(dev->hpa.start, 4096); 1528 void __iomem *addr = ioremap_nocache(dev->hpa.start, 4096);
1529 1529
1530 /* Read HW Rev First */ 1530 /* Read HW Rev First */
1531 func_class = READ_REG32(addr + LBA_FCLASS); 1531 func_class = READ_REG32(addr + LBA_FCLASS);
@@ -1619,7 +1619,7 @@ lba_driver_probe(struct parisc_device *dev)
1619 } else { 1619 } else {
1620 if (!astro_iop_base) { 1620 if (!astro_iop_base) {
1621 /* Sprockets PDC uses NPIOP region */ 1621 /* Sprockets PDC uses NPIOP region */
1622 astro_iop_base = ioremap(LBA_PORT_BASE, 64 * 1024); 1622 astro_iop_base = ioremap_nocache(LBA_PORT_BASE, 64 * 1024);
1623 pci_port = &lba_astro_port_ops; 1623 pci_port = &lba_astro_port_ops;
1624 } 1624 }
1625 1625
@@ -1700,7 +1700,7 @@ void __init lba_init(void)
1700*/ 1700*/
1701void lba_set_iregs(struct parisc_device *lba, u32 ibase, u32 imask) 1701void lba_set_iregs(struct parisc_device *lba, u32 ibase, u32 imask)
1702{ 1702{
1703 void __iomem * base_addr = ioremap(lba->hpa.start, 4096); 1703 void __iomem * base_addr = ioremap_nocache(lba->hpa.start, 4096);
1704 1704
1705 imask <<= 2; /* adjust for hints - 2 more bits */ 1705 imask <<= 2; /* adjust for hints - 2 more bits */
1706 1706
diff --git a/drivers/parisc/pdc_stable.c b/drivers/parisc/pdc_stable.c
index a28e17898fbd..4e53be9c03ab 100644
--- a/drivers/parisc/pdc_stable.c
+++ b/drivers/parisc/pdc_stable.c
@@ -4,9 +4,8 @@
4 * Copyright (C) 2005-2006 Thibaut VARENE <varenet@parisc-linux.org> 4 * Copyright (C) 2005-2006 Thibaut VARENE <varenet@parisc-linux.org>
5 * 5 *
6 * This program is free software; you can redistribute it and/or modify 6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by 7 * it under the terms of the GNU General Public License, version 2, as
8 * the Free Software Foundation; either version 2 of the License, or 8 * published by the Free Software Foundation.
9 * (at your option) any later version.
10 * 9 *
11 * This program is distributed in the hope that it will be useful, 10 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
diff --git a/drivers/parisc/sba_iommu.c b/drivers/parisc/sba_iommu.c
index 0821747e44cf..42b32ff2fca6 100644
--- a/drivers/parisc/sba_iommu.c
+++ b/drivers/parisc/sba_iommu.c
@@ -1642,9 +1642,9 @@ sba_ioc_init(struct parisc_device *sba, struct ioc *ioc, int ioc_num)
1642** 1642**
1643**************************************************************************/ 1643**************************************************************************/
1644 1644
1645static void __iomem *ioc_remap(struct sba_device *sba_dev, int offset) 1645static void __iomem *ioc_remap(struct sba_device *sba_dev, unsigned int offset)
1646{ 1646{
1647 return ioremap(sba_dev->dev->hpa.start + offset, SBA_FUNC_SIZE); 1647 return ioremap_nocache(sba_dev->dev->hpa.start + offset, SBA_FUNC_SIZE);
1648} 1648}
1649 1649
1650static void sba_hw_init(struct sba_device *sba_dev) 1650static void sba_hw_init(struct sba_device *sba_dev)
@@ -2040,7 +2040,7 @@ sba_driver_callback(struct parisc_device *dev)
2040 u32 func_class; 2040 u32 func_class;
2041 int i; 2041 int i;
2042 char *version; 2042 char *version;
2043 void __iomem *sba_addr = ioremap(dev->hpa.start, SBA_FUNC_SIZE); 2043 void __iomem *sba_addr = ioremap_nocache(dev->hpa.start, SBA_FUNC_SIZE);
2044 struct proc_dir_entry *info_entry, *bitmap_entry, *root; 2044 struct proc_dir_entry *info_entry, *bitmap_entry, *root;
2045 2045
2046 sba_dump_ranges(sba_addr); 2046 sba_dump_ranges(sba_addr);
diff --git a/drivers/parisc/superio.c b/drivers/parisc/superio.c
index ad6d3b28a3a6..719b863bc20e 100644
--- a/drivers/parisc/superio.c
+++ b/drivers/parisc/superio.c
@@ -12,6 +12,7 @@
12 * (C) Copyright 2001 John Marvin <jsm fc hp com> 12 * (C) Copyright 2001 John Marvin <jsm fc hp com>
13 * (C) Copyright 2003 Grant Grundler <grundler parisc-linux org> 13 * (C) Copyright 2003 Grant Grundler <grundler parisc-linux org>
14 * (C) Copyright 2005 Kyle McMartin <kyle@parisc-linux.org> 14 * (C) Copyright 2005 Kyle McMartin <kyle@parisc-linux.org>
15 * (C) Copyright 2006 Helge Deller <deller@gmx.de>
15 * 16 *
16 * This program is free software; you can redistribute it and/or 17 * This program is free software; you can redistribute it and/or
17 * modify it under the terms of the GNU General Public License as 18 * modify it under the terms of the GNU General Public License as
@@ -388,43 +389,34 @@ int superio_fixup_irq(struct pci_dev *pcidev)
388 return local_irq; 389 return local_irq;
389} 390}
390 391
391static struct uart_port serial[] = {
392 {
393 .iotype = UPIO_PORT,
394 .line = 0,
395 .type = PORT_16550A,
396 .uartclk = 115200*16,
397 .fifosize = 16,
398 },
399 {
400 .iotype = UPIO_PORT,
401 .line = 1,
402 .type = PORT_16550A,
403 .uartclk = 115200*16,
404 .fifosize = 16,
405 }
406};
407
408static void __devinit superio_serial_init(void) 392static void __devinit superio_serial_init(void)
409{ 393{
410#ifdef CONFIG_SERIAL_8250 394#ifdef CONFIG_SERIAL_8250
411 int retval; 395 int retval;
412 396 struct uart_port serial_port;
413 serial[0].iobase = sio_dev.sp1_base; 397
414 serial[0].irq = SP1_IRQ; 398 memset(&serial_port, 0, sizeof(serial_port));
415 spin_lock_init(&serial[0].lock); 399 serial_port.iotype = UPIO_PORT;
416 400 serial_port.type = PORT_16550A;
417 retval = early_serial_setup(&serial[0]); 401 serial_port.uartclk = 115200*16;
402 serial_port.fifosize = 16;
403 spin_lock_init(&serial_port.lock);
404
405 /* serial port #1 */
406 serial_port.iobase = sio_dev.sp1_base;
407 serial_port.irq = SP1_IRQ;
408 serial_port.line = 0;
409 retval = early_serial_setup(&serial_port);
418 if (retval < 0) { 410 if (retval < 0) {
419 printk(KERN_WARNING PFX "Register Serial #0 failed.\n"); 411 printk(KERN_WARNING PFX "Register Serial #0 failed.\n");
420 return; 412 return;
421 } 413 }
422 414
423 serial[1].iobase = sio_dev.sp2_base; 415 /* serial port #2 */
424 serial[1].irq = SP2_IRQ; 416 serial_port.iobase = sio_dev.sp2_base;
425 spin_lock_init(&serial[1].lock); 417 serial_port.irq = SP2_IRQ;
426 retval = early_serial_setup(&serial[1]); 418 serial_port.line = 1;
427 419 retval = early_serial_setup(&serial_port);
428 if (retval < 0) 420 if (retval < 0)
429 printk(KERN_WARNING PFX "Register Serial #1 failed.\n"); 421 printk(KERN_WARNING PFX "Register Serial #1 failed.\n");
430#endif /* CONFIG_SERIAL_8250 */ 422#endif /* CONFIG_SERIAL_8250 */
diff --git a/drivers/pcmcia/vrc4171_card.c b/drivers/pcmcia/vrc4171_card.c
index 0574efd7828a..459e6e1946fd 100644
--- a/drivers/pcmcia/vrc4171_card.c
+++ b/drivers/pcmcia/vrc4171_card.c
@@ -634,7 +634,7 @@ static void vrc4171_remove_sockets(void)
634static int __devinit vrc4171_card_setup(char *options) 634static int __devinit vrc4171_card_setup(char *options)
635{ 635{
636 if (options == NULL || *options == '\0') 636 if (options == NULL || *options == '\0')
637 return 0; 637 return 1;
638 638
639 if (strncmp(options, "irq:", 4) == 0) { 639 if (strncmp(options, "irq:", 4) == 0) {
640 int irq; 640 int irq;
@@ -644,7 +644,7 @@ static int __devinit vrc4171_card_setup(char *options)
644 vrc4171_irq = irq; 644 vrc4171_irq = irq;
645 645
646 if (*options != ',') 646 if (*options != ',')
647 return 0; 647 return 1;
648 options++; 648 options++;
649 } 649 }
650 650
@@ -663,10 +663,10 @@ static int __devinit vrc4171_card_setup(char *options)
663 } 663 }
664 664
665 if (*options != ',') 665 if (*options != ',')
666 return 0; 666 return 1;
667 options++; 667 options++;
668 } else 668 } else
669 return 0; 669 return 1;
670 670
671 } 671 }
672 672
@@ -688,7 +688,7 @@ static int __devinit vrc4171_card_setup(char *options)
688 } 688 }
689 689
690 if (*options != ',') 690 if (*options != ',')
691 return 0; 691 return 1;
692 options++; 692 options++;
693 693
694 if (strncmp(options, "memnoprobe", 10) == 0) 694 if (strncmp(options, "memnoprobe", 10) == 0)
@@ -700,7 +700,7 @@ static int __devinit vrc4171_card_setup(char *options)
700 } 700 }
701 } 701 }
702 702
703 return 0; 703 return 1;
704} 704}
705 705
706__setup("vrc4171_card=", vrc4171_card_setup); 706__setup("vrc4171_card=", vrc4171_card_setup);
diff --git a/drivers/pcmcia/vrc4173_cardu.c b/drivers/pcmcia/vrc4173_cardu.c
index 57f38dba0a48..6004196f7cc1 100644
--- a/drivers/pcmcia/vrc4173_cardu.c
+++ b/drivers/pcmcia/vrc4173_cardu.c
@@ -516,7 +516,7 @@ static int __devinit vrc4173_cardu_probe(struct pci_dev *dev,
516static int __devinit vrc4173_cardu_setup(char *options) 516static int __devinit vrc4173_cardu_setup(char *options)
517{ 517{
518 if (options == NULL || *options == '\0') 518 if (options == NULL || *options == '\0')
519 return 0; 519 return 1;
520 520
521 if (strncmp(options, "cardu1:", 7) == 0) { 521 if (strncmp(options, "cardu1:", 7) == 0) {
522 options += 7; 522 options += 7;
@@ -527,9 +527,9 @@ static int __devinit vrc4173_cardu_setup(char *options)
527 } 527 }
528 528
529 if (*options != ',') 529 if (*options != ',')
530 return 0; 530 return 1;
531 } else 531 } else
532 return 0; 532 return 1;
533 } 533 }
534 534
535 if (strncmp(options, "cardu2:", 7) == 0) { 535 if (strncmp(options, "cardu2:", 7) == 0) {
@@ -538,7 +538,7 @@ static int __devinit vrc4173_cardu_setup(char *options)
538 cardu_sockets[CARDU2].noprobe = 1; 538 cardu_sockets[CARDU2].noprobe = 1;
539 } 539 }
540 540
541 return 0; 541 return 1;
542} 542}
543 543
544__setup("vrc4173_cardu=", vrc4173_cardu_setup); 544__setup("vrc4173_cardu=", vrc4173_cardu_setup);
diff --git a/drivers/scsi/ahci.c b/drivers/scsi/ahci.c
index ffba65656a83..1bd82c4e52a0 100644
--- a/drivers/scsi/ahci.c
+++ b/drivers/scsi/ahci.c
@@ -293,6 +293,10 @@ static const struct pci_device_id ahci_pci_tbl[] = {
293 board_ahci }, /* JMicron JMB360 */ 293 board_ahci }, /* JMicron JMB360 */
294 { 0x197b, 0x2363, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 294 { 0x197b, 0x2363, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
295 board_ahci }, /* JMicron JMB363 */ 295 board_ahci }, /* JMicron JMB363 */
296 { PCI_VENDOR_ID_ATI, 0x4380, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
297 board_ahci }, /* ATI SB600 non-raid */
298 { PCI_VENDOR_ID_ATI, 0x4381, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
299 board_ahci }, /* ATI SB600 raid */
296 { } /* terminate list */ 300 { } /* terminate list */
297}; 301};
298 302
diff --git a/drivers/scsi/ata_piix.c b/drivers/scsi/ata_piix.c
index 2d5be84d8bd4..24e71b555172 100644
--- a/drivers/scsi/ata_piix.c
+++ b/drivers/scsi/ata_piix.c
@@ -301,7 +301,7 @@ static struct piix_map_db ich6_map_db = {
301 .mask = 0x3, 301 .mask = 0x3,
302 .map = { 302 .map = {
303 /* PM PS SM SS MAP */ 303 /* PM PS SM SS MAP */
304 { P0, P1, P2, P3 }, /* 00b */ 304 { P0, P2, P1, P3 }, /* 00b */
305 { IDE, IDE, P1, P3 }, /* 01b */ 305 { IDE, IDE, P1, P3 }, /* 01b */
306 { P0, P2, IDE, IDE }, /* 10b */ 306 { P0, P2, IDE, IDE }, /* 10b */
307 { RV, RV, RV, RV }, 307 { RV, RV, RV, RV },
@@ -312,7 +312,7 @@ static struct piix_map_db ich6m_map_db = {
312 .mask = 0x3, 312 .mask = 0x3,
313 .map = { 313 .map = {
314 /* PM PS SM SS MAP */ 314 /* PM PS SM SS MAP */
315 { P0, P1, P2, P3 }, /* 00b */ 315 { P0, P2, RV, RV }, /* 00b */
316 { RV, RV, RV, RV }, 316 { RV, RV, RV, RV },
317 { P0, P2, IDE, IDE }, /* 10b */ 317 { P0, P2, IDE, IDE }, /* 10b */
318 { RV, RV, RV, RV }, 318 { RV, RV, RV, RV },
diff --git a/drivers/scsi/ibmmca.c b/drivers/scsi/ibmmca.c
index 3a8462e8d063..24eb59e143a9 100644
--- a/drivers/scsi/ibmmca.c
+++ b/drivers/scsi/ibmmca.c
@@ -2488,7 +2488,7 @@ static int option_setup(char *str)
2488 } 2488 }
2489 ints[0] = i - 1; 2489 ints[0] = i - 1;
2490 internal_ibmmca_scsi_setup(cur, ints); 2490 internal_ibmmca_scsi_setup(cur, ints);
2491 return 0; 2491 return 1;
2492} 2492}
2493 2493
2494__setup("ibmmcascsi=", option_setup); 2494__setup("ibmmcascsi=", option_setup);
diff --git a/drivers/scsi/lasi700.c b/drivers/scsi/lasi700.c
index 459a4daebece..eb7bd310cc82 100644
--- a/drivers/scsi/lasi700.c
+++ b/drivers/scsi/lasi700.c
@@ -112,7 +112,7 @@ lasi700_probe(struct parisc_device *dev)
112 112
113 hostdata->dev = &dev->dev; 113 hostdata->dev = &dev->dev;
114 dma_set_mask(&dev->dev, DMA_32BIT_MASK); 114 dma_set_mask(&dev->dev, DMA_32BIT_MASK);
115 hostdata->base = ioremap(base, 0x100); 115 hostdata->base = ioremap_nocache(base, 0x100);
116 hostdata->differential = 0; 116 hostdata->differential = 0;
117 117
118 if (dev->id.sversion == LASI_700_SVERSION) { 118 if (dev->id.sversion == LASI_700_SVERSION) {
diff --git a/drivers/scsi/libata-bmdma.c b/drivers/scsi/libata-bmdma.c
index 95d81d86d8b7..835dff0bafdc 100644
--- a/drivers/scsi/libata-bmdma.c
+++ b/drivers/scsi/libata-bmdma.c
@@ -703,6 +703,7 @@ ata_pci_init_native_mode(struct pci_dev *pdev, struct ata_port_info **port, int
703 struct ata_probe_ent *probe_ent = 703 struct ata_probe_ent *probe_ent =
704 ata_probe_ent_alloc(pci_dev_to_dev(pdev), port[0]); 704 ata_probe_ent_alloc(pci_dev_to_dev(pdev), port[0]);
705 int p = 0; 705 int p = 0;
706 unsigned long bmdma;
706 707
707 if (!probe_ent) 708 if (!probe_ent)
708 return NULL; 709 return NULL;
@@ -716,7 +717,12 @@ ata_pci_init_native_mode(struct pci_dev *pdev, struct ata_port_info **port, int
716 probe_ent->port[p].altstatus_addr = 717 probe_ent->port[p].altstatus_addr =
717 probe_ent->port[p].ctl_addr = 718 probe_ent->port[p].ctl_addr =
718 pci_resource_start(pdev, 1) | ATA_PCI_CTL_OFS; 719 pci_resource_start(pdev, 1) | ATA_PCI_CTL_OFS;
719 probe_ent->port[p].bmdma_addr = pci_resource_start(pdev, 4); 720 bmdma = pci_resource_start(pdev, 4);
721 if (bmdma) {
722 if (inb(bmdma + 2) & 0x80)
723 probe_ent->host_set_flags |= ATA_HOST_SIMPLEX;
724 probe_ent->port[p].bmdma_addr = bmdma;
725 }
720 ata_std_ports(&probe_ent->port[p]); 726 ata_std_ports(&probe_ent->port[p]);
721 p++; 727 p++;
722 } 728 }
@@ -726,7 +732,13 @@ ata_pci_init_native_mode(struct pci_dev *pdev, struct ata_port_info **port, int
726 probe_ent->port[p].altstatus_addr = 732 probe_ent->port[p].altstatus_addr =
727 probe_ent->port[p].ctl_addr = 733 probe_ent->port[p].ctl_addr =
728 pci_resource_start(pdev, 3) | ATA_PCI_CTL_OFS; 734 pci_resource_start(pdev, 3) | ATA_PCI_CTL_OFS;
729 probe_ent->port[p].bmdma_addr = pci_resource_start(pdev, 4) + 8; 735 bmdma = pci_resource_start(pdev, 4);
736 if (bmdma) {
737 bmdma += 8;
738 if(inb(bmdma + 2) & 0x80)
739 probe_ent->host_set_flags |= ATA_HOST_SIMPLEX;
740 probe_ent->port[p].bmdma_addr = bmdma;
741 }
730 ata_std_ports(&probe_ent->port[p]); 742 ata_std_ports(&probe_ent->port[p]);
731 p++; 743 p++;
732 } 744 }
@@ -740,6 +752,7 @@ static struct ata_probe_ent *ata_pci_init_legacy_port(struct pci_dev *pdev,
740 struct ata_port_info *port, int port_num) 752 struct ata_port_info *port, int port_num)
741{ 753{
742 struct ata_probe_ent *probe_ent; 754 struct ata_probe_ent *probe_ent;
755 unsigned long bmdma;
743 756
744 probe_ent = ata_probe_ent_alloc(pci_dev_to_dev(pdev), port); 757 probe_ent = ata_probe_ent_alloc(pci_dev_to_dev(pdev), port);
745 if (!probe_ent) 758 if (!probe_ent)
@@ -766,8 +779,13 @@ static struct ata_probe_ent *ata_pci_init_legacy_port(struct pci_dev *pdev,
766 break; 779 break;
767 } 780 }
768 781
769 probe_ent->port[0].bmdma_addr = 782 bmdma = pci_resource_start(pdev, 4);
770 pci_resource_start(pdev, 4) + 8 * port_num; 783 if (bmdma != 0) {
784 bmdma += 8 * port_num;
785 probe_ent->port[0].bmdma_addr = bmdma;
786 if (inb(bmdma + 2) & 0x80)
787 probe_ent->host_set_flags |= ATA_HOST_SIMPLEX;
788 }
771 ata_std_ports(&probe_ent->port[0]); 789 ata_std_ports(&probe_ent->port[0]);
772 790
773 return probe_ent; 791 return probe_ent;
diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c
index d279666dcb38..e63c1ff1e102 100644
--- a/drivers/scsi/libata-core.c
+++ b/drivers/scsi/libata-core.c
@@ -62,7 +62,9 @@
62#include "libata.h" 62#include "libata.h"
63 63
64static unsigned int ata_dev_init_params(struct ata_port *ap, 64static unsigned int ata_dev_init_params(struct ata_port *ap,
65 struct ata_device *dev); 65 struct ata_device *dev,
66 u16 heads,
67 u16 sectors);
66static void ata_set_mode(struct ata_port *ap); 68static void ata_set_mode(struct ata_port *ap);
67static unsigned int ata_dev_set_xfermode(struct ata_port *ap, 69static unsigned int ata_dev_set_xfermode(struct ata_port *ap,
68 struct ata_device *dev); 70 struct ata_device *dev);
@@ -276,7 +278,7 @@ static void ata_unpack_xfermask(unsigned int xfer_mask,
276} 278}
277 279
278static const struct ata_xfer_ent { 280static const struct ata_xfer_ent {
279 unsigned int shift, bits; 281 int shift, bits;
280 u8 base; 282 u8 base;
281} ata_xfer_tbl[] = { 283} ata_xfer_tbl[] = {
282 { ATA_SHIFT_PIO, ATA_BITS_PIO, XFER_PIO_0 }, 284 { ATA_SHIFT_PIO, ATA_BITS_PIO, XFER_PIO_0 },
@@ -987,9 +989,7 @@ ata_exec_internal(struct ata_port *ap, struct ata_device *dev,
987 qc->private_data = &wait; 989 qc->private_data = &wait;
988 qc->complete_fn = ata_qc_complete_internal; 990 qc->complete_fn = ata_qc_complete_internal;
989 991
990 qc->err_mask = ata_qc_issue(qc); 992 ata_qc_issue(qc);
991 if (qc->err_mask)
992 ata_qc_complete(qc);
993 993
994 spin_unlock_irqrestore(&ap->host_set->lock, flags); 994 spin_unlock_irqrestore(&ap->host_set->lock, flags);
995 995
@@ -1081,9 +1081,8 @@ unsigned int ata_pio_need_iordy(const struct ata_device *adev)
1081 * 1081 *
1082 * Read ID data from the specified device. ATA_CMD_ID_ATA is 1082 * Read ID data from the specified device. ATA_CMD_ID_ATA is
1083 * performed on ATA devices and ATA_CMD_ID_ATAPI on ATAPI 1083 * performed on ATA devices and ATA_CMD_ID_ATAPI on ATAPI
1084 * devices. This function also takes care of EDD signature 1084 * devices. This function also issues ATA_CMD_INIT_DEV_PARAMS
1085 * misreporting (to be removed once EDD support is gone) and 1085 * for pre-ATA4 drives.
1086 * issues ATA_CMD_INIT_DEV_PARAMS for pre-ATA4 drives.
1087 * 1086 *
1088 * LOCKING: 1087 * LOCKING:
1089 * Kernel thread context (may sleep) 1088 * Kernel thread context (may sleep)
@@ -1095,7 +1094,6 @@ static int ata_dev_read_id(struct ata_port *ap, struct ata_device *dev,
1095 unsigned int *p_class, int post_reset, u16 **p_id) 1094 unsigned int *p_class, int post_reset, u16 **p_id)
1096{ 1095{
1097 unsigned int class = *p_class; 1096 unsigned int class = *p_class;
1098 unsigned int using_edd;
1099 struct ata_taskfile tf; 1097 struct ata_taskfile tf;
1100 unsigned int err_mask = 0; 1098 unsigned int err_mask = 0;
1101 u16 *id; 1099 u16 *id;
@@ -1104,12 +1102,6 @@ static int ata_dev_read_id(struct ata_port *ap, struct ata_device *dev,
1104 1102
1105 DPRINTK("ENTER, host %u, dev %u\n", ap->id, dev->devno); 1103 DPRINTK("ENTER, host %u, dev %u\n", ap->id, dev->devno);
1106 1104
1107 if (ap->ops->probe_reset ||
1108 ap->flags & (ATA_FLAG_SRST | ATA_FLAG_SATA_RESET))
1109 using_edd = 0;
1110 else
1111 using_edd = 1;
1112
1113 ata_dev_select(ap, dev->devno, 1, 1); /* select device 0/1 */ 1105 ata_dev_select(ap, dev->devno, 1, 1); /* select device 0/1 */
1114 1106
1115 id = kmalloc(sizeof(id[0]) * ATA_ID_WORDS, GFP_KERNEL); 1107 id = kmalloc(sizeof(id[0]) * ATA_ID_WORDS, GFP_KERNEL);
@@ -1139,39 +1131,16 @@ static int ata_dev_read_id(struct ata_port *ap, struct ata_device *dev,
1139 1131
1140 err_mask = ata_exec_internal(ap, dev, &tf, DMA_FROM_DEVICE, 1132 err_mask = ata_exec_internal(ap, dev, &tf, DMA_FROM_DEVICE,
1141 id, sizeof(id[0]) * ATA_ID_WORDS); 1133 id, sizeof(id[0]) * ATA_ID_WORDS);
1142
1143 if (err_mask) { 1134 if (err_mask) {
1144 rc = -EIO; 1135 rc = -EIO;
1145 reason = "I/O error"; 1136 reason = "I/O error";
1146
1147 if (err_mask & ~AC_ERR_DEV)
1148 goto err_out;
1149
1150 /*
1151 * arg! EDD works for all test cases, but seems to return
1152 * the ATA signature for some ATAPI devices. Until the
1153 * reason for this is found and fixed, we fix up the mess
1154 * here. If IDENTIFY DEVICE returns command aborted
1155 * (as ATAPI devices do), then we issue an
1156 * IDENTIFY PACKET DEVICE.
1157 *
1158 * ATA software reset (SRST, the default) does not appear
1159 * to have this problem.
1160 */
1161 if ((using_edd) && (class == ATA_DEV_ATA)) {
1162 u8 err = tf.feature;
1163 if (err & ATA_ABORTED) {
1164 class = ATA_DEV_ATAPI;
1165 goto retry;
1166 }
1167 }
1168 goto err_out; 1137 goto err_out;
1169 } 1138 }
1170 1139
1171 swap_buf_le16(id, ATA_ID_WORDS); 1140 swap_buf_le16(id, ATA_ID_WORDS);
1172 1141
1173 /* sanity check */ 1142 /* sanity check */
1174 if ((class == ATA_DEV_ATA) != ata_id_is_ata(id)) { 1143 if ((class == ATA_DEV_ATA) != (ata_id_is_ata(id) | ata_id_is_cfa(id))) {
1175 rc = -EINVAL; 1144 rc = -EINVAL;
1176 reason = "device reports illegal type"; 1145 reason = "device reports illegal type";
1177 goto err_out; 1146 goto err_out;
@@ -1187,7 +1156,7 @@ static int ata_dev_read_id(struct ata_port *ap, struct ata_device *dev,
1187 * Some drives were very specific about that exact sequence. 1156 * Some drives were very specific about that exact sequence.
1188 */ 1157 */
1189 if (ata_id_major_version(id) < 4 || !ata_id_has_lba(id)) { 1158 if (ata_id_major_version(id) < 4 || !ata_id_has_lba(id)) {
1190 err_mask = ata_dev_init_params(ap, dev); 1159 err_mask = ata_dev_init_params(ap, dev, id[3], id[6]);
1191 if (err_mask) { 1160 if (err_mask) {
1192 rc = -EIO; 1161 rc = -EIO;
1193 reason = "INIT_DEV_PARAMS failed"; 1162 reason = "INIT_DEV_PARAMS failed";
@@ -1440,7 +1409,11 @@ static int ata_bus_probe(struct ata_port *ap)
1440 if (!found) 1409 if (!found)
1441 goto err_out_disable; 1410 goto err_out_disable;
1442 1411
1443 ata_set_mode(ap); 1412 if (ap->ops->set_mode)
1413 ap->ops->set_mode(ap);
1414 else
1415 ata_set_mode(ap);
1416
1444 if (ap->flags & ATA_FLAG_PORT_DISABLED) 1417 if (ap->flags & ATA_FLAG_PORT_DISABLED)
1445 goto err_out_disable; 1418 goto err_out_disable;
1446 1419
@@ -1845,7 +1818,7 @@ static void ata_host_set_dma(struct ata_port *ap)
1845 */ 1818 */
1846static void ata_set_mode(struct ata_port *ap) 1819static void ata_set_mode(struct ata_port *ap)
1847{ 1820{
1848 int i, rc; 1821 int i, rc, used_dma = 0;
1849 1822
1850 /* step 1: calculate xfer_mask */ 1823 /* step 1: calculate xfer_mask */
1851 for (i = 0; i < ATA_MAX_DEVICES; i++) { 1824 for (i = 0; i < ATA_MAX_DEVICES; i++) {
@@ -1863,6 +1836,9 @@ static void ata_set_mode(struct ata_port *ap)
1863 dma_mask = ata_pack_xfermask(0, dev->mwdma_mask, dev->udma_mask); 1836 dma_mask = ata_pack_xfermask(0, dev->mwdma_mask, dev->udma_mask);
1864 dev->pio_mode = ata_xfer_mask2mode(pio_mask); 1837 dev->pio_mode = ata_xfer_mask2mode(pio_mask);
1865 dev->dma_mode = ata_xfer_mask2mode(dma_mask); 1838 dev->dma_mode = ata_xfer_mask2mode(dma_mask);
1839
1840 if (dev->dma_mode)
1841 used_dma = 1;
1866 } 1842 }
1867 1843
1868 /* step 2: always set host PIO timings */ 1844 /* step 2: always set host PIO timings */
@@ -1884,6 +1860,17 @@ static void ata_set_mode(struct ata_port *ap)
1884 goto err_out; 1860 goto err_out;
1885 } 1861 }
1886 1862
1863 /*
1864 * Record simplex status. If we selected DMA then the other
1865 * host channels are not permitted to do so.
1866 */
1867
1868 if (used_dma && (ap->host_set->flags & ATA_HOST_SIMPLEX))
1869 ap->host_set->simplex_claimed = 1;
1870
1871 /*
1872 * Chip specific finalisation
1873 */
1887 if (ap->ops->post_set_mode) 1874 if (ap->ops->post_set_mode)
1888 ap->ops->post_set_mode(ap); 1875 ap->ops->post_set_mode(ap);
1889 1876
@@ -2005,45 +1992,6 @@ static void ata_bus_post_reset(struct ata_port *ap, unsigned int devmask)
2005 ap->ops->dev_select(ap, 0); 1992 ap->ops->dev_select(ap, 0);
2006} 1993}
2007 1994
2008/**
2009 * ata_bus_edd - Issue EXECUTE DEVICE DIAGNOSTIC command.
2010 * @ap: Port to reset and probe
2011 *
2012 * Use the EXECUTE DEVICE DIAGNOSTIC command to reset and
2013 * probe the bus. Not often used these days.
2014 *
2015 * LOCKING:
2016 * PCI/etc. bus probe sem.
2017 * Obtains host_set lock.
2018 *
2019 */
2020
2021static unsigned int ata_bus_edd(struct ata_port *ap)
2022{
2023 struct ata_taskfile tf;
2024 unsigned long flags;
2025
2026 /* set up execute-device-diag (bus reset) taskfile */
2027 /* also, take interrupts to a known state (disabled) */
2028 DPRINTK("execute-device-diag\n");
2029 ata_tf_init(ap, &tf, 0);
2030 tf.ctl |= ATA_NIEN;
2031 tf.command = ATA_CMD_EDD;
2032 tf.protocol = ATA_PROT_NODATA;
2033
2034 /* do bus reset */
2035 spin_lock_irqsave(&ap->host_set->lock, flags);
2036 ata_tf_to_host(ap, &tf);
2037 spin_unlock_irqrestore(&ap->host_set->lock, flags);
2038
2039 /* spec says at least 2ms. but who knows with those
2040 * crazy ATAPI devices...
2041 */
2042 msleep(150);
2043
2044 return ata_busy_sleep(ap, ATA_TMOUT_BOOT_QUICK, ATA_TMOUT_BOOT);
2045}
2046
2047static unsigned int ata_bus_softreset(struct ata_port *ap, 1995static unsigned int ata_bus_softreset(struct ata_port *ap,
2048 unsigned int devmask) 1996 unsigned int devmask)
2049{ 1997{
@@ -2078,13 +2026,12 @@ static unsigned int ata_bus_softreset(struct ata_port *ap,
2078 */ 2026 */
2079 msleep(150); 2027 msleep(150);
2080 2028
2081
2082 /* Before we perform post reset processing we want to see if 2029 /* Before we perform post reset processing we want to see if
2083 the bus shows 0xFF because the odd clown forgets the D7 pulldown 2030 * the bus shows 0xFF because the odd clown forgets the D7
2084 resistor */ 2031 * pulldown resistor.
2085 2032 */
2086 if (ata_check_status(ap) == 0xFF) 2033 if (ata_check_status(ap) == 0xFF)
2087 return 1; /* Positive is failure for some reason */ 2034 return AC_ERR_OTHER;
2088 2035
2089 ata_bus_post_reset(ap, devmask); 2036 ata_bus_post_reset(ap, devmask);
2090 2037
@@ -2116,7 +2063,7 @@ void ata_bus_reset(struct ata_port *ap)
2116 struct ata_ioports *ioaddr = &ap->ioaddr; 2063 struct ata_ioports *ioaddr = &ap->ioaddr;
2117 unsigned int slave_possible = ap->flags & ATA_FLAG_SLAVE_POSS; 2064 unsigned int slave_possible = ap->flags & ATA_FLAG_SLAVE_POSS;
2118 u8 err; 2065 u8 err;
2119 unsigned int dev0, dev1 = 0, rc = 0, devmask = 0; 2066 unsigned int dev0, dev1 = 0, devmask = 0;
2120 2067
2121 DPRINTK("ENTER, host %u, port %u\n", ap->id, ap->port_no); 2068 DPRINTK("ENTER, host %u, port %u\n", ap->id, ap->port_no);
2122 2069
@@ -2139,18 +2086,8 @@ void ata_bus_reset(struct ata_port *ap)
2139 2086
2140 /* issue bus reset */ 2087 /* issue bus reset */
2141 if (ap->flags & ATA_FLAG_SRST) 2088 if (ap->flags & ATA_FLAG_SRST)
2142 rc = ata_bus_softreset(ap, devmask); 2089 if (ata_bus_softreset(ap, devmask))
2143 else if ((ap->flags & ATA_FLAG_SATA_RESET) == 0) { 2090 goto err_out;
2144 /* set up device control */
2145 if (ap->flags & ATA_FLAG_MMIO)
2146 writeb(ap->ctl, (void __iomem *) ioaddr->ctl_addr);
2147 else
2148 outb(ap->ctl, ioaddr->ctl_addr);
2149 rc = ata_bus_edd(ap);
2150 }
2151
2152 if (rc)
2153 goto err_out;
2154 2091
2155 /* 2092 /*
2156 * determine by signature whether we have ATA or ATAPI devices 2093 * determine by signature whether we have ATA or ATAPI devices
@@ -2223,9 +2160,9 @@ static int sata_phy_resume(struct ata_port *ap)
2223 * so makes reset sequence different from the original 2160 * so makes reset sequence different from the original
2224 * ->phy_reset implementation and Jeff nervous. :-P 2161 * ->phy_reset implementation and Jeff nervous. :-P
2225 */ 2162 */
2226extern void ata_std_probeinit(struct ata_port *ap) 2163void ata_std_probeinit(struct ata_port *ap)
2227{ 2164{
2228 if (ap->flags & ATA_FLAG_SATA && ap->ops->scr_read) { 2165 if ((ap->flags & ATA_FLAG_SATA) && ap->ops->scr_read) {
2229 sata_phy_resume(ap); 2166 sata_phy_resume(ap);
2230 if (sata_dev_present(ap)) 2167 if (sata_dev_present(ap))
2231 ata_busy_sleep(ap, ATA_TMOUT_BOOT_QUICK, ATA_TMOUT_BOOT); 2168 ata_busy_sleep(ap, ATA_TMOUT_BOOT_QUICK, ATA_TMOUT_BOOT);
@@ -2714,18 +2651,23 @@ static int ata_dma_blacklisted(const struct ata_device *dev)
2714 * known limits including host controller limits, device 2651 * known limits including host controller limits, device
2715 * blacklist, etc... 2652 * blacklist, etc...
2716 * 2653 *
2654 * FIXME: The current implementation limits all transfer modes to
2655 * the fastest of the lowested device on the port. This is not
2656 * required on most controllers.
2657 *
2717 * LOCKING: 2658 * LOCKING:
2718 * None. 2659 * None.
2719 */ 2660 */
2720static void ata_dev_xfermask(struct ata_port *ap, struct ata_device *dev) 2661static void ata_dev_xfermask(struct ata_port *ap, struct ata_device *dev)
2721{ 2662{
2663 struct ata_host_set *hs = ap->host_set;
2722 unsigned long xfer_mask; 2664 unsigned long xfer_mask;
2723 int i; 2665 int i;
2724 2666
2725 xfer_mask = ata_pack_xfermask(ap->pio_mask, ap->mwdma_mask, 2667 xfer_mask = ata_pack_xfermask(ap->pio_mask, ap->mwdma_mask,
2726 ap->udma_mask); 2668 ap->udma_mask);
2727 2669
2728 /* use port-wide xfermask for now */ 2670 /* FIXME: Use port-wide xfermask for now */
2729 for (i = 0; i < ATA_MAX_DEVICES; i++) { 2671 for (i = 0; i < ATA_MAX_DEVICES; i++) {
2730 struct ata_device *d = &ap->device[i]; 2672 struct ata_device *d = &ap->device[i];
2731 if (!ata_dev_present(d)) 2673 if (!ata_dev_present(d))
@@ -2735,12 +2677,23 @@ static void ata_dev_xfermask(struct ata_port *ap, struct ata_device *dev)
2735 xfer_mask &= ata_id_xfermask(d->id); 2677 xfer_mask &= ata_id_xfermask(d->id);
2736 if (ata_dma_blacklisted(d)) 2678 if (ata_dma_blacklisted(d))
2737 xfer_mask &= ~(ATA_MASK_MWDMA | ATA_MASK_UDMA); 2679 xfer_mask &= ~(ATA_MASK_MWDMA | ATA_MASK_UDMA);
2680 /* Apply cable rule here. Don't apply it early because when
2681 we handle hot plug the cable type can itself change */
2682 if (ap->cbl == ATA_CBL_PATA40)
2683 xfer_mask &= ~(0xF8 << ATA_SHIFT_UDMA);
2738 } 2684 }
2739 2685
2740 if (ata_dma_blacklisted(dev)) 2686 if (ata_dma_blacklisted(dev))
2741 printk(KERN_WARNING "ata%u: dev %u is on DMA blacklist, " 2687 printk(KERN_WARNING "ata%u: dev %u is on DMA blacklist, "
2742 "disabling DMA\n", ap->id, dev->devno); 2688 "disabling DMA\n", ap->id, dev->devno);
2743 2689
2690 if (hs->flags & ATA_HOST_SIMPLEX) {
2691 if (hs->simplex_claimed)
2692 xfer_mask &= ~(ATA_MASK_MWDMA | ATA_MASK_UDMA);
2693 }
2694 if (ap->ops->mode_filter)
2695 xfer_mask = ap->ops->mode_filter(ap, dev, xfer_mask);
2696
2744 ata_unpack_xfermask(xfer_mask, &dev->pio_mask, &dev->mwdma_mask, 2697 ata_unpack_xfermask(xfer_mask, &dev->pio_mask, &dev->mwdma_mask,
2745 &dev->udma_mask); 2698 &dev->udma_mask);
2746} 2699}
@@ -2795,16 +2748,16 @@ static unsigned int ata_dev_set_xfermode(struct ata_port *ap,
2795 */ 2748 */
2796 2749
2797static unsigned int ata_dev_init_params(struct ata_port *ap, 2750static unsigned int ata_dev_init_params(struct ata_port *ap,
2798 struct ata_device *dev) 2751 struct ata_device *dev,
2752 u16 heads,
2753 u16 sectors)
2799{ 2754{
2800 struct ata_taskfile tf; 2755 struct ata_taskfile tf;
2801 unsigned int err_mask; 2756 unsigned int err_mask;
2802 u16 sectors = dev->id[6];
2803 u16 heads = dev->id[3];
2804 2757
2805 /* Number of sectors per track 1-255. Number of heads 1-16 */ 2758 /* Number of sectors per track 1-255. Number of heads 1-16 */
2806 if (sectors < 1 || sectors > 255 || heads < 1 || heads > 16) 2759 if (sectors < 1 || sectors > 255 || heads < 1 || heads > 16)
2807 return 0; 2760 return AC_ERR_INVALID;
2808 2761
2809 /* set up init dev params taskfile */ 2762 /* set up init dev params taskfile */
2810 DPRINTK("init dev params \n"); 2763 DPRINTK("init dev params \n");
@@ -4042,15 +3995,14 @@ static inline int ata_should_dma_map(struct ata_queued_cmd *qc)
4042 * 3995 *
4043 * LOCKING: 3996 * LOCKING:
4044 * spin_lock_irqsave(host_set lock) 3997 * spin_lock_irqsave(host_set lock)
4045 *
4046 * RETURNS:
4047 * Zero on success, AC_ERR_* mask on failure
4048 */ 3998 */
4049 3999void ata_qc_issue(struct ata_queued_cmd *qc)
4050unsigned int ata_qc_issue(struct ata_queued_cmd *qc)
4051{ 4000{
4052 struct ata_port *ap = qc->ap; 4001 struct ata_port *ap = qc->ap;
4053 4002
4003 qc->ap->active_tag = qc->tag;
4004 qc->flags |= ATA_QCFLAG_ACTIVE;
4005
4054 if (ata_should_dma_map(qc)) { 4006 if (ata_should_dma_map(qc)) {
4055 if (qc->flags & ATA_QCFLAG_SG) { 4007 if (qc->flags & ATA_QCFLAG_SG) {
4056 if (ata_sg_setup(qc)) 4008 if (ata_sg_setup(qc))
@@ -4065,17 +4017,18 @@ unsigned int ata_qc_issue(struct ata_queued_cmd *qc)
4065 4017
4066 ap->ops->qc_prep(qc); 4018 ap->ops->qc_prep(qc);
4067 4019
4068 qc->ap->active_tag = qc->tag; 4020 qc->err_mask |= ap->ops->qc_issue(qc);
4069 qc->flags |= ATA_QCFLAG_ACTIVE; 4021 if (unlikely(qc->err_mask))
4070 4022 goto err;
4071 return ap->ops->qc_issue(qc); 4023 return;
4072 4024
4073sg_err: 4025sg_err:
4074 qc->flags &= ~ATA_QCFLAG_DMAMAP; 4026 qc->flags &= ~ATA_QCFLAG_DMAMAP;
4075 return AC_ERR_SYSTEM; 4027 qc->err_mask |= AC_ERR_SYSTEM;
4028err:
4029 ata_qc_complete(qc);
4076} 4030}
4077 4031
4078
4079/** 4032/**
4080 * ata_qc_issue_prot - issue taskfile to device in proto-dependent manner 4033 * ata_qc_issue_prot - issue taskfile to device in proto-dependent manner
4081 * @qc: command to issue to device 4034 * @qc: command to issue to device
@@ -4536,6 +4489,14 @@ static struct ata_port * ata_host_add(const struct ata_probe_ent *ent,
4536 int rc; 4489 int rc;
4537 4490
4538 DPRINTK("ENTER\n"); 4491 DPRINTK("ENTER\n");
4492
4493 if (!ent->port_ops->probe_reset &&
4494 !(ent->host_flags & (ATA_FLAG_SATA_RESET | ATA_FLAG_SRST))) {
4495 printk(KERN_ERR "ata%u: no reset mechanism available\n",
4496 port_no);
4497 return NULL;
4498 }
4499
4539 host = scsi_host_alloc(ent->sht, sizeof(struct ata_port)); 4500 host = scsi_host_alloc(ent->sht, sizeof(struct ata_port));
4540 if (!host) 4501 if (!host)
4541 return NULL; 4502 return NULL;
@@ -4596,6 +4557,7 @@ int ata_device_add(const struct ata_probe_ent *ent)
4596 host_set->mmio_base = ent->mmio_base; 4557 host_set->mmio_base = ent->mmio_base;
4597 host_set->private_data = ent->private_data; 4558 host_set->private_data = ent->private_data;
4598 host_set->ops = ent->port_ops; 4559 host_set->ops = ent->port_ops;
4560 host_set->flags = ent->host_set_flags;
4599 4561
4600 /* register each port bound to this device */ 4562 /* register each port bound to this device */
4601 for (i = 0; i < ent->n_ports; i++) { 4563 for (i = 0; i < ent->n_ports; i++) {
diff --git a/drivers/scsi/libata-scsi.c b/drivers/scsi/libata-scsi.c
index 628191bfd990..53f5b0d9161c 100644
--- a/drivers/scsi/libata-scsi.c
+++ b/drivers/scsi/libata-scsi.c
@@ -1431,9 +1431,7 @@ static void ata_scsi_translate(struct ata_port *ap, struct ata_device *dev,
1431 goto early_finish; 1431 goto early_finish;
1432 1432
1433 /* select device, send command to hardware */ 1433 /* select device, send command to hardware */
1434 qc->err_mask = ata_qc_issue(qc); 1434 ata_qc_issue(qc);
1435 if (qc->err_mask)
1436 ata_qc_complete(qc);
1437 1435
1438 VPRINTK("EXIT\n"); 1436 VPRINTK("EXIT\n");
1439 return; 1437 return;
@@ -2199,9 +2197,7 @@ static void atapi_request_sense(struct ata_queued_cmd *qc)
2199 2197
2200 qc->complete_fn = atapi_sense_complete; 2198 qc->complete_fn = atapi_sense_complete;
2201 2199
2202 qc->err_mask = ata_qc_issue(qc); 2200 ata_qc_issue(qc);
2203 if (qc->err_mask)
2204 ata_qc_complete(qc);
2205 2201
2206 DPRINTK("EXIT\n"); 2202 DPRINTK("EXIT\n");
2207} 2203}
diff --git a/drivers/scsi/libata.h b/drivers/scsi/libata.h
index 65f52beea884..1c755b14521a 100644
--- a/drivers/scsi/libata.h
+++ b/drivers/scsi/libata.h
@@ -47,7 +47,7 @@ extern struct ata_queued_cmd *ata_qc_new_init(struct ata_port *ap,
47extern int ata_rwcmd_protocol(struct ata_queued_cmd *qc); 47extern int ata_rwcmd_protocol(struct ata_queued_cmd *qc);
48extern void ata_port_flush_task(struct ata_port *ap); 48extern void ata_port_flush_task(struct ata_port *ap);
49extern void ata_qc_free(struct ata_queued_cmd *qc); 49extern void ata_qc_free(struct ata_queued_cmd *qc);
50extern unsigned int ata_qc_issue(struct ata_queued_cmd *qc); 50extern void ata_qc_issue(struct ata_queued_cmd *qc);
51extern int ata_check_atapi_dma(struct ata_queued_cmd *qc); 51extern int ata_check_atapi_dma(struct ata_queued_cmd *qc);
52extern void ata_dev_select(struct ata_port *ap, unsigned int device, 52extern void ata_dev_select(struct ata_port *ap, unsigned int device,
53 unsigned int wait, unsigned int can_sleep); 53 unsigned int wait, unsigned int can_sleep);
diff --git a/drivers/scsi/mesh.c b/drivers/scsi/mesh.c
index d6d2125f9044..f852421002ef 100644
--- a/drivers/scsi/mesh.c
+++ b/drivers/scsi/mesh.c
@@ -1748,7 +1748,7 @@ static int mesh_host_reset(struct scsi_cmnd *cmd)
1748 1748
1749static void set_mesh_power(struct mesh_state *ms, int state) 1749static void set_mesh_power(struct mesh_state *ms, int state)
1750{ 1750{
1751 if (_machine != _MACH_Pmac) 1751 if (!machine_is(powermac))
1752 return; 1752 return;
1753 if (state) { 1753 if (state) {
1754 pmac_call_feature(PMAC_FTR_MESH_ENABLE, macio_get_of_node(ms->mdev), 0, 1); 1754 pmac_call_feature(PMAC_FTR_MESH_ENABLE, macio_get_of_node(ms->mdev), 0, 1);
diff --git a/drivers/scsi/sata_mv.c b/drivers/scsi/sata_mv.c
index 275ed9bd898c..fa901fd65085 100644
--- a/drivers/scsi/sata_mv.c
+++ b/drivers/scsi/sata_mv.c
@@ -1010,7 +1010,7 @@ static void mv_fill_sg(struct ata_queued_cmd *qc)
1010 1010
1011 pp->sg_tbl[i].addr = cpu_to_le32(addr & 0xffffffff); 1011 pp->sg_tbl[i].addr = cpu_to_le32(addr & 0xffffffff);
1012 pp->sg_tbl[i].addr_hi = cpu_to_le32((addr >> 16) >> 16); 1012 pp->sg_tbl[i].addr_hi = cpu_to_le32((addr >> 16) >> 16);
1013 pp->sg_tbl[i].flags_size = cpu_to_le32(len); 1013 pp->sg_tbl[i].flags_size = cpu_to_le32(len & 0xffff);
1014 1014
1015 sg_len -= len; 1015 sg_len -= len;
1016 addr += len; 1016 addr += len;
@@ -1350,7 +1350,6 @@ static void mv_host_intr(struct ata_host_set *host_set, u32 relevant,
1350{ 1350{
1351 void __iomem *mmio = host_set->mmio_base; 1351 void __iomem *mmio = host_set->mmio_base;
1352 void __iomem *hc_mmio = mv_hc_base(mmio, hc); 1352 void __iomem *hc_mmio = mv_hc_base(mmio, hc);
1353 struct ata_port *ap;
1354 struct ata_queued_cmd *qc; 1353 struct ata_queued_cmd *qc;
1355 u32 hc_irq_cause; 1354 u32 hc_irq_cause;
1356 int shift, port, port0, hard_port, handled; 1355 int shift, port, port0, hard_port, handled;
@@ -1373,25 +1372,32 @@ static void mv_host_intr(struct ata_host_set *host_set, u32 relevant,
1373 1372
1374 for (port = port0; port < port0 + MV_PORTS_PER_HC; port++) { 1373 for (port = port0; port < port0 + MV_PORTS_PER_HC; port++) {
1375 u8 ata_status = 0; 1374 u8 ata_status = 0;
1376 ap = host_set->ports[port]; 1375 struct ata_port *ap = host_set->ports[port];
1376 struct mv_port_priv *pp = ap->private_data;
1377
1377 hard_port = port & MV_PORT_MASK; /* range 0-3 */ 1378 hard_port = port & MV_PORT_MASK; /* range 0-3 */
1378 handled = 0; /* ensure ata_status is set if handled++ */ 1379 handled = 0; /* ensure ata_status is set if handled++ */
1379 1380
1380 if ((CRPB_DMA_DONE << hard_port) & hc_irq_cause) { 1381 /* Note that DEV_IRQ might happen spuriously during EDMA,
1381 /* new CRPB on the queue; just one at a time until NCQ 1382 * and should be ignored in such cases. We could mask it,
1382 */ 1383 * but it's pretty rare and may not be worth the overhead.
1383 ata_status = mv_get_crpb_status(ap); 1384 */
1384 handled++; 1385 if (pp->pp_flags & MV_PP_FLAG_EDMA_EN) {
1385 } else if ((DEV_IRQ << hard_port) & hc_irq_cause) { 1386 /* EDMA: check for response queue interrupt */
1386 /* received ATA IRQ; read the status reg to clear INTRQ 1387 if ((CRPB_DMA_DONE << hard_port) & hc_irq_cause) {
1387 */ 1388 ata_status = mv_get_crpb_status(ap);
1388 ata_status = readb((void __iomem *) 1389 handled = 1;
1390 }
1391 } else {
1392 /* PIO: check for device (drive) interrupt */
1393 if ((DEV_IRQ << hard_port) & hc_irq_cause) {
1394 ata_status = readb((void __iomem *)
1389 ap->ioaddr.status_addr); 1395 ap->ioaddr.status_addr);
1390 handled++; 1396 handled = 1;
1397 }
1391 } 1398 }
1392 1399
1393 if (ap && 1400 if (ap->flags & (ATA_FLAG_PORT_DISABLED | ATA_FLAG_NOINTR))
1394 (ap->flags & (ATA_FLAG_PORT_DISABLED | ATA_FLAG_NOINTR)))
1395 continue; 1401 continue;
1396 1402
1397 err_mask = ac_err_mask(ata_status); 1403 err_mask = ac_err_mask(ata_status);
@@ -1403,12 +1409,12 @@ static void mv_host_intr(struct ata_host_set *host_set, u32 relevant,
1403 if ((PORT0_ERR << shift) & relevant) { 1409 if ((PORT0_ERR << shift) & relevant) {
1404 mv_err_intr(ap); 1410 mv_err_intr(ap);
1405 err_mask |= AC_ERR_OTHER; 1411 err_mask |= AC_ERR_OTHER;
1406 handled++; 1412 handled = 1;
1407 } 1413 }
1408 1414
1409 if (handled && ap) { 1415 if (handled) {
1410 qc = ata_qc_from_tag(ap, ap->active_tag); 1416 qc = ata_qc_from_tag(ap, ap->active_tag);
1411 if (NULL != qc) { 1417 if (qc && (qc->flags & ATA_QCFLAG_ACTIVE)) {
1412 VPRINTK("port %u IRQ found for qc, " 1418 VPRINTK("port %u IRQ found for qc, "
1413 "ata_status 0x%x\n", port,ata_status); 1419 "ata_status 0x%x\n", port,ata_status);
1414 /* mark qc status appropriately */ 1420 /* mark qc status appropriately */
diff --git a/drivers/scsi/zalon.c b/drivers/scsi/zalon.c
index b131432c677d..a6cfbb3b361c 100644
--- a/drivers/scsi/zalon.c
+++ b/drivers/scsi/zalon.c
@@ -88,7 +88,7 @@ zalon_probe(struct parisc_device *dev)
88 struct gsc_irq gsc_irq; 88 struct gsc_irq gsc_irq;
89 u32 zalon_vers; 89 u32 zalon_vers;
90 int error = -ENODEV; 90 int error = -ENODEV;
91 void __iomem *zalon = ioremap(dev->hpa.start, 4096); 91 void __iomem *zalon = ioremap_nocache(dev->hpa.start, 4096);
92 void __iomem *io_port = zalon + GSC_SCSI_ZALON_OFFSET; 92 void __iomem *io_port = zalon + GSC_SCSI_ZALON_OFFSET;
93 static int unit = 0; 93 static int unit = 0;
94 struct Scsi_Host *host; 94 struct Scsi_Host *host;
diff --git a/drivers/serial/8250_gsc.c b/drivers/serial/8250_gsc.c
index 8b4947933d9b..913c71cc0569 100644
--- a/drivers/serial/8250_gsc.c
+++ b/drivers/serial/8250_gsc.c
@@ -52,13 +52,14 @@ serial_init_chip(struct parisc_device *dev)
52 address += 0x800; 52 address += 0x800;
53 } 53 }
54 54
55 memset(&port, 0, sizeof(struct uart_port)); 55 memset(&port, 0, sizeof(port));
56 port.mapbase = address; 56 port.iotype = UPIO_MEM;
57 port.irq = dev->irq; 57 port.uartclk = LASI_BASE_BAUD * 16;
58 port.iotype = UPIO_MEM; 58 port.mapbase = address;
59 port.flags = UPF_IOREMAP | UPF_BOOT_AUTOCONF; 59 port.membase = ioremap_nocache(address, 16);
60 port.uartclk = LASI_BASE_BAUD * 16; 60 port.irq = dev->irq;
61 port.dev = &dev->dev; 61 port.flags = UPF_BOOT_AUTOCONF;
62 port.dev = &dev->dev;
62 63
63 err = serial8250_register_port(&port); 64 err = serial8250_register_port(&port);
64 if (err < 0) { 65 if (err < 0) {
diff --git a/drivers/serial/jsm/jsm_tty.c b/drivers/serial/jsm/jsm_tty.c
index 4d48b625cd3d..7d823705193c 100644
--- a/drivers/serial/jsm/jsm_tty.c
+++ b/drivers/serial/jsm/jsm_tty.c
@@ -142,12 +142,14 @@ static void jsm_tty_send_xchar(struct uart_port *port, char ch)
142{ 142{
143 unsigned long lock_flags; 143 unsigned long lock_flags;
144 struct jsm_channel *channel = (struct jsm_channel *)port; 144 struct jsm_channel *channel = (struct jsm_channel *)port;
145 struct termios *termios;
145 146
146 spin_lock_irqsave(&port->lock, lock_flags); 147 spin_lock_irqsave(&port->lock, lock_flags);
147 if (ch == port->info->tty->termios->c_cc[VSTART]) 148 termios = port->info->tty->termios;
149 if (ch == termios->c_cc[VSTART])
148 channel->ch_bd->bd_ops->send_start_character(channel); 150 channel->ch_bd->bd_ops->send_start_character(channel);
149 151
150 if (ch == port->info->tty->termios->c_cc[VSTOP]) 152 if (ch == termios->c_cc[VSTOP])
151 channel->ch_bd->bd_ops->send_stop_character(channel); 153 channel->ch_bd->bd_ops->send_stop_character(channel);
152 spin_unlock_irqrestore(&port->lock, lock_flags); 154 spin_unlock_irqrestore(&port->lock, lock_flags);
153} 155}
@@ -178,6 +180,7 @@ static int jsm_tty_open(struct uart_port *port)
178 struct jsm_board *brd; 180 struct jsm_board *brd;
179 int rc = 0; 181 int rc = 0;
180 struct jsm_channel *channel = (struct jsm_channel *)port; 182 struct jsm_channel *channel = (struct jsm_channel *)port;
183 struct termios *termios;
181 184
182 /* Get board pointer from our array of majors we have allocated */ 185 /* Get board pointer from our array of majors we have allocated */
183 brd = channel->ch_bd; 186 brd = channel->ch_bd;
@@ -239,12 +242,13 @@ static int jsm_tty_open(struct uart_port *port)
239 channel->ch_cached_lsr = 0; 242 channel->ch_cached_lsr = 0;
240 channel->ch_stops_sent = 0; 243 channel->ch_stops_sent = 0;
241 244
242 channel->ch_c_cflag = port->info->tty->termios->c_cflag; 245 termios = port->info->tty->termios;
243 channel->ch_c_iflag = port->info->tty->termios->c_iflag; 246 channel->ch_c_cflag = termios->c_cflag;
244 channel->ch_c_oflag = port->info->tty->termios->c_oflag; 247 channel->ch_c_iflag = termios->c_iflag;
245 channel->ch_c_lflag = port->info->tty->termios->c_lflag; 248 channel->ch_c_oflag = termios->c_oflag;
246 channel->ch_startc = port->info->tty->termios->c_cc[VSTART]; 249 channel->ch_c_lflag = termios->c_lflag;
247 channel->ch_stopc = port->info->tty->termios->c_cc[VSTOP]; 250 channel->ch_startc = termios->c_cc[VSTART];
251 channel->ch_stopc = termios->c_cc[VSTOP];
248 252
249 /* Tell UART to init itself */ 253 /* Tell UART to init itself */
250 brd->bd_ops->uart_init(channel); 254 brd->bd_ops->uart_init(channel);
@@ -784,6 +788,7 @@ static void jsm_carrier(struct jsm_channel *ch)
784 788
785void jsm_check_queue_flow_control(struct jsm_channel *ch) 789void jsm_check_queue_flow_control(struct jsm_channel *ch)
786{ 790{
791 struct board_ops *bd_ops = ch->ch_bd->bd_ops;
787 int qleft = 0; 792 int qleft = 0;
788 793
789 /* Store how much space we have left in the queue */ 794 /* Store how much space we have left in the queue */
@@ -809,7 +814,7 @@ void jsm_check_queue_flow_control(struct jsm_channel *ch)
809 /* HWFLOW */ 814 /* HWFLOW */
810 if (ch->ch_c_cflag & CRTSCTS) { 815 if (ch->ch_c_cflag & CRTSCTS) {
811 if(!(ch->ch_flags & CH_RECEIVER_OFF)) { 816 if(!(ch->ch_flags & CH_RECEIVER_OFF)) {
812 ch->ch_bd->bd_ops->disable_receiver(ch); 817 bd_ops->disable_receiver(ch);
813 ch->ch_flags |= (CH_RECEIVER_OFF); 818 ch->ch_flags |= (CH_RECEIVER_OFF);
814 jsm_printk(READ, INFO, &ch->ch_bd->pci_dev, 819 jsm_printk(READ, INFO, &ch->ch_bd->pci_dev,
815 "Internal queue hit hilevel mark (%d)! Turning off interrupts.\n", 820 "Internal queue hit hilevel mark (%d)! Turning off interrupts.\n",
@@ -819,7 +824,7 @@ void jsm_check_queue_flow_control(struct jsm_channel *ch)
819 /* SWFLOW */ 824 /* SWFLOW */
820 else if (ch->ch_c_iflag & IXOFF) { 825 else if (ch->ch_c_iflag & IXOFF) {
821 if (ch->ch_stops_sent <= MAX_STOPS_SENT) { 826 if (ch->ch_stops_sent <= MAX_STOPS_SENT) {
822 ch->ch_bd->bd_ops->send_stop_character(ch); 827 bd_ops->send_stop_character(ch);
823 ch->ch_stops_sent++; 828 ch->ch_stops_sent++;
824 jsm_printk(READ, INFO, &ch->ch_bd->pci_dev, 829 jsm_printk(READ, INFO, &ch->ch_bd->pci_dev,
825 "Sending stop char! Times sent: %x\n", ch->ch_stops_sent); 830 "Sending stop char! Times sent: %x\n", ch->ch_stops_sent);
@@ -846,7 +851,7 @@ void jsm_check_queue_flow_control(struct jsm_channel *ch)
846 /* HWFLOW */ 851 /* HWFLOW */
847 if (ch->ch_c_cflag & CRTSCTS) { 852 if (ch->ch_c_cflag & CRTSCTS) {
848 if (ch->ch_flags & CH_RECEIVER_OFF) { 853 if (ch->ch_flags & CH_RECEIVER_OFF) {
849 ch->ch_bd->bd_ops->enable_receiver(ch); 854 bd_ops->enable_receiver(ch);
850 ch->ch_flags &= ~(CH_RECEIVER_OFF); 855 ch->ch_flags &= ~(CH_RECEIVER_OFF);
851 jsm_printk(READ, INFO, &ch->ch_bd->pci_dev, 856 jsm_printk(READ, INFO, &ch->ch_bd->pci_dev,
852 "Internal queue hit lowlevel mark (%d)! Turning on interrupts.\n", 857 "Internal queue hit lowlevel mark (%d)! Turning on interrupts.\n",
@@ -856,7 +861,7 @@ void jsm_check_queue_flow_control(struct jsm_channel *ch)
856 /* SWFLOW */ 861 /* SWFLOW */
857 else if (ch->ch_c_iflag & IXOFF && ch->ch_stops_sent) { 862 else if (ch->ch_c_iflag & IXOFF && ch->ch_stops_sent) {
858 ch->ch_stops_sent = 0; 863 ch->ch_stops_sent = 0;
859 ch->ch_bd->bd_ops->send_start_character(ch); 864 bd_ops->send_start_character(ch);
860 jsm_printk(READ, INFO, &ch->ch_bd->pci_dev, "Sending start char!\n"); 865 jsm_printk(READ, INFO, &ch->ch_bd->pci_dev, "Sending start char!\n");
861 } 866 }
862 } 867 }
diff --git a/drivers/serial/mux.c b/drivers/serial/mux.c
index 868eaf4a1a68..64c0e89124c9 100644
--- a/drivers/serial/mux.c
+++ b/drivers/serial/mux.c
@@ -51,7 +51,7 @@
51#define MUX_BREAK(status) ((status & 0xF000) == 0x2000) 51#define MUX_BREAK(status) ((status & 0xF000) == 0x2000)
52 52
53#define MUX_NR 256 53#define MUX_NR 256
54static unsigned int port_cnt = 0; 54static unsigned int port_cnt __read_mostly;
55static struct uart_port mux_ports[MUX_NR]; 55static struct uart_port mux_ports[MUX_NR];
56 56
57static struct uart_driver mux_driver = { 57static struct uart_driver mux_driver = {
@@ -461,7 +461,7 @@ static int __init mux_probe(struct parisc_device *dev)
461 port->iobase = 0; 461 port->iobase = 0;
462 port->mapbase = dev->hpa.start + MUX_OFFSET + 462 port->mapbase = dev->hpa.start + MUX_OFFSET +
463 (i * MUX_LINE_OFFSET); 463 (i * MUX_LINE_OFFSET);
464 port->membase = ioremap(port->mapbase, MUX_LINE_OFFSET); 464 port->membase = ioremap_nocache(port->mapbase, MUX_LINE_OFFSET);
465 port->iotype = UPIO_MEM; 465 port->iotype = UPIO_MEM;
466 port->type = PORT_MUX; 466 port->type = PORT_MUX;
467 port->irq = NO_IRQ; 467 port->irq = NO_IRQ;
diff --git a/drivers/usb/core/hcd-pci.c b/drivers/usb/core/hcd-pci.c
index e0afb5ad29e5..0d2193b69235 100644
--- a/drivers/usb/core/hcd-pci.c
+++ b/drivers/usb/core/hcd-pci.c
@@ -296,7 +296,7 @@ done:
296 296
297#ifdef CONFIG_PPC_PMAC 297#ifdef CONFIG_PPC_PMAC
298 /* Disable ASIC clocks for USB */ 298 /* Disable ASIC clocks for USB */
299 if (_machine == _MACH_Pmac) { 299 if (machine_is(powermac)) {
300 struct device_node *of_node; 300 struct device_node *of_node;
301 301
302 of_node = pci_device_to_OF_node (dev); 302 of_node = pci_device_to_OF_node (dev);
@@ -331,7 +331,7 @@ int usb_hcd_pci_resume (struct pci_dev *dev)
331 331
332#ifdef CONFIG_PPC_PMAC 332#ifdef CONFIG_PPC_PMAC
333 /* Reenable ASIC clocks for USB */ 333 /* Reenable ASIC clocks for USB */
334 if (_machine == _MACH_Pmac) { 334 if (machine_is(powermac)) {
335 struct device_node *of_node; 335 struct device_node *of_node;
336 336
337 of_node = pci_device_to_OF_node (dev); 337 of_node = pci_device_to_OF_node (dev);
diff --git a/drivers/usb/net/zd1201.c b/drivers/usb/net/zd1201.c
index fe9b60cd8d95..9b1e4ed1d07e 100644
--- a/drivers/usb/net/zd1201.c
+++ b/drivers/usb/net/zd1201.c
@@ -1736,6 +1736,7 @@ static const struct iw_handler_def zd1201_iw_handlers = {
1736 .standard = (iw_handler *)zd1201_iw_handler, 1736 .standard = (iw_handler *)zd1201_iw_handler,
1737 .private = (iw_handler *)zd1201_private_handler, 1737 .private = (iw_handler *)zd1201_private_handler,
1738 .private_args = (struct iw_priv_args *) zd1201_private_args, 1738 .private_args = (struct iw_priv_args *) zd1201_private_args,
1739 .get_wireless_stats = zd1201_get_wireless_stats,
1739}; 1740};
1740 1741
1741static int zd1201_probe(struct usb_interface *interface, 1742static int zd1201_probe(struct usb_interface *interface,
@@ -1796,7 +1797,6 @@ static int zd1201_probe(struct usb_interface *interface,
1796 zd->dev->open = zd1201_net_open; 1797 zd->dev->open = zd1201_net_open;
1797 zd->dev->stop = zd1201_net_stop; 1798 zd->dev->stop = zd1201_net_stop;
1798 zd->dev->get_stats = zd1201_get_stats; 1799 zd->dev->get_stats = zd1201_get_stats;
1799 zd->dev->get_wireless_stats = zd1201_get_wireless_stats;
1800 zd->dev->wireless_handlers = 1800 zd->dev->wireless_handlers =
1801 (struct iw_handler_def *)&zd1201_iw_handlers; 1801 (struct iw_handler_def *)&zd1201_iw_handlers;
1802 zd->dev->hard_start_xmit = zd1201_hard_start_xmit; 1802 zd->dev->hard_start_xmit = zd1201_hard_start_xmit;
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 22e9d696fdd2..f87c0171f4ec 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -904,18 +904,6 @@ config FB_MATROX_MULTIHEAD
904 There is no need for enabling 'Matrox multihead support' if you have 904 There is no need for enabling 'Matrox multihead support' if you have
905 only one Matrox card in the box. 905 only one Matrox card in the box.
906 906
907config FB_RADEON_OLD
908 tristate "ATI Radeon display support (Old driver)"
909 depends on FB && PCI
910 select FB_CFB_FILLRECT
911 select FB_CFB_COPYAREA
912 select FB_CFB_IMAGEBLIT
913 select FB_MACMODES if PPC
914 help
915 Choose this option if you want to use an ATI Radeon graphics card as
916 a framebuffer device. There are both PCI and AGP versions. You
917 don't need to choose this to run the Radeon in plain VGA mode.
918
919config FB_RADEON 907config FB_RADEON
920 tristate "ATI Radeon display support" 908 tristate "ATI Radeon display support"
921 depends on FB && PCI 909 depends on FB && PCI
diff --git a/drivers/video/Makefile b/drivers/video/Makefile
index cb90218515ac..23de3b2c7856 100644
--- a/drivers/video/Makefile
+++ b/drivers/video/Makefile
@@ -39,7 +39,6 @@ obj-$(CONFIG_FB_KYRO) += kyro/
39obj-$(CONFIG_FB_SAVAGE) += savage/ 39obj-$(CONFIG_FB_SAVAGE) += savage/
40obj-$(CONFIG_FB_GEODE) += geode/ 40obj-$(CONFIG_FB_GEODE) += geode/
41obj-$(CONFIG_FB_I810) += vgastate.o 41obj-$(CONFIG_FB_I810) += vgastate.o
42obj-$(CONFIG_FB_RADEON_OLD) += radeonfb.o
43obj-$(CONFIG_FB_NEOMAGIC) += neofb.o vgastate.o 42obj-$(CONFIG_FB_NEOMAGIC) += neofb.o vgastate.o
44obj-$(CONFIG_FB_VIRGE) += virgefb.o 43obj-$(CONFIG_FB_VIRGE) += virgefb.o
45obj-$(CONFIG_FB_3DFX) += tdfxfb.o 44obj-$(CONFIG_FB_3DFX) += tdfxfb.o
diff --git a/drivers/video/aty/aty128fb.c b/drivers/video/aty/aty128fb.c
index 821c6da8e42c..f7bbff4ddc6a 100644
--- a/drivers/video/aty/aty128fb.c
+++ b/drivers/video/aty/aty128fb.c
@@ -67,6 +67,7 @@
67#include <asm/io.h> 67#include <asm/io.h>
68 68
69#ifdef CONFIG_PPC_PMAC 69#ifdef CONFIG_PPC_PMAC
70#include <asm/machdep.h>
70#include <asm/pmac_feature.h> 71#include <asm/pmac_feature.h>
71#include <asm/prom.h> 72#include <asm/prom.h>
72#include <asm/pci-bridge.h> 73#include <asm/pci-bridge.h>
@@ -1748,7 +1749,7 @@ static int __init aty128_init(struct pci_dev *pdev, const struct pci_device_id *
1748 1749
1749 var = default_var; 1750 var = default_var;
1750#ifdef CONFIG_PPC_PMAC 1751#ifdef CONFIG_PPC_PMAC
1751 if (_machine == _MACH_Pmac) { 1752 if (machine_is(powermac)) {
1752 /* Indicate sleep capability */ 1753 /* Indicate sleep capability */
1753 if (par->chip_gen == rage_M3) { 1754 if (par->chip_gen == rage_M3) {
1754 pmac_call_feature(PMAC_FTR_DEVICE_CAN_WAKE, NULL, 0, 1); 1755 pmac_call_feature(PMAC_FTR_DEVICE_CAN_WAKE, NULL, 0, 1);
@@ -2011,7 +2012,7 @@ static int aty128fb_blank(int blank, struct fb_info *fb)
2011 return 0; 2012 return 0;
2012 2013
2013#ifdef CONFIG_PMAC_BACKLIGHT 2014#ifdef CONFIG_PMAC_BACKLIGHT
2014 if ((_machine == _MACH_Pmac) && blank) 2015 if (machine_is(powermac) && blank)
2015 set_backlight_enable(0); 2016 set_backlight_enable(0);
2016#endif /* CONFIG_PMAC_BACKLIGHT */ 2017#endif /* CONFIG_PMAC_BACKLIGHT */
2017 2018
@@ -2029,7 +2030,7 @@ static int aty128fb_blank(int blank, struct fb_info *fb)
2029 aty128_set_lcd_enable(par, par->lcd_on && !blank); 2030 aty128_set_lcd_enable(par, par->lcd_on && !blank);
2030 } 2031 }
2031#ifdef CONFIG_PMAC_BACKLIGHT 2032#ifdef CONFIG_PMAC_BACKLIGHT
2032 if ((_machine == _MACH_Pmac) && !blank) 2033 if (machine_is(powermac) && !blank)
2033 set_backlight_enable(1); 2034 set_backlight_enable(1);
2034#endif /* CONFIG_PMAC_BACKLIGHT */ 2035#endif /* CONFIG_PMAC_BACKLIGHT */
2035 return 0; 2036 return 0;
diff --git a/drivers/video/aty/atyfb_base.c b/drivers/video/aty/atyfb_base.c
index e799fcca365a..b39e72d5413b 100644
--- a/drivers/video/aty/atyfb_base.c
+++ b/drivers/video/aty/atyfb_base.c
@@ -75,6 +75,7 @@
75#include "ati_ids.h" 75#include "ati_ids.h"
76 76
77#ifdef __powerpc__ 77#ifdef __powerpc__
78#include <asm/machdep.h>
78#include <asm/prom.h> 79#include <asm/prom.h>
79#include "../macmodes.h" 80#include "../macmodes.h"
80#endif 81#endif
@@ -2518,7 +2519,7 @@ static int __init aty_init(struct fb_info *info, const char *name)
2518 2519
2519 memset(&var, 0, sizeof(var)); 2520 memset(&var, 0, sizeof(var));
2520#ifdef CONFIG_PPC 2521#ifdef CONFIG_PPC
2521 if (_machine == _MACH_Pmac) { 2522 if (machine_is(powermac)) {
2522 /* 2523 /*
2523 * FIXME: The NVRAM stuff should be put in a Mac-specific file, as it 2524 * FIXME: The NVRAM stuff should be put in a Mac-specific file, as it
2524 * applies to all Mac video cards 2525 * applies to all Mac video cards
@@ -2673,7 +2674,7 @@ static int atyfb_blank(int blank, struct fb_info *info)
2673 return 0; 2674 return 0;
2674 2675
2675#ifdef CONFIG_PMAC_BACKLIGHT 2676#ifdef CONFIG_PMAC_BACKLIGHT
2676 if ((_machine == _MACH_Pmac) && blank > FB_BLANK_NORMAL) 2677 if (machine_is(powermac) && blank > FB_BLANK_NORMAL)
2677 set_backlight_enable(0); 2678 set_backlight_enable(0);
2678#elif defined(CONFIG_FB_ATY_GENERIC_LCD) 2679#elif defined(CONFIG_FB_ATY_GENERIC_LCD)
2679 if (par->lcd_table && blank > FB_BLANK_NORMAL && 2680 if (par->lcd_table && blank > FB_BLANK_NORMAL &&
@@ -2705,7 +2706,7 @@ static int atyfb_blank(int blank, struct fb_info *info)
2705 aty_st_le32(CRTC_GEN_CNTL, gen_cntl, par); 2706 aty_st_le32(CRTC_GEN_CNTL, gen_cntl, par);
2706 2707
2707#ifdef CONFIG_PMAC_BACKLIGHT 2708#ifdef CONFIG_PMAC_BACKLIGHT
2708 if ((_machine == _MACH_Pmac) && blank <= FB_BLANK_NORMAL) 2709 if (machine_is(powermac) && blank <= FB_BLANK_NORMAL)
2709 set_backlight_enable(1); 2710 set_backlight_enable(1);
2710#elif defined(CONFIG_FB_ATY_GENERIC_LCD) 2711#elif defined(CONFIG_FB_ATY_GENERIC_LCD)
2711 if (par->lcd_table && blank <= FB_BLANK_NORMAL && 2712 if (par->lcd_table && blank <= FB_BLANK_NORMAL &&
diff --git a/drivers/video/aty/radeon_pm.c b/drivers/video/aty/radeon_pm.c
index 5886a2f1323e..c7091761cef4 100644
--- a/drivers/video/aty/radeon_pm.c
+++ b/drivers/video/aty/radeon_pm.c
@@ -20,7 +20,7 @@
20#include <linux/agp_backend.h> 20#include <linux/agp_backend.h>
21 21
22#ifdef CONFIG_PPC_PMAC 22#ifdef CONFIG_PPC_PMAC
23#include <asm/processor.h> 23#include <asm/machdep.h>
24#include <asm/prom.h> 24#include <asm/prom.h>
25#include <asm/pmac_feature.h> 25#include <asm/pmac_feature.h>
26#endif 26#endif
@@ -2745,7 +2745,7 @@ void radeonfb_pm_init(struct radeonfb_info *rinfo, int dynclk)
2745 rinfo->pm_mode |= radeon_pm_off; 2745 rinfo->pm_mode |= radeon_pm_off;
2746 } 2746 }
2747#if defined(CONFIG_PPC_PMAC) 2747#if defined(CONFIG_PPC_PMAC)
2748 if (_machine == _MACH_Pmac && rinfo->of_node) { 2748 if (machine_is(powermac) && rinfo->of_node) {
2749 if (rinfo->is_mobility && rinfo->pm_reg && 2749 if (rinfo->is_mobility && rinfo->pm_reg &&
2750 rinfo->family <= CHIP_FAMILY_RV250) 2750 rinfo->family <= CHIP_FAMILY_RV250)
2751 rinfo->pm_mode |= radeon_pm_d2; 2751 rinfo->pm_mode |= radeon_pm_d2;
diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig
index 9d996f2c10d5..b895eaaa73fd 100644
--- a/drivers/video/backlight/Kconfig
+++ b/drivers/video/backlight/Kconfig
@@ -43,11 +43,11 @@ config LCD_DEVICE
43 default y 43 default y
44 44
45config BACKLIGHT_CORGI 45config BACKLIGHT_CORGI
46 tristate "Sharp Corgi Backlight Driver (SL-C7xx Series)" 46 tristate "Sharp Corgi Backlight Driver (SL Series)"
47 depends on BACKLIGHT_DEVICE && PXA_SHARPSL 47 depends on BACKLIGHT_DEVICE && PXA_SHARPSL
48 default y 48 default y
49 help 49 help
50 If you have a Sharp Zaurus SL-C7xx, say y to enable the 50 If you have a Sharp Zaurus SL-C7xx, SL-Cxx00 or SL-6000x say y to enable the
51 backlight driver. 51 backlight driver.
52 52
53config BACKLIGHT_HP680 53config BACKLIGHT_HP680
diff --git a/drivers/video/backlight/backlight.c b/drivers/video/backlight/backlight.c
index 151fda8dded0..334b1db1bd7c 100644
--- a/drivers/video/backlight/backlight.c
+++ b/drivers/video/backlight/backlight.c
@@ -16,14 +16,12 @@
16 16
17static ssize_t backlight_show_power(struct class_device *cdev, char *buf) 17static ssize_t backlight_show_power(struct class_device *cdev, char *buf)
18{ 18{
19 int rc; 19 int rc = -ENXIO;
20 struct backlight_device *bd = to_backlight_device(cdev); 20 struct backlight_device *bd = to_backlight_device(cdev);
21 21
22 down(&bd->sem); 22 down(&bd->sem);
23 if (likely(bd->props && bd->props->get_power)) 23 if (likely(bd->props))
24 rc = sprintf(buf, "%d\n", bd->props->get_power(bd)); 24 rc = sprintf(buf, "%d\n", bd->props->power);
25 else
26 rc = -ENXIO;
27 up(&bd->sem); 25 up(&bd->sem);
28 26
29 return rc; 27 return rc;
@@ -31,7 +29,7 @@ static ssize_t backlight_show_power(struct class_device *cdev, char *buf)
31 29
32static ssize_t backlight_store_power(struct class_device *cdev, const char *buf, size_t count) 30static ssize_t backlight_store_power(struct class_device *cdev, const char *buf, size_t count)
33{ 31{
34 int rc, power; 32 int rc = -ENXIO, power;
35 char *endp; 33 char *endp;
36 struct backlight_device *bd = to_backlight_device(cdev); 34 struct backlight_device *bd = to_backlight_device(cdev);
37 35
@@ -40,12 +38,13 @@ static ssize_t backlight_store_power(struct class_device *cdev, const char *buf,
40 return -EINVAL; 38 return -EINVAL;
41 39
42 down(&bd->sem); 40 down(&bd->sem);
43 if (likely(bd->props && bd->props->set_power)) { 41 if (likely(bd->props)) {
44 pr_debug("backlight: set power to %d\n", power); 42 pr_debug("backlight: set power to %d\n", power);
45 bd->props->set_power(bd, power); 43 bd->props->power = power;
44 if (likely(bd->props->update_status))
45 bd->props->update_status(bd);
46 rc = count; 46 rc = count;
47 } else 47 }
48 rc = -ENXIO;
49 up(&bd->sem); 48 up(&bd->sem);
50 49
51 return rc; 50 return rc;
@@ -53,14 +52,12 @@ static ssize_t backlight_store_power(struct class_device *cdev, const char *buf,
53 52
54static ssize_t backlight_show_brightness(struct class_device *cdev, char *buf) 53static ssize_t backlight_show_brightness(struct class_device *cdev, char *buf)
55{ 54{
56 int rc; 55 int rc = -ENXIO;
57 struct backlight_device *bd = to_backlight_device(cdev); 56 struct backlight_device *bd = to_backlight_device(cdev);
58 57
59 down(&bd->sem); 58 down(&bd->sem);
60 if (likely(bd->props && bd->props->get_brightness)) 59 if (likely(bd->props))
61 rc = sprintf(buf, "%d\n", bd->props->get_brightness(bd)); 60 rc = sprintf(buf, "%d\n", bd->props->brightness);
62 else
63 rc = -ENXIO;
64 up(&bd->sem); 61 up(&bd->sem);
65 62
66 return rc; 63 return rc;
@@ -68,7 +65,7 @@ static ssize_t backlight_show_brightness(struct class_device *cdev, char *buf)
68 65
69static ssize_t backlight_store_brightness(struct class_device *cdev, const char *buf, size_t count) 66static ssize_t backlight_store_brightness(struct class_device *cdev, const char *buf, size_t count)
70{ 67{
71 int rc, brightness; 68 int rc = -ENXIO, brightness;
72 char *endp; 69 char *endp;
73 struct backlight_device *bd = to_backlight_device(cdev); 70 struct backlight_device *bd = to_backlight_device(cdev);
74 71
@@ -77,12 +74,18 @@ static ssize_t backlight_store_brightness(struct class_device *cdev, const char
77 return -EINVAL; 74 return -EINVAL;
78 75
79 down(&bd->sem); 76 down(&bd->sem);
80 if (likely(bd->props && bd->props->set_brightness)) { 77 if (likely(bd->props)) {
81 pr_debug("backlight: set brightness to %d\n", brightness); 78 if (brightness > bd->props->max_brightness)
82 bd->props->set_brightness(bd, brightness); 79 rc = -EINVAL;
83 rc = count; 80 else {
84 } else 81 pr_debug("backlight: set brightness to %d\n",
85 rc = -ENXIO; 82 brightness);
83 bd->props->brightness = brightness;
84 if (likely(bd->props->update_status))
85 bd->props->update_status(bd);
86 rc = count;
87 }
88 }
86 up(&bd->sem); 89 up(&bd->sem);
87 90
88 return rc; 91 return rc;
@@ -90,14 +93,26 @@ static ssize_t backlight_store_brightness(struct class_device *cdev, const char
90 93
91static ssize_t backlight_show_max_brightness(struct class_device *cdev, char *buf) 94static ssize_t backlight_show_max_brightness(struct class_device *cdev, char *buf)
92{ 95{
93 int rc; 96 int rc = -ENXIO;
94 struct backlight_device *bd = to_backlight_device(cdev); 97 struct backlight_device *bd = to_backlight_device(cdev);
95 98
96 down(&bd->sem); 99 down(&bd->sem);
97 if (likely(bd->props)) 100 if (likely(bd->props))
98 rc = sprintf(buf, "%d\n", bd->props->max_brightness); 101 rc = sprintf(buf, "%d\n", bd->props->max_brightness);
99 else 102 up(&bd->sem);
100 rc = -ENXIO; 103
104 return rc;
105}
106
107static ssize_t backlight_show_actual_brightness(struct class_device *cdev,
108 char *buf)
109{
110 int rc = -ENXIO;
111 struct backlight_device *bd = to_backlight_device(cdev);
112
113 down(&bd->sem);
114 if (likely(bd->props && bd->props->get_brightness))
115 rc = sprintf(buf, "%d\n", bd->props->get_brightness(bd));
101 up(&bd->sem); 116 up(&bd->sem);
102 117
103 return rc; 118 return rc;
@@ -123,7 +138,10 @@ static struct class backlight_class = {
123 138
124static struct class_device_attribute bl_class_device_attributes[] = { 139static struct class_device_attribute bl_class_device_attributes[] = {
125 DECLARE_ATTR(power, 0644, backlight_show_power, backlight_store_power), 140 DECLARE_ATTR(power, 0644, backlight_show_power, backlight_store_power),
126 DECLARE_ATTR(brightness, 0644, backlight_show_brightness, backlight_store_brightness), 141 DECLARE_ATTR(brightness, 0644, backlight_show_brightness,
142 backlight_store_brightness),
143 DECLARE_ATTR(actual_brightness, 0444, backlight_show_actual_brightness,
144 NULL),
127 DECLARE_ATTR(max_brightness, 0444, backlight_show_max_brightness, NULL), 145 DECLARE_ATTR(max_brightness, 0444, backlight_show_max_brightness, NULL),
128}; 146};
129 147
@@ -144,8 +162,12 @@ static int fb_notifier_callback(struct notifier_block *self,
144 bd = container_of(self, struct backlight_device, fb_notif); 162 bd = container_of(self, struct backlight_device, fb_notif);
145 down(&bd->sem); 163 down(&bd->sem);
146 if (bd->props) 164 if (bd->props)
147 if (!bd->props->check_fb || bd->props->check_fb(evdata->info)) 165 if (!bd->props->check_fb ||
148 bd->props->set_power(bd, *(int *)evdata->data); 166 bd->props->check_fb(evdata->info)) {
167 bd->props->fb_blank = *(int *)evdata->data;
168 if (likely(bd->props && bd->props->update_status))
169 bd->props->update_status(bd);
170 }
149 up(&bd->sem); 171 up(&bd->sem);
150 return 0; 172 return 0;
151} 173}
@@ -231,6 +253,12 @@ void backlight_device_unregister(struct backlight_device *bd)
231 &bl_class_device_attributes[i]); 253 &bl_class_device_attributes[i]);
232 254
233 down(&bd->sem); 255 down(&bd->sem);
256 if (likely(bd->props && bd->props->update_status)) {
257 bd->props->brightness = 0;
258 bd->props->power = 0;
259 bd->props->update_status(bd);
260 }
261
234 bd->props = NULL; 262 bd->props = NULL;
235 up(&bd->sem); 263 up(&bd->sem);
236 264
diff --git a/drivers/video/backlight/corgi_bl.c b/drivers/video/backlight/corgi_bl.c
index d0aaf450e8c7..2ebbfd95145f 100644
--- a/drivers/video/backlight/corgi_bl.c
+++ b/drivers/video/backlight/corgi_bl.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Backlight Driver for Sharp Corgi 2 * Backlight Driver for Sharp Zaurus Handhelds (various models)
3 * 3 *
4 * Copyright (c) 2004-2005 Richard Purdie 4 * Copyright (c) 2004-2006 Richard Purdie
5 * 5 *
6 * Based on Sharp's 2.4 Backlight Driver 6 * Based on Sharp's 2.4 Backlight Driver
7 * 7 *
@@ -15,80 +15,63 @@
15#include <linux/kernel.h> 15#include <linux/kernel.h>
16#include <linux/init.h> 16#include <linux/init.h>
17#include <linux/platform_device.h> 17#include <linux/platform_device.h>
18#include <linux/spinlock.h> 18#include <linux/mutex.h>
19#include <linux/fb.h> 19#include <linux/fb.h>
20#include <linux/backlight.h> 20#include <linux/backlight.h>
21
22#include <asm/arch/sharpsl.h> 21#include <asm/arch/sharpsl.h>
23#include <asm/hardware/sharpsl_pm.h> 22#include <asm/hardware/sharpsl_pm.h>
24 23
25#define CORGI_DEFAULT_INTENSITY 0x1f 24static int corgibl_intensity;
26#define CORGI_LIMIT_MASK 0x0b 25static DEFINE_MUTEX(bl_mutex);
27
28static int corgibl_powermode = FB_BLANK_UNBLANK;
29static int current_intensity = 0;
30static int corgibl_limit = 0;
31static void (*corgibl_mach_set_intensity)(int intensity);
32static spinlock_t bl_lock = SPIN_LOCK_UNLOCKED;
33static struct backlight_properties corgibl_data; 26static struct backlight_properties corgibl_data;
27static struct backlight_device *corgi_backlight_device;
28static struct corgibl_machinfo *bl_machinfo;
34 29
35static void corgibl_send_intensity(int intensity) 30static unsigned long corgibl_flags;
31#define CORGIBL_SUSPENDED 0x01
32#define CORGIBL_BATTLOW 0x02
33
34static int corgibl_send_intensity(struct backlight_device *bd)
36{ 35{
37 unsigned long flags;
38 void (*corgi_kick_batt)(void); 36 void (*corgi_kick_batt)(void);
37 int intensity = bd->props->brightness;
39 38
40 if (corgibl_powermode != FB_BLANK_UNBLANK) { 39 if (bd->props->power != FB_BLANK_UNBLANK)
41 intensity = 0; 40 intensity = 0;
42 } else { 41 if (bd->props->fb_blank != FB_BLANK_UNBLANK)
43 if (corgibl_limit) 42 intensity = 0;
44 intensity &= CORGI_LIMIT_MASK; 43 if (corgibl_flags & CORGIBL_SUSPENDED)
45 } 44 intensity = 0;
46 45 if (corgibl_flags & CORGIBL_BATTLOW)
47 spin_lock_irqsave(&bl_lock, flags); 46 intensity &= bl_machinfo->limit_mask;
48 47
49 corgibl_mach_set_intensity(intensity); 48 mutex_lock(&bl_mutex);
49 bl_machinfo->set_bl_intensity(intensity);
50 mutex_unlock(&bl_mutex);
50 51
51 spin_unlock_irqrestore(&bl_lock, flags); 52 corgibl_intensity = intensity;
52 53
53 corgi_kick_batt = symbol_get(sharpsl_battery_kick); 54 corgi_kick_batt = symbol_get(sharpsl_battery_kick);
54 if (corgi_kick_batt) { 55 if (corgi_kick_batt) {
55 corgi_kick_batt(); 56 corgi_kick_batt();
56 symbol_put(sharpsl_battery_kick); 57 symbol_put(sharpsl_battery_kick);
57 } 58 }
58}
59 59
60static void corgibl_blank(int blank) 60 return 0;
61{
62 switch(blank) {
63
64 case FB_BLANK_NORMAL:
65 case FB_BLANK_VSYNC_SUSPEND:
66 case FB_BLANK_HSYNC_SUSPEND:
67 case FB_BLANK_POWERDOWN:
68 if (corgibl_powermode == FB_BLANK_UNBLANK) {
69 corgibl_send_intensity(0);
70 corgibl_powermode = blank;
71 }
72 break;
73 case FB_BLANK_UNBLANK:
74 if (corgibl_powermode != FB_BLANK_UNBLANK) {
75 corgibl_powermode = blank;
76 corgibl_send_intensity(current_intensity);
77 }
78 break;
79 }
80} 61}
81 62
82#ifdef CONFIG_PM 63#ifdef CONFIG_PM
83static int corgibl_suspend(struct platform_device *dev, pm_message_t state) 64static int corgibl_suspend(struct platform_device *dev, pm_message_t state)
84{ 65{
85 corgibl_blank(FB_BLANK_POWERDOWN); 66 corgibl_flags |= CORGIBL_SUSPENDED;
67 corgibl_send_intensity(corgi_backlight_device);
86 return 0; 68 return 0;
87} 69}
88 70
89static int corgibl_resume(struct platform_device *dev) 71static int corgibl_resume(struct platform_device *dev)
90{ 72{
91 corgibl_blank(FB_BLANK_UNBLANK); 73 corgibl_flags &= ~CORGIBL_SUSPENDED;
74 corgibl_send_intensity(corgi_backlight_device);
92 return 0; 75 return 0;
93} 76}
94#else 77#else
@@ -96,68 +79,55 @@ static int corgibl_resume(struct platform_device *dev)
96#define corgibl_resume NULL 79#define corgibl_resume NULL
97#endif 80#endif
98 81
99 82static int corgibl_get_intensity(struct backlight_device *bd)
100static int corgibl_set_power(struct backlight_device *bd, int state)
101{
102 corgibl_blank(state);
103 return 0;
104}
105
106static int corgibl_get_power(struct backlight_device *bd)
107{ 83{
108 return corgibl_powermode; 84 return corgibl_intensity;
109} 85}
110 86
111static int corgibl_set_intensity(struct backlight_device *bd, int intensity) 87static int corgibl_set_intensity(struct backlight_device *bd)
112{ 88{
113 if (intensity > corgibl_data.max_brightness) 89 corgibl_send_intensity(corgi_backlight_device);
114 intensity = corgibl_data.max_brightness;
115 corgibl_send_intensity(intensity);
116 current_intensity=intensity;
117 return 0; 90 return 0;
118} 91}
119 92
120static int corgibl_get_intensity(struct backlight_device *bd)
121{
122 return current_intensity;
123}
124
125/* 93/*
126 * Called when the battery is low to limit the backlight intensity. 94 * Called when the battery is low to limit the backlight intensity.
127 * If limit==0 clear any limit, otherwise limit the intensity 95 * If limit==0 clear any limit, otherwise limit the intensity
128 */ 96 */
129void corgibl_limit_intensity(int limit) 97void corgibl_limit_intensity(int limit)
130{ 98{
131 corgibl_limit = (limit ? 1 : 0); 99 if (limit)
132 corgibl_send_intensity(current_intensity); 100 corgibl_flags |= CORGIBL_BATTLOW;
101 else
102 corgibl_flags &= ~CORGIBL_BATTLOW;
103 corgibl_send_intensity(corgi_backlight_device);
133} 104}
134EXPORT_SYMBOL(corgibl_limit_intensity); 105EXPORT_SYMBOL(corgibl_limit_intensity);
135 106
136 107
137static struct backlight_properties corgibl_data = { 108static struct backlight_properties corgibl_data = {
138 .owner = THIS_MODULE, 109 .owner = THIS_MODULE,
139 .get_power = corgibl_get_power,
140 .set_power = corgibl_set_power,
141 .get_brightness = corgibl_get_intensity, 110 .get_brightness = corgibl_get_intensity,
142 .set_brightness = corgibl_set_intensity, 111 .update_status = corgibl_set_intensity,
143}; 112};
144 113
145static struct backlight_device *corgi_backlight_device;
146
147static int __init corgibl_probe(struct platform_device *pdev) 114static int __init corgibl_probe(struct platform_device *pdev)
148{ 115{
149 struct corgibl_machinfo *machinfo = pdev->dev.platform_data; 116 struct corgibl_machinfo *machinfo = pdev->dev.platform_data;
150 117
118 bl_machinfo = machinfo;
151 corgibl_data.max_brightness = machinfo->max_intensity; 119 corgibl_data.max_brightness = machinfo->max_intensity;
152 corgibl_mach_set_intensity = machinfo->set_bl_intensity; 120 if (!machinfo->limit_mask)
121 machinfo->limit_mask = -1;
153 122
154 corgi_backlight_device = backlight_device_register ("corgi-bl", 123 corgi_backlight_device = backlight_device_register ("corgi-bl",
155 NULL, &corgibl_data); 124 NULL, &corgibl_data);
156 if (IS_ERR (corgi_backlight_device)) 125 if (IS_ERR (corgi_backlight_device))
157 return PTR_ERR (corgi_backlight_device); 126 return PTR_ERR (corgi_backlight_device);
158 127
159 corgibl_set_intensity(NULL, CORGI_DEFAULT_INTENSITY); 128 corgibl_data.power = FB_BLANK_UNBLANK;
160 corgibl_limit_intensity(0); 129 corgibl_data.brightness = machinfo->default_intensity;
130 corgibl_send_intensity(corgi_backlight_device);
161 131
162 printk("Corgi Backlight Driver Initialized.\n"); 132 printk("Corgi Backlight Driver Initialized.\n");
163 return 0; 133 return 0;
@@ -167,8 +137,6 @@ static int corgibl_remove(struct platform_device *dev)
167{ 137{
168 backlight_device_unregister(corgi_backlight_device); 138 backlight_device_unregister(corgi_backlight_device);
169 139
170 corgibl_set_intensity(NULL, 0);
171
172 printk("Corgi Backlight Driver Unloaded\n"); 140 printk("Corgi Backlight Driver Unloaded\n");
173 return 0; 141 return 0;
174} 142}
diff --git a/drivers/video/backlight/hp680_bl.c b/drivers/video/backlight/hp680_bl.c
index 95da4c9ed1f1..a71e984c93d4 100644
--- a/drivers/video/backlight/hp680_bl.c
+++ b/drivers/video/backlight/hp680_bl.c
@@ -13,7 +13,7 @@
13#include <linux/module.h> 13#include <linux/module.h>
14#include <linux/kernel.h> 14#include <linux/kernel.h>
15#include <linux/init.h> 15#include <linux/init.h>
16#include <linux/device.h> 16#include <linux/platform_device.h>
17#include <linux/spinlock.h> 17#include <linux/spinlock.h>
18#include <linux/fb.h> 18#include <linux/fb.h>
19#include <linux/backlight.h> 19#include <linux/backlight.h>
@@ -25,66 +25,58 @@
25#define HP680_MAX_INTENSITY 255 25#define HP680_MAX_INTENSITY 255
26#define HP680_DEFAULT_INTENSITY 10 26#define HP680_DEFAULT_INTENSITY 10
27 27
28static int hp680bl_powermode = FB_BLANK_UNBLANK; 28static int hp680bl_suspended;
29static int current_intensity = 0; 29static int current_intensity = 0;
30static spinlock_t bl_lock = SPIN_LOCK_UNLOCKED; 30static spinlock_t bl_lock = SPIN_LOCK_UNLOCKED;
31static struct backlight_device *hp680_backlight_device;
31 32
32static void hp680bl_send_intensity(int intensity) 33static void hp680bl_send_intensity(struct backlight_device *bd)
33{ 34{
34 unsigned long flags; 35 unsigned long flags;
36 u16 v;
37 int intensity = bd->props->brightness;
35 38
36 if (hp680bl_powermode != FB_BLANK_UNBLANK) 39 if (bd->props->power != FB_BLANK_UNBLANK)
40 intensity = 0;
41 if (bd->props->fb_blank != FB_BLANK_UNBLANK)
42 intensity = 0;
43 if (hp680bl_suspended)
37 intensity = 0; 44 intensity = 0;
38 45
39 spin_lock_irqsave(&bl_lock, flags); 46 spin_lock_irqsave(&bl_lock, flags);
40 sh_dac_output(255-(u8)intensity, DAC_LCD_BRIGHTNESS); 47 if (intensity && current_intensity == 0) {
48 sh_dac_enable(DAC_LCD_BRIGHTNESS);
49 v = inw(HD64461_GPBDR);
50 v &= ~HD64461_GPBDR_LCDOFF;
51 outw(v, HD64461_GPBDR);
52 sh_dac_output(255-(u8)intensity, DAC_LCD_BRIGHTNESS);
53 } else if (intensity == 0 && current_intensity != 0) {
54 sh_dac_output(255-(u8)intensity, DAC_LCD_BRIGHTNESS);
55 sh_dac_disable(DAC_LCD_BRIGHTNESS);
56 v = inw(HD64461_GPBDR);
57 v |= HD64461_GPBDR_LCDOFF;
58 outw(v, HD64461_GPBDR);
59 } else if (intensity) {
60 sh_dac_output(255-(u8)intensity, DAC_LCD_BRIGHTNESS);
61 }
41 spin_unlock_irqrestore(&bl_lock, flags); 62 spin_unlock_irqrestore(&bl_lock, flags);
42}
43 63
44static void hp680bl_blank(int blank) 64 current_intensity = intensity;
45{
46 u16 v;
47
48 switch(blank) {
49
50 case FB_BLANK_NORMAL:
51 case FB_BLANK_VSYNC_SUSPEND:
52 case FB_BLANK_HSYNC_SUSPEND:
53 case FB_BLANK_POWERDOWN:
54 if (hp680bl_powermode == FB_BLANK_UNBLANK) {
55 hp680bl_send_intensity(0);
56 hp680bl_powermode = blank;
57 sh_dac_disable(DAC_LCD_BRIGHTNESS);
58 v = inw(HD64461_GPBDR);
59 v |= HD64461_GPBDR_LCDOFF;
60 outw(v, HD64461_GPBDR);
61 }
62 break;
63 case FB_BLANK_UNBLANK:
64 if (hp680bl_powermode != FB_BLANK_UNBLANK) {
65 sh_dac_enable(DAC_LCD_BRIGHTNESS);
66 v = inw(HD64461_GPBDR);
67 v &= ~HD64461_GPBDR_LCDOFF;
68 outw(v, HD64461_GPBDR);
69 hp680bl_powermode = blank;
70 hp680bl_send_intensity(current_intensity);
71 }
72 break;
73 }
74} 65}
75 66
67
76#ifdef CONFIG_PM 68#ifdef CONFIG_PM
77static int hp680bl_suspend(struct device *dev, pm_message_t state, u32 level) 69static int hp680bl_suspend(struct platform_device *dev, pm_message_t state)
78{ 70{
79 if (level == SUSPEND_POWER_DOWN) 71 hp680bl_suspended = 1;
80 hp680bl_blank(FB_BLANK_POWERDOWN); 72 hp680bl_send_intensity(hp680_backlight_device);
81 return 0; 73 return 0;
82} 74}
83 75
84static int hp680bl_resume(struct device *dev, u32 level) 76static int hp680bl_resume(struct platform_device *dev)
85{ 77{
86 if (level == RESUME_POWER_ON) 78 hp680bl_suspended = 0;
87 hp680bl_blank(FB_BLANK_UNBLANK); 79 hp680bl_send_intensity(hp680_backlight_device);
88 return 0; 80 return 0;
89} 81}
90#else 82#else
@@ -92,24 +84,9 @@ static int hp680bl_resume(struct device *dev, u32 level)
92#define hp680bl_resume NULL 84#define hp680bl_resume NULL
93#endif 85#endif
94 86
95 87static int hp680bl_set_intensity(struct backlight_device *bd)
96static int hp680bl_set_power(struct backlight_device *bd, int state)
97{ 88{
98 hp680bl_blank(state); 89 hp680bl_send_intensity(bd);
99 return 0;
100}
101
102static int hp680bl_get_power(struct backlight_device *bd)
103{
104 return hp680bl_powermode;
105}
106
107static int hp680bl_set_intensity(struct backlight_device *bd, int intensity)
108{
109 if (intensity > HP680_MAX_INTENSITY)
110 intensity = HP680_MAX_INTENSITY;
111 hp680bl_send_intensity(intensity);
112 current_intensity = intensity;
113 return 0; 90 return 0;
114} 91}
115 92
@@ -120,65 +97,67 @@ static int hp680bl_get_intensity(struct backlight_device *bd)
120 97
121static struct backlight_properties hp680bl_data = { 98static struct backlight_properties hp680bl_data = {
122 .owner = THIS_MODULE, 99 .owner = THIS_MODULE,
123 .get_power = hp680bl_get_power,
124 .set_power = hp680bl_set_power,
125 .max_brightness = HP680_MAX_INTENSITY, 100 .max_brightness = HP680_MAX_INTENSITY,
126 .get_brightness = hp680bl_get_intensity, 101 .get_brightness = hp680bl_get_intensity,
127 .set_brightness = hp680bl_set_intensity, 102 .update_status = hp680bl_set_intensity,
128}; 103};
129 104
130static struct backlight_device *hp680_backlight_device; 105static int __init hp680bl_probe(struct platform_device *dev)
131
132static int __init hp680bl_probe(struct device *dev)
133{ 106{
134 hp680_backlight_device = backlight_device_register ("hp680-bl", 107 hp680_backlight_device = backlight_device_register ("hp680-bl",
135 NULL, &hp680bl_data); 108 NULL, &hp680bl_data);
136 if (IS_ERR (hp680_backlight_device)) 109 if (IS_ERR (hp680_backlight_device))
137 return PTR_ERR (hp680_backlight_device); 110 return PTR_ERR (hp680_backlight_device);
138 111
139 hp680bl_set_intensity(NULL, HP680_DEFAULT_INTENSITY); 112 hp680_backlight_device->props->brightness = HP680_DEFAULT_INTENSITY;
113 hp680bl_send_intensity(hp680_backlight_device);
140 114
141 return 0; 115 return 0;
142} 116}
143 117
144static int hp680bl_remove(struct device *dev) 118static int hp680bl_remove(struct platform_device *dev)
145{ 119{
146 backlight_device_unregister(hp680_backlight_device); 120 backlight_device_unregister(hp680_backlight_device);
147 121
148 return 0; 122 return 0;
149} 123}
150 124
151static struct device_driver hp680bl_driver = { 125static struct platform_driver hp680bl_driver = {
152 .name = "hp680-bl",
153 .bus = &platform_bus_type,
154 .probe = hp680bl_probe, 126 .probe = hp680bl_probe,
155 .remove = hp680bl_remove, 127 .remove = hp680bl_remove,
156 .suspend = hp680bl_suspend, 128 .suspend = hp680bl_suspend,
157 .resume = hp680bl_resume, 129 .resume = hp680bl_resume,
130 .driver = {
131 .name = "hp680-bl",
132 },
158}; 133};
159 134
160static struct platform_device hp680bl_device = { 135static struct platform_device *hp680bl_device;
161 .name = "hp680-bl",
162 .id = -1,
163};
164 136
165static int __init hp680bl_init(void) 137static int __init hp680bl_init(void)
166{ 138{
167 int ret; 139 int ret;
168 140
169 ret=driver_register(&hp680bl_driver); 141 ret = platform_driver_register(&hp680bl_driver);
170 if (!ret) { 142 if (!ret) {
171 ret = platform_device_register(&hp680bl_device); 143 hp680bl_device = platform_device_alloc("hp680-bl", -1);
172 if (ret) 144 if (!hp680bl_device)
173 driver_unregister(&hp680bl_driver); 145 return -ENOMEM;
146
147 ret = platform_device_add(hp680bl_device);
148
149 if (ret) {
150 platform_device_put(hp680bl_device);
151 platform_driver_unregister(&hp680bl_driver);
152 }
174 } 153 }
175 return ret; 154 return ret;
176} 155}
177 156
178static void __exit hp680bl_exit(void) 157static void __exit hp680bl_exit(void)
179{ 158{
180 platform_device_unregister(&hp680bl_device); 159 platform_device_unregister(hp680bl_device);
181 driver_unregister(&hp680bl_driver); 160 platform_driver_unregister(&hp680bl_driver);
182} 161}
183 162
184module_init(hp680bl_init); 163module_init(hp680bl_init);
diff --git a/drivers/video/cfbimgblt.c b/drivers/video/cfbimgblt.c
index 910e2338a27e..8ba6152db2fd 100644
--- a/drivers/video/cfbimgblt.c
+++ b/drivers/video/cfbimgblt.c
@@ -169,7 +169,7 @@ static inline void slow_imageblit(const struct fb_image *image, struct fb_info *
169 169
170 while (j--) { 170 while (j--) {
171 l--; 171 l--;
172 color = (*s & 1 << (FB_BIT_NR(l))) ? fgcolor : bgcolor; 172 color = (*s & (1 << l)) ? fgcolor : bgcolor;
173 val |= FB_SHIFT_HIGH(color, shift); 173 val |= FB_SHIFT_HIGH(color, shift);
174 174
175 /* Did the bitshift spill bits to the next long? */ 175 /* Did the bitshift spill bits to the next long? */
diff --git a/drivers/video/cirrusfb.c b/drivers/video/cirrusfb.c
index 66d6f2f0a219..1103010af54a 100644
--- a/drivers/video/cirrusfb.c
+++ b/drivers/video/cirrusfb.c
@@ -60,8 +60,8 @@
60#include <asm/amigahw.h> 60#include <asm/amigahw.h>
61#endif 61#endif
62#ifdef CONFIG_PPC_PREP 62#ifdef CONFIG_PPC_PREP
63#include <asm/processor.h> 63#include <asm/machdep.h>
64#define isPReP (_machine == _MACH_prep) 64#define isPReP (machine_is(prep))
65#else 65#else
66#define isPReP 0 66#define isPReP 0
67#endif 67#endif
diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c
index 041d06987861..ca020719d20b 100644
--- a/drivers/video/console/fbcon.c
+++ b/drivers/video/console/fbcon.c
@@ -466,7 +466,7 @@ static int __init fb_console_setup(char *this_opt)
466 int i, j; 466 int i, j;
467 467
468 if (!this_opt || !*this_opt) 468 if (!this_opt || !*this_opt)
469 return 0; 469 return 1;
470 470
471 while ((options = strsep(&this_opt, ",")) != NULL) { 471 while ((options = strsep(&this_opt, ",")) != NULL) {
472 if (!strncmp(options, "font:", 5)) 472 if (!strncmp(options, "font:", 5))
@@ -481,10 +481,10 @@ static int __init fb_console_setup(char *this_opt)
481 options++; 481 options++;
482 } 482 }
483 if (*options != ',') 483 if (*options != ',')
484 return 0; 484 return 1;
485 options++; 485 options++;
486 } else 486 } else
487 return 0; 487 return 1;
488 } 488 }
489 489
490 if (!strncmp(options, "map:", 4)) { 490 if (!strncmp(options, "map:", 4)) {
@@ -496,7 +496,7 @@ static int __init fb_console_setup(char *this_opt)
496 con2fb_map_boot[i] = 496 con2fb_map_boot[i] =
497 (options[j++]-'0') % FB_MAX; 497 (options[j++]-'0') % FB_MAX;
498 } 498 }
499 return 0; 499 return 1;
500 } 500 }
501 501
502 if (!strncmp(options, "vc:", 3)) { 502 if (!strncmp(options, "vc:", 3)) {
@@ -518,7 +518,7 @@ static int __init fb_console_setup(char *this_opt)
518 rotate = 0; 518 rotate = 0;
519 } 519 }
520 } 520 }
521 return 0; 521 return 1;
522} 522}
523 523
524__setup("fbcon=", fb_console_setup); 524__setup("fbcon=", fb_console_setup);
@@ -1142,6 +1142,7 @@ static void fbcon_init(struct vc_data *vc, int init)
1142 set_blitting_type(vc, info); 1142 set_blitting_type(vc, info);
1143 } 1143 }
1144 1144
1145 ops->p = &fb_display[fg_console];
1145} 1146}
1146 1147
1147static void fbcon_deinit(struct vc_data *vc) 1148static void fbcon_deinit(struct vc_data *vc)
diff --git a/drivers/video/console/sticore.c b/drivers/video/console/sticore.c
index 0339f5640a78..74ac2acaf72c 100644
--- a/drivers/video/console/sticore.c
+++ b/drivers/video/console/sticore.c
@@ -275,7 +275,7 @@ static int __init sti_setup(char *str)
275 if (str) 275 if (str)
276 strlcpy (default_sti_path, str, sizeof (default_sti_path)); 276 strlcpy (default_sti_path, str, sizeof (default_sti_path));
277 277
278 return 0; 278 return 1;
279} 279}
280 280
281/* Assuming the machine has multiple STI consoles (=graphic cards) which 281/* Assuming the machine has multiple STI consoles (=graphic cards) which
@@ -321,7 +321,7 @@ static int __init sti_font_setup(char *str)
321 i++; 321 i++;
322 } 322 }
323 323
324 return 0; 324 return 1;
325} 325}
326 326
327/* The optional linux kernel parameter "sti_font" defines which font 327/* The optional linux kernel parameter "sti_font" defines which font
@@ -373,7 +373,7 @@ sti_dump_globcfg(struct sti_glob_cfg *glob_cfg, unsigned int sti_mem_request)
373 glob_cfg->save_addr)); 373 glob_cfg->save_addr));
374 374
375 /* dump extended cfg */ 375 /* dump extended cfg */
376 cfg = PTR_STI(glob_cfg->ext_ptr); 376 cfg = PTR_STI((unsigned long)glob_cfg->ext_ptr);
377 DPRINTK(( KERN_INFO 377 DPRINTK(( KERN_INFO
378 "monitor %d\n" 378 "monitor %d\n"
379 "in friendly mode: %d\n" 379 "in friendly mode: %d\n"
@@ -453,25 +453,11 @@ sti_init_glob_cfg(struct sti_struct *sti,
453 sti->regions_phys[i] = 453 sti->regions_phys[i] =
454 REGION_OFFSET_TO_PHYS(sti->regions[i], newhpa); 454 REGION_OFFSET_TO_PHYS(sti->regions[i], newhpa);
455 455
456 /* remap virtually */
457 /* FIXME: add BTLB support if btlb==1 */
458 len = sti->regions[i].region_desc.length * 4096; 456 len = sti->regions[i].region_desc.length * 4096;
459
460/* XXX: Enabling IOREMAP debugging causes a crash, so we must be passing
461 * a virtual address to something expecting a physical address that doesn't
462 * go through a readX macro */
463#if 0
464 if (len)
465 glob_cfg->region_ptrs[i] = (unsigned long) (
466 sti->regions[i].region_desc.cache ?
467 ioremap(sti->regions_phys[i], len) :
468 ioremap_nocache(sti->regions_phys[i], len) );
469#else
470 if (len) 457 if (len)
471 glob_cfg->region_ptrs[i] = sti->regions_phys[i]; 458 glob_cfg->region_ptrs[i] = sti->regions_phys[i];
472#endif
473 459
474 DPRINTK(("region #%d: phys %08lx, virt %08x, len=%lukB, " 460 DPRINTK(("region #%d: phys %08lx, region_ptr %08x, len=%lukB, "
475 "btlb=%d, sysonly=%d, cache=%d, last=%d\n", 461 "btlb=%d, sysonly=%d, cache=%d, last=%d\n",
476 i, sti->regions_phys[i], glob_cfg->region_ptrs[i], 462 i, sti->regions_phys[i], glob_cfg->region_ptrs[i],
477 len/1024, 463 len/1024,
diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c
index b1a8dca76430..944855b3e4af 100644
--- a/drivers/video/fbmem.c
+++ b/drivers/video/fbmem.c
@@ -1588,7 +1588,7 @@ static int __init video_setup(char *options)
1588 } 1588 }
1589 } 1589 }
1590 1590
1591 return 0; 1591 return 1;
1592} 1592}
1593__setup("video=", video_setup); 1593__setup("video=", video_setup);
1594#endif 1594#endif
diff --git a/drivers/video/matrox/matroxfb_base.c b/drivers/video/matrox/matroxfb_base.c
index 951c9974a1d3..23c1827b2d0b 100644
--- a/drivers/video/matrox/matroxfb_base.c
+++ b/drivers/video/matrox/matroxfb_base.c
@@ -115,6 +115,7 @@
115#include <asm/uaccess.h> 115#include <asm/uaccess.h>
116 116
117#ifdef CONFIG_PPC_PMAC 117#ifdef CONFIG_PPC_PMAC
118#include <asm/machdep.h>
118unsigned char nvram_read_byte(int); 119unsigned char nvram_read_byte(int);
119static int default_vmode = VMODE_NVRAM; 120static int default_vmode = VMODE_NVRAM;
120static int default_cmode = CMODE_NVRAM; 121static int default_cmode = CMODE_NVRAM;
@@ -1833,7 +1834,7 @@ static int initMatrox2(WPMINFO struct board* b){
1833 /* FIXME: Where to move this?! */ 1834 /* FIXME: Where to move this?! */
1834#if defined(CONFIG_PPC_PMAC) 1835#if defined(CONFIG_PPC_PMAC)
1835#ifndef MODULE 1836#ifndef MODULE
1836 if (_machine == _MACH_Pmac) { 1837 if (machine_is(powermac)) {
1837 struct fb_var_screeninfo var; 1838 struct fb_var_screeninfo var;
1838 if (default_vmode <= 0 || default_vmode > VMODE_MAX) 1839 if (default_vmode <= 0 || default_vmode > VMODE_MAX)
1839 default_vmode = VMODE_640_480_60; 1840 default_vmode = VMODE_640_480_60;
diff --git a/drivers/video/nvidia/nvidia.c b/drivers/video/nvidia/nvidia.c
index 6d3e4890cb43..093ab9977c7c 100644
--- a/drivers/video/nvidia/nvidia.c
+++ b/drivers/video/nvidia/nvidia.c
@@ -30,6 +30,7 @@
30#include <asm/pci-bridge.h> 30#include <asm/pci-bridge.h>
31#endif 31#endif
32#ifdef CONFIG_PMAC_BACKLIGHT 32#ifdef CONFIG_PMAC_BACKLIGHT
33#include <asm/machdep.h>
33#include <asm/backlight.h> 34#include <asm/backlight.h>
34#endif 35#endif
35 36
@@ -1355,7 +1356,7 @@ static int nvidiafb_blank(int blank, struct fb_info *info)
1355 NVWriteCrtc(par, 0x1a, vesa); 1356 NVWriteCrtc(par, 0x1a, vesa);
1356 1357
1357#ifdef CONFIG_PMAC_BACKLIGHT 1358#ifdef CONFIG_PMAC_BACKLIGHT
1358 if (par->FlatPanel && _machine == _MACH_Pmac) { 1359 if (par->FlatPanel && machine_is(powermac)) {
1359 set_backlight_enable(!blank); 1360 set_backlight_enable(!blank);
1360 } 1361 }
1361#endif 1362#endif
@@ -1741,7 +1742,7 @@ static int __devinit nvidiafb_probe(struct pci_dev *pd,
1741 info->fix.id, 1742 info->fix.id,
1742 par->FbMapSize / (1024 * 1024), info->fix.smem_start); 1743 par->FbMapSize / (1024 * 1024), info->fix.smem_start);
1743#ifdef CONFIG_PMAC_BACKLIGHT 1744#ifdef CONFIG_PMAC_BACKLIGHT
1744 if (par->FlatPanel && _machine == _MACH_Pmac) 1745 if (par->FlatPanel && machine_is(powermac))
1745 register_backlight_controller(&nvidia_backlight_controller, 1746 register_backlight_controller(&nvidia_backlight_controller,
1746 par, "mnca"); 1747 par, "mnca");
1747#endif 1748#endif
diff --git a/drivers/video/pxafb.c b/drivers/video/pxafb.c
index 53ad61f1038c..809fc5eefc15 100644
--- a/drivers/video/pxafb.c
+++ b/drivers/video/pxafb.c
@@ -232,9 +232,9 @@ static int pxafb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
232 if (var->yres < MIN_YRES) 232 if (var->yres < MIN_YRES)
233 var->yres = MIN_YRES; 233 var->yres = MIN_YRES;
234 if (var->xres > fbi->max_xres) 234 if (var->xres > fbi->max_xres)
235 var->xres = fbi->max_xres; 235 return -EINVAL;
236 if (var->yres > fbi->max_yres) 236 if (var->yres > fbi->max_yres)
237 var->yres = fbi->max_yres; 237 return -EINVAL;
238 var->xres_virtual = 238 var->xres_virtual =
239 max(var->xres_virtual, var->xres); 239 max(var->xres_virtual, var->xres);
240 var->yres_virtual = 240 var->yres_virtual =
@@ -781,7 +781,7 @@ static void pxafb_disable_controller(struct pxafb_info *fbi)
781 LCCR0 &= ~LCCR0_LDM; /* Enable LCD Disable Done Interrupt */ 781 LCCR0 &= ~LCCR0_LDM; /* Enable LCD Disable Done Interrupt */
782 LCCR0 |= LCCR0_DIS; /* Disable LCD Controller */ 782 LCCR0 |= LCCR0_DIS; /* Disable LCD Controller */
783 783
784 schedule_timeout(20 * HZ / 1000); 784 schedule_timeout(200 * HZ / 1000);
785 remove_wait_queue(&fbi->ctrlr_wait, &wait); 785 remove_wait_queue(&fbi->ctrlr_wait, &wait);
786 786
787 /* disable LCD controller clock */ 787 /* disable LCD controller clock */
@@ -1274,7 +1274,7 @@ int __init pxafb_probe(struct platform_device *dev)
1274 struct pxafb_mach_info *inf; 1274 struct pxafb_mach_info *inf;
1275 int ret; 1275 int ret;
1276 1276
1277 dev_dbg(dev, "pxafb_probe\n"); 1277 dev_dbg(&dev->dev, "pxafb_probe\n");
1278 1278
1279 inf = dev->dev.platform_data; 1279 inf = dev->dev.platform_data;
1280 ret = -ENOMEM; 1280 ret = -ENOMEM;
diff --git a/drivers/video/radeonfb.c b/drivers/video/radeonfb.c
deleted file mode 100644
index 24982adb3aa2..000000000000
--- a/drivers/video/radeonfb.c
+++ /dev/null
@@ -1,3167 +0,0 @@
1/*
2 * drivers/video/radeonfb.c
3 * framebuffer driver for ATI Radeon chipset video boards
4 *
5 * Copyright 2000 Ani Joshi <ajoshi@kernel.crashing.org>
6 *
7 *
8 * ChangeLog:
9 * 2000-08-03 initial version 0.0.1
10 * 2000-09-10 more bug fixes, public release 0.0.5
11 * 2001-02-19 mode bug fixes, 0.0.7
12 * 2001-07-05 fixed scrolling issues, engine initialization,
13 * and minor mode tweaking, 0.0.9
14 * 2001-09-07 Radeon VE support, Nick Kurshev
15 * blanking, pan_display, and cmap fixes, 0.1.0
16 * 2001-10-10 Radeon 7500 and 8500 support, and experimental
17 * flat panel support, 0.1.1
18 * 2001-11-17 Radeon M6 (ppc) support, Daniel Berlin, 0.1.2
19 * 2001-11-18 DFP fixes, Kevin Hendricks, 0.1.3
20 * 2001-11-29 more cmap, backlight fixes, Benjamin Herrenschmidt
21 * 2002-01-18 DFP panel detection via BIOS, Michael Clark, 0.1.4
22 * 2002-06-02 console switching, mode set fixes, accel fixes
23 * 2002-06-03 MTRR support, Peter Horton, 0.1.5
24 * 2002-09-21 rv250, r300, m9 initial support,
25 * added mirror option, 0.1.6
26 *
27 * Special thanks to ATI DevRel team for their hardware donations.
28 *
29 */
30
31
32#define RADEON_VERSION "0.1.6"
33
34
35#include <linux/config.h>
36#include <linux/module.h>
37#include <linux/kernel.h>
38#include <linux/errno.h>
39#include <linux/string.h>
40#include <linux/mm.h>
41#include <linux/tty.h>
42#include <linux/slab.h>
43#include <linux/delay.h>
44#include <linux/fb.h>
45#include <linux/ioport.h>
46#include <linux/init.h>
47#include <linux/pci.h>
48#include <linux/vmalloc.h>
49
50#include <asm/io.h>
51#include <asm/uaccess.h>
52#if defined(__powerpc__)
53#include <asm/prom.h>
54#include <asm/pci-bridge.h>
55#include "macmodes.h"
56
57#ifdef CONFIG_NVRAM
58#include <linux/nvram.h>
59#endif
60
61#ifdef CONFIG_PMAC_BACKLIGHT
62#include <asm/backlight.h>
63#endif
64
65#ifdef CONFIG_BOOTX_TEXT
66#include <asm/btext.h>
67#endif
68
69#ifdef CONFIG_ADB_PMU
70#include <linux/adb.h>
71#include <linux/pmu.h>
72#endif
73
74#endif /* __powerpc__ */
75
76#ifdef CONFIG_MTRR
77#include <asm/mtrr.h>
78#endif
79
80#include <video/radeon.h>
81#include <linux/radeonfb.h>
82
83#define DEBUG 0
84
85#if DEBUG
86#define RTRACE printk
87#else
88#define RTRACE if(0) printk
89#endif
90
91// XXX
92#undef CONFIG_PMAC_PBOOK
93
94
95enum radeon_chips {
96 RADEON_QD,
97 RADEON_QE,
98 RADEON_QF,
99 RADEON_QG,
100 RADEON_QY,
101 RADEON_QZ,
102 RADEON_LW,
103 RADEON_LX,
104 RADEON_LY,
105 RADEON_LZ,
106 RADEON_QL,
107 RADEON_QN,
108 RADEON_QO,
109 RADEON_Ql,
110 RADEON_BB,
111 RADEON_QW,
112 RADEON_QX,
113 RADEON_Id,
114 RADEON_Ie,
115 RADEON_If,
116 RADEON_Ig,
117 RADEON_Ya,
118 RADEON_Yd,
119 RADEON_Ld,
120 RADEON_Le,
121 RADEON_Lf,
122 RADEON_Lg,
123 RADEON_ND,
124 RADEON_NE,
125 RADEON_NF,
126 RADEON_NG,
127 RADEON_QM
128};
129
130enum radeon_arch {
131 RADEON_R100,
132 RADEON_RV100,
133 RADEON_R200,
134 RADEON_RV200,
135 RADEON_RV250,
136 RADEON_R300,
137 RADEON_M6,
138 RADEON_M7,
139 RADEON_M9
140};
141
142static struct radeon_chip_info {
143 const char *name;
144 unsigned char arch;
145} radeon_chip_info[] __devinitdata = {
146 { "QD", RADEON_R100 },
147 { "QE", RADEON_R100 },
148 { "QF", RADEON_R100 },
149 { "QG", RADEON_R100 },
150 { "VE QY", RADEON_RV100 },
151 { "VE QZ", RADEON_RV100 },
152 { "M7 LW", RADEON_M7 },
153 { "M7 LX", RADEON_M7 },
154 { "M6 LY", RADEON_M6 },
155 { "M6 LZ", RADEON_M6 },
156 { "8500 QL", RADEON_R200 },
157 { "8500 QN", RADEON_R200 },
158 { "8500 QO", RADEON_R200 },
159 { "8500 Ql", RADEON_R200 },
160 { "8500 BB", RADEON_R200 },
161 { "7500 QW", RADEON_RV200 },
162 { "7500 QX", RADEON_RV200 },
163 { "9000 Id", RADEON_RV250 },
164 { "9000 Ie", RADEON_RV250 },
165 { "9000 If", RADEON_RV250 },
166 { "9000 Ig", RADEON_RV250 },
167 { "M9 Ld", RADEON_M9 },
168 { "M9 Le", RADEON_M9 },
169 { "M9 Lf", RADEON_M9 },
170 { "M9 Lg", RADEON_M9 },
171 { "9700 ND", RADEON_R300 },
172 { "9700 NE", RADEON_R300 },
173 { "9700 NF", RADEON_R300 },
174 { "9700 NG", RADEON_R300 },
175 { "9100 QM", RADEON_R200 }
176};
177
178
179enum radeon_montype
180{
181 MT_NONE,
182 MT_CRT, /* CRT */
183 MT_LCD, /* LCD */
184 MT_DFP, /* DVI */
185 MT_CTV, /* composite TV */
186 MT_STV /* S-Video out */
187};
188
189
190static struct pci_device_id radeonfb_pci_table[] = {
191 { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_QD, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_QD},
192 { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_QE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_QE},
193 { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_QF, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_QF},
194 { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_QG, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_QG},
195 { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_QY, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_QY},
196 { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_QZ, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_QZ},
197 { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_LW, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_LW},
198 { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_LX, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_LX},
199 { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_LY, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_LY},
200 { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_LZ, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_LZ},
201 { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_QL, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_QL},
202 { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_QN, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_QN},
203 { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_QO, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_QO},
204 { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_Ql, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_Ql},
205 { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_BB, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_BB},
206 { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_QW, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_QW},
207 { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_QX, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_QX},
208 { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_Id, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_Id},
209 { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_Ie, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_Ie},
210 { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_If, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_If},
211 { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_Ig, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_Ig},
212 { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_Ya, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_Ya},
213 { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_Yd, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_Yd},
214 { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_Ld, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_Ld},
215 { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_Le, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_Le},
216 { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_Lf, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_Lf},
217 { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_Lg, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_Lg},
218 { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_ND, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_ND},
219 { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_NE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_NE},
220 { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_NF, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_NF},
221 { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_NG, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_NG},
222 { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_QM, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_QM},
223 { 0, }
224};
225MODULE_DEVICE_TABLE(pci, radeonfb_pci_table);
226
227
228typedef struct {
229 u16 reg;
230 u32 val;
231} reg_val;
232
233
234/* these common regs are cleared before mode setting so they do not
235 * interfere with anything
236 */
237static reg_val common_regs[] = {
238 { OVR_CLR, 0 },
239 { OVR_WID_LEFT_RIGHT, 0 },
240 { OVR_WID_TOP_BOTTOM, 0 },
241 { OV0_SCALE_CNTL, 0 },
242 { SUBPIC_CNTL, 0 },
243 { VIPH_CONTROL, 0 },
244 { I2C_CNTL_1, 0 },
245 { GEN_INT_CNTL, 0 },
246 { CAP0_TRIG_CNTL, 0 },
247};
248
249static reg_val common_regs_m6[] = {
250 { OVR_CLR, 0 },
251 { OVR_WID_LEFT_RIGHT, 0 },
252 { OVR_WID_TOP_BOTTOM, 0 },
253 { OV0_SCALE_CNTL, 0 },
254 { SUBPIC_CNTL, 0 },
255 { GEN_INT_CNTL, 0 },
256 { CAP0_TRIG_CNTL, 0 }
257};
258
259typedef struct {
260 u8 clock_chip_type;
261 u8 struct_size;
262 u8 accelerator_entry;
263 u8 VGA_entry;
264 u16 VGA_table_offset;
265 u16 POST_table_offset;
266 u16 XCLK;
267 u16 MCLK;
268 u8 num_PLL_blocks;
269 u8 size_PLL_blocks;
270 u16 PCLK_ref_freq;
271 u16 PCLK_ref_divider;
272 u32 PCLK_min_freq;
273 u32 PCLK_max_freq;
274 u16 MCLK_ref_freq;
275 u16 MCLK_ref_divider;
276 u32 MCLK_min_freq;
277 u32 MCLK_max_freq;
278 u16 XCLK_ref_freq;
279 u16 XCLK_ref_divider;
280 u32 XCLK_min_freq;
281 u32 XCLK_max_freq;
282} __attribute__ ((packed)) PLL_BLOCK;
283
284
285struct pll_info {
286 int ppll_max;
287 int ppll_min;
288 int xclk;
289 int ref_div;
290 int ref_clk;
291};
292
293
294struct ram_info {
295 int ml;
296 int mb;
297 int trcd;
298 int trp;
299 int twr;
300 int cl;
301 int tr2w;
302 int loop_latency;
303 int rloop;
304};
305
306
307struct radeon_regs {
308 /* CRTC regs */
309 u32 crtc_h_total_disp;
310 u32 crtc_h_sync_strt_wid;
311 u32 crtc_v_total_disp;
312 u32 crtc_v_sync_strt_wid;
313 u32 crtc_pitch;
314 u32 crtc_gen_cntl;
315 u32 crtc_ext_cntl;
316 u32 dac_cntl;
317
318 u32 flags;
319 u32 pix_clock;
320 int xres, yres;
321
322 /* DDA regs */
323 u32 dda_config;
324 u32 dda_on_off;
325
326 /* PLL regs */
327 u32 ppll_div_3;
328 u32 ppll_ref_div;
329 u32 vclk_ecp_cntl;
330
331 /* Flat panel regs */
332 u32 fp_crtc_h_total_disp;
333 u32 fp_crtc_v_total_disp;
334 u32 fp_gen_cntl;
335 u32 fp_h_sync_strt_wid;
336 u32 fp_horz_stretch;
337 u32 fp_panel_cntl;
338 u32 fp_v_sync_strt_wid;
339 u32 fp_vert_stretch;
340 u32 lvds_gen_cntl;
341 u32 lvds_pll_cntl;
342 u32 tmds_crc;
343 u32 tmds_transmitter_cntl;
344
345#if defined(__BIG_ENDIAN)
346 u32 surface_cntl;
347#endif
348};
349
350
351struct radeonfb_info {
352 struct fb_info info;
353
354 struct radeon_regs state;
355 struct radeon_regs init_state;
356
357 char name[32];
358 char ram_type[12];
359
360 unsigned long mmio_base_phys;
361 unsigned long fb_base_phys;
362
363 void __iomem *mmio_base;
364 void __iomem *fb_base;
365
366 struct pci_dev *pdev;
367
368 unsigned char *EDID;
369 unsigned char __iomem *bios_seg;
370
371 u32 pseudo_palette[17];
372 struct { u8 red, green, blue, pad; } palette[256];
373
374 int chipset;
375 unsigned char arch;
376 int video_ram;
377 u8 rev;
378 int pitch, bpp, depth;
379 int xres, yres, pixclock;
380 int xres_virtual, yres_virtual;
381 u32 accel_flags;
382
383 int use_default_var;
384 int got_dfpinfo;
385
386 int hasCRTC2;
387 int crtDisp_type;
388 int dviDisp_type;
389
390 int panel_xres, panel_yres;
391 int clock;
392 int hOver_plus, hSync_width, hblank;
393 int vOver_plus, vSync_width, vblank;
394 int hAct_high, vAct_high, interlaced;
395 int synct, misc;
396
397 u32 dp_gui_master_cntl;
398
399 struct pll_info pll;
400 int pll_output_freq, post_div, fb_div;
401
402 struct ram_info ram;
403
404 int mtrr_hdl;
405
406#ifdef CONFIG_PMAC_PBOOK
407 int pm_reg;
408 u32 save_regs[64];
409 u32 mdll, mdll2;
410#endif /* CONFIG_PMAC_PBOOK */
411 int asleep;
412
413 struct radeonfb_info *next;
414};
415
416
417static struct fb_var_screeninfo radeonfb_default_var = {
418 640, 480, 640, 480, 0, 0, 8, 0,
419 {0, 6, 0}, {0, 6, 0}, {0, 6, 0}, {0, 0, 0},
420 0, 0, -1, -1, 0, 39721, 40, 24, 32, 11, 96, 2,
421 0, FB_VMODE_NONINTERLACED
422};
423
424/*
425 * IO macros
426 */
427
428#define INREG8(addr) readb((rinfo->mmio_base)+addr)
429#define OUTREG8(addr,val) writeb(val, (rinfo->mmio_base)+addr)
430#define INREG(addr) readl((rinfo->mmio_base)+addr)
431#define OUTREG(addr,val) writel(val, (rinfo->mmio_base)+addr)
432
433#define OUTPLL(addr,val) \
434 do { \
435 OUTREG8(CLOCK_CNTL_INDEX, (addr & 0x0000003f) | 0x00000080); \
436 OUTREG(CLOCK_CNTL_DATA, val); \
437 } while(0)
438
439#define OUTPLLP(addr,val,mask) \
440 do { \
441 unsigned int _tmp = INPLL(addr); \
442 _tmp &= (mask); \
443 _tmp |= (val); \
444 OUTPLL(addr, _tmp); \
445 } while (0)
446
447#define OUTREGP(addr,val,mask) \
448 do { \
449 unsigned int _tmp = INREG(addr); \
450 _tmp &= (mask); \
451 _tmp |= (val); \
452 OUTREG(addr, _tmp); \
453 } while (0)
454
455
456static __inline__ u32 _INPLL(struct radeonfb_info *rinfo, u32 addr)
457{
458 OUTREG8(CLOCK_CNTL_INDEX, addr & 0x0000003f);
459 return (INREG(CLOCK_CNTL_DATA));
460}
461
462#define INPLL(addr) _INPLL(rinfo, addr)
463
464#define PRIMARY_MONITOR(rinfo) ((rinfo->dviDisp_type != MT_NONE) && \
465 (rinfo->dviDisp_type != MT_STV) && \
466 (rinfo->dviDisp_type != MT_CTV) ? \
467 rinfo->dviDisp_type : rinfo->crtDisp_type)
468
469static char *GET_MON_NAME(int type)
470{
471 char *pret = NULL;
472
473 switch (type) {
474 case MT_NONE:
475 pret = "no";
476 break;
477 case MT_CRT:
478 pret = "CRT";
479 break;
480 case MT_DFP:
481 pret = "DFP";
482 break;
483 case MT_LCD:
484 pret = "LCD";
485 break;
486 case MT_CTV:
487 pret = "CTV";
488 break;
489 case MT_STV:
490 pret = "STV";
491 break;
492 }
493
494 return pret;
495}
496
497
498/*
499 * 2D engine routines
500 */
501
502static __inline__ void radeon_engine_flush (struct radeonfb_info *rinfo)
503{
504 int i;
505
506 /* initiate flush */
507 OUTREGP(RB2D_DSTCACHE_CTLSTAT, RB2D_DC_FLUSH_ALL,
508 ~RB2D_DC_FLUSH_ALL);
509
510 for (i=0; i < 2000000; i++) {
511 if (!(INREG(RB2D_DSTCACHE_CTLSTAT) & RB2D_DC_BUSY))
512 break;
513 }
514}
515
516
517static __inline__ void _radeon_fifo_wait (struct radeonfb_info *rinfo, int entries)
518{
519 int i;
520
521 for (i=0; i<2000000; i++)
522 if ((INREG(RBBM_STATUS) & 0x7f) >= entries)
523 return;
524}
525
526
527static __inline__ void _radeon_engine_idle (struct radeonfb_info *rinfo)
528{
529 int i;
530
531 /* ensure FIFO is empty before waiting for idle */
532 _radeon_fifo_wait (rinfo, 64);
533
534 for (i=0; i<2000000; i++) {
535 if (((INREG(RBBM_STATUS) & GUI_ACTIVE)) == 0) {
536 radeon_engine_flush (rinfo);
537 return;
538 }
539 }
540}
541
542
543#define radeon_engine_idle() _radeon_engine_idle(rinfo)
544#define radeon_fifo_wait(entries) _radeon_fifo_wait(rinfo,entries)
545
546
547
548/*
549 * helper routines
550 */
551
552static __inline__ u32 radeon_get_dstbpp(u16 depth)
553{
554 switch (depth) {
555 case 8:
556 return DST_8BPP;
557 case 15:
558 return DST_15BPP;
559 case 16:
560 return DST_16BPP;
561 case 32:
562 return DST_32BPP;
563 default:
564 return 0;
565 }
566}
567
568
569static inline int var_to_depth(const struct fb_var_screeninfo *var)
570{
571 if (var->bits_per_pixel != 16)
572 return var->bits_per_pixel;
573 return (var->green.length == 6) ? 16 : 15;
574}
575
576
577static void _radeon_engine_reset(struct radeonfb_info *rinfo)
578{
579 u32 clock_cntl_index, mclk_cntl, rbbm_soft_reset;
580
581 radeon_engine_flush (rinfo);
582
583 clock_cntl_index = INREG(CLOCK_CNTL_INDEX);
584 mclk_cntl = INPLL(MCLK_CNTL);
585
586 OUTPLL(MCLK_CNTL, (mclk_cntl |
587 FORCEON_MCLKA |
588 FORCEON_MCLKB |
589 FORCEON_YCLKA |
590 FORCEON_YCLKB |
591 FORCEON_MC |
592 FORCEON_AIC));
593 rbbm_soft_reset = INREG(RBBM_SOFT_RESET);
594
595 OUTREG(RBBM_SOFT_RESET, rbbm_soft_reset |
596 SOFT_RESET_CP |
597 SOFT_RESET_HI |
598 SOFT_RESET_SE |
599 SOFT_RESET_RE |
600 SOFT_RESET_PP |
601 SOFT_RESET_E2 |
602 SOFT_RESET_RB);
603 INREG(RBBM_SOFT_RESET);
604 OUTREG(RBBM_SOFT_RESET, rbbm_soft_reset & (u32)
605 ~(SOFT_RESET_CP |
606 SOFT_RESET_HI |
607 SOFT_RESET_SE |
608 SOFT_RESET_RE |
609 SOFT_RESET_PP |
610 SOFT_RESET_E2 |
611 SOFT_RESET_RB));
612 INREG(RBBM_SOFT_RESET);
613
614 OUTPLL(MCLK_CNTL, mclk_cntl);
615 OUTREG(CLOCK_CNTL_INDEX, clock_cntl_index);
616 OUTREG(RBBM_SOFT_RESET, rbbm_soft_reset);
617
618 return;
619}
620
621#define radeon_engine_reset() _radeon_engine_reset(rinfo)
622
623
624static __inline__ int round_div(int num, int den)
625{
626 return (num + (den / 2)) / den;
627}
628
629
630
631static __inline__ int min_bits_req(int val)
632{
633 int bits_req = 0;
634
635 if (val == 0)
636 bits_req = 1;
637
638 while (val) {
639 val >>= 1;
640 bits_req++;
641 }
642
643 return (bits_req);
644}
645
646
647static __inline__ int _max(int val1, int val2)
648{
649 if (val1 >= val2)
650 return val1;
651 else
652 return val2;
653}
654
655
656
657/*
658 * globals
659 */
660
661#ifndef MODULE
662static char *mode_option;
663#endif
664
665static char noaccel = 0;
666static char mirror = 0;
667static int panel_yres = 0;
668static char force_dfp = 0;
669static struct radeonfb_info *board_list = NULL;
670static char nomtrr = 0;
671
672/*
673 * prototypes
674 */
675
676static void radeon_save_state (struct radeonfb_info *rinfo,
677 struct radeon_regs *save);
678static void radeon_engine_init (struct radeonfb_info *rinfo);
679static void radeon_write_mode (struct radeonfb_info *rinfo,
680 struct radeon_regs *mode);
681static int __devinit radeon_set_fbinfo (struct radeonfb_info *rinfo);
682static int __devinit radeon_init_disp (struct radeonfb_info *rinfo);
683static int radeon_init_disp_var (struct radeonfb_info *rinfo, struct fb_var_screeninfo *var);
684static void __iomem *radeon_find_rom(struct radeonfb_info *rinfo);
685static void radeon_get_pllinfo(struct radeonfb_info *rinfo, void __iomem *bios_seg);
686static void radeon_get_moninfo (struct radeonfb_info *rinfo);
687static int radeon_get_dfpinfo (struct radeonfb_info *rinfo);
688static int radeon_get_dfpinfo_BIOS(struct radeonfb_info *rinfo);
689static void radeon_get_EDID(struct radeonfb_info *rinfo);
690static int radeon_dfp_parse_EDID(struct radeonfb_info *rinfo);
691static void radeon_update_default_var(struct radeonfb_info *rinfo);
692
693#ifdef CONFIG_PPC_OF
694
695static int radeon_read_OF (struct radeonfb_info *rinfo);
696static int radeon_get_EDID_OF(struct radeonfb_info *rinfo);
697extern struct device_node *pci_device_to_OF_node(struct pci_dev *dev);
698
699#ifdef CONFIG_PMAC_PBOOK
700int radeon_sleep_notify(struct pmu_sleep_notifier *self, int when);
701static struct pmu_sleep_notifier radeon_sleep_notifier = {
702 radeon_sleep_notify, SLEEP_LEVEL_VIDEO,
703};
704#endif /* CONFIG_PMAC_PBOOK */
705#ifdef CONFIG_PMAC_BACKLIGHT
706static int radeon_set_backlight_enable(int on, int level, void *data);
707static int radeon_set_backlight_level(int level, void *data);
708static struct backlight_controller radeon_backlight_controller = {
709 radeon_set_backlight_enable,
710 radeon_set_backlight_level
711};
712#endif /* CONFIG_PMAC_BACKLIGHT */
713
714#endif /* CONFIG_PPC_OF */
715
716
717static void __iomem *radeon_find_rom(struct radeonfb_info *rinfo)
718{
719#if defined(__i386__)
720 u32 segstart;
721 char __iomem *rom_base;
722 char __iomem *rom;
723 int stage;
724 int i,j;
725 char aty_rom_sig[] = "761295520";
726 char *radeon_sig[] = {
727 "RG6",
728 "RADEON"
729 };
730
731 for(segstart=0x000c0000; segstart<0x000f0000; segstart+=0x00001000) {
732
733 stage = 1;
734
735 rom_base = ioremap(segstart, 0x1000);
736
737 if ((*rom_base == 0x55) && (((*(rom_base + 1)) & 0xff) == 0xaa))
738 stage = 2;
739
740
741 if (stage != 2) {
742 iounmap(rom_base);
743 continue;
744 }
745
746 rom = rom_base;
747
748 for (i = 0; (i < 128 - strlen(aty_rom_sig)) && (stage != 3); i++) {
749 if (aty_rom_sig[0] == *rom)
750 if (strncmp(aty_rom_sig, rom,
751 strlen(aty_rom_sig)) == 0)
752 stage = 3;
753 rom++;
754 }
755 if (stage != 3) {
756 iounmap(rom_base);
757 continue;
758 }
759 rom = rom_base;
760
761 for (i = 0; (i < 512) && (stage != 4); i++) {
762 for (j = 0; j < ARRAY_SIZE(radeon_sig); j++) {
763 if (radeon_sig[j][0] == *rom)
764 if (strncmp(radeon_sig[j], rom,
765 strlen(radeon_sig[j])) == 0) {
766 stage = 4;
767 break;
768 }
769 }
770 rom++;
771 }
772 if (stage != 4) {
773 iounmap(rom_base);
774 continue;
775 }
776
777 return rom_base;
778 }
779#endif
780 return NULL;
781}
782
783
784
785
786static void radeon_get_pllinfo(struct radeonfb_info *rinfo, void __iomem *bios_seg)
787{
788 void __iomem *bios_header;
789 void __iomem *header_ptr;
790 u16 bios_header_offset, pll_info_offset;
791 PLL_BLOCK pll;
792
793 if (bios_seg) {
794 bios_header = bios_seg + 0x48L;
795 header_ptr = bios_header;
796
797 bios_header_offset = readw(header_ptr);
798 bios_header = bios_seg + bios_header_offset;
799 bios_header += 0x30;
800
801 header_ptr = bios_header;
802 pll_info_offset = readw(header_ptr);
803 header_ptr = bios_seg + pll_info_offset;
804
805 memcpy_fromio(&pll, header_ptr, 50);
806
807 rinfo->pll.xclk = (u32)pll.XCLK;
808 rinfo->pll.ref_clk = (u32)pll.PCLK_ref_freq;
809 rinfo->pll.ref_div = (u32)pll.PCLK_ref_divider;
810 rinfo->pll.ppll_min = pll.PCLK_min_freq;
811 rinfo->pll.ppll_max = pll.PCLK_max_freq;
812
813 printk("radeonfb: ref_clk=%d, ref_div=%d, xclk=%d from BIOS\n",
814 rinfo->pll.ref_clk, rinfo->pll.ref_div, rinfo->pll.xclk);
815 } else {
816#ifdef CONFIG_PPC_OF
817 if (radeon_read_OF(rinfo)) {
818 unsigned int tmp, Nx, M, ref_div, xclk;
819
820 tmp = INPLL(M_SPLL_REF_FB_DIV);
821 ref_div = INPLL(PPLL_REF_DIV) & 0x3ff;
822
823 Nx = (tmp & 0xff00) >> 8;
824 M = (tmp & 0xff);
825 xclk = ((((2 * Nx * rinfo->pll.ref_clk) + (M)) /
826 (2 * M)));
827
828 rinfo->pll.xclk = xclk;
829 rinfo->pll.ref_div = ref_div;
830 rinfo->pll.ppll_min = 12000;
831 rinfo->pll.ppll_max = 35000;
832
833 printk("radeonfb: ref_clk=%d, ref_div=%d, xclk=%d from OF\n",
834 rinfo->pll.ref_clk, rinfo->pll.ref_div, rinfo->pll.xclk);
835
836 return;
837 }
838#endif
839 /* no BIOS or BIOS not found, use defaults */
840 switch (rinfo->chipset) {
841 case PCI_DEVICE_ID_ATI_RADEON_QW:
842 case PCI_DEVICE_ID_ATI_RADEON_QX:
843 rinfo->pll.ppll_max = 35000;
844 rinfo->pll.ppll_min = 12000;
845 rinfo->pll.xclk = 23000;
846 rinfo->pll.ref_div = 12;
847 rinfo->pll.ref_clk = 2700;
848 break;
849 case PCI_DEVICE_ID_ATI_RADEON_QL:
850 case PCI_DEVICE_ID_ATI_RADEON_QN:
851 case PCI_DEVICE_ID_ATI_RADEON_QO:
852 case PCI_DEVICE_ID_ATI_RADEON_Ql:
853 case PCI_DEVICE_ID_ATI_RADEON_BB:
854 rinfo->pll.ppll_max = 35000;
855 rinfo->pll.ppll_min = 12000;
856 rinfo->pll.xclk = 27500;
857 rinfo->pll.ref_div = 12;
858 rinfo->pll.ref_clk = 2700;
859 break;
860 case PCI_DEVICE_ID_ATI_RADEON_Id:
861 case PCI_DEVICE_ID_ATI_RADEON_Ie:
862 case PCI_DEVICE_ID_ATI_RADEON_If:
863 case PCI_DEVICE_ID_ATI_RADEON_Ig:
864 rinfo->pll.ppll_max = 35000;
865 rinfo->pll.ppll_min = 12000;
866 rinfo->pll.xclk = 25000;
867 rinfo->pll.ref_div = 12;
868 rinfo->pll.ref_clk = 2700;
869 break;
870 case PCI_DEVICE_ID_ATI_RADEON_ND:
871 case PCI_DEVICE_ID_ATI_RADEON_NE:
872 case PCI_DEVICE_ID_ATI_RADEON_NF:
873 case PCI_DEVICE_ID_ATI_RADEON_NG:
874 rinfo->pll.ppll_max = 40000;
875 rinfo->pll.ppll_min = 20000;
876 rinfo->pll.xclk = 27000;
877 rinfo->pll.ref_div = 12;
878 rinfo->pll.ref_clk = 2700;
879 break;
880 case PCI_DEVICE_ID_ATI_RADEON_QD:
881 case PCI_DEVICE_ID_ATI_RADEON_QE:
882 case PCI_DEVICE_ID_ATI_RADEON_QF:
883 case PCI_DEVICE_ID_ATI_RADEON_QG:
884 default:
885 rinfo->pll.ppll_max = 35000;
886 rinfo->pll.ppll_min = 12000;
887 rinfo->pll.xclk = 16600;
888 rinfo->pll.ref_div = 67;
889 rinfo->pll.ref_clk = 2700;
890 break;
891 }
892
893 printk("radeonfb: ref_clk=%d, ref_div=%d, xclk=%d defaults\n",
894 rinfo->pll.ref_clk, rinfo->pll.ref_div, rinfo->pll.xclk);
895 }
896}
897
898
899static void radeon_get_moninfo (struct radeonfb_info *rinfo)
900{
901 unsigned int tmp;
902
903 if (force_dfp) {
904 rinfo->dviDisp_type = MT_DFP;
905 return;
906 }
907
908 tmp = INREG(BIOS_4_SCRATCH);
909 printk(KERN_DEBUG "radeon_get_moninfo: bios 4 scratch = %x\n", tmp);
910
911 if (rinfo->hasCRTC2) {
912 /* primary DVI port */
913 if (tmp & 0x08)
914 rinfo->dviDisp_type = MT_DFP;
915 else if (tmp & 0x4)
916 rinfo->dviDisp_type = MT_LCD;
917 else if (tmp & 0x200)
918 rinfo->dviDisp_type = MT_CRT;
919 else if (tmp & 0x10)
920 rinfo->dviDisp_type = MT_CTV;
921 else if (tmp & 0x20)
922 rinfo->dviDisp_type = MT_STV;
923
924 /* secondary CRT port */
925 if (tmp & 0x2)
926 rinfo->crtDisp_type = MT_CRT;
927 else if (tmp & 0x800)
928 rinfo->crtDisp_type = MT_DFP;
929 else if (tmp & 0x400)
930 rinfo->crtDisp_type = MT_LCD;
931 else if (tmp & 0x1000)
932 rinfo->crtDisp_type = MT_CTV;
933 else if (tmp & 0x2000)
934 rinfo->crtDisp_type = MT_STV;
935 } else {
936 rinfo->dviDisp_type = MT_NONE;
937
938 tmp = INREG(FP_GEN_CNTL);
939
940 if (tmp & FP_EN_TMDS)
941 rinfo->crtDisp_type = MT_DFP;
942 else
943 rinfo->crtDisp_type = MT_CRT;
944 }
945}
946
947
948
949static void radeon_get_EDID(struct radeonfb_info *rinfo)
950{
951#ifdef CONFIG_PPC_OF
952 if (!radeon_get_EDID_OF(rinfo))
953 RTRACE("radeonfb: could not retrieve EDID from OF\n");
954#else
955 /* XXX use other methods later */
956#endif
957}
958
959
960#ifdef CONFIG_PPC_OF
961static int radeon_get_EDID_OF(struct radeonfb_info *rinfo)
962{
963 struct device_node *dp;
964 unsigned char *pedid = NULL;
965 static char *propnames[] = { "DFP,EDID", "LCD,EDID", "EDID", "EDID1", NULL };
966 int i;
967
968 dp = pci_device_to_OF_node(rinfo->pdev);
969 while (dp != NULL) {
970 for (i = 0; propnames[i] != NULL; ++i) {
971 pedid = (unsigned char *)
972 get_property(dp, propnames[i], NULL);
973 if (pedid != NULL) {
974 rinfo->EDID = pedid;
975 return 1;
976 }
977 }
978 dp = dp->child;
979 }
980 return 0;
981}
982#endif /* CONFIG_PPC_OF */
983
984
985static int radeon_dfp_parse_EDID(struct radeonfb_info *rinfo)
986{
987 unsigned char *block = rinfo->EDID;
988
989 if (!block)
990 return 0;
991
992 /* jump to the detailed timing block section */
993 block += 54;
994
995 rinfo->clock = (block[0] + (block[1] << 8));
996 rinfo->panel_xres = (block[2] + ((block[4] & 0xf0) << 4));
997 rinfo->hblank = (block[3] + ((block[4] & 0x0f) << 8));
998 rinfo->panel_yres = (block[5] + ((block[7] & 0xf0) << 4));
999 rinfo->vblank = (block[6] + ((block[7] & 0x0f) << 8));
1000 rinfo->hOver_plus = (block[8] + ((block[11] & 0xc0) << 2));
1001 rinfo->hSync_width = (block[9] + ((block[11] & 0x30) << 4));
1002 rinfo->vOver_plus = ((block[10] >> 4) + ((block[11] & 0x0c) << 2));
1003 rinfo->vSync_width = ((block[10] & 0x0f) + ((block[11] & 0x03) << 4));
1004 rinfo->interlaced = ((block[17] & 0x80) >> 7);
1005 rinfo->synct = ((block[17] & 0x18) >> 3);
1006 rinfo->misc = ((block[17] & 0x06) >> 1);
1007 rinfo->hAct_high = rinfo->vAct_high = 0;
1008 if (rinfo->synct == 3) {
1009 if (rinfo->misc & 2)
1010 rinfo->hAct_high = 1;
1011 if (rinfo->misc & 1)
1012 rinfo->vAct_high = 1;
1013 }
1014
1015 printk("radeonfb: detected DFP panel size from EDID: %dx%d\n",
1016 rinfo->panel_xres, rinfo->panel_yres);
1017
1018 rinfo->got_dfpinfo = 1;
1019
1020 return 1;
1021}
1022
1023
1024static void radeon_update_default_var(struct radeonfb_info *rinfo)
1025{
1026 struct fb_var_screeninfo *var = &radeonfb_default_var;
1027
1028 var->xres = rinfo->panel_xres;
1029 var->yres = rinfo->panel_yres;
1030 var->xres_virtual = rinfo->panel_xres;
1031 var->yres_virtual = rinfo->panel_yres;
1032 var->xoffset = var->yoffset = 0;
1033 var->bits_per_pixel = 8;
1034 var->pixclock = 100000000 / rinfo->clock;
1035 var->left_margin = (rinfo->hblank - rinfo->hOver_plus - rinfo->hSync_width);
1036 var->right_margin = rinfo->hOver_plus;
1037 var->upper_margin = (rinfo->vblank - rinfo->vOver_plus - rinfo->vSync_width);
1038 var->lower_margin = rinfo->vOver_plus;
1039 var->hsync_len = rinfo->hSync_width;
1040 var->vsync_len = rinfo->vSync_width;
1041 var->sync = 0;
1042 if (rinfo->synct == 3) {
1043 if (rinfo->hAct_high)
1044 var->sync |= FB_SYNC_HOR_HIGH_ACT;
1045 if (rinfo->vAct_high)
1046 var->sync |= FB_SYNC_VERT_HIGH_ACT;
1047 }
1048
1049 var->vmode = 0;
1050 if (rinfo->interlaced)
1051 var->vmode |= FB_VMODE_INTERLACED;
1052
1053 rinfo->use_default_var = 1;
1054}
1055
1056
1057static int radeon_get_dfpinfo_BIOS(struct radeonfb_info *rinfo)
1058{
1059 char __iomem *fpbiosstart, *tmp, *tmp0;
1060 char stmp[30];
1061 int i;
1062
1063 if (!rinfo->bios_seg)
1064 return 0;
1065
1066 if (!(fpbiosstart = rinfo->bios_seg + readw(rinfo->bios_seg + 0x48))) {
1067 printk("radeonfb: Failed to detect DFP panel info using BIOS\n");
1068 return 0;
1069 }
1070
1071 if (!(tmp = rinfo->bios_seg + readw(fpbiosstart + 0x40))) {
1072 printk("radeonfb: Failed to detect DFP panel info using BIOS\n");
1073 return 0;
1074 }
1075
1076 for(i=0; i<24; i++)
1077 stmp[i] = readb(tmp+i+1);
1078 stmp[24] = 0;
1079 printk("radeonfb: panel ID string: %s\n", stmp);
1080 rinfo->panel_xres = readw(tmp + 25);
1081 rinfo->panel_yres = readw(tmp + 27);
1082 printk("radeonfb: detected DFP panel size from BIOS: %dx%d\n",
1083 rinfo->panel_xres, rinfo->panel_yres);
1084
1085 for(i=0; i<32; i++) {
1086 tmp0 = rinfo->bios_seg + readw(tmp+64+i*2);
1087 if (tmp0 == 0)
1088 break;
1089 if ((readw(tmp0) == rinfo->panel_xres) &&
1090 (readw(tmp0+2) == rinfo->panel_yres)) {
1091 rinfo->hblank = (readw(tmp0+17) - readw(tmp0+19)) * 8;
1092 rinfo->hOver_plus = ((readw(tmp0+21) - readw(tmp0+19) -1) * 8) & 0x7fff;
1093 rinfo->hSync_width = readb(tmp0+23) * 8;
1094 rinfo->vblank = readw(tmp0+24) - readw(tmp0+26);
1095 rinfo->vOver_plus = (readw(tmp0+28) & 0x7ff) - readw(tmp0+26);
1096 rinfo->vSync_width = (readw(tmp0+28) & 0xf800) >> 11;
1097 rinfo->clock = readw(tmp0+9);
1098
1099 rinfo->got_dfpinfo = 1;
1100 return 1;
1101 }
1102 }
1103
1104 return 0;
1105}
1106
1107
1108
1109static int radeon_get_dfpinfo (struct radeonfb_info *rinfo)
1110{
1111 unsigned int tmp;
1112 unsigned short a, b;
1113
1114 if (radeon_get_dfpinfo_BIOS(rinfo))
1115 radeon_update_default_var(rinfo);
1116
1117 if (radeon_dfp_parse_EDID(rinfo))
1118 radeon_update_default_var(rinfo);
1119
1120 if (!rinfo->got_dfpinfo) {
1121 /*
1122 * it seems all else has failed now and we
1123 * resort to probing registers for our DFP info
1124 */
1125 if (panel_yres) {
1126 rinfo->panel_yres = panel_yres;
1127 } else {
1128 tmp = INREG(FP_VERT_STRETCH);
1129 tmp &= 0x00fff000;
1130 rinfo->panel_yres = (unsigned short)(tmp >> 0x0c) + 1;
1131 }
1132
1133 switch (rinfo->panel_yres) {
1134 case 480:
1135 rinfo->panel_xres = 640;
1136 break;
1137 case 600:
1138 rinfo->panel_xres = 800;
1139 break;
1140 case 768:
1141#if defined(__powerpc__)
1142 if (rinfo->dviDisp_type == MT_LCD)
1143 rinfo->panel_xres = 1152;
1144 else
1145#endif
1146 rinfo->panel_xres = 1024;
1147 break;
1148 case 1024:
1149 rinfo->panel_xres = 1280;
1150 break;
1151 case 1050:
1152 rinfo->panel_xres = 1400;
1153 break;
1154 case 1200:
1155 rinfo->panel_xres = 1600;
1156 break;
1157 default:
1158 printk("radeonfb: Failed to detect DFP panel size\n");
1159 return 0;
1160 }
1161
1162 printk("radeonfb: detected DFP panel size from registers: %dx%d\n",
1163 rinfo->panel_xres, rinfo->panel_yres);
1164
1165 tmp = INREG(FP_CRTC_H_TOTAL_DISP);
1166 a = (tmp & FP_CRTC_H_TOTAL_MASK) + 4;
1167 b = (tmp & 0x01ff0000) >> FP_CRTC_H_DISP_SHIFT;
1168 rinfo->hblank = (a - b + 1) * 8;
1169
1170 tmp = INREG(FP_H_SYNC_STRT_WID);
1171 rinfo->hOver_plus = (unsigned short) ((tmp & FP_H_SYNC_STRT_CHAR_MASK) >>
1172 FP_H_SYNC_STRT_CHAR_SHIFT) - b - 1;
1173 rinfo->hOver_plus *= 8;
1174 rinfo->hSync_width = (unsigned short) ((tmp & FP_H_SYNC_WID_MASK) >>
1175 FP_H_SYNC_WID_SHIFT);
1176 rinfo->hSync_width *= 8;
1177 tmp = INREG(FP_CRTC_V_TOTAL_DISP);
1178 a = (tmp & FP_CRTC_V_TOTAL_MASK) + 1;
1179 b = (tmp & FP_CRTC_V_DISP_MASK) >> FP_CRTC_V_DISP_SHIFT;
1180 rinfo->vblank = a - b /* + 24 */ ;
1181
1182 tmp = INREG(FP_V_SYNC_STRT_WID);
1183 rinfo->vOver_plus = (unsigned short) (tmp & FP_V_SYNC_STRT_MASK)
1184 - b + 1;
1185 rinfo->vSync_width = (unsigned short) ((tmp & FP_V_SYNC_WID_MASK) >>
1186 FP_V_SYNC_WID_SHIFT);
1187
1188 return 1;
1189 }
1190
1191 return 1;
1192}
1193
1194
1195#ifdef CONFIG_PPC_OF
1196static int radeon_read_OF (struct radeonfb_info *rinfo)
1197{
1198 struct device_node *dp;
1199 unsigned int *xtal;
1200
1201 dp = pci_device_to_OF_node(rinfo->pdev);
1202
1203 xtal = (unsigned int *) get_property(dp, "ATY,RefCLK", NULL);
1204
1205 rinfo->pll.ref_clk = *xtal / 10;
1206
1207 if (*xtal)
1208 return 1;
1209 else
1210 return 0;
1211}
1212#endif
1213
1214
1215static void radeon_engine_init (struct radeonfb_info *rinfo)
1216{
1217 u32 temp;
1218
1219 /* disable 3D engine */
1220 OUTREG(RB3D_CNTL, 0);
1221
1222 radeon_engine_reset ();
1223
1224 radeon_fifo_wait (1);
1225 OUTREG(RB2D_DSTCACHE_MODE, 0);
1226
1227 radeon_fifo_wait (1);
1228 temp = INREG(DEFAULT_PITCH_OFFSET);
1229 OUTREG(DEFAULT_PITCH_OFFSET, ((temp & 0xc0000000) |
1230 (rinfo->pitch << 0x16)));
1231
1232 radeon_fifo_wait (1);
1233 OUTREGP(DP_DATATYPE, 0, ~HOST_BIG_ENDIAN_EN);
1234
1235 radeon_fifo_wait (1);
1236 OUTREG(DEFAULT_SC_BOTTOM_RIGHT, (DEFAULT_SC_RIGHT_MAX |
1237 DEFAULT_SC_BOTTOM_MAX));
1238
1239 temp = radeon_get_dstbpp(rinfo->depth);
1240 rinfo->dp_gui_master_cntl = ((temp << 8) | GMC_CLR_CMP_CNTL_DIS);
1241 radeon_fifo_wait (1);
1242 OUTREG(DP_GUI_MASTER_CNTL, (rinfo->dp_gui_master_cntl |
1243 GMC_BRUSH_SOLID_COLOR |
1244 GMC_SRC_DATATYPE_COLOR));
1245
1246 radeon_fifo_wait (7);
1247
1248 /* clear line drawing regs */
1249 OUTREG(DST_LINE_START, 0);
1250 OUTREG(DST_LINE_END, 0);
1251
1252 /* set brush color regs */
1253 OUTREG(DP_BRUSH_FRGD_CLR, 0xffffffff);
1254 OUTREG(DP_BRUSH_BKGD_CLR, 0x00000000);
1255
1256 /* set source color regs */
1257 OUTREG(DP_SRC_FRGD_CLR, 0xffffffff);
1258 OUTREG(DP_SRC_BKGD_CLR, 0x00000000);
1259
1260 /* default write mask */
1261 OUTREG(DP_WRITE_MSK, 0xffffffff);
1262
1263 radeon_engine_idle ();
1264}
1265
1266
1267static int __devinit radeon_init_disp (struct radeonfb_info *rinfo)
1268{
1269 struct fb_info *info = &rinfo->info;
1270 struct fb_var_screeninfo var;
1271
1272 var = radeonfb_default_var;
1273 if ((radeon_init_disp_var(rinfo, &var)) < 0)
1274 return -1;
1275
1276 rinfo->depth = var_to_depth(&var);
1277 rinfo->bpp = var.bits_per_pixel;
1278
1279 info->var = var;
1280 fb_alloc_cmap(&info->cmap, 256, 0);
1281
1282 var.activate = FB_ACTIVATE_NOW;
1283 return 0;
1284}
1285
1286
1287static int radeon_init_disp_var (struct radeonfb_info *rinfo,
1288 struct fb_var_screeninfo *var)
1289{
1290#ifndef MODULE
1291 if (mode_option)
1292 fb_find_mode (var, &rinfo->info, mode_option,
1293 NULL, 0, NULL, 8);
1294 else
1295#endif
1296 if (rinfo->use_default_var)
1297 /* We will use the modified default far */
1298 *var = radeonfb_default_var;
1299 else
1300
1301 fb_find_mode (var, &rinfo->info, "640x480-8@60",
1302 NULL, 0, NULL, 0);
1303
1304 if (noaccel)
1305 var->accel_flags &= ~FB_ACCELF_TEXT;
1306 else
1307 var->accel_flags |= FB_ACCELF_TEXT;
1308
1309 return 0;
1310}
1311
1312
1313static int radeon_do_maximize(struct radeonfb_info *rinfo,
1314 struct fb_var_screeninfo *var,
1315 struct fb_var_screeninfo *v,
1316 int nom, int den)
1317{
1318 static struct {
1319 int xres, yres;
1320 } modes[] = {
1321 {1600, 1280},
1322 {1280, 1024},
1323 {1024, 768},
1324 {800, 600},
1325 {640, 480},
1326 {-1, -1}
1327 };
1328 int i;
1329
1330 /* use highest possible virtual resolution */
1331 if (v->xres_virtual == -1 && v->yres_virtual == -1) {
1332 printk("radeonfb: using max available virtual resolution\n");
1333 for (i=0; modes[i].xres != -1; i++) {
1334 if (modes[i].xres * nom / den * modes[i].yres <
1335 rinfo->video_ram / 2)
1336 break;
1337 }
1338 if (modes[i].xres == -1) {
1339 printk("radeonfb: could not find virtual resolution that fits into video memory!\n");
1340 return -EINVAL;
1341 }
1342 v->xres_virtual = modes[i].xres;
1343 v->yres_virtual = modes[i].yres;
1344
1345 printk("radeonfb: virtual resolution set to max of %dx%d\n",
1346 v->xres_virtual, v->yres_virtual);
1347 } else if (v->xres_virtual == -1) {
1348 v->xres_virtual = (rinfo->video_ram * den /
1349 (nom * v->yres_virtual * 2)) & ~15;
1350 } else if (v->yres_virtual == -1) {
1351 v->xres_virtual = (v->xres_virtual + 15) & ~15;
1352 v->yres_virtual = rinfo->video_ram * den /
1353 (nom * v->xres_virtual *2);
1354 } else {
1355 if (v->xres_virtual * nom / den * v->yres_virtual >
1356 rinfo->video_ram) {
1357 return -EINVAL;
1358 }
1359 }
1360
1361 if (v->xres_virtual * nom / den >= 8192) {
1362 v->xres_virtual = 8192 * den / nom - 16;
1363 }
1364
1365 if (v->xres_virtual < v->xres)
1366 return -EINVAL;
1367
1368 if (v->yres_virtual < v->yres)
1369 return -EINVAL;
1370
1371 return 0;
1372}
1373
1374
1375static int radeonfb_check_var (struct fb_var_screeninfo *var, struct fb_info *info)
1376{
1377 struct radeonfb_info *rinfo = (struct radeonfb_info *) info->par;
1378 struct fb_var_screeninfo v;
1379 int nom, den;
1380
1381 memcpy (&v, var, sizeof (v));
1382
1383 switch (v.bits_per_pixel) {
1384 case 0 ... 8:
1385 v.bits_per_pixel = 8;
1386 break;
1387 case 9 ... 16:
1388 v.bits_per_pixel = 16;
1389 break;
1390 case 17 ... 24:
1391#if 0 /* Doesn't seem to work */
1392 v.bits_per_pixel = 24;
1393 break;
1394#endif
1395 return -EINVAL;
1396 case 25 ... 32:
1397 v.bits_per_pixel = 32;
1398 break;
1399 default:
1400 return -EINVAL;
1401 }
1402
1403 switch (var_to_depth(&v)) {
1404 case 8:
1405 nom = den = 1;
1406 v.red.offset = v.green.offset = v.blue.offset = 0;
1407 v.red.length = v.green.length = v.blue.length = 8;
1408 v.transp.offset = v.transp.length = 0;
1409 break;
1410 case 15:
1411 nom = 2;
1412 den = 1;
1413 v.red.offset = 10;
1414 v.green.offset = 5;
1415 v.blue.offset = 0;
1416 v.red.length = v.green.length = v.blue.length = 5;
1417 v.transp.offset = v.transp.length = 0;
1418 break;
1419 case 16:
1420 nom = 2;
1421 den = 1;
1422 v.red.offset = 11;
1423 v.green.offset = 5;
1424 v.blue.offset = 0;
1425 v.red.length = 5;
1426 v.green.length = 6;
1427 v.blue.length = 5;
1428 v.transp.offset = v.transp.length = 0;
1429 break;
1430 case 24:
1431 nom = 4;
1432 den = 1;
1433 v.red.offset = 16;
1434 v.green.offset = 8;
1435 v.blue.offset = 0;
1436 v.red.length = v.blue.length = v.green.length = 8;
1437 v.transp.offset = v.transp.length = 0;
1438 break;
1439 case 32:
1440 nom = 4;
1441 den = 1;
1442 v.red.offset = 16;
1443 v.green.offset = 8;
1444 v.blue.offset = 0;
1445 v.red.length = v.blue.length = v.green.length = 8;
1446 v.transp.offset = 24;
1447 v.transp.length = 8;
1448 break;
1449 default:
1450 printk ("radeonfb: mode %dx%dx%d rejected, color depth invalid\n",
1451 var->xres, var->yres, var->bits_per_pixel);
1452 return -EINVAL;
1453 }
1454
1455 if (radeon_do_maximize(rinfo, var, &v, nom, den) < 0)
1456 return -EINVAL;
1457
1458 if (v.xoffset < 0)
1459 v.xoffset = 0;
1460 if (v.yoffset < 0)
1461 v.yoffset = 0;
1462
1463 if (v.xoffset > v.xres_virtual - v.xres)
1464 v.xoffset = v.xres_virtual - v.xres - 1;
1465
1466 if (v.yoffset > v.yres_virtual - v.yres)
1467 v.yoffset = v.yres_virtual - v.yres - 1;
1468
1469 v.red.msb_right = v.green.msb_right = v.blue.msb_right =
1470 v.transp.offset = v.transp.length =
1471 v.transp.msb_right = 0;
1472
1473 if (noaccel)
1474 v.accel_flags = 0;
1475
1476 memcpy(var, &v, sizeof(v));
1477
1478 return 0;
1479}
1480
1481
1482static int radeonfb_pan_display (struct fb_var_screeninfo *var,
1483 struct fb_info *info)
1484{
1485 struct radeonfb_info *rinfo = (struct radeonfb_info *) info;
1486
1487 if ((var->xoffset + var->xres > var->xres_virtual)
1488 || (var->yoffset + var->yres > var->yres_virtual))
1489 return -EINVAL;
1490
1491 if (rinfo->asleep)
1492 return 0;
1493
1494 OUTREG(CRTC_OFFSET, ((var->yoffset * var->xres_virtual + var->xoffset)
1495 * var->bits_per_pixel / 8) & ~7);
1496 return 0;
1497}
1498
1499
1500static int radeonfb_ioctl (struct fb_info *info, unsigned int cmd,
1501 unsigned long arg)
1502{
1503 struct radeonfb_info *rinfo = (struct radeonfb_info *) info;
1504 unsigned int tmp;
1505 u32 value = 0;
1506 int rc;
1507
1508 switch (cmd) {
1509 /*
1510 * TODO: set mirror accordingly for non-Mobility chipsets with 2 CRTC's
1511 */
1512 case FBIO_RADEON_SET_MIRROR:
1513 switch (rinfo->arch) {
1514 case RADEON_R100:
1515 case RADEON_RV100:
1516 case RADEON_R200:
1517 case RADEON_RV200:
1518 case RADEON_RV250:
1519 case RADEON_R300:
1520 return -EINVAL;
1521 default:
1522 /* RADEON M6, RADEON_M7, RADEON_M9 */
1523 break;
1524 }
1525
1526 rc = get_user(value, (__u32 __user *)arg);
1527
1528 if (rc)
1529 return rc;
1530
1531 if (value & 0x01) {
1532 tmp = INREG(LVDS_GEN_CNTL);
1533
1534 tmp |= (LVDS_ON | LVDS_BLON);
1535 } else {
1536 tmp = INREG(LVDS_GEN_CNTL);
1537
1538 tmp &= ~(LVDS_ON | LVDS_BLON);
1539 }
1540
1541 OUTREG(LVDS_GEN_CNTL, tmp);
1542
1543 if (value & 0x02) {
1544 tmp = INREG(CRTC_EXT_CNTL);
1545 tmp |= CRTC_CRT_ON;
1546
1547 mirror = 1;
1548 } else {
1549 tmp = INREG(CRTC_EXT_CNTL);
1550 tmp &= ~CRTC_CRT_ON;
1551
1552 mirror = 0;
1553 }
1554
1555 OUTREG(CRTC_EXT_CNTL, tmp);
1556
1557 break;
1558 case FBIO_RADEON_GET_MIRROR:
1559 switch (rinfo->arch) {
1560 case RADEON_R100:
1561 case RADEON_RV100:
1562 case RADEON_R200:
1563 case RADEON_RV200:
1564 case RADEON_RV250:
1565 case RADEON_R300:
1566 return -EINVAL;
1567 default:
1568 /* RADEON M6, RADEON_M7, RADEON_M9 */
1569 break;
1570 }
1571
1572 tmp = INREG(LVDS_GEN_CNTL);
1573 if ((LVDS_ON | LVDS_BLON) & tmp)
1574 value |= 0x01;
1575
1576 tmp = INREG(CRTC_EXT_CNTL);
1577 if (CRTC_CRT_ON & tmp)
1578 value |= 0x02;
1579
1580 return put_user(value, (__u32 __user *)arg);
1581 default:
1582 return -EINVAL;
1583 }
1584
1585 return -EINVAL;
1586}
1587
1588
1589static int radeonfb_blank (int blank, struct fb_info *info)
1590{
1591 struct radeonfb_info *rinfo = (struct radeonfb_info *) info;
1592 u32 val = INREG(CRTC_EXT_CNTL);
1593 u32 val2 = INREG(LVDS_GEN_CNTL);
1594
1595 if (rinfo->asleep)
1596 return 0;
1597
1598#ifdef CONFIG_PMAC_BACKLIGHT
1599 if (rinfo->dviDisp_type == MT_LCD && _machine == _MACH_Pmac) {
1600 set_backlight_enable(!blank);
1601 return 0;
1602 }
1603#endif
1604
1605 /* reset it */
1606 val &= ~(CRTC_DISPLAY_DIS | CRTC_HSYNC_DIS |
1607 CRTC_VSYNC_DIS);
1608 val2 &= ~(LVDS_DISPLAY_DIS);
1609
1610 switch (blank) {
1611 case FB_BLANK_UNBLANK:
1612 case FB_BLANK_NORMAL:
1613 break;
1614 case FB_BLANK_VSYNC_SUSPEND:
1615 val |= (CRTC_DISPLAY_DIS | CRTC_VSYNC_DIS);
1616 break;
1617 case FB_BLANK_HSYNC_SUSPEND:
1618 val |= (CRTC_DISPLAY_DIS | CRTC_HSYNC_DIS);
1619 break;
1620 case FB_BLANK_POWERDOWN:
1621 val |= (CRTC_DISPLAY_DIS | CRTC_VSYNC_DIS |
1622 CRTC_HSYNC_DIS);
1623 val2 |= (LVDS_DISPLAY_DIS);
1624 break;
1625 }
1626
1627 switch (rinfo->dviDisp_type) {
1628 case MT_LCD:
1629 OUTREG(LVDS_GEN_CNTL, val2);
1630 break;
1631 case MT_CRT:
1632 default:
1633 OUTREG(CRTC_EXT_CNTL, val);
1634 break;
1635 }
1636
1637 /* let fbcon do a soft blank for us */
1638 return (blank == FB_BLANK_NORMAL) ? 1 : 0;
1639}
1640
1641
1642static int radeonfb_setcolreg (unsigned regno, unsigned red, unsigned green,
1643 unsigned blue, unsigned transp, struct fb_info *info)
1644{
1645 struct radeonfb_info *rinfo = (struct radeonfb_info *) info;
1646 u32 pindex, vclk_cntl;
1647 unsigned int i;
1648
1649 if (regno > 255)
1650 return 1;
1651
1652 red >>= 8;
1653 green >>= 8;
1654 blue >>= 8;
1655 rinfo->palette[regno].red = red;
1656 rinfo->palette[regno].green = green;
1657 rinfo->palette[regno].blue = blue;
1658
1659 /* default */
1660 pindex = regno;
1661
1662 if (!rinfo->asleep) {
1663 vclk_cntl = INPLL(VCLK_ECP_CNTL);
1664 OUTPLL(VCLK_ECP_CNTL, vclk_cntl & ~PIXCLK_DAC_ALWAYS_ONb);
1665
1666 if (rinfo->bpp == 16) {
1667 pindex = regno * 8;
1668
1669 if (rinfo->depth == 16 && regno > 63)
1670 return 1;
1671 if (rinfo->depth == 15 && regno > 31)
1672 return 1;
1673
1674 /* For 565, the green component is mixed one order below */
1675 if (rinfo->depth == 16) {
1676 OUTREG(PALETTE_INDEX, pindex>>1);
1677 OUTREG(PALETTE_DATA, (rinfo->palette[regno>>1].red << 16) |
1678 (green << 8) | (rinfo->palette[regno>>1].blue));
1679 green = rinfo->palette[regno<<1].green;
1680 }
1681 }
1682
1683 if (rinfo->depth != 16 || regno < 32) {
1684 OUTREG(PALETTE_INDEX, pindex);
1685 OUTREG(PALETTE_DATA, (red << 16) | (green << 8) | blue);
1686 }
1687
1688 OUTPLL(VCLK_ECP_CNTL, vclk_cntl);
1689 }
1690 if (regno < 16) {
1691 switch (rinfo->depth) {
1692 case 15:
1693 ((u16 *) (info->pseudo_palette))[regno] =
1694 (regno << 10) | (regno << 5) | regno;
1695 break;
1696 case 16:
1697 ((u16 *) (info->pseudo_palette))[regno] =
1698 (regno << 11) | (regno << 6) | regno;
1699 break;
1700 case 24:
1701 ((u32 *) (info->pseudo_palette))[regno] =
1702 (regno << 16) | (regno << 8) | regno;
1703 break;
1704 case 32:
1705 i = (regno << 8) | regno;
1706 ((u32 *) (info->pseudo_palette))[regno] =
1707 (i << 16) | i;
1708 break;
1709 }
1710 }
1711 return 0;
1712}
1713
1714
1715
1716static void radeon_save_state (struct radeonfb_info *rinfo,
1717 struct radeon_regs *save)
1718{
1719 /* CRTC regs */
1720 save->crtc_gen_cntl = INREG(CRTC_GEN_CNTL);
1721 save->crtc_ext_cntl = INREG(CRTC_EXT_CNTL);
1722 save->dac_cntl = INREG(DAC_CNTL);
1723 save->crtc_h_total_disp = INREG(CRTC_H_TOTAL_DISP);
1724 save->crtc_h_sync_strt_wid = INREG(CRTC_H_SYNC_STRT_WID);
1725 save->crtc_v_total_disp = INREG(CRTC_V_TOTAL_DISP);
1726 save->crtc_v_sync_strt_wid = INREG(CRTC_V_SYNC_STRT_WID);
1727 save->crtc_pitch = INREG(CRTC_PITCH);
1728#if defined(__BIG_ENDIAN)
1729 save->surface_cntl = INREG(SURFACE_CNTL);
1730#endif
1731
1732 /* FP regs */
1733 save->fp_crtc_h_total_disp = INREG(FP_CRTC_H_TOTAL_DISP);
1734 save->fp_crtc_v_total_disp = INREG(FP_CRTC_V_TOTAL_DISP);
1735 save->fp_gen_cntl = INREG(FP_GEN_CNTL);
1736 save->fp_h_sync_strt_wid = INREG(FP_H_SYNC_STRT_WID);
1737 save->fp_horz_stretch = INREG(FP_HORZ_STRETCH);
1738 save->fp_v_sync_strt_wid = INREG(FP_V_SYNC_STRT_WID);
1739 save->fp_vert_stretch = INREG(FP_VERT_STRETCH);
1740 save->lvds_gen_cntl = INREG(LVDS_GEN_CNTL);
1741 save->lvds_pll_cntl = INREG(LVDS_PLL_CNTL);
1742 save->tmds_crc = INREG(TMDS_CRC);
1743 save->tmds_transmitter_cntl = INREG(TMDS_TRANSMITTER_CNTL);
1744 save->vclk_ecp_cntl = INPLL(VCLK_ECP_CNTL);
1745}
1746
1747
1748
1749static int radeonfb_set_par (struct fb_info *info)
1750{
1751 struct radeonfb_info *rinfo = (struct radeonfb_info *)info->par;
1752 struct fb_var_screeninfo *mode = &info->var;
1753 struct radeon_regs newmode;
1754 int hTotal, vTotal, hSyncStart, hSyncEnd,
1755 hSyncPol, vSyncStart, vSyncEnd, vSyncPol, cSync;
1756 u8 hsync_adj_tab[] = {0, 0x12, 9, 9, 6, 5};
1757 u8 hsync_fudge_fp[] = {2, 2, 0, 0, 5, 5};
1758 u32 dotClock = 1000000000 / mode->pixclock,
1759 sync, h_sync_pol, v_sync_pol;
1760 int freq = dotClock / 10; /* x 100 */
1761 int xclk_freq, vclk_freq, xclk_per_trans, xclk_per_trans_precise;
1762 int useable_precision, roff, ron;
1763 int min_bits, format = 0;
1764 int hsync_start, hsync_fudge, bytpp, hsync_wid, vsync_wid;
1765 int primary_mon = PRIMARY_MONITOR(rinfo);
1766 int depth = var_to_depth(mode);
1767 int accel = (mode->accel_flags & FB_ACCELF_TEXT) != 0;
1768
1769 rinfo->xres = mode->xres;
1770 rinfo->yres = mode->yres;
1771 rinfo->xres_virtual = mode->xres_virtual;
1772 rinfo->yres_virtual = mode->yres_virtual;
1773 rinfo->pixclock = mode->pixclock;
1774
1775 hSyncStart = mode->xres + mode->right_margin;
1776 hSyncEnd = hSyncStart + mode->hsync_len;
1777 hTotal = hSyncEnd + mode->left_margin;
1778
1779 vSyncStart = mode->yres + mode->lower_margin;
1780 vSyncEnd = vSyncStart + mode->vsync_len;
1781 vTotal = vSyncEnd + mode->upper_margin;
1782
1783 if ((primary_mon == MT_DFP) || (primary_mon == MT_LCD)) {
1784 if (rinfo->panel_xres < mode->xres)
1785 rinfo->xres = mode->xres = rinfo->panel_xres;
1786 if (rinfo->panel_yres < mode->yres)
1787 rinfo->yres = mode->yres = rinfo->panel_yres;
1788
1789 hTotal = mode->xres + rinfo->hblank;
1790 hSyncStart = mode->xres + rinfo->hOver_plus;
1791 hSyncEnd = hSyncStart + rinfo->hSync_width;
1792
1793 vTotal = mode->yres + rinfo->vblank;
1794 vSyncStart = mode->yres + rinfo->vOver_plus;
1795 vSyncEnd = vSyncStart + rinfo->vSync_width;
1796 }
1797
1798 sync = mode->sync;
1799 h_sync_pol = sync & FB_SYNC_HOR_HIGH_ACT ? 0 : 1;
1800 v_sync_pol = sync & FB_SYNC_VERT_HIGH_ACT ? 0 : 1;
1801
1802 RTRACE("hStart = %d, hEnd = %d, hTotal = %d\n",
1803 hSyncStart, hSyncEnd, hTotal);
1804 RTRACE("vStart = %d, vEnd = %d, vTotal = %d\n",
1805 vSyncStart, vSyncEnd, vTotal);
1806
1807 hsync_wid = (hSyncEnd - hSyncStart) / 8;
1808 vsync_wid = vSyncEnd - vSyncStart;
1809 if (hsync_wid == 0)
1810 hsync_wid = 1;
1811 else if (hsync_wid > 0x3f) /* max */
1812 hsync_wid = 0x3f;
1813
1814 if (vsync_wid == 0)
1815 vsync_wid = 1;
1816 else if (vsync_wid > 0x1f) /* max */
1817 vsync_wid = 0x1f;
1818
1819 hSyncPol = mode->sync & FB_SYNC_HOR_HIGH_ACT ? 0 : 1;
1820 vSyncPol = mode->sync & FB_SYNC_VERT_HIGH_ACT ? 0 : 1;
1821
1822 cSync = mode->sync & FB_SYNC_COMP_HIGH_ACT ? (1 << 4) : 0;
1823
1824 format = radeon_get_dstbpp(depth);
1825 bytpp = mode->bits_per_pixel >> 3;
1826
1827 if ((primary_mon == MT_DFP) || (primary_mon == MT_LCD))
1828 hsync_fudge = hsync_fudge_fp[format-1];
1829 else
1830 hsync_fudge = hsync_adj_tab[format-1];
1831
1832 hsync_start = hSyncStart - 8 + hsync_fudge;
1833
1834 newmode.crtc_gen_cntl = CRTC_EXT_DISP_EN | CRTC_EN |
1835 (format << 8);
1836
1837 if ((primary_mon == MT_DFP) || (primary_mon == MT_LCD)) {
1838 newmode.crtc_ext_cntl = VGA_ATI_LINEAR | XCRT_CNT_EN;
1839 if (mirror)
1840 newmode.crtc_ext_cntl |= CRTC_CRT_ON;
1841
1842 newmode.crtc_gen_cntl &= ~(CRTC_DBL_SCAN_EN |
1843 CRTC_INTERLACE_EN);
1844 } else {
1845 newmode.crtc_ext_cntl = VGA_ATI_LINEAR | XCRT_CNT_EN |
1846 CRTC_CRT_ON;
1847 }
1848
1849 newmode.dac_cntl = /* INREG(DAC_CNTL) | */ DAC_MASK_ALL | DAC_VGA_ADR_EN |
1850 DAC_8BIT_EN;
1851
1852 newmode.crtc_h_total_disp = ((((hTotal / 8) - 1) & 0x3ff) |
1853 (((mode->xres / 8) - 1) << 16));
1854
1855 newmode.crtc_h_sync_strt_wid = ((hsync_start & 0x1fff) |
1856 (hsync_wid << 16) | (h_sync_pol << 23));
1857
1858 newmode.crtc_v_total_disp = ((vTotal - 1) & 0xffff) |
1859 ((mode->yres - 1) << 16);
1860
1861 newmode.crtc_v_sync_strt_wid = (((vSyncStart - 1) & 0xfff) |
1862 (vsync_wid << 16) | (v_sync_pol << 23));
1863
1864 if (accel) {
1865 /* We first calculate the engine pitch */
1866 rinfo->pitch = ((mode->xres_virtual * ((mode->bits_per_pixel + 1) / 8) + 0x3f)
1867 & ~(0x3f)) >> 6;
1868
1869 /* Then, re-multiply it to get the CRTC pitch */
1870 newmode.crtc_pitch = (rinfo->pitch << 3) / ((mode->bits_per_pixel + 1) / 8);
1871 } else
1872 newmode.crtc_pitch = (mode->xres_virtual >> 3);
1873 newmode.crtc_pitch |= (newmode.crtc_pitch << 16);
1874
1875#if defined(__BIG_ENDIAN)
1876 /*
1877 * It looks like recent chips have a problem with SURFACE_CNTL,
1878 * setting SURF_TRANSLATION_DIS completely disables the
1879 * swapper as well, so we leave it unset now.
1880 */
1881 newmode.surface_cntl = 0;
1882
1883 /* Setup swapping on both apertures, though we currently
1884 * only use aperture 0, enabling swapper on aperture 1
1885 * won't harm
1886 */
1887 switch (mode->bits_per_pixel) {
1888 case 16:
1889 newmode.surface_cntl |= NONSURF_AP0_SWP_16BPP;
1890 newmode.surface_cntl |= NONSURF_AP1_SWP_16BPP;
1891 break;
1892 case 24:
1893 case 32:
1894 newmode.surface_cntl |= NONSURF_AP0_SWP_32BPP;
1895 newmode.surface_cntl |= NONSURF_AP1_SWP_32BPP;
1896 break;
1897 }
1898#endif
1899
1900 rinfo->pitch = ((mode->xres_virtual * ((mode->bits_per_pixel + 1) / 8) + 0x3f)
1901 & ~(0x3f)) / 64;
1902
1903 RTRACE("h_total_disp = 0x%x\t hsync_strt_wid = 0x%x\n",
1904 newmode.crtc_h_total_disp, newmode.crtc_h_sync_strt_wid);
1905 RTRACE("v_total_disp = 0x%x\t vsync_strt_wid = 0x%x\n",
1906 newmode.crtc_v_total_disp, newmode.crtc_v_sync_strt_wid);
1907
1908 newmode.xres = mode->xres;
1909 newmode.yres = mode->yres;
1910
1911 rinfo->bpp = mode->bits_per_pixel;
1912 rinfo->depth = depth;
1913
1914 if (freq > rinfo->pll.ppll_max)
1915 freq = rinfo->pll.ppll_max;
1916 if (freq*12 < rinfo->pll.ppll_min)
1917 freq = rinfo->pll.ppll_min / 12;
1918
1919 {
1920 struct {
1921 int divider;
1922 int bitvalue;
1923 } *post_div,
1924 post_divs[] = {
1925 { 1, 0 },
1926 { 2, 1 },
1927 { 4, 2 },
1928 { 8, 3 },
1929 { 3, 4 },
1930 { 16, 5 },
1931 { 6, 6 },
1932 { 12, 7 },
1933 { 0, 0 },
1934 };
1935
1936 for (post_div = &post_divs[0]; post_div->divider; ++post_div) {
1937 rinfo->pll_output_freq = post_div->divider * freq;
1938 if (rinfo->pll_output_freq >= rinfo->pll.ppll_min &&
1939 rinfo->pll_output_freq <= rinfo->pll.ppll_max)
1940 break;
1941 }
1942
1943 rinfo->post_div = post_div->divider;
1944 rinfo->fb_div = round_div(rinfo->pll.ref_div*rinfo->pll_output_freq,
1945 rinfo->pll.ref_clk);
1946 newmode.ppll_ref_div = rinfo->pll.ref_div;
1947 newmode.ppll_div_3 = rinfo->fb_div | (post_div->bitvalue << 16);
1948 }
1949 newmode.vclk_ecp_cntl = rinfo->init_state.vclk_ecp_cntl;
1950
1951#ifdef CONFIG_PPC_OF
1952 /* Gross hack for iBook with M7 until I find out a proper fix */
1953 if (machine_is_compatible("PowerBook4,3") && rinfo->arch == RADEON_M7)
1954 newmode.ppll_div_3 = 0x000600ad;
1955#endif /* CONFIG_PPC_OF */
1956
1957 RTRACE("post div = 0x%x\n", rinfo->post_div);
1958 RTRACE("fb_div = 0x%x\n", rinfo->fb_div);
1959 RTRACE("ppll_div_3 = 0x%x\n", newmode.ppll_div_3);
1960
1961 /* DDA */
1962 vclk_freq = round_div(rinfo->pll.ref_clk * rinfo->fb_div,
1963 rinfo->pll.ref_div * rinfo->post_div);
1964 xclk_freq = rinfo->pll.xclk;
1965
1966 xclk_per_trans = round_div(xclk_freq * 128, vclk_freq * mode->bits_per_pixel);
1967
1968 min_bits = min_bits_req(xclk_per_trans);
1969 useable_precision = min_bits + 1;
1970
1971 xclk_per_trans_precise = round_div((xclk_freq * 128) << (11 - useable_precision),
1972 vclk_freq * mode->bits_per_pixel);
1973
1974 ron = (4 * rinfo->ram.mb + 3 * _max(rinfo->ram.trcd - 2, 0) +
1975 2 * rinfo->ram.trp + rinfo->ram.twr + rinfo->ram.cl + rinfo->ram.tr2w +
1976 xclk_per_trans) << (11 - useable_precision);
1977 roff = xclk_per_trans_precise * (32 - 4);
1978
1979 RTRACE("ron = %d, roff = %d\n", ron, roff);
1980 RTRACE("vclk_freq = %d, per = %d\n", vclk_freq, xclk_per_trans_precise);
1981
1982 if ((ron + rinfo->ram.rloop) >= roff) {
1983 printk("radeonfb: error ron out of range\n");
1984 return -EINVAL;
1985 }
1986
1987 newmode.dda_config = (xclk_per_trans_precise |
1988 (useable_precision << 16) |
1989 (rinfo->ram.rloop << 20));
1990 newmode.dda_on_off = (ron << 16) | roff;
1991
1992 if ((primary_mon == MT_DFP) || (primary_mon == MT_LCD)) {
1993 unsigned int hRatio, vRatio;
1994
1995 /* We force the pixel clock to be always enabled. Allowing it
1996 * to be power managed during blanking would save power, but has
1997 * nasty interactions with the 2D engine & sleep code that haven't
1998 * been solved yet. --BenH
1999 */
2000 newmode.vclk_ecp_cntl &= ~PIXCLK_DAC_ALWAYS_ONb;
2001
2002 if (mode->xres > rinfo->panel_xres)
2003 mode->xres = rinfo->panel_xres;
2004 if (mode->yres > rinfo->panel_yres)
2005 mode->yres = rinfo->panel_yres;
2006
2007 newmode.fp_horz_stretch = (((rinfo->panel_xres / 8) - 1)
2008 << HORZ_PANEL_SHIFT);
2009 newmode.fp_vert_stretch = ((rinfo->panel_yres - 1)
2010 << VERT_PANEL_SHIFT);
2011
2012 if (mode->xres != rinfo->panel_xres) {
2013 hRatio = round_div(mode->xres * HORZ_STRETCH_RATIO_MAX,
2014 rinfo->panel_xres);
2015 newmode.fp_horz_stretch = (((((unsigned long)hRatio) & HORZ_STRETCH_RATIO_MASK)) |
2016 (newmode.fp_horz_stretch &
2017 (HORZ_PANEL_SIZE | HORZ_FP_LOOP_STRETCH |
2018 HORZ_AUTO_RATIO_INC)));
2019 newmode.fp_horz_stretch |= (HORZ_STRETCH_BLEND |
2020 HORZ_STRETCH_ENABLE);
2021 }
2022 newmode.fp_horz_stretch &= ~HORZ_AUTO_RATIO;
2023
2024 if (mode->yres != rinfo->panel_yres) {
2025 vRatio = round_div(mode->yres * VERT_STRETCH_RATIO_MAX,
2026 rinfo->panel_yres);
2027 newmode.fp_vert_stretch = (((((unsigned long)vRatio) & VERT_STRETCH_RATIO_MASK)) |
2028 (newmode.fp_vert_stretch &
2029 (VERT_PANEL_SIZE | VERT_STRETCH_RESERVED)));
2030 newmode.fp_vert_stretch |= (VERT_STRETCH_BLEND |
2031 VERT_STRETCH_ENABLE);
2032 }
2033 newmode.fp_vert_stretch &= ~VERT_AUTO_RATIO_EN;
2034
2035 newmode.fp_gen_cntl = (rinfo->init_state.fp_gen_cntl & (u32)
2036 ~(FP_SEL_CRTC2 |
2037 FP_RMX_HVSYNC_CONTROL_EN |
2038 FP_DFP_SYNC_SEL |
2039 FP_CRT_SYNC_SEL |
2040 FP_CRTC_LOCK_8DOT |
2041 FP_USE_SHADOW_EN |
2042 FP_CRTC_USE_SHADOW_VEND |
2043 FP_CRT_SYNC_ALT));
2044
2045 newmode.fp_gen_cntl |= (FP_CRTC_DONT_SHADOW_VPAR |
2046 FP_CRTC_DONT_SHADOW_HEND);
2047
2048 newmode.lvds_gen_cntl = rinfo->init_state.lvds_gen_cntl;
2049 newmode.lvds_pll_cntl = rinfo->init_state.lvds_pll_cntl;
2050 newmode.tmds_crc = rinfo->init_state.tmds_crc;
2051 newmode.tmds_transmitter_cntl = rinfo->init_state.tmds_transmitter_cntl;
2052
2053 if (primary_mon == MT_LCD) {
2054 newmode.lvds_gen_cntl |= (LVDS_ON | LVDS_BLON);
2055 newmode.fp_gen_cntl &= ~(FP_FPON | FP_TMDS_EN);
2056 } else {
2057 /* DFP */
2058 newmode.fp_gen_cntl |= (FP_FPON | FP_TMDS_EN);
2059 newmode.tmds_transmitter_cntl = (TMDS_RAN_PAT_RST |
2060 TMDS_ICHCSEL | TMDS_PLL_EN) &
2061 ~(TMDS_PLLRST);
2062 newmode.crtc_ext_cntl &= ~CRTC_CRT_ON;
2063 }
2064
2065 newmode.fp_crtc_h_total_disp = (((rinfo->hblank / 8) & 0x3ff) |
2066 (((mode->xres / 8) - 1) << 16));
2067 newmode.fp_crtc_v_total_disp = (rinfo->vblank & 0xffff) |
2068 ((mode->yres - 1) << 16);
2069 newmode.fp_h_sync_strt_wid = ((rinfo->hOver_plus & 0x1fff) |
2070 (hsync_wid << 16) | (h_sync_pol << 23));
2071 newmode.fp_v_sync_strt_wid = ((rinfo->vOver_plus & 0xfff) |
2072 (vsync_wid << 16) | (v_sync_pol << 23));
2073 }
2074
2075 /* do it! */
2076 if (!rinfo->asleep) {
2077 radeon_write_mode (rinfo, &newmode);
2078 /* (re)initialize the engine */
2079 if (noaccel)
2080 radeon_engine_init (rinfo);
2081
2082 }
2083 /* Update fix */
2084 if (accel)
2085 info->fix.line_length = rinfo->pitch*64;
2086 else
2087 info->fix.line_length = mode->xres_virtual * ((mode->bits_per_pixel + 1) / 8);
2088 info->fix.visual = rinfo->depth == 8 ? FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_DIRECTCOLOR;
2089
2090#ifdef CONFIG_BOOTX_TEXT
2091 /* Update debug text engine */
2092 btext_update_display(rinfo->fb_base_phys, mode->xres, mode->yres,
2093 rinfo->depth, info->fix.line_length);
2094#endif
2095
2096 return 0;
2097}
2098
2099
2100static void radeon_write_mode (struct radeonfb_info *rinfo,
2101 struct radeon_regs *mode)
2102{
2103 int i;
2104 int primary_mon = PRIMARY_MONITOR(rinfo);
2105
2106 radeonfb_blank(VESA_POWERDOWN, (struct fb_info *)rinfo);
2107
2108
2109 if (rinfo->arch == RADEON_M6) {
2110 for (i=0; i<7; i++)
2111 OUTREG(common_regs_m6[i].reg, common_regs_m6[i].val);
2112 } else {
2113 for (i=0; i<9; i++)
2114 OUTREG(common_regs[i].reg, common_regs[i].val);
2115 }
2116
2117 OUTREG(CRTC_GEN_CNTL, mode->crtc_gen_cntl);
2118 OUTREGP(CRTC_EXT_CNTL, mode->crtc_ext_cntl,
2119 CRTC_HSYNC_DIS | CRTC_VSYNC_DIS | CRTC_DISPLAY_DIS);
2120 OUTREGP(DAC_CNTL, mode->dac_cntl, DAC_RANGE_CNTL | DAC_BLANKING);
2121 OUTREG(CRTC_H_TOTAL_DISP, mode->crtc_h_total_disp);
2122 OUTREG(CRTC_H_SYNC_STRT_WID, mode->crtc_h_sync_strt_wid);
2123 OUTREG(CRTC_V_TOTAL_DISP, mode->crtc_v_total_disp);
2124 OUTREG(CRTC_V_SYNC_STRT_WID, mode->crtc_v_sync_strt_wid);
2125 OUTREG(CRTC_OFFSET, 0);
2126 OUTREG(CRTC_OFFSET_CNTL, 0);
2127 OUTREG(CRTC_PITCH, mode->crtc_pitch);
2128
2129#if defined(__BIG_ENDIAN)
2130 OUTREG(SURFACE_CNTL, mode->surface_cntl);
2131#endif
2132
2133 while ((INREG(CLOCK_CNTL_INDEX) & PPLL_DIV_SEL_MASK) !=
2134 PPLL_DIV_SEL_MASK) {
2135 OUTREGP(CLOCK_CNTL_INDEX, PPLL_DIV_SEL_MASK, 0xffff);
2136 }
2137
2138 OUTPLLP(PPLL_CNTL, PPLL_RESET, 0xffff);
2139
2140 while ((INPLL(PPLL_REF_DIV) & PPLL_REF_DIV_MASK) !=
2141 (mode->ppll_ref_div & PPLL_REF_DIV_MASK)) {
2142 OUTPLLP(PPLL_REF_DIV, mode->ppll_ref_div, ~PPLL_REF_DIV_MASK);
2143 }
2144
2145 while ((INPLL(PPLL_DIV_3) & PPLL_FB3_DIV_MASK) !=
2146 (mode->ppll_div_3 & PPLL_FB3_DIV_MASK)) {
2147 OUTPLLP(PPLL_DIV_3, mode->ppll_div_3, ~PPLL_FB3_DIV_MASK);
2148 }
2149
2150 while ((INPLL(PPLL_DIV_3) & PPLL_POST3_DIV_MASK) !=
2151 (mode->ppll_div_3 & PPLL_POST3_DIV_MASK)) {
2152 OUTPLLP(PPLL_DIV_3, mode->ppll_div_3, ~PPLL_POST3_DIV_MASK);
2153 }
2154
2155 OUTPLL(HTOTAL_CNTL, 0);
2156
2157 OUTPLLP(PPLL_CNTL, 0, ~PPLL_RESET);
2158
2159// OUTREG(DDA_CONFIG, mode->dda_config);
2160// OUTREG(DDA_ON_OFF, mode->dda_on_off);
2161
2162 if ((primary_mon == MT_DFP) || (primary_mon == MT_LCD)) {
2163 OUTREG(FP_CRTC_H_TOTAL_DISP, mode->fp_crtc_h_total_disp);
2164 OUTREG(FP_CRTC_V_TOTAL_DISP, mode->fp_crtc_v_total_disp);
2165 OUTREG(FP_H_SYNC_STRT_WID, mode->fp_h_sync_strt_wid);
2166 OUTREG(FP_V_SYNC_STRT_WID, mode->fp_v_sync_strt_wid);
2167 OUTREG(FP_HORZ_STRETCH, mode->fp_horz_stretch);
2168 OUTREG(FP_VERT_STRETCH, mode->fp_vert_stretch);
2169 OUTREG(FP_GEN_CNTL, mode->fp_gen_cntl);
2170 OUTREG(TMDS_CRC, mode->tmds_crc);
2171 OUTREG(TMDS_TRANSMITTER_CNTL, mode->tmds_transmitter_cntl);
2172
2173 if (primary_mon == MT_LCD) {
2174 unsigned int tmp = INREG(LVDS_GEN_CNTL);
2175
2176 mode->lvds_gen_cntl &= ~LVDS_STATE_MASK;
2177 mode->lvds_gen_cntl |= (rinfo->init_state.lvds_gen_cntl & LVDS_STATE_MASK);
2178
2179 if ((tmp & (LVDS_ON | LVDS_BLON)) ==
2180 (mode->lvds_gen_cntl & (LVDS_ON | LVDS_BLON))) {
2181 OUTREG(LVDS_GEN_CNTL, mode->lvds_gen_cntl);
2182 } else {
2183 if (mode->lvds_gen_cntl & (LVDS_ON | LVDS_BLON)) {
2184 udelay(1000);
2185 OUTREG(LVDS_GEN_CNTL, mode->lvds_gen_cntl);
2186 } else {
2187 OUTREG(LVDS_GEN_CNTL, mode->lvds_gen_cntl |
2188 LVDS_BLON);
2189 udelay(1000);
2190 OUTREG(LVDS_GEN_CNTL, mode->lvds_gen_cntl);
2191 }
2192 }
2193 }
2194 }
2195
2196 radeonfb_blank(VESA_NO_BLANKING, (struct fb_info *)rinfo);
2197
2198 OUTPLL(VCLK_ECP_CNTL, mode->vclk_ecp_cntl);
2199
2200 return;
2201}
2202
2203static struct fb_ops radeonfb_ops = {
2204 .owner = THIS_MODULE,
2205 .fb_check_var = radeonfb_check_var,
2206 .fb_set_par = radeonfb_set_par,
2207 .fb_setcolreg = radeonfb_setcolreg,
2208 .fb_pan_display = radeonfb_pan_display,
2209 .fb_blank = radeonfb_blank,
2210 .fb_ioctl = radeonfb_ioctl,
2211#if 0
2212 .fb_fillrect = radeonfb_fillrect,
2213 .fb_copyarea = radeonfb_copyarea,
2214 .fb_imageblit = radeonfb_imageblit,
2215 .fb_rasterimg = radeonfb_rasterimg,
2216#else
2217 .fb_fillrect = cfb_fillrect,
2218 .fb_copyarea = cfb_copyarea,
2219 .fb_imageblit = cfb_imageblit,
2220#endif
2221};
2222
2223
2224static int __devinit radeon_set_fbinfo (struct radeonfb_info *rinfo)
2225{
2226 struct fb_info *info;
2227
2228 info = &rinfo->info;
2229
2230 info->par = rinfo;
2231 info->pseudo_palette = rinfo->pseudo_palette;
2232 info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN;
2233 info->fbops = &radeonfb_ops;
2234 info->screen_base = rinfo->fb_base;
2235
2236 /* Fill fix common fields */
2237 strlcpy(info->fix.id, rinfo->name, sizeof(info->fix.id));
2238 info->fix.smem_start = rinfo->fb_base_phys;
2239 info->fix.smem_len = rinfo->video_ram;
2240 info->fix.type = FB_TYPE_PACKED_PIXELS;
2241 info->fix.visual = FB_VISUAL_PSEUDOCOLOR;
2242 info->fix.xpanstep = 8;
2243 info->fix.ypanstep = 1;
2244 info->fix.ywrapstep = 0;
2245 info->fix.type_aux = 0;
2246 info->fix.mmio_start = rinfo->mmio_base_phys;
2247 info->fix.mmio_len = RADEON_REGSIZE;
2248 if (noaccel)
2249 info->fix.accel = FB_ACCEL_NONE;
2250 else
2251 info->fix.accel = FB_ACCEL_ATI_RADEON;
2252
2253 if (radeon_init_disp (rinfo) < 0)
2254 return -1;
2255
2256 return 0;
2257}
2258
2259
2260#ifdef CONFIG_PMAC_BACKLIGHT
2261
2262/* TODO: Dbl check these tables, we don't go up to full ON backlight
2263 * in these, possibly because we noticed MacOS doesn't, but I'd prefer
2264 * having some more official numbers from ATI
2265 */
2266static int backlight_conv_m6[] = {
2267 0xff, 0xc0, 0xb5, 0xaa, 0x9f, 0x94, 0x89, 0x7e,
2268 0x73, 0x68, 0x5d, 0x52, 0x47, 0x3c, 0x31, 0x24
2269};
2270static int backlight_conv_m7[] = {
2271 0x00, 0x3f, 0x4a, 0x55, 0x60, 0x6b, 0x76, 0x81,
2272 0x8c, 0x97, 0xa2, 0xad, 0xb8, 0xc3, 0xce, 0xd9
2273};
2274
2275#define BACKLIGHT_LVDS_OFF
2276#undef BACKLIGHT_DAC_OFF
2277
2278/* We turn off the LCD completely instead of just dimming the backlight.
2279 * This provides some greater power saving and the display is useless
2280 * without backlight anyway.
2281 */
2282
2283static int radeon_set_backlight_enable(int on, int level, void *data)
2284{
2285 struct radeonfb_info *rinfo = (struct radeonfb_info *)data;
2286 unsigned int lvds_gen_cntl = INREG(LVDS_GEN_CNTL);
2287 int* conv_table;
2288
2289 /* Pardon me for that hack... maybe some day we can figure
2290 * out in what direction backlight should work on a given
2291 * panel ?
2292 */
2293 if ((rinfo->arch == RADEON_M7 || rinfo->arch == RADEON_M9)
2294 && !machine_is_compatible("PowerBook4,3"))
2295 conv_table = backlight_conv_m7;
2296 else
2297 conv_table = backlight_conv_m6;
2298
2299 lvds_gen_cntl |= (LVDS_BL_MOD_EN | LVDS_BLON);
2300 if (on && (level > BACKLIGHT_OFF)) {
2301 lvds_gen_cntl |= LVDS_DIGON;
2302 if (!(lvds_gen_cntl & LVDS_ON)) {
2303 lvds_gen_cntl &= ~LVDS_BLON;
2304 OUTREG(LVDS_GEN_CNTL, lvds_gen_cntl);
2305 (void)INREG(LVDS_GEN_CNTL);
2306 mdelay(10);
2307 lvds_gen_cntl |= LVDS_BLON;
2308 OUTREG(LVDS_GEN_CNTL, lvds_gen_cntl);
2309 }
2310 lvds_gen_cntl &= ~LVDS_BL_MOD_LEVEL_MASK;
2311 lvds_gen_cntl |= (conv_table[level] <<
2312 LVDS_BL_MOD_LEVEL_SHIFT);
2313 lvds_gen_cntl |= (LVDS_ON | LVDS_EN);
2314 lvds_gen_cntl &= ~LVDS_DISPLAY_DIS;
2315 } else {
2316 lvds_gen_cntl &= ~LVDS_BL_MOD_LEVEL_MASK;
2317 lvds_gen_cntl |= (conv_table[0] <<
2318 LVDS_BL_MOD_LEVEL_SHIFT);
2319 lvds_gen_cntl |= LVDS_DISPLAY_DIS;
2320 OUTREG(LVDS_GEN_CNTL, lvds_gen_cntl);
2321 udelay(10);
2322 lvds_gen_cntl &= ~(LVDS_ON | LVDS_EN | LVDS_BLON | LVDS_DIGON);
2323 }
2324
2325 OUTREG(LVDS_GEN_CNTL, lvds_gen_cntl);
2326 rinfo->init_state.lvds_gen_cntl &= ~LVDS_STATE_MASK;
2327 rinfo->init_state.lvds_gen_cntl |= (lvds_gen_cntl & LVDS_STATE_MASK);
2328
2329 return 0;
2330}
2331
2332static int radeon_set_backlight_level(int level, void *data)
2333{
2334 return radeon_set_backlight_enable(1, level, data);
2335}
2336#endif /* CONFIG_PMAC_BACKLIGHT */
2337
2338
2339#ifdef CONFIG_PMAC_PBOOK
2340
2341static u32 dbg_clk;
2342
2343/*
2344 * Radeon M6 Power Management code. This code currently only supports
2345 * the mobile chips, it's based from some informations provided by ATI
2346 * along with hours of tracing of MacOS drivers
2347 */
2348
2349static void radeon_pm_save_regs(struct radeonfb_info *rinfo)
2350{
2351 rinfo->save_regs[0] = INPLL(PLL_PWRMGT_CNTL);
2352 rinfo->save_regs[1] = INPLL(CLK_PWRMGT_CNTL);
2353 rinfo->save_regs[2] = INPLL(MCLK_CNTL);
2354 rinfo->save_regs[3] = INPLL(SCLK_CNTL);
2355 rinfo->save_regs[4] = INPLL(CLK_PIN_CNTL);
2356 rinfo->save_regs[5] = INPLL(VCLK_ECP_CNTL);
2357 rinfo->save_regs[6] = INPLL(PIXCLKS_CNTL);
2358 rinfo->save_regs[7] = INPLL(MCLK_MISC);
2359 rinfo->save_regs[8] = INPLL(P2PLL_CNTL);
2360
2361 rinfo->save_regs[9] = INREG(DISP_MISC_CNTL);
2362 rinfo->save_regs[10] = INREG(DISP_PWR_MAN);
2363 rinfo->save_regs[11] = INREG(LVDS_GEN_CNTL);
2364 rinfo->save_regs[12] = INREG(LVDS_PLL_CNTL);
2365 rinfo->save_regs[13] = INREG(TV_DAC_CNTL);
2366 rinfo->save_regs[14] = INREG(BUS_CNTL1);
2367 rinfo->save_regs[15] = INREG(CRTC_OFFSET_CNTL);
2368 rinfo->save_regs[16] = INREG(AGP_CNTL);
2369 rinfo->save_regs[17] = (INREG(CRTC_GEN_CNTL) & 0xfdffffff) | 0x04000000;
2370 rinfo->save_regs[18] = (INREG(CRTC2_GEN_CNTL) & 0xfdffffff) | 0x04000000;
2371 rinfo->save_regs[19] = INREG(GPIOPAD_A);
2372 rinfo->save_regs[20] = INREG(GPIOPAD_EN);
2373 rinfo->save_regs[21] = INREG(GPIOPAD_MASK);
2374 rinfo->save_regs[22] = INREG(ZV_LCDPAD_A);
2375 rinfo->save_regs[23] = INREG(ZV_LCDPAD_EN);
2376 rinfo->save_regs[24] = INREG(ZV_LCDPAD_MASK);
2377 rinfo->save_regs[25] = INREG(GPIO_VGA_DDC);
2378 rinfo->save_regs[26] = INREG(GPIO_DVI_DDC);
2379 rinfo->save_regs[27] = INREG(GPIO_MONID);
2380 rinfo->save_regs[28] = INREG(GPIO_CRT2_DDC);
2381
2382 rinfo->save_regs[29] = INREG(SURFACE_CNTL);
2383 rinfo->save_regs[30] = INREG(MC_FB_LOCATION);
2384 rinfo->save_regs[31] = INREG(DISPLAY_BASE_ADDR);
2385 rinfo->save_regs[32] = INREG(MC_AGP_LOCATION);
2386 rinfo->save_regs[33] = INREG(CRTC2_DISPLAY_BASE_ADDR);
2387}
2388
2389static void radeon_pm_restore_regs(struct radeonfb_info *rinfo)
2390{
2391 OUTPLL(P2PLL_CNTL, rinfo->save_regs[8] & 0xFFFFFFFE); /* First */
2392
2393 OUTPLL(PLL_PWRMGT_CNTL, rinfo->save_regs[0]);
2394 OUTPLL(CLK_PWRMGT_CNTL, rinfo->save_regs[1]);
2395 OUTPLL(MCLK_CNTL, rinfo->save_regs[2]);
2396 OUTPLL(SCLK_CNTL, rinfo->save_regs[3]);
2397 OUTPLL(CLK_PIN_CNTL, rinfo->save_regs[4]);
2398 OUTPLL(VCLK_ECP_CNTL, rinfo->save_regs[5]);
2399 OUTPLL(PIXCLKS_CNTL, rinfo->save_regs[6]);
2400 OUTPLL(MCLK_MISC, rinfo->save_regs[7]);
2401
2402 OUTREG(DISP_MISC_CNTL, rinfo->save_regs[9]);
2403 OUTREG(DISP_PWR_MAN, rinfo->save_regs[10]);
2404 OUTREG(LVDS_GEN_CNTL, rinfo->save_regs[11]);
2405 OUTREG(LVDS_PLL_CNTL,rinfo->save_regs[12]);
2406 OUTREG(TV_DAC_CNTL, rinfo->save_regs[13]);
2407 OUTREG(BUS_CNTL1, rinfo->save_regs[14]);
2408 OUTREG(CRTC_OFFSET_CNTL, rinfo->save_regs[15]);
2409 OUTREG(AGP_CNTL, rinfo->save_regs[16]);
2410 OUTREG(CRTC_GEN_CNTL, rinfo->save_regs[17]);
2411 OUTREG(CRTC2_GEN_CNTL, rinfo->save_regs[18]);
2412
2413 // wait VBL before that one ?
2414 OUTPLL(P2PLL_CNTL, rinfo->save_regs[8]);
2415
2416 OUTREG(GPIOPAD_A, rinfo->save_regs[19]);
2417 OUTREG(GPIOPAD_EN, rinfo->save_regs[20]);
2418 OUTREG(GPIOPAD_MASK, rinfo->save_regs[21]);
2419 OUTREG(ZV_LCDPAD_A, rinfo->save_regs[22]);
2420 OUTREG(ZV_LCDPAD_EN, rinfo->save_regs[23]);
2421 OUTREG(ZV_LCDPAD_MASK, rinfo->save_regs[24]);
2422 OUTREG(GPIO_VGA_DDC, rinfo->save_regs[25]);
2423 OUTREG(GPIO_DVI_DDC, rinfo->save_regs[26]);
2424 OUTREG(GPIO_MONID, rinfo->save_regs[27]);
2425 OUTREG(GPIO_CRT2_DDC, rinfo->save_regs[28]);
2426}
2427
2428static void radeon_pm_disable_iopad(struct radeonfb_info *rinfo)
2429{
2430 OUTREG(GPIOPAD_MASK, 0x0001ffff);
2431 OUTREG(GPIOPAD_EN, 0x00000400);
2432 OUTREG(GPIOPAD_A, 0x00000000);
2433 OUTREG(ZV_LCDPAD_MASK, 0x00000000);
2434 OUTREG(ZV_LCDPAD_EN, 0x00000000);
2435 OUTREG(ZV_LCDPAD_A, 0x00000000);
2436 OUTREG(GPIO_VGA_DDC, 0x00030000);
2437 OUTREG(GPIO_DVI_DDC, 0x00000000);
2438 OUTREG(GPIO_MONID, 0x00030000);
2439 OUTREG(GPIO_CRT2_DDC, 0x00000000);
2440}
2441
2442static void radeon_pm_program_v2clk(struct radeonfb_info *rinfo)
2443{
2444//
2445// u32 reg;
2446//
2447// OUTPLL(P2PLL_REF_DIV, 0x0c);
2448//
2449// .../... figure out what macos does here
2450}
2451
2452static void radeon_pm_low_current(struct radeonfb_info *rinfo)
2453{
2454 u32 reg;
2455
2456 reg = INREG(BUS_CNTL1);
2457 reg &= ~BUS_CNTL1_MOBILE_PLATFORM_SEL_MASK;
2458 reg |= BUS_CNTL1_AGPCLK_VALID | (1<<BUS_CNTL1_MOBILE_PLATFORM_SEL_SHIFT);
2459 OUTREG(BUS_CNTL1, reg);
2460
2461 reg = INPLL(PLL_PWRMGT_CNTL);
2462 reg |= PLL_PWRMGT_CNTL_SPLL_TURNOFF | PLL_PWRMGT_CNTL_PPLL_TURNOFF |
2463 PLL_PWRMGT_CNTL_P2PLL_TURNOFF | PLL_PWRMGT_CNTL_TVPLL_TURNOFF;
2464 reg &= ~PLL_PWRMGT_CNTL_SU_MCLK_USE_BCLK;
2465 reg &= ~PLL_PWRMGT_CNTL_MOBILE_SU;
2466 OUTPLL(PLL_PWRMGT_CNTL, reg);
2467
2468// reg = INPLL(TV_PLL_CNTL1);
2469// reg |= TV_PLL_CNTL1__TVPLL_RESET | TV_PLL_CNTL1__TVPLL_SLEEP;
2470// OUTPLL(TV_PLL_CNTL1, reg);
2471
2472 reg = INREG(TV_DAC_CNTL);
2473 reg &= ~(TV_DAC_CNTL_BGADJ_MASK |TV_DAC_CNTL_DACADJ_MASK);
2474 reg |=TV_DAC_CNTL_BGSLEEP | TV_DAC_CNTL_RDACPD | TV_DAC_CNTL_GDACPD |
2475 TV_DAC_CNTL_BDACPD |
2476 (8<<TV_DAC_CNTL_BGADJ__SHIFT) | (8<<TV_DAC_CNTL_DACADJ__SHIFT);
2477 OUTREG(TV_DAC_CNTL, reg);
2478
2479 reg = INREG(TMDS_TRANSMITTER_CNTL);
2480 reg &= ~(TMDS_PLL_EN |TMDS_PLLRST);
2481 OUTREG(TMDS_TRANSMITTER_CNTL, reg);
2482
2483// lvds_pll_cntl = regr32(g, LVDS_PLL_CNTL);
2484// lvds_pll_cntl &= ~LVDS_PLL_CNTL__LVDS_PLL_EN;
2485// lvds_pll_cntl |= LVDS_PLL_CNTL__LVDS_PLL_RESET;
2486// regw32(g, LVDS_PLL_CNTL, lvds_pll_cntl);
2487
2488 reg = INREG(DAC_CNTL);
2489 reg &= ~DAC_CMP_EN;
2490 OUTREG(DAC_CNTL, reg);
2491
2492 reg = INREG(DAC_CNTL2);
2493 reg &= ~DAC2_CMP_EN;
2494 OUTREG(DAC_CNTL2, reg);
2495
2496 reg = INREG(TV_DAC_CNTL);
2497 reg &= ~TV_DAC_CNTL_DETECT;
2498 OUTREG(TV_DAC_CNTL, reg);
2499}
2500
2501static void radeon_pm_setup_for_suspend(struct radeonfb_info *rinfo)
2502{
2503 /* This code is disabled. It does what is in the pm_init
2504 * function of the MacOS driver code ATI sent me. However,
2505 * it doesn't fix my sleep problem, and is causing other issues
2506 * on wakeup (bascially the machine dying when switching consoles
2507 * I haven't had time to investigate this yet
2508 */
2509#if 0
2510 u32 disp_misc_cntl;
2511 u32 disp_pwr_man;
2512 u32 temp;
2513
2514 // set SPLL, MPLL, PPLL, P2PLL, TVPLL, SCLK, MCLK, PCLK, P2CLK,
2515 // TCLK and TEST_MODE to 0
2516 temp = INPLL(CLK_PWRMGT_CNTL);
2517 OUTPLL(CLK_PWRMGT_CNTL , temp & ~0xc00002ff);
2518
2519 // Turn on Power Management
2520 temp = INPLL(CLK_PWRMGT_CNTL);
2521 OUTPLL(CLK_PWRMGT_CNTL , temp | 0x00000400);
2522
2523 // Turn off display clock if using mobile chips
2524 temp = INPLL(CLK_PWRMGT_CNTL);
2525 OUTREG(CLK_PWRMGT_CNTL , temp | 0x00100000);
2526
2527 // Force PIXCLK_ALWAYS_ON and PIXCLK_DAC_ALWAYS_ON
2528 temp = INPLL(VCLK_ECP_CNTL);
2529 OUTPLL(VCLK_ECP_CNTL, temp & ~0x000000c0);
2530
2531 // Force ECP_FORCE_ON to 1
2532 temp = INPLL(VCLK_ECP_CNTL);
2533 OUTPLL(VCLK_ECP_CNTL, temp | 0x00040000);
2534
2535 // Force PIXCLK_BLEND_ALWAYS_ON and PIXCLK_GV_ALWAYS_ON
2536 temp = INPLL(PIXCLKS_CNTL);
2537 OUTPLL(PIXCLKS_CNTL, temp & ~0x00001800);
2538
2539 // Forcing SCLK_CNTL to ON
2540 OUTPLL(SCLK_CNTL, (INPLL(SCLK_CNTL)& 0x00000007) | 0xffff8000 );
2541
2542 // Set PM control over XTALIN pad
2543 temp = INPLL(CLK_PIN_CNTL);
2544 OUTPLL(CLK_PIN_CNTL, temp | 0x00080000);
2545
2546 // Force MCLK and YCLK and MC as dynamic
2547 temp = INPLL(MCLK_CNTL);
2548 OUTPLL(MCLK_CNTL, temp & 0xffeaffff);
2549
2550 // PLL_TURNOFF
2551 temp = INPLL(PLL_PWRMGT_CNTL);
2552 OUTPLL(PLL_PWRMGT_CNTL, temp | 0x0000001f);
2553
2554 // set MOBILE_SU to 1 if M6 or DDR64 is detected
2555 temp = INPLL(PLL_PWRMGT_CNTL);
2556 OUTPLL(PLL_PWRMGT_CNTL, temp | 0x00010000);
2557
2558 // select PM access mode (PM_MODE_SEL) (use ACPI mode)
2559// temp = INPLL(PLL_PWRMGT_CNTL);
2560// OUTPLL(PLL_PWRMGT_CNTL, temp | 0x00002000);
2561 temp = INPLL(PLL_PWRMGT_CNTL);
2562 OUTPLL(PLL_PWRMGT_CNTL, temp & ~0x00002000);
2563
2564 // set DISP_MISC_CNTL register
2565 disp_misc_cntl = INREG(DISP_MISC_CNTL);
2566 disp_misc_cntl &= ~( DISP_MISC_CNTL_SOFT_RESET_GRPH_PP |
2567 DISP_MISC_CNTL_SOFT_RESET_SUBPIC_PP |
2568 DISP_MISC_CNTL_SOFT_RESET_OV0_PP |
2569 DISP_MISC_CNTL_SOFT_RESET_GRPH_SCLK |
2570 DISP_MISC_CNTL_SOFT_RESET_SUBPIC_SCLK |
2571 DISP_MISC_CNTL_SOFT_RESET_OV0_SCLK |
2572 DISP_MISC_CNTL_SOFT_RESET_GRPH2_PP |
2573 DISP_MISC_CNTL_SOFT_RESET_GRPH2_SCLK |
2574 DISP_MISC_CNTL_SOFT_RESET_LVDS |
2575 DISP_MISC_CNTL_SOFT_RESET_TMDS |
2576 DISP_MISC_CNTL_SOFT_RESET_DIG_TMDS |
2577 DISP_MISC_CNTL_SOFT_RESET_TV);
2578 OUTREG(DISP_MISC_CNTL, disp_misc_cntl);
2579
2580 // set DISP_PWR_MAN register
2581 disp_pwr_man = INREG(DISP_PWR_MAN);
2582 // clau - 9.29.2000 - changes made to bit23:18 to set to 1 as requested by George
2583 disp_pwr_man |= (DISP_PWR_MAN_DIG_TMDS_ENABLE_RST |
2584 DISP_PWR_MAN_TV_ENABLE_RST |
2585 // DISP_PWR_MAN_AUTO_PWRUP_EN |
2586 DISP_PWR_MAN_DISP_D3_GRPH_RST |
2587 DISP_PWR_MAN_DISP_D3_SUBPIC_RST |
2588 DISP_PWR_MAN_DISP_D3_OV0_RST |
2589 DISP_PWR_MAN_DISP_D1D2_GRPH_RST |
2590 DISP_PWR_MAN_DISP_D1D2_SUBPIC_RST |
2591 DISP_PWR_MAN_DISP_D1D2_OV0_RST);
2592 disp_pwr_man &= ~(DISP_PWR_MAN_DISP_PWR_MAN_D3_CRTC_EN |
2593 DISP_PWR_MAN_DISP2_PWR_MAN_D3_CRTC2_EN|
2594 DISP_PWR_MAN_DISP_D3_RST |
2595 DISP_PWR_MAN_DISP_D3_REG_RST);
2596 OUTREG(DISP_PWR_MAN, disp_pwr_man);
2597
2598 // clau - 10.24.2000
2599 // - add in setting for BUS_CNTL1 b27:26 = 0x01 and b31 = 0x1
2600 // - add in setting for AGP_CNTL b7:0 = 0x20
2601 // - add in setting for DVI_DDC_DATA_OUT_EN b17:16 = 0x0
2602
2603 // the following settings (two lines) are applied at a later part of this function, only on mobile platform
2604 // requres -mobile flag
2605 OUTREG(BUS_CNTL1, (INREG(BUS_CNTL1) & 0xf3ffffff) | 0x04000000);
2606 OUTREG(BUS_CNTL1, INREG(BUS_CNTL1) | 0x80000000);
2607 OUTREG(AGP_CNTL, (INREG(AGP_CNTL) & 0xffffff00) | 0x20);
2608 OUTREG(GPIO_DVI_DDC, INREG(GPIO_DVI_DDC) & 0xfffcffff);
2609
2610 // yulee - 12.12.2000
2611 // A12 only
2612 // EN_MCLK_TRISTATE_IN_SUSPEND@MCLK_MISC = 1
2613 // ACCESS_REGS_IN_SUSPEND@CLK_PIN_CNTL = 0
2614 // only on mobile platform
2615 OUTPLL(MCLK_MISC, INPLL(MCLK_MISC) | 0x00040000 );
2616
2617 // yulee -12.12.2000
2618 // AGPCLK_VALID@BUS_CNTL1 = 1
2619 // MOBILE_PLATFORM_SEL@BUS_CNTL1 = 01
2620 // CRTC_STEREO_SYNC_OUT_EN@CRTC_OFFSET_CNTL = 0
2621 // CG_CLK_TO_OUTPIN@CLK_PIN_CNTL = 0
2622 // only on mobile platform
2623 OUTPLL(CLK_PIN_CNTL, INPLL(CLK_PIN_CNTL ) & 0xFFFFF7FF );
2624 OUTREG(BUS_CNTL1, (INREG(BUS_CNTL1 ) & 0xF3FFFFFF) | 0x84000000 );
2625 OUTREG(CRTC_OFFSET_CNTL, INREG(CRTC_OFFSET_CNTL ) & 0xFFEFFFFF );
2626
2627 mdelay(100);
2628#endif
2629
2630 /* Disable CRTCs */
2631 OUTREG(CRTC_GEN_CNTL, (INREG(CRTC_GEN_CNTL) & ~CRTC_EN) | CRTC_DISP_REQ_EN_B);
2632 OUTREG(CRTC2_GEN_CNTL, (INREG(CRTC2_GEN_CNTL) & ~CRTC2_EN) | CRTC2_DISP_REQ_EN_B);
2633 (void)INREG(CRTC2_GEN_CNTL);
2634 mdelay(17);
2635}
2636
2637static void radeon_set_suspend(struct radeonfb_info *rinfo, int suspend)
2638{
2639 u16 pwr_cmd;
2640
2641 if (!rinfo->pm_reg)
2642 return;
2643
2644 /* Set the chip into appropriate suspend mode (we use D2,
2645 * D3 would require a compete re-initialization of the chip,
2646 * including PCI config registers, clocks, AGP conf, ...)
2647 */
2648 if (suspend) {
2649 /* According to ATI, we should program V2CLK here, I have
2650 * to verify what's up exactly
2651 */
2652 /* Save some registers */
2653 radeon_pm_save_regs(rinfo);
2654
2655 /* Check that on M7 too, might work might not. M7 may also
2656 * need explicit enabling of PM
2657 */
2658 if (rinfo->arch == RADEON_M6) {
2659 /* Program V2CLK */
2660 radeon_pm_program_v2clk(rinfo);
2661
2662 /* Disable IO PADs */
2663 radeon_pm_disable_iopad(rinfo);
2664
2665 /* Set low current */
2666 radeon_pm_low_current(rinfo);
2667
2668 /* Prepare chip for power management */
2669 radeon_pm_setup_for_suspend(rinfo);
2670
2671 /* Reset the MDLL */
2672 OUTPLL(MDLL_CKO, INPLL(MDLL_CKO) | MCKOA_RESET);
2673 (void)INPLL(MDLL_RDCKA);
2674 OUTPLL(MDLL_CKO, INPLL(MDLL_CKO) & ~MCKOA_RESET);
2675 (void)INPLL(MDLL_RDCKA);
2676 }
2677
2678 /* Switch PCI power managment to D2. */
2679 for (;;) {
2680 pci_read_config_word(
2681 rinfo->pdev, rinfo->pm_reg+PCI_PM_CTRL,
2682 &pwr_cmd);
2683 if (pwr_cmd & 2)
2684 break;
2685 pci_write_config_word(
2686 rinfo->pdev, rinfo->pm_reg+PCI_PM_CTRL,
2687 (pwr_cmd & ~PCI_PM_CTRL_STATE_MASK) | 2);
2688 mdelay(500);
2689 }
2690 } else {
2691 /* Switch back PCI powermanagment to D0 */
2692 mdelay(200);
2693 pci_write_config_word(rinfo->pdev, rinfo->pm_reg+PCI_PM_CTRL, 0);
2694 mdelay(500);
2695
2696 dbg_clk = INPLL(1);
2697
2698 /* Do we need that on M7 ? */
2699 if (rinfo->arch == RADEON_M6) {
2700 /* Restore the MDLL */
2701 OUTPLL(MDLL_CKO, INPLL(MDLL_CKO) & ~MCKOA_RESET);
2702 (void)INPLL(MDLL_CKO);
2703 }
2704
2705 /* Restore some registers */
2706 radeon_pm_restore_regs(rinfo);
2707 }
2708}
2709
2710/*
2711 * Save the contents of the framebuffer when we go to sleep,
2712 * and restore it when we wake up again.
2713 */
2714
2715int radeon_sleep_notify(struct pmu_sleep_notifier *self, int when)
2716{
2717 struct radeonfb_info *rinfo;
2718
2719 for (rinfo = board_list; rinfo != NULL; rinfo = rinfo->next) {
2720 struct fb_fix_screeninfo fix;
2721 int nb;
2722 struct display *disp;
2723
2724 disp = (rinfo->currcon < 0) ? rinfo->info.disp : &fb_display[rinfo->currcon];
2725
2726 switch (rinfo->arch) {
2727 case RADEON_M6:
2728 case RADEON_M7:
2729 case RADEON_M9:
2730 break;
2731 default:
2732 return PBOOK_SLEEP_REFUSE;
2733 }
2734
2735 radeonfb_get_fix(&fix, fg_console, (struct fb_info *)rinfo);
2736 nb = fb_display[fg_console].var.yres * fix.line_length;
2737
2738 switch (when) {
2739 case PBOOK_SLEEP_NOW:
2740 acquire_console_sem();
2741 disp->dispsw = &fbcon_dummy;
2742
2743 if (!noaccel) {
2744 /* Make sure engine is reset */
2745 radeon_engine_reset();
2746 radeon_engine_idle();
2747 }
2748
2749 /* Blank display and LCD */
2750 radeonfb_blank(VESA_POWERDOWN+1,
2751 (struct fb_info *)rinfo);
2752
2753 /* Sleep */
2754 rinfo->asleep = 1;
2755 radeon_set_suspend(rinfo, 1);
2756 release_console_sem();
2757
2758 break;
2759 case PBOOK_WAKE:
2760 acquire_console_sem();
2761 /* Wakeup */
2762 radeon_set_suspend(rinfo, 0);
2763
2764 if (!noaccel)
2765 radeon_engine_init(rinfo);
2766 rinfo->asleep = 0;
2767 radeon_set_dispsw(rinfo, disp);
2768 radeon_load_video_mode(rinfo, &disp->var);
2769 do_install_cmap(rinfo->currcon < 0 ? 0 : rinfo->currcon,
2770 (struct fb_info *)rinfo);
2771
2772 radeonfb_blank(0, (struct fb_info *)rinfo);
2773 release_console_sem();
2774 printk("CLK_PIN_CNTL on wakeup was: %08x\n", dbg_clk);
2775 break;
2776 }
2777 }
2778
2779 return PBOOK_SLEEP_OK;
2780}
2781
2782#endif /* CONFIG_PMAC_PBOOK */
2783
2784static int radeonfb_pci_register (struct pci_dev *pdev,
2785 const struct pci_device_id *ent)
2786{
2787 struct radeonfb_info *rinfo;
2788 struct radeon_chip_info *rci = &radeon_chip_info[ent->driver_data];
2789 u32 tmp;
2790
2791 RTRACE("radeonfb_pci_register BEGIN\n");
2792
2793 /* Enable device in PCI config */
2794 if (pci_enable_device(pdev) != 0) {
2795 printk(KERN_ERR "radeonfb: Cannot enable PCI device\n");
2796 return -ENODEV;
2797 }
2798
2799 rinfo = kmalloc (sizeof (struct radeonfb_info), GFP_KERNEL);
2800 if (!rinfo) {
2801 printk ("radeonfb: could not allocate memory\n");
2802 return -ENODEV;
2803 }
2804
2805 memset (rinfo, 0, sizeof (struct radeonfb_info));
2806 //info = &rinfo->info;
2807 rinfo->pdev = pdev;
2808 strcpy(rinfo->name, rci->name);
2809 rinfo->arch = rci->arch;
2810
2811 /* Set base addrs */
2812 rinfo->fb_base_phys = pci_resource_start (pdev, 0);
2813 rinfo->mmio_base_phys = pci_resource_start (pdev, 2);
2814
2815 /* request the mem regions */
2816 if (!request_mem_region (rinfo->fb_base_phys,
2817 pci_resource_len(pdev, 0), "radeonfb")) {
2818 printk ("radeonfb: cannot reserve FB region\n");
2819 kfree (rinfo);
2820 return -ENODEV;
2821 }
2822
2823 if (!request_mem_region (rinfo->mmio_base_phys,
2824 pci_resource_len(pdev, 2), "radeonfb")) {
2825 printk ("radeonfb: cannot reserve MMIO region\n");
2826 release_mem_region (rinfo->fb_base_phys,
2827 pci_resource_len(pdev, 0));
2828 kfree (rinfo);
2829 return -ENODEV;
2830 }
2831
2832 /* map the regions */
2833 rinfo->mmio_base = ioremap (rinfo->mmio_base_phys, RADEON_REGSIZE);
2834 if (!rinfo->mmio_base) {
2835 printk ("radeonfb: cannot map MMIO\n");
2836 release_mem_region (rinfo->mmio_base_phys,
2837 pci_resource_len(pdev, 2));
2838 release_mem_region (rinfo->fb_base_phys,
2839 pci_resource_len(pdev, 0));
2840 kfree (rinfo);
2841 return -ENODEV;
2842 }
2843
2844 rinfo->chipset = pdev->device;
2845
2846 switch (rinfo->arch) {
2847 case RADEON_R100:
2848 rinfo->hasCRTC2 = 0;
2849 break;
2850 default:
2851 /* all the rest have it */
2852 rinfo->hasCRTC2 = 1;
2853 break;
2854 }
2855#if 0
2856 if (rinfo->arch == RADEON_M7) {
2857 /*
2858 * Noticed some errors in accel with M7, will have to work these out...
2859 */
2860 noaccel = 1;
2861 }
2862#endif
2863 if (mirror)
2864 printk("radeonfb: mirroring display to CRT\n");
2865
2866 /* framebuffer size */
2867 tmp = INREG(CONFIG_MEMSIZE);
2868
2869 /* mem size is bits [28:0], mask off the rest */
2870 rinfo->video_ram = tmp & CONFIG_MEMSIZE_MASK;
2871
2872 /* ram type */
2873 tmp = INREG(MEM_SDRAM_MODE_REG);
2874 switch ((MEM_CFG_TYPE & tmp) >> 30) {
2875 case 0:
2876 /* SDR SGRAM (2:1) */
2877 strcpy(rinfo->ram_type, "SDR SGRAM");
2878 rinfo->ram.ml = 4;
2879 rinfo->ram.mb = 4;
2880 rinfo->ram.trcd = 1;
2881 rinfo->ram.trp = 2;
2882 rinfo->ram.twr = 1;
2883 rinfo->ram.cl = 2;
2884 rinfo->ram.loop_latency = 16;
2885 rinfo->ram.rloop = 16;
2886
2887 break;
2888 case 1:
2889 /* DDR SGRAM */
2890 strcpy(rinfo->ram_type, "DDR SGRAM");
2891 rinfo->ram.ml = 4;
2892 rinfo->ram.mb = 4;
2893 rinfo->ram.trcd = 3;
2894 rinfo->ram.trp = 3;
2895 rinfo->ram.twr = 2;
2896 rinfo->ram.cl = 3;
2897 rinfo->ram.tr2w = 1;
2898 rinfo->ram.loop_latency = 16;
2899 rinfo->ram.rloop = 16;
2900
2901 break;
2902 default:
2903 /* 64-bit SDR SGRAM */
2904 strcpy(rinfo->ram_type, "SDR SGRAM 64");
2905 rinfo->ram.ml = 4;
2906 rinfo->ram.mb = 8;
2907 rinfo->ram.trcd = 3;
2908 rinfo->ram.trp = 3;
2909 rinfo->ram.twr = 1;
2910 rinfo->ram.cl = 3;
2911 rinfo->ram.tr2w = 1;
2912 rinfo->ram.loop_latency = 17;
2913 rinfo->ram.rloop = 17;
2914
2915 break;
2916 }
2917
2918 rinfo->bios_seg = radeon_find_rom(rinfo);
2919 radeon_get_pllinfo(rinfo, rinfo->bios_seg);
2920
2921 /*
2922 * Hack to get around some busted production M6's
2923 * reporting no ram
2924 */
2925 if (rinfo->video_ram == 0) {
2926 switch (pdev->device) {
2927 case PCI_DEVICE_ID_ATI_RADEON_LY:
2928 case PCI_DEVICE_ID_ATI_RADEON_LZ:
2929 rinfo->video_ram = 8192 * 1024;
2930 break;
2931 default:
2932 break;
2933 }
2934 }
2935
2936
2937 RTRACE("radeonfb: probed %s %dk videoram\n", (rinfo->ram_type), (rinfo->video_ram/1024));
2938
2939#if !defined(__powerpc__)
2940 radeon_get_moninfo(rinfo);
2941#else
2942 switch (pdev->device) {
2943 case PCI_DEVICE_ID_ATI_RADEON_LW:
2944 case PCI_DEVICE_ID_ATI_RADEON_LX:
2945 case PCI_DEVICE_ID_ATI_RADEON_LY:
2946 case PCI_DEVICE_ID_ATI_RADEON_LZ:
2947 rinfo->dviDisp_type = MT_LCD;
2948 break;
2949 default:
2950 radeon_get_moninfo(rinfo);
2951 break;
2952 }
2953#endif
2954
2955 radeon_get_EDID(rinfo);
2956
2957 if ((rinfo->dviDisp_type == MT_DFP) || (rinfo->dviDisp_type == MT_LCD) ||
2958 (rinfo->crtDisp_type == MT_DFP)) {
2959 if (!radeon_get_dfpinfo(rinfo)) {
2960 iounmap(rinfo->mmio_base);
2961 release_mem_region (rinfo->mmio_base_phys,
2962 pci_resource_len(pdev, 2));
2963 release_mem_region (rinfo->fb_base_phys,
2964 pci_resource_len(pdev, 0));
2965 kfree (rinfo);
2966 return -ENODEV;
2967 }
2968 }
2969
2970 rinfo->fb_base = ioremap (rinfo->fb_base_phys, rinfo->video_ram);
2971 if (!rinfo->fb_base) {
2972 printk ("radeonfb: cannot map FB\n");
2973 iounmap(rinfo->mmio_base);
2974 release_mem_region (rinfo->mmio_base_phys,
2975 pci_resource_len(pdev, 2));
2976 release_mem_region (rinfo->fb_base_phys,
2977 pci_resource_len(pdev, 0));
2978 kfree (rinfo);
2979 return -ENODEV;
2980 }
2981
2982 /* I SHOULD FIX THAT CRAP ! I should probably mimmic XFree DRI
2983 * driver setup here.
2984 *
2985 * On PPC, OF based cards setup the internal memory
2986 * mapping in strange ways. We change it so that the
2987 * framebuffer is mapped at 0 and given half of the card's
2988 * address space (2Gb). AGP is mapped high (0xe0000000) and
2989 * can use up to 512Mb. Once DRI is fully implemented, we
2990 * will have to setup the PCI remapper to remap the agp_special_page
2991 * memory page somewhere between those regions so that the card
2992 * use a normal PCI bus master cycle to access the ring read ptr.
2993 * --BenH.
2994 */
2995#ifdef CONFIG_ALL_PPC
2996 if (rinfo->hasCRTC2)
2997 OUTREG(CRTC2_GEN_CNTL,
2998 (INREG(CRTC2_GEN_CNTL) & ~CRTC2_EN) | CRTC2_DISP_REQ_EN_B);
2999 OUTREG(CRTC_EXT_CNTL, INREG(CRTC_EXT_CNTL) | CRTC_DISPLAY_DIS);
3000 OUTREG(MC_FB_LOCATION, 0x7fff0000);
3001 OUTREG(MC_AGP_LOCATION, 0xffffe000);
3002 OUTREG(DISPLAY_BASE_ADDR, 0x00000000);
3003 if (rinfo->hasCRTC2)
3004 OUTREG(CRTC2_DISPLAY_BASE_ADDR, 0x00000000);
3005 OUTREG(SRC_OFFSET, 0x00000000);
3006 OUTREG(DST_OFFSET, 0x00000000);
3007 mdelay(10);
3008 OUTREG(CRTC_EXT_CNTL, INREG(CRTC_EXT_CNTL) & ~CRTC_DISPLAY_DIS);
3009#endif /* CONFIG_ALL_PPC */
3010
3011 /* save current mode regs before we switch into the new one
3012 * so we can restore this upon __exit
3013 */
3014 radeon_save_state (rinfo, &rinfo->init_state);
3015
3016 /* set all the vital stuff */
3017 radeon_set_fbinfo (rinfo);
3018
3019 pci_set_drvdata(pdev, rinfo);
3020 rinfo->next = board_list;
3021 board_list = rinfo;
3022 ((struct fb_info *) rinfo)->device = &pdev->dev;
3023 if (register_framebuffer ((struct fb_info *) rinfo) < 0) {
3024 printk ("radeonfb: could not register framebuffer\n");
3025 iounmap(rinfo->fb_base);
3026 iounmap(rinfo->mmio_base);
3027 release_mem_region (rinfo->mmio_base_phys,
3028 pci_resource_len(pdev, 2));
3029 release_mem_region (rinfo->fb_base_phys,
3030 pci_resource_len(pdev, 0));
3031 kfree (rinfo);
3032 return -ENODEV;
3033 }
3034
3035#ifdef CONFIG_MTRR
3036 rinfo->mtrr_hdl = nomtrr ? -1 : mtrr_add(rinfo->fb_base_phys,
3037 rinfo->video_ram,
3038 MTRR_TYPE_WRCOMB, 1);
3039#endif
3040
3041#ifdef CONFIG_PMAC_BACKLIGHT
3042 if (rinfo->dviDisp_type == MT_LCD)
3043 register_backlight_controller(&radeon_backlight_controller,
3044 rinfo, "ati");
3045#endif
3046
3047#ifdef CONFIG_PMAC_PBOOK
3048 if (rinfo->dviDisp_type == MT_LCD) {
3049 rinfo->pm_reg = pci_find_capability(pdev, PCI_CAP_ID_PM);
3050 pmu_register_sleep_notifier(&radeon_sleep_notifier);
3051 }
3052#endif
3053
3054 printk ("radeonfb: ATI Radeon %s %s %d MB\n", rinfo->name, rinfo->ram_type,
3055 (rinfo->video_ram/(1024*1024)));
3056
3057 if (rinfo->hasCRTC2) {
3058 printk("radeonfb: DVI port %s monitor connected\n",
3059 GET_MON_NAME(rinfo->dviDisp_type));
3060 printk("radeonfb: CRT port %s monitor connected\n",
3061 GET_MON_NAME(rinfo->crtDisp_type));
3062 } else {
3063 printk("radeonfb: CRT port %s monitor connected\n",
3064 GET_MON_NAME(rinfo->crtDisp_type));
3065 }
3066
3067 RTRACE("radeonfb_pci_register END\n");
3068
3069 return 0;
3070}
3071
3072
3073
3074static void __devexit radeonfb_pci_unregister (struct pci_dev *pdev)
3075{
3076 struct radeonfb_info *rinfo = pci_get_drvdata(pdev);
3077
3078 if (!rinfo)
3079 return;
3080
3081 /* restore original state
3082 *
3083 * Doesn't quite work yet, possibly because of the PPC hacking
3084 * I do on startup, disable for now. --BenH
3085 */
3086 radeon_write_mode (rinfo, &rinfo->init_state);
3087
3088#ifdef CONFIG_MTRR
3089 if (rinfo->mtrr_hdl >= 0)
3090 mtrr_del(rinfo->mtrr_hdl, 0, 0);
3091#endif
3092
3093 unregister_framebuffer ((struct fb_info *) rinfo);
3094
3095 iounmap(rinfo->mmio_base);
3096 iounmap(rinfo->fb_base);
3097
3098 release_mem_region (rinfo->mmio_base_phys,
3099 pci_resource_len(pdev, 2));
3100 release_mem_region (rinfo->fb_base_phys,
3101 pci_resource_len(pdev, 0));
3102
3103 kfree (rinfo);
3104}
3105
3106
3107static struct pci_driver radeonfb_driver = {
3108 .name = "radeonfb",
3109 .id_table = radeonfb_pci_table,
3110 .probe = radeonfb_pci_register,
3111 .remove = __devexit_p(radeonfb_pci_unregister),
3112};
3113
3114#ifndef MODULE
3115static int __init radeonfb_old_setup (char *options)
3116{
3117 char *this_opt;
3118
3119 if (!options || !*options)
3120 return 0;
3121
3122 while ((this_opt = strsep (&options, ",")) != NULL) {
3123 if (!*this_opt)
3124 continue;
3125 if (!strncmp(this_opt, "noaccel", 7)) {
3126 noaccel = 1;
3127 } else if (!strncmp(this_opt, "mirror", 6)) {
3128 mirror = 1;
3129 } else if (!strncmp(this_opt, "dfp", 3)) {
3130 force_dfp = 1;
3131 } else if (!strncmp(this_opt, "panel_yres:", 11)) {
3132 panel_yres = simple_strtoul((this_opt+11), NULL, 0);
3133 } else if (!strncmp(this_opt, "nomtrr", 6)) {
3134 nomtrr = 1;
3135 } else
3136 mode_option = this_opt;
3137 }
3138
3139 return 0;
3140}
3141#endif /* MODULE */
3142
3143static int __init radeonfb_old_init (void)
3144{
3145#ifndef MODULE
3146 char *option = NULL;
3147
3148 if (fb_get_options("radeonfb_old", &option))
3149 return -ENODEV;
3150 radeonfb_old_setup(option);
3151#endif
3152 return pci_register_driver (&radeonfb_driver);
3153}
3154
3155
3156static void __exit radeonfb_old_exit (void)
3157{
3158 pci_unregister_driver (&radeonfb_driver);
3159}
3160
3161module_init(radeonfb_old_init);
3162module_exit(radeonfb_old_exit);
3163
3164
3165MODULE_AUTHOR("Ani Joshi");
3166MODULE_DESCRIPTION("framebuffer driver for ATI Radeon chipset");
3167MODULE_LICENSE("GPL");
diff --git a/drivers/video/riva/fbdev.c b/drivers/video/riva/fbdev.c
index f841f013b96f..3e9308f0f165 100644
--- a/drivers/video/riva/fbdev.c
+++ b/drivers/video/riva/fbdev.c
@@ -49,6 +49,7 @@
49#include <asm/pci-bridge.h> 49#include <asm/pci-bridge.h>
50#endif 50#endif
51#ifdef CONFIG_PMAC_BACKLIGHT 51#ifdef CONFIG_PMAC_BACKLIGHT
52#include <asm/machdep.h>
52#include <asm/backlight.h> 53#include <asm/backlight.h>
53#endif 54#endif
54 55
@@ -1247,7 +1248,7 @@ static int rivafb_blank(int blank, struct fb_info *info)
1247 CRTCout(par, 0x1a, vesa); 1248 CRTCout(par, 0x1a, vesa);
1248 1249
1249#ifdef CONFIG_PMAC_BACKLIGHT 1250#ifdef CONFIG_PMAC_BACKLIGHT
1250 if ( par->FlatPanel && _machine == _MACH_Pmac) { 1251 if ( par->FlatPanel && machine_is(powermac)) {
1251 set_backlight_enable(!blank); 1252 set_backlight_enable(!blank);
1252 } 1253 }
1253#endif 1254#endif
@@ -2037,9 +2038,9 @@ static int __devinit rivafb_probe(struct pci_dev *pd,
2037 info->fix.smem_len / (1024 * 1024), 2038 info->fix.smem_len / (1024 * 1024),
2038 info->fix.smem_start); 2039 info->fix.smem_start);
2039#ifdef CONFIG_PMAC_BACKLIGHT 2040#ifdef CONFIG_PMAC_BACKLIGHT
2040 if (default_par->FlatPanel && _machine == _MACH_Pmac) 2041 if (default_par->FlatPanel && machine_is(powermac))
2041 register_backlight_controller(&riva_backlight_controller, 2042 register_backlight_controller(&riva_backlight_controller,
2042 default_par, "mnca"); 2043 default_par, "mnca");
2043#endif 2044#endif
2044 NVTRACE_LEAVE(); 2045 NVTRACE_LEAVE();
2045 return 0; 2046 return 0;
diff --git a/drivers/video/sticore.h b/drivers/video/sticore.h
index dc93336af557..1a9a60c74be3 100644
--- a/drivers/video/sticore.h
+++ b/drivers/video/sticore.h
@@ -34,36 +34,20 @@
34 * for them to fix it and steal their solution. prumpf 34 * for them to fix it and steal their solution. prumpf
35 */ 35 */
36 36
37#define STI_WAIT 1 37#include <asm/io.h>
38
39#include <asm/io.h> /* for USE_HPPA_IOREMAP */
40
41#if USE_HPPA_IOREMAP
42 38
43#define STI_PTR(p) (p) 39#define STI_WAIT 1
44#define PTR_STI(p) (p)
45static inline int STI_CALL( unsigned long func,
46 void *flags, void *inptr, void *outptr, void *glob_cfg )
47{
48 int (*f)(void *,void *,void *,void *);
49 f = (void*)func;
50 return f(flags, inptr, outptr, glob_cfg);
51}
52
53#else /* !USE_HPPA_IOREMAP */
54 40
55#define STI_PTR(p) ( virt_to_phys(p) ) 41#define STI_PTR(p) ( virt_to_phys(p) )
56#define PTR_STI(p) ( phys_to_virt((long)p) ) 42#define PTR_STI(p) ( phys_to_virt((unsigned long)p) )
57#define STI_CALL(func, flags, inptr, outptr, glob_cfg) \ 43#define STI_CALL(func, flags, inptr, outptr, glob_cfg) \
58 ({ \ 44 ({ \
59 pdc_sti_call( func, (unsigned long)STI_PTR(flags), \ 45 pdc_sti_call( func, STI_PTR(flags), \
60 (unsigned long)STI_PTR(inptr), \ 46 STI_PTR(inptr), \
61 (unsigned long)STI_PTR(outptr), \ 47 STI_PTR(outptr), \
62 (unsigned long)STI_PTR(glob_cfg)); \ 48 STI_PTR(glob_cfg)); \
63 }) 49 })
64 50
65#endif /* USE_HPPA_IOREMAP */
66
67 51
68#define sti_onscreen_x(sti) (sti->glob_cfg->onscreen_x) 52#define sti_onscreen_x(sti) (sti->glob_cfg->onscreen_x)
69#define sti_onscreen_y(sti) (sti->glob_cfg->onscreen_y) 53#define sti_onscreen_y(sti) (sti->glob_cfg->onscreen_y)
@@ -352,8 +336,9 @@ struct sti_struct {
352 struct sti_conf_outptr outptr; /* configuration */ 336 struct sti_conf_outptr outptr; /* configuration */
353 struct sti_conf_outptr_ext outptr_ext; 337 struct sti_conf_outptr_ext outptr_ext;
354 338
355 /* PCI data structures (pg. 17ff from sti.pdf) */
356 struct pci_dev *pd; 339 struct pci_dev *pd;
340
341 /* PCI data structures (pg. 17ff from sti.pdf) */
357 u8 rm_entry[16]; /* pci region mapper array == pci config space offset */ 342 u8 rm_entry[16]; /* pci region mapper array == pci config space offset */
358 343
359 /* pointer to the fb_info where this STI device is used */ 344 /* pointer to the fb_info where this STI device is used */
diff --git a/drivers/video/stifb.c b/drivers/video/stifb.c
index 56d71d6e9a72..4a292aae6eb2 100644
--- a/drivers/video/stifb.c
+++ b/drivers/video/stifb.c
@@ -3,7 +3,7 @@
3 * Low level Frame buffer driver for HP workstations with 3 * Low level Frame buffer driver for HP workstations with
4 * STI (standard text interface) video firmware. 4 * STI (standard text interface) video firmware.
5 * 5 *
6 * Copyright (C) 2001-2005 Helge Deller <deller@gmx.de> 6 * Copyright (C) 2001-2006 Helge Deller <deller@gmx.de>
7 * Portions Copyright (C) 2001 Thomas Bogendoerfer <tsbogend@alpha.franken.de> 7 * Portions Copyright (C) 2001 Thomas Bogendoerfer <tsbogend@alpha.franken.de>
8 * 8 *
9 * Based on: 9 * Based on:
@@ -514,7 +514,7 @@ rattlerSetupPlanes(struct stifb_info *fb)
514 SETUP_HW(fb); 514 SETUP_HW(fb);
515 WRITE_BYTE(1, fb, REG_16b1); 515 WRITE_BYTE(1, fb, REG_16b1);
516 516
517 fb_memset(fb->info.fix.smem_start, 0xff, 517 fb_memset((void*)fb->info.fix.smem_start, 0xff,
518 fb->info.var.yres*fb->info.fix.line_length); 518 fb->info.var.yres*fb->info.fix.line_length);
519 519
520 CRX24_SET_OVLY_MASK(fb); 520 CRX24_SET_OVLY_MASK(fb);
@@ -908,83 +908,6 @@ SETUP_HCRX(struct stifb_info *fb)
908 908
909/* ------------------- driver specific functions --------------------------- */ 909/* ------------------- driver specific functions --------------------------- */
910 910
911#define TMPBUFLEN 2048
912
913static ssize_t
914stifb_read(struct file *file, char *buf, size_t count, loff_t *ppos)
915{
916 unsigned long p = *ppos;
917 struct inode *inode = file->f_dentry->d_inode;
918 int fbidx = iminor(inode);
919 struct fb_info *info = registered_fb[fbidx];
920 char tmpbuf[TMPBUFLEN];
921
922 if (!info || ! info->screen_base)
923 return -ENODEV;
924
925 if (p >= info->fix.smem_len)
926 return 0;
927 if (count >= info->fix.smem_len)
928 count = info->fix.smem_len;
929 if (count + p > info->fix.smem_len)
930 count = info->fix.smem_len - p;
931 if (count > sizeof(tmpbuf))
932 count = sizeof(tmpbuf);
933 if (count) {
934 char *base_addr;
935
936 base_addr = info->screen_base;
937 memcpy_fromio(&tmpbuf, base_addr+p, count);
938 count -= copy_to_user(buf, &tmpbuf, count);
939 if (!count)
940 return -EFAULT;
941 *ppos += count;
942 }
943 return count;
944}
945
946static ssize_t
947stifb_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
948{
949 struct inode *inode = file->f_dentry->d_inode;
950 int fbidx = iminor(inode);
951 struct fb_info *info = registered_fb[fbidx];
952 unsigned long p = *ppos;
953 size_t c;
954 int err;
955 char tmpbuf[TMPBUFLEN];
956
957 if (!info || !info->screen_base)
958 return -ENODEV;
959
960 if (p > info->fix.smem_len)
961 return -ENOSPC;
962 if (count >= info->fix.smem_len)
963 count = info->fix.smem_len;
964 err = 0;
965 if (count + p > info->fix.smem_len) {
966 count = info->fix.smem_len - p;
967 err = -ENOSPC;
968 }
969
970 p += (unsigned long)info->screen_base;
971 c = count;
972 while (c) {
973 int len = c > sizeof(tmpbuf) ? sizeof(tmpbuf) : c;
974 err = -EFAULT;
975 if (copy_from_user(&tmpbuf, buf, len))
976 break;
977 memcpy_toio(p, &tmpbuf, len);
978 c -= len;
979 p += len;
980 buf += len;
981 *ppos += len;
982 }
983 if (count-c)
984 return (count-c);
985 return err;
986}
987
988static int 911static int
989stifb_setcolreg(u_int regno, u_int red, u_int green, 912stifb_setcolreg(u_int regno, u_int red, u_int green,
990 u_int blue, u_int transp, struct fb_info *info) 913 u_int blue, u_int transp, struct fb_info *info)
@@ -1137,8 +1060,6 @@ stifb_init_display(struct stifb_info *fb)
1137 1060
1138static struct fb_ops stifb_ops = { 1061static struct fb_ops stifb_ops = {
1139 .owner = THIS_MODULE, 1062 .owner = THIS_MODULE,
1140 .fb_read = stifb_read,
1141 .fb_write = stifb_write,
1142 .fb_setcolreg = stifb_setcolreg, 1063 .fb_setcolreg = stifb_setcolreg,
1143 .fb_blank = stifb_blank, 1064 .fb_blank = stifb_blank,
1144 .fb_fillrect = cfb_fillrect, 1065 .fb_fillrect = cfb_fillrect,
@@ -1162,7 +1083,7 @@ stifb_init_fb(struct sti_struct *sti, int bpp_pref)
1162 char *dev_name; 1083 char *dev_name;
1163 int bpp, xres, yres; 1084 int bpp, xres, yres;
1164 1085
1165 fb = kmalloc(sizeof(*fb), GFP_ATOMIC); 1086 fb = kzalloc(sizeof(*fb), GFP_ATOMIC);
1166 if (!fb) { 1087 if (!fb) {
1167 printk(KERN_ERR "stifb: Could not allocate stifb structure\n"); 1088 printk(KERN_ERR "stifb: Could not allocate stifb structure\n");
1168 return -ENODEV; 1089 return -ENODEV;
@@ -1171,7 +1092,6 @@ stifb_init_fb(struct sti_struct *sti, int bpp_pref)
1171 info = &fb->info; 1092 info = &fb->info;
1172 1093
1173 /* set struct to a known state */ 1094 /* set struct to a known state */
1174 memset(fb, 0, sizeof(*fb));
1175 fix = &info->fix; 1095 fix = &info->fix;
1176 var = &info->var; 1096 var = &info->var;
1177 1097
@@ -1234,7 +1154,7 @@ stifb_init_fb(struct sti_struct *sti, int bpp_pref)
1234 case S9000_ID_TOMCAT: /* Dual CRX, behaves else like a CRX */ 1154 case S9000_ID_TOMCAT: /* Dual CRX, behaves else like a CRX */
1235 /* FIXME: TomCat supports two heads: 1155 /* FIXME: TomCat supports two heads:
1236 * fb.iobase = REGION_BASE(fb_info,3); 1156 * fb.iobase = REGION_BASE(fb_info,3);
1237 * fb.screen_base = (void*) REGION_BASE(fb_info,2); 1157 * fb.screen_base = ioremap_nocache(REGION_BASE(fb_info,2),xxx);
1238 * for now we only support the left one ! */ 1158 * for now we only support the left one ! */
1239 xres = fb->ngle_rom.x_size_visible; 1159 xres = fb->ngle_rom.x_size_visible;
1240 yres = fb->ngle_rom.y_size_visible; 1160 yres = fb->ngle_rom.y_size_visible;
@@ -1327,7 +1247,8 @@ stifb_init_fb(struct sti_struct *sti, int bpp_pref)
1327 1247
1328 strcpy(fix->id, "stifb"); 1248 strcpy(fix->id, "stifb");
1329 info->fbops = &stifb_ops; 1249 info->fbops = &stifb_ops;
1330 info->screen_base = (void*) REGION_BASE(fb,1); 1250 info->screen_base = ioremap_nocache(REGION_BASE(fb,1), fix->smem_len);
1251 info->screen_size = fix->smem_len;
1331 info->flags = FBINFO_DEFAULT; 1252 info->flags = FBINFO_DEFAULT;
1332 info->pseudo_palette = &fb->pseudo_palette; 1253 info->pseudo_palette = &fb->pseudo_palette;
1333 1254
@@ -1457,7 +1378,7 @@ stifb_setup(char *options)
1457 int i; 1378 int i;
1458 1379
1459 if (!options || !*options) 1380 if (!options || !*options)
1460 return 0; 1381 return 1;
1461 1382
1462 if (strncmp(options, "off", 3) == 0) { 1383 if (strncmp(options, "off", 3) == 0) {
1463 stifb_disabled = 1; 1384 stifb_disabled = 1;
@@ -1472,7 +1393,7 @@ stifb_setup(char *options)
1472 stifb_bpp_pref[i] = simple_strtoul(options, &options, 10); 1393 stifb_bpp_pref[i] = simple_strtoul(options, &options, 10);
1473 } 1394 }
1474 } 1395 }
1475 return 0; 1396 return 1;
1476} 1397}
1477 1398
1478__setup("stifb=", stifb_setup); 1399__setup("stifb=", stifb_setup);
diff --git a/drivers/video/w100fb.c b/drivers/video/w100fb.c
index f6e24ee85f07..5fc86ea20692 100644
--- a/drivers/video/w100fb.c
+++ b/drivers/video/w100fb.c
@@ -4,8 +4,9 @@
4 * Frame Buffer Device for ATI Imageon w100 (Wallaby) 4 * Frame Buffer Device for ATI Imageon w100 (Wallaby)
5 * 5 *
6 * Copyright (C) 2002, ATI Corp. 6 * Copyright (C) 2002, ATI Corp.
7 * Copyright (C) 2004-2005 Richard Purdie 7 * Copyright (C) 2004-2006 Richard Purdie
8 * Copyright (c) 2005 Ian Molton 8 * Copyright (c) 2005 Ian Molton
9 * Copyright (c) 2006 Alberto Mardegan
9 * 10 *
10 * Rewritten for 2.6 by Richard Purdie <rpurdie@rpsys.net> 11 * Rewritten for 2.6 by Richard Purdie <rpurdie@rpsys.net>
11 * 12 *
@@ -14,6 +15,9 @@
14 * 15 *
15 * w32xx support by Ian Molton 16 * w32xx support by Ian Molton
16 * 17 *
18 * Hardware acceleration support by Alberto Mardegan
19 * <mardy@users.sourceforge.net>
20 *
17 * This program is free software; you can redistribute it and/or modify 21 * This program is free software; you can redistribute it and/or modify
18 * it under the terms of the GNU General Public License version 2 as 22 * it under the terms of the GNU General Public License version 2 as
19 * published by the Free Software Foundation. 23 * published by the Free Software Foundation.
@@ -47,6 +51,7 @@ static void w100_set_dispregs(struct w100fb_par*);
47static void w100_update_enable(void); 51static void w100_update_enable(void);
48static void w100_update_disable(void); 52static void w100_update_disable(void);
49static void calc_hsync(struct w100fb_par *par); 53static void calc_hsync(struct w100fb_par *par);
54static void w100_init_graphic_engine(struct w100fb_par *par);
50struct w100_pll_info *w100_get_xtal_table(unsigned int freq); 55struct w100_pll_info *w100_get_xtal_table(unsigned int freq);
51 56
52/* Pseudo palette size */ 57/* Pseudo palette size */
@@ -248,6 +253,152 @@ static int w100fb_blank(int blank_mode, struct fb_info *info)
248} 253}
249 254
250 255
256static void w100_fifo_wait(int entries)
257{
258 union rbbm_status_u status;
259 int i;
260
261 for (i = 0; i < 2000000; i++) {
262 status.val = readl(remapped_regs + mmRBBM_STATUS);
263 if (status.f.cmdfifo_avail >= entries)
264 return;
265 udelay(1);
266 }
267 printk(KERN_ERR "w100fb: FIFO Timeout!\n");
268}
269
270
271static int w100fb_sync(struct fb_info *info)
272{
273 union rbbm_status_u status;
274 int i;
275
276 for (i = 0; i < 2000000; i++) {
277 status.val = readl(remapped_regs + mmRBBM_STATUS);
278 if (!status.f.gui_active)
279 return 0;
280 udelay(1);
281 }
282 printk(KERN_ERR "w100fb: Graphic engine timeout!\n");
283 return -EBUSY;
284}
285
286
287static void w100_init_graphic_engine(struct w100fb_par *par)
288{
289 union dp_gui_master_cntl_u gmc;
290 union dp_mix_u dp_mix;
291 union dp_datatype_u dp_datatype;
292 union dp_cntl_u dp_cntl;
293
294 w100_fifo_wait(4);
295 writel(W100_FB_BASE, remapped_regs + mmDST_OFFSET);
296 writel(par->xres, remapped_regs + mmDST_PITCH);
297 writel(W100_FB_BASE, remapped_regs + mmSRC_OFFSET);
298 writel(par->xres, remapped_regs + mmSRC_PITCH);
299
300 w100_fifo_wait(3);
301 writel(0, remapped_regs + mmSC_TOP_LEFT);
302 writel((par->yres << 16) | par->xres, remapped_regs + mmSC_BOTTOM_RIGHT);
303 writel(0x1fff1fff, remapped_regs + mmSRC_SC_BOTTOM_RIGHT);
304
305 w100_fifo_wait(4);
306 dp_cntl.val = 0;
307 dp_cntl.f.dst_x_dir = 1;
308 dp_cntl.f.dst_y_dir = 1;
309 dp_cntl.f.src_x_dir = 1;
310 dp_cntl.f.src_y_dir = 1;
311 dp_cntl.f.dst_major_x = 1;
312 dp_cntl.f.src_major_x = 1;
313 writel(dp_cntl.val, remapped_regs + mmDP_CNTL);
314
315 gmc.val = 0;
316 gmc.f.gmc_src_pitch_offset_cntl = 1;
317 gmc.f.gmc_dst_pitch_offset_cntl = 1;
318 gmc.f.gmc_src_clipping = 1;
319 gmc.f.gmc_dst_clipping = 1;
320 gmc.f.gmc_brush_datatype = GMC_BRUSH_NONE;
321 gmc.f.gmc_dst_datatype = 3; /* from DstType_16Bpp_444 */
322 gmc.f.gmc_src_datatype = SRC_DATATYPE_EQU_DST;
323 gmc.f.gmc_byte_pix_order = 1;
324 gmc.f.gmc_default_sel = 0;
325 gmc.f.gmc_rop3 = ROP3_SRCCOPY;
326 gmc.f.gmc_dp_src_source = DP_SRC_MEM_RECTANGULAR;
327 gmc.f.gmc_clr_cmp_fcn_dis = 1;
328 gmc.f.gmc_wr_msk_dis = 1;
329 gmc.f.gmc_dp_op = DP_OP_ROP;
330 writel(gmc.val, remapped_regs + mmDP_GUI_MASTER_CNTL);
331
332 dp_datatype.val = dp_mix.val = 0;
333 dp_datatype.f.dp_dst_datatype = gmc.f.gmc_dst_datatype;
334 dp_datatype.f.dp_brush_datatype = gmc.f.gmc_brush_datatype;
335 dp_datatype.f.dp_src2_type = 0;
336 dp_datatype.f.dp_src2_datatype = gmc.f.gmc_src_datatype;
337 dp_datatype.f.dp_src_datatype = gmc.f.gmc_src_datatype;
338 dp_datatype.f.dp_byte_pix_order = gmc.f.gmc_byte_pix_order;
339 writel(dp_datatype.val, remapped_regs + mmDP_DATATYPE);
340
341 dp_mix.f.dp_src_source = gmc.f.gmc_dp_src_source;
342 dp_mix.f.dp_src2_source = 1;
343 dp_mix.f.dp_rop3 = gmc.f.gmc_rop3;
344 dp_mix.f.dp_op = gmc.f.gmc_dp_op;
345 writel(dp_mix.val, remapped_regs + mmDP_MIX);
346}
347
348
349static void w100fb_fillrect(struct fb_info *info,
350 const struct fb_fillrect *rect)
351{
352 union dp_gui_master_cntl_u gmc;
353
354 if (info->state != FBINFO_STATE_RUNNING)
355 return;
356 if (info->flags & FBINFO_HWACCEL_DISABLED) {
357 cfb_fillrect(info, rect);
358 return;
359 }
360
361 gmc.val = readl(remapped_regs + mmDP_GUI_MASTER_CNTL);
362 gmc.f.gmc_rop3 = ROP3_PATCOPY;
363 gmc.f.gmc_brush_datatype = GMC_BRUSH_SOLID_COLOR;
364 w100_fifo_wait(2);
365 writel(gmc.val, remapped_regs + mmDP_GUI_MASTER_CNTL);
366 writel(rect->color, remapped_regs + mmDP_BRUSH_FRGD_CLR);
367
368 w100_fifo_wait(2);
369 writel((rect->dy << 16) | (rect->dx & 0xffff), remapped_regs + mmDST_Y_X);
370 writel((rect->width << 16) | (rect->height & 0xffff),
371 remapped_regs + mmDST_WIDTH_HEIGHT);
372}
373
374
375static void w100fb_copyarea(struct fb_info *info,
376 const struct fb_copyarea *area)
377{
378 u32 dx = area->dx, dy = area->dy, sx = area->sx, sy = area->sy;
379 u32 h = area->height, w = area->width;
380 union dp_gui_master_cntl_u gmc;
381
382 if (info->state != FBINFO_STATE_RUNNING)
383 return;
384 if (info->flags & FBINFO_HWACCEL_DISABLED) {
385 cfb_copyarea(info, area);
386 return;
387 }
388
389 gmc.val = readl(remapped_regs + mmDP_GUI_MASTER_CNTL);
390 gmc.f.gmc_rop3 = ROP3_SRCCOPY;
391 gmc.f.gmc_brush_datatype = GMC_BRUSH_NONE;
392 w100_fifo_wait(1);
393 writel(gmc.val, remapped_regs + mmDP_GUI_MASTER_CNTL);
394
395 w100_fifo_wait(3);
396 writel((sy << 16) | (sx & 0xffff), remapped_regs + mmSRC_Y_X);
397 writel((dy << 16) | (dx & 0xffff), remapped_regs + mmDST_Y_X);
398 writel((w << 16) | (h & 0xffff), remapped_regs + mmDST_WIDTH_HEIGHT);
399}
400
401
251/* 402/*
252 * Change the resolution by calling the appropriate hardware functions 403 * Change the resolution by calling the appropriate hardware functions
253 */ 404 */
@@ -265,6 +416,7 @@ static void w100fb_activate_var(struct w100fb_par *par)
265 w100_init_lcd(par); 416 w100_init_lcd(par);
266 w100_set_dispregs(par); 417 w100_set_dispregs(par);
267 w100_update_enable(); 418 w100_update_enable();
419 w100_init_graphic_engine(par);
268 420
269 calc_hsync(par); 421 calc_hsync(par);
270 422
@@ -394,9 +546,10 @@ static struct fb_ops w100fb_ops = {
394 .fb_set_par = w100fb_set_par, 546 .fb_set_par = w100fb_set_par,
395 .fb_setcolreg = w100fb_setcolreg, 547 .fb_setcolreg = w100fb_setcolreg,
396 .fb_blank = w100fb_blank, 548 .fb_blank = w100fb_blank,
397 .fb_fillrect = cfb_fillrect, 549 .fb_fillrect = w100fb_fillrect,
398 .fb_copyarea = cfb_copyarea, 550 .fb_copyarea = w100fb_copyarea,
399 .fb_imageblit = cfb_imageblit, 551 .fb_imageblit = cfb_imageblit,
552 .fb_sync = w100fb_sync,
400}; 553};
401 554
402#ifdef CONFIG_PM 555#ifdef CONFIG_PM
@@ -543,7 +696,8 @@ int __init w100fb_probe(struct platform_device *pdev)
543 } 696 }
544 697
545 info->fbops = &w100fb_ops; 698 info->fbops = &w100fb_ops;
546 info->flags = FBINFO_DEFAULT; 699 info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_COPYAREA |
700 FBINFO_HWACCEL_FILLRECT;
547 info->node = -1; 701 info->node = -1;
548 info->screen_base = remapped_fbuf + (W100_FB_BASE-MEM_WINDOW_BASE); 702 info->screen_base = remapped_fbuf + (W100_FB_BASE-MEM_WINDOW_BASE);
549 info->screen_size = REMAPPED_FB_LEN; 703 info->screen_size = REMAPPED_FB_LEN;
diff --git a/drivers/video/w100fb.h b/drivers/video/w100fb.h
index 7a58a1e3e427..fffae7b4f6e9 100644
--- a/drivers/video/w100fb.h
+++ b/drivers/video/w100fb.h
@@ -122,15 +122,32 @@
122/* Block DISPLAY End: */ 122/* Block DISPLAY End: */
123 123
124/* Block GFX Start: */ 124/* Block GFX Start: */
125#define mmDST_OFFSET 0x1004
126#define mmDST_PITCH 0x1008
127#define mmDST_Y_X 0x1038
128#define mmDST_WIDTH_HEIGHT 0x1198
129#define mmDP_GUI_MASTER_CNTL 0x106C
125#define mmBRUSH_OFFSET 0x108C 130#define mmBRUSH_OFFSET 0x108C
126#define mmBRUSH_Y_X 0x1074 131#define mmBRUSH_Y_X 0x1074
132#define mmDP_BRUSH_FRGD_CLR 0x107C
133#define mmSRC_OFFSET 0x11AC
134#define mmSRC_PITCH 0x11B0
135#define mmSRC_Y_X 0x1034
127#define mmDEFAULT_PITCH_OFFSET 0x10A0 136#define mmDEFAULT_PITCH_OFFSET 0x10A0
128#define mmDEFAULT_SC_BOTTOM_RIGHT 0x10A8 137#define mmDEFAULT_SC_BOTTOM_RIGHT 0x10A8
129#define mmDEFAULT2_SC_BOTTOM_RIGHT 0x10AC 138#define mmDEFAULT2_SC_BOTTOM_RIGHT 0x10AC
139#define mmSC_TOP_LEFT 0x11BC
140#define mmSC_BOTTOM_RIGHT 0x11C0
141#define mmSRC_SC_BOTTOM_RIGHT 0x11C4
130#define mmGLOBAL_ALPHA 0x1210 142#define mmGLOBAL_ALPHA 0x1210
131#define mmFILTER_COEF 0x1214 143#define mmFILTER_COEF 0x1214
132#define mmMVC_CNTL_START 0x11E0 144#define mmMVC_CNTL_START 0x11E0
133#define mmE2_ARITHMETIC_CNTL 0x1220 145#define mmE2_ARITHMETIC_CNTL 0x1220
146#define mmDP_CNTL 0x11C8
147#define mmDP_CNTL_DST_DIR 0x11CC
148#define mmDP_DATATYPE 0x12C4
149#define mmDP_MIX 0x12C8
150#define mmDP_WRITE_MSK 0x12CC
134#define mmENG_CNTL 0x13E8 151#define mmENG_CNTL 0x13E8
135#define mmENG_PERF_CNT 0x13F0 152#define mmENG_PERF_CNT 0x13F0
136/* Block GFX End: */ 153/* Block GFX End: */
@@ -179,6 +196,7 @@
179/* Block RBBM Start: */ 196/* Block RBBM Start: */
180#define mmWAIT_UNTIL 0x1400 197#define mmWAIT_UNTIL 0x1400
181#define mmISYNC_CNTL 0x1404 198#define mmISYNC_CNTL 0x1404
199#define mmRBBM_STATUS 0x0140
182#define mmRBBM_CNTL 0x0144 200#define mmRBBM_CNTL 0x0144
183#define mmNQWAIT_UNTIL 0x0150 201#define mmNQWAIT_UNTIL 0x0150
184/* Block RBBM End: */ 202/* Block RBBM End: */
@@ -225,147 +243,147 @@
225/* Register structure definitions */ 243/* Register structure definitions */
226 244
227struct wrap_top_dir_t { 245struct wrap_top_dir_t {
228 unsigned long top_addr : 23; 246 u32 top_addr : 23;
229 unsigned long : 9; 247 u32 : 9;
230} __attribute__((packed)); 248} __attribute__((packed));
231 249
232union wrap_top_dir_u { 250union wrap_top_dir_u {
233 unsigned long val : 32; 251 u32 val : 32;
234 struct wrap_top_dir_t f; 252 struct wrap_top_dir_t f;
235} __attribute__((packed)); 253} __attribute__((packed));
236 254
237struct wrap_start_dir_t { 255struct wrap_start_dir_t {
238 unsigned long start_addr : 23; 256 u32 start_addr : 23;
239 unsigned long : 9; 257 u32 : 9;
240} __attribute__((packed)); 258} __attribute__((packed));
241 259
242union wrap_start_dir_u { 260union wrap_start_dir_u {
243 unsigned long val : 32; 261 u32 val : 32;
244 struct wrap_start_dir_t f; 262 struct wrap_start_dir_t f;
245} __attribute__((packed)); 263} __attribute__((packed));
246 264
247struct cif_cntl_t { 265struct cif_cntl_t {
248 unsigned long swap_reg : 2; 266 u32 swap_reg : 2;
249 unsigned long swap_fbuf_1 : 2; 267 u32 swap_fbuf_1 : 2;
250 unsigned long swap_fbuf_2 : 2; 268 u32 swap_fbuf_2 : 2;
251 unsigned long swap_fbuf_3 : 2; 269 u32 swap_fbuf_3 : 2;
252 unsigned long pmi_int_disable : 1; 270 u32 pmi_int_disable : 1;
253 unsigned long pmi_schmen_disable : 1; 271 u32 pmi_schmen_disable : 1;
254 unsigned long intb_oe : 1; 272 u32 intb_oe : 1;
255 unsigned long en_wait_to_compensate_dq_prop_dly : 1; 273 u32 en_wait_to_compensate_dq_prop_dly : 1;
256 unsigned long compensate_wait_rd_size : 2; 274 u32 compensate_wait_rd_size : 2;
257 unsigned long wait_asserted_timeout_val : 2; 275 u32 wait_asserted_timeout_val : 2;
258 unsigned long wait_masked_val : 2; 276 u32 wait_masked_val : 2;
259 unsigned long en_wait_timeout : 1; 277 u32 en_wait_timeout : 1;
260 unsigned long en_one_clk_setup_before_wait : 1; 278 u32 en_one_clk_setup_before_wait : 1;
261 unsigned long interrupt_active_high : 1; 279 u32 interrupt_active_high : 1;
262 unsigned long en_overwrite_straps : 1; 280 u32 en_overwrite_straps : 1;
263 unsigned long strap_wait_active_hi : 1; 281 u32 strap_wait_active_hi : 1;
264 unsigned long lat_busy_count : 2; 282 u32 lat_busy_count : 2;
265 unsigned long lat_rd_pm4_sclk_busy : 1; 283 u32 lat_rd_pm4_sclk_busy : 1;
266 unsigned long dis_system_bits : 1; 284 u32 dis_system_bits : 1;
267 unsigned long dis_mr : 1; 285 u32 dis_mr : 1;
268 unsigned long cif_spare_1 : 4; 286 u32 cif_spare_1 : 4;
269} __attribute__((packed)); 287} __attribute__((packed));
270 288
271union cif_cntl_u { 289union cif_cntl_u {
272 unsigned long val : 32; 290 u32 val : 32;
273 struct cif_cntl_t f; 291 struct cif_cntl_t f;
274} __attribute__((packed)); 292} __attribute__((packed));
275 293
276struct cfgreg_base_t { 294struct cfgreg_base_t {
277 unsigned long cfgreg_base : 24; 295 u32 cfgreg_base : 24;
278 unsigned long : 8; 296 u32 : 8;
279} __attribute__((packed)); 297} __attribute__((packed));
280 298
281union cfgreg_base_u { 299union cfgreg_base_u {
282 unsigned long val : 32; 300 u32 val : 32;
283 struct cfgreg_base_t f; 301 struct cfgreg_base_t f;
284} __attribute__((packed)); 302} __attribute__((packed));
285 303
286struct cif_io_t { 304struct cif_io_t {
287 unsigned long dq_srp : 1; 305 u32 dq_srp : 1;
288 unsigned long dq_srn : 1; 306 u32 dq_srn : 1;
289 unsigned long dq_sp : 4; 307 u32 dq_sp : 4;
290 unsigned long dq_sn : 4; 308 u32 dq_sn : 4;
291 unsigned long waitb_srp : 1; 309 u32 waitb_srp : 1;
292 unsigned long waitb_srn : 1; 310 u32 waitb_srn : 1;
293 unsigned long waitb_sp : 4; 311 u32 waitb_sp : 4;
294 unsigned long waitb_sn : 4; 312 u32 waitb_sn : 4;
295 unsigned long intb_srp : 1; 313 u32 intb_srp : 1;
296 unsigned long intb_srn : 1; 314 u32 intb_srn : 1;
297 unsigned long intb_sp : 4; 315 u32 intb_sp : 4;
298 unsigned long intb_sn : 4; 316 u32 intb_sn : 4;
299 unsigned long : 2; 317 u32 : 2;
300} __attribute__((packed)); 318} __attribute__((packed));
301 319
302union cif_io_u { 320union cif_io_u {
303 unsigned long val : 32; 321 u32 val : 32;
304 struct cif_io_t f; 322 struct cif_io_t f;
305} __attribute__((packed)); 323} __attribute__((packed));
306 324
307struct cif_read_dbg_t { 325struct cif_read_dbg_t {
308 unsigned long unpacker_pre_fetch_trig_gen : 2; 326 u32 unpacker_pre_fetch_trig_gen : 2;
309 unsigned long dly_second_rd_fetch_trig : 1; 327 u32 dly_second_rd_fetch_trig : 1;
310 unsigned long rst_rd_burst_id : 1; 328 u32 rst_rd_burst_id : 1;
311 unsigned long dis_rd_burst_id : 1; 329 u32 dis_rd_burst_id : 1;
312 unsigned long en_block_rd_when_packer_is_not_emp : 1; 330 u32 en_block_rd_when_packer_is_not_emp : 1;
313 unsigned long dis_pre_fetch_cntl_sm : 1; 331 u32 dis_pre_fetch_cntl_sm : 1;
314 unsigned long rbbm_chrncy_dis : 1; 332 u32 rbbm_chrncy_dis : 1;
315 unsigned long rbbm_rd_after_wr_lat : 2; 333 u32 rbbm_rd_after_wr_lat : 2;
316 unsigned long dis_be_during_rd : 1; 334 u32 dis_be_during_rd : 1;
317 unsigned long one_clk_invalidate_pulse : 1; 335 u32 one_clk_invalidate_pulse : 1;
318 unsigned long dis_chnl_priority : 1; 336 u32 dis_chnl_priority : 1;
319 unsigned long rst_read_path_a_pls : 1; 337 u32 rst_read_path_a_pls : 1;
320 unsigned long rst_read_path_b_pls : 1; 338 u32 rst_read_path_b_pls : 1;
321 unsigned long dis_reg_rd_fetch_trig : 1; 339 u32 dis_reg_rd_fetch_trig : 1;
322 unsigned long dis_rd_fetch_trig_from_ind_addr : 1; 340 u32 dis_rd_fetch_trig_from_ind_addr : 1;
323 unsigned long dis_rd_same_byte_to_trig_fetch : 1; 341 u32 dis_rd_same_byte_to_trig_fetch : 1;
324 unsigned long dis_dir_wrap : 1; 342 u32 dis_dir_wrap : 1;
325 unsigned long dis_ring_buf_to_force_dec : 1; 343 u32 dis_ring_buf_to_force_dec : 1;
326 unsigned long dis_addr_comp_in_16bit : 1; 344 u32 dis_addr_comp_in_16bit : 1;
327 unsigned long clr_w : 1; 345 u32 clr_w : 1;
328 unsigned long err_rd_tag_is_3 : 1; 346 u32 err_rd_tag_is_3 : 1;
329 unsigned long err_load_when_ful_a : 1; 347 u32 err_load_when_ful_a : 1;
330 unsigned long err_load_when_ful_b : 1; 348 u32 err_load_when_ful_b : 1;
331 unsigned long : 7; 349 u32 : 7;
332} __attribute__((packed)); 350} __attribute__((packed));
333 351
334union cif_read_dbg_u { 352union cif_read_dbg_u {
335 unsigned long val : 32; 353 u32 val : 32;
336 struct cif_read_dbg_t f; 354 struct cif_read_dbg_t f;
337} __attribute__((packed)); 355} __attribute__((packed));
338 356
339struct cif_write_dbg_t { 357struct cif_write_dbg_t {
340 unsigned long packer_timeout_count : 2; 358 u32 packer_timeout_count : 2;
341 unsigned long en_upper_load_cond : 1; 359 u32 en_upper_load_cond : 1;
342 unsigned long en_chnl_change_cond : 1; 360 u32 en_chnl_change_cond : 1;
343 unsigned long dis_addr_comp_cond : 1; 361 u32 dis_addr_comp_cond : 1;
344 unsigned long dis_load_same_byte_addr_cond : 1; 362 u32 dis_load_same_byte_addr_cond : 1;
345 unsigned long dis_timeout_cond : 1; 363 u32 dis_timeout_cond : 1;
346 unsigned long dis_timeout_during_rbbm : 1; 364 u32 dis_timeout_during_rbbm : 1;
347 unsigned long dis_packer_ful_during_rbbm_timeout : 1; 365 u32 dis_packer_ful_during_rbbm_timeout : 1;
348 unsigned long en_dword_split_to_rbbm : 1; 366 u32 en_dword_split_to_rbbm : 1;
349 unsigned long en_dummy_val : 1; 367 u32 en_dummy_val : 1;
350 unsigned long dummy_val_sel : 1; 368 u32 dummy_val_sel : 1;
351 unsigned long mask_pm4_wrptr_dec : 1; 369 u32 mask_pm4_wrptr_dec : 1;
352 unsigned long dis_mc_clean_cond : 1; 370 u32 dis_mc_clean_cond : 1;
353 unsigned long err_two_reqi_during_ful : 1; 371 u32 err_two_reqi_during_ful : 1;
354 unsigned long err_reqi_during_idle_clk : 1; 372 u32 err_reqi_during_idle_clk : 1;
355 unsigned long err_global : 1; 373 u32 err_global : 1;
356 unsigned long en_wr_buf_dbg_load : 1; 374 u32 en_wr_buf_dbg_load : 1;
357 unsigned long en_wr_buf_dbg_path : 1; 375 u32 en_wr_buf_dbg_path : 1;
358 unsigned long sel_wr_buf_byte : 3; 376 u32 sel_wr_buf_byte : 3;
359 unsigned long dis_rd_flush_wr : 1; 377 u32 dis_rd_flush_wr : 1;
360 unsigned long dis_packer_ful_cond : 1; 378 u32 dis_packer_ful_cond : 1;
361 unsigned long dis_invalidate_by_ops_chnl : 1; 379 u32 dis_invalidate_by_ops_chnl : 1;
362 unsigned long en_halt_when_reqi_err : 1; 380 u32 en_halt_when_reqi_err : 1;
363 unsigned long cif_spare_2 : 5; 381 u32 cif_spare_2 : 5;
364 unsigned long : 1; 382 u32 : 1;
365} __attribute__((packed)); 383} __attribute__((packed));
366 384
367union cif_write_dbg_u { 385union cif_write_dbg_u {
368 unsigned long val : 32; 386 u32 val : 32;
369 struct cif_write_dbg_t f; 387 struct cif_write_dbg_t f;
370} __attribute__((packed)); 388} __attribute__((packed));
371 389
@@ -403,327 +421,327 @@ union cpu_defaults_u {
403} __attribute__((packed)); 421} __attribute__((packed));
404 422
405struct crtc_total_t { 423struct crtc_total_t {
406 unsigned long crtc_h_total : 10; 424 u32 crtc_h_total : 10;
407 unsigned long : 6; 425 u32 : 6;
408 unsigned long crtc_v_total : 10; 426 u32 crtc_v_total : 10;
409 unsigned long : 6; 427 u32 : 6;
410} __attribute__((packed)); 428} __attribute__((packed));
411 429
412union crtc_total_u { 430union crtc_total_u {
413 unsigned long val : 32; 431 u32 val : 32;
414 struct crtc_total_t f; 432 struct crtc_total_t f;
415} __attribute__((packed)); 433} __attribute__((packed));
416 434
417struct crtc_ss_t { 435struct crtc_ss_t {
418 unsigned long ss_start : 10; 436 u32 ss_start : 10;
419 unsigned long : 6; 437 u32 : 6;
420 unsigned long ss_end : 10; 438 u32 ss_end : 10;
421 unsigned long : 2; 439 u32 : 2;
422 unsigned long ss_align : 1; 440 u32 ss_align : 1;
423 unsigned long ss_pol : 1; 441 u32 ss_pol : 1;
424 unsigned long ss_run_mode : 1; 442 u32 ss_run_mode : 1;
425 unsigned long ss_en : 1; 443 u32 ss_en : 1;
426} __attribute__((packed)); 444} __attribute__((packed));
427 445
428union crtc_ss_u { 446union crtc_ss_u {
429 unsigned long val : 32; 447 u32 val : 32;
430 struct crtc_ss_t f; 448 struct crtc_ss_t f;
431} __attribute__((packed)); 449} __attribute__((packed));
432 450
433struct active_h_disp_t { 451struct active_h_disp_t {
434 unsigned long active_h_start : 10; 452 u32 active_h_start : 10;
435 unsigned long : 6; 453 u32 : 6;
436 unsigned long active_h_end : 10; 454 u32 active_h_end : 10;
437 unsigned long : 6; 455 u32 : 6;
438} __attribute__((packed)); 456} __attribute__((packed));
439 457
440union active_h_disp_u { 458union active_h_disp_u {
441 unsigned long val : 32; 459 u32 val : 32;
442 struct active_h_disp_t f; 460 struct active_h_disp_t f;
443} __attribute__((packed)); 461} __attribute__((packed));
444 462
445struct active_v_disp_t { 463struct active_v_disp_t {
446 unsigned long active_v_start : 10; 464 u32 active_v_start : 10;
447 unsigned long : 6; 465 u32 : 6;
448 unsigned long active_v_end : 10; 466 u32 active_v_end : 10;
449 unsigned long : 6; 467 u32 : 6;
450} __attribute__((packed)); 468} __attribute__((packed));
451 469
452union active_v_disp_u { 470union active_v_disp_u {
453 unsigned long val : 32; 471 u32 val : 32;
454 struct active_v_disp_t f; 472 struct active_v_disp_t f;
455} __attribute__((packed)); 473} __attribute__((packed));
456 474
457struct graphic_h_disp_t { 475struct graphic_h_disp_t {
458 unsigned long graphic_h_start : 10; 476 u32 graphic_h_start : 10;
459 unsigned long : 6; 477 u32 : 6;
460 unsigned long graphic_h_end : 10; 478 u32 graphic_h_end : 10;
461 unsigned long : 6; 479 u32 : 6;
462} __attribute__((packed)); 480} __attribute__((packed));
463 481
464union graphic_h_disp_u { 482union graphic_h_disp_u {
465 unsigned long val : 32; 483 u32 val : 32;
466 struct graphic_h_disp_t f; 484 struct graphic_h_disp_t f;
467} __attribute__((packed)); 485} __attribute__((packed));
468 486
469struct graphic_v_disp_t { 487struct graphic_v_disp_t {
470 unsigned long graphic_v_start : 10; 488 u32 graphic_v_start : 10;
471 unsigned long : 6; 489 u32 : 6;
472 unsigned long graphic_v_end : 10; 490 u32 graphic_v_end : 10;
473 unsigned long : 6; 491 u32 : 6;
474} __attribute__((packed)); 492} __attribute__((packed));
475 493
476union graphic_v_disp_u{ 494union graphic_v_disp_u{
477 unsigned long val : 32; 495 u32 val : 32;
478 struct graphic_v_disp_t f; 496 struct graphic_v_disp_t f;
479} __attribute__((packed)); 497} __attribute__((packed));
480 498
481struct graphic_ctrl_t_w100 { 499struct graphic_ctrl_t_w100 {
482 unsigned long color_depth : 3; 500 u32 color_depth : 3;
483 unsigned long portrait_mode : 2; 501 u32 portrait_mode : 2;
484 unsigned long low_power_on : 1; 502 u32 low_power_on : 1;
485 unsigned long req_freq : 4; 503 u32 req_freq : 4;
486 unsigned long en_crtc : 1; 504 u32 en_crtc : 1;
487 unsigned long en_graphic_req : 1; 505 u32 en_graphic_req : 1;
488 unsigned long en_graphic_crtc : 1; 506 u32 en_graphic_crtc : 1;
489 unsigned long total_req_graphic : 9; 507 u32 total_req_graphic : 9;
490 unsigned long lcd_pclk_on : 1; 508 u32 lcd_pclk_on : 1;
491 unsigned long lcd_sclk_on : 1; 509 u32 lcd_sclk_on : 1;
492 unsigned long pclk_running : 1; 510 u32 pclk_running : 1;
493 unsigned long sclk_running : 1; 511 u32 sclk_running : 1;
494 unsigned long : 6; 512 u32 : 6;
495} __attribute__((packed)); 513} __attribute__((packed));
496 514
497struct graphic_ctrl_t_w32xx { 515struct graphic_ctrl_t_w32xx {
498 unsigned long color_depth : 3; 516 u32 color_depth : 3;
499 unsigned long portrait_mode : 2; 517 u32 portrait_mode : 2;
500 unsigned long low_power_on : 1; 518 u32 low_power_on : 1;
501 unsigned long req_freq : 4; 519 u32 req_freq : 4;
502 unsigned long en_crtc : 1; 520 u32 en_crtc : 1;
503 unsigned long en_graphic_req : 1; 521 u32 en_graphic_req : 1;
504 unsigned long en_graphic_crtc : 1; 522 u32 en_graphic_crtc : 1;
505 unsigned long total_req_graphic : 10; 523 u32 total_req_graphic : 10;
506 unsigned long lcd_pclk_on : 1; 524 u32 lcd_pclk_on : 1;
507 unsigned long lcd_sclk_on : 1; 525 u32 lcd_sclk_on : 1;
508 unsigned long pclk_running : 1; 526 u32 pclk_running : 1;
509 unsigned long sclk_running : 1; 527 u32 sclk_running : 1;
510 unsigned long : 5; 528 u32 : 5;
511} __attribute__((packed)); 529} __attribute__((packed));
512 530
513union graphic_ctrl_u { 531union graphic_ctrl_u {
514 unsigned long val : 32; 532 u32 val : 32;
515 struct graphic_ctrl_t_w100 f_w100; 533 struct graphic_ctrl_t_w100 f_w100;
516 struct graphic_ctrl_t_w32xx f_w32xx; 534 struct graphic_ctrl_t_w32xx f_w32xx;
517} __attribute__((packed)); 535} __attribute__((packed));
518 536
519struct video_ctrl_t { 537struct video_ctrl_t {
520 unsigned long video_mode : 1; 538 u32 video_mode : 1;
521 unsigned long keyer_en : 1; 539 u32 keyer_en : 1;
522 unsigned long en_video_req : 1; 540 u32 en_video_req : 1;
523 unsigned long en_graphic_req_video : 1; 541 u32 en_graphic_req_video : 1;
524 unsigned long en_video_crtc : 1; 542 u32 en_video_crtc : 1;
525 unsigned long video_hor_exp : 2; 543 u32 video_hor_exp : 2;
526 unsigned long video_ver_exp : 2; 544 u32 video_ver_exp : 2;
527 unsigned long uv_combine : 1; 545 u32 uv_combine : 1;
528 unsigned long total_req_video : 9; 546 u32 total_req_video : 9;
529 unsigned long video_ch_sel : 1; 547 u32 video_ch_sel : 1;
530 unsigned long video_portrait : 2; 548 u32 video_portrait : 2;
531 unsigned long yuv2rgb_en : 1; 549 u32 yuv2rgb_en : 1;
532 unsigned long yuv2rgb_option : 1; 550 u32 yuv2rgb_option : 1;
533 unsigned long video_inv_hor : 1; 551 u32 video_inv_hor : 1;
534 unsigned long video_inv_ver : 1; 552 u32 video_inv_ver : 1;
535 unsigned long gamma_sel : 2; 553 u32 gamma_sel : 2;
536 unsigned long dis_limit : 1; 554 u32 dis_limit : 1;
537 unsigned long en_uv_hblend : 1; 555 u32 en_uv_hblend : 1;
538 unsigned long rgb_gamma_sel : 2; 556 u32 rgb_gamma_sel : 2;
539} __attribute__((packed)); 557} __attribute__((packed));
540 558
541union video_ctrl_u { 559union video_ctrl_u {
542 unsigned long val : 32; 560 u32 val : 32;
543 struct video_ctrl_t f; 561 struct video_ctrl_t f;
544} __attribute__((packed)); 562} __attribute__((packed));
545 563
546struct disp_db_buf_cntl_rd_t { 564struct disp_db_buf_cntl_rd_t {
547 unsigned long en_db_buf : 1; 565 u32 en_db_buf : 1;
548 unsigned long update_db_buf_done : 1; 566 u32 update_db_buf_done : 1;
549 unsigned long db_buf_cntl : 6; 567 u32 db_buf_cntl : 6;
550 unsigned long : 24; 568 u32 : 24;
551} __attribute__((packed)); 569} __attribute__((packed));
552 570
553union disp_db_buf_cntl_rd_u { 571union disp_db_buf_cntl_rd_u {
554 unsigned long val : 32; 572 u32 val : 32;
555 struct disp_db_buf_cntl_rd_t f; 573 struct disp_db_buf_cntl_rd_t f;
556} __attribute__((packed)); 574} __attribute__((packed));
557 575
558struct disp_db_buf_cntl_wr_t { 576struct disp_db_buf_cntl_wr_t {
559 unsigned long en_db_buf : 1; 577 u32 en_db_buf : 1;
560 unsigned long update_db_buf : 1; 578 u32 update_db_buf : 1;
561 unsigned long db_buf_cntl : 6; 579 u32 db_buf_cntl : 6;
562 unsigned long : 24; 580 u32 : 24;
563} __attribute__((packed)); 581} __attribute__((packed));
564 582
565union disp_db_buf_cntl_wr_u { 583union disp_db_buf_cntl_wr_u {
566 unsigned long val : 32; 584 u32 val : 32;
567 struct disp_db_buf_cntl_wr_t f; 585 struct disp_db_buf_cntl_wr_t f;
568} __attribute__((packed)); 586} __attribute__((packed));
569 587
570struct gamma_value1_t { 588struct gamma_value1_t {
571 unsigned long gamma1 : 8; 589 u32 gamma1 : 8;
572 unsigned long gamma2 : 8; 590 u32 gamma2 : 8;
573 unsigned long gamma3 : 8; 591 u32 gamma3 : 8;
574 unsigned long gamma4 : 8; 592 u32 gamma4 : 8;
575} __attribute__((packed)); 593} __attribute__((packed));
576 594
577union gamma_value1_u { 595union gamma_value1_u {
578 unsigned long val : 32; 596 u32 val : 32;
579 struct gamma_value1_t f; 597 struct gamma_value1_t f;
580} __attribute__((packed)); 598} __attribute__((packed));
581 599
582struct gamma_value2_t { 600struct gamma_value2_t {
583 unsigned long gamma5 : 8; 601 u32 gamma5 : 8;
584 unsigned long gamma6 : 8; 602 u32 gamma6 : 8;
585 unsigned long gamma7 : 8; 603 u32 gamma7 : 8;
586 unsigned long gamma8 : 8; 604 u32 gamma8 : 8;
587} __attribute__((packed)); 605} __attribute__((packed));
588 606
589union gamma_value2_u { 607union gamma_value2_u {
590 unsigned long val : 32; 608 u32 val : 32;
591 struct gamma_value2_t f; 609 struct gamma_value2_t f;
592} __attribute__((packed)); 610} __attribute__((packed));
593 611
594struct gamma_slope_t { 612struct gamma_slope_t {
595 unsigned long slope1 : 3; 613 u32 slope1 : 3;
596 unsigned long slope2 : 3; 614 u32 slope2 : 3;
597 unsigned long slope3 : 3; 615 u32 slope3 : 3;
598 unsigned long slope4 : 3; 616 u32 slope4 : 3;
599 unsigned long slope5 : 3; 617 u32 slope5 : 3;
600 unsigned long slope6 : 3; 618 u32 slope6 : 3;
601 unsigned long slope7 : 3; 619 u32 slope7 : 3;
602 unsigned long slope8 : 3; 620 u32 slope8 : 3;
603 unsigned long : 8; 621 u32 : 8;
604} __attribute__((packed)); 622} __attribute__((packed));
605 623
606union gamma_slope_u { 624union gamma_slope_u {
607 unsigned long val : 32; 625 u32 val : 32;
608 struct gamma_slope_t f; 626 struct gamma_slope_t f;
609} __attribute__((packed)); 627} __attribute__((packed));
610 628
611struct mc_ext_mem_location_t { 629struct mc_ext_mem_location_t {
612 unsigned long mc_ext_mem_start : 16; 630 u32 mc_ext_mem_start : 16;
613 unsigned long mc_ext_mem_top : 16; 631 u32 mc_ext_mem_top : 16;
614} __attribute__((packed)); 632} __attribute__((packed));
615 633
616union mc_ext_mem_location_u { 634union mc_ext_mem_location_u {
617 unsigned long val : 32; 635 u32 val : 32;
618 struct mc_ext_mem_location_t f; 636 struct mc_ext_mem_location_t f;
619} __attribute__((packed)); 637} __attribute__((packed));
620 638
621struct mc_fb_location_t { 639struct mc_fb_location_t {
622 unsigned long mc_fb_start : 16; 640 u32 mc_fb_start : 16;
623 unsigned long mc_fb_top : 16; 641 u32 mc_fb_top : 16;
624} __attribute__((packed)); 642} __attribute__((packed));
625 643
626union mc_fb_location_u { 644union mc_fb_location_u {
627 unsigned long val : 32; 645 u32 val : 32;
628 struct mc_fb_location_t f; 646 struct mc_fb_location_t f;
629} __attribute__((packed)); 647} __attribute__((packed));
630 648
631struct clk_pin_cntl_t { 649struct clk_pin_cntl_t {
632 unsigned long osc_en : 1; 650 u32 osc_en : 1;
633 unsigned long osc_gain : 5; 651 u32 osc_gain : 5;
634 unsigned long dont_use_xtalin : 1; 652 u32 dont_use_xtalin : 1;
635 unsigned long xtalin_pm_en : 1; 653 u32 xtalin_pm_en : 1;
636 unsigned long xtalin_dbl_en : 1; 654 u32 xtalin_dbl_en : 1;
637 unsigned long : 7; 655 u32 : 7;
638 unsigned long cg_debug : 16; 656 u32 cg_debug : 16;
639} __attribute__((packed)); 657} __attribute__((packed));
640 658
641union clk_pin_cntl_u { 659union clk_pin_cntl_u {
642 unsigned long val : 32; 660 u32 val : 32;
643 struct clk_pin_cntl_t f; 661 struct clk_pin_cntl_t f;
644} __attribute__((packed)); 662} __attribute__((packed));
645 663
646struct pll_ref_fb_div_t { 664struct pll_ref_fb_div_t {
647 unsigned long pll_ref_div : 4; 665 u32 pll_ref_div : 4;
648 unsigned long : 4; 666 u32 : 4;
649 unsigned long pll_fb_div_int : 6; 667 u32 pll_fb_div_int : 6;
650 unsigned long : 2; 668 u32 : 2;
651 unsigned long pll_fb_div_frac : 3; 669 u32 pll_fb_div_frac : 3;
652 unsigned long : 1; 670 u32 : 1;
653 unsigned long pll_reset_time : 4; 671 u32 pll_reset_time : 4;
654 unsigned long pll_lock_time : 8; 672 u32 pll_lock_time : 8;
655} __attribute__((packed)); 673} __attribute__((packed));
656 674
657union pll_ref_fb_div_u { 675union pll_ref_fb_div_u {
658 unsigned long val : 32; 676 u32 val : 32;
659 struct pll_ref_fb_div_t f; 677 struct pll_ref_fb_div_t f;
660} __attribute__((packed)); 678} __attribute__((packed));
661 679
662struct pll_cntl_t { 680struct pll_cntl_t {
663 unsigned long pll_pwdn : 1; 681 u32 pll_pwdn : 1;
664 unsigned long pll_reset : 1; 682 u32 pll_reset : 1;
665 unsigned long pll_pm_en : 1; 683 u32 pll_pm_en : 1;
666 unsigned long pll_mode : 1; 684 u32 pll_mode : 1;
667 unsigned long pll_refclk_sel : 1; 685 u32 pll_refclk_sel : 1;
668 unsigned long pll_fbclk_sel : 1; 686 u32 pll_fbclk_sel : 1;
669 unsigned long pll_tcpoff : 1; 687 u32 pll_tcpoff : 1;
670 unsigned long pll_pcp : 3; 688 u32 pll_pcp : 3;
671 unsigned long pll_pvg : 3; 689 u32 pll_pvg : 3;
672 unsigned long pll_vcofr : 1; 690 u32 pll_vcofr : 1;
673 unsigned long pll_ioffset : 2; 691 u32 pll_ioffset : 2;
674 unsigned long pll_pecc_mode : 2; 692 u32 pll_pecc_mode : 2;
675 unsigned long pll_pecc_scon : 2; 693 u32 pll_pecc_scon : 2;
676 unsigned long pll_dactal : 4; 694 u32 pll_dactal : 4;
677 unsigned long pll_cp_clip : 2; 695 u32 pll_cp_clip : 2;
678 unsigned long pll_conf : 3; 696 u32 pll_conf : 3;
679 unsigned long pll_mbctrl : 2; 697 u32 pll_mbctrl : 2;
680 unsigned long pll_ring_off : 1; 698 u32 pll_ring_off : 1;
681} __attribute__((packed)); 699} __attribute__((packed));
682 700
683union pll_cntl_u { 701union pll_cntl_u {
684 unsigned long val : 32; 702 u32 val : 32;
685 struct pll_cntl_t f; 703 struct pll_cntl_t f;
686} __attribute__((packed)); 704} __attribute__((packed));
687 705
688struct sclk_cntl_t { 706struct sclk_cntl_t {
689 unsigned long sclk_src_sel : 2; 707 u32 sclk_src_sel : 2;
690 unsigned long : 2; 708 u32 : 2;
691 unsigned long sclk_post_div_fast : 4; 709 u32 sclk_post_div_fast : 4;
692 unsigned long sclk_clkon_hys : 3; 710 u32 sclk_clkon_hys : 3;
693 unsigned long sclk_post_div_slow : 4; 711 u32 sclk_post_div_slow : 4;
694 unsigned long disp_cg_ok2switch_en : 1; 712 u32 disp_cg_ok2switch_en : 1;
695 unsigned long sclk_force_reg : 1; 713 u32 sclk_force_reg : 1;
696 unsigned long sclk_force_disp : 1; 714 u32 sclk_force_disp : 1;
697 unsigned long sclk_force_mc : 1; 715 u32 sclk_force_mc : 1;
698 unsigned long sclk_force_extmc : 1; 716 u32 sclk_force_extmc : 1;
699 unsigned long sclk_force_cp : 1; 717 u32 sclk_force_cp : 1;
700 unsigned long sclk_force_e2 : 1; 718 u32 sclk_force_e2 : 1;
701 unsigned long sclk_force_e3 : 1; 719 u32 sclk_force_e3 : 1;
702 unsigned long sclk_force_idct : 1; 720 u32 sclk_force_idct : 1;
703 unsigned long sclk_force_bist : 1; 721 u32 sclk_force_bist : 1;
704 unsigned long busy_extend_cp : 1; 722 u32 busy_extend_cp : 1;
705 unsigned long busy_extend_e2 : 1; 723 u32 busy_extend_e2 : 1;
706 unsigned long busy_extend_e3 : 1; 724 u32 busy_extend_e3 : 1;
707 unsigned long busy_extend_idct : 1; 725 u32 busy_extend_idct : 1;
708 unsigned long : 3; 726 u32 : 3;
709} __attribute__((packed)); 727} __attribute__((packed));
710 728
711union sclk_cntl_u { 729union sclk_cntl_u {
712 unsigned long val : 32; 730 u32 val : 32;
713 struct sclk_cntl_t f; 731 struct sclk_cntl_t f;
714} __attribute__((packed)); 732} __attribute__((packed));
715 733
716struct pclk_cntl_t { 734struct pclk_cntl_t {
717 unsigned long pclk_src_sel : 2; 735 u32 pclk_src_sel : 2;
718 unsigned long : 2; 736 u32 : 2;
719 unsigned long pclk_post_div : 4; 737 u32 pclk_post_div : 4;
720 unsigned long : 8; 738 u32 : 8;
721 unsigned long pclk_force_disp : 1; 739 u32 pclk_force_disp : 1;
722 unsigned long : 15; 740 u32 : 15;
723} __attribute__((packed)); 741} __attribute__((packed));
724 742
725union pclk_cntl_u { 743union pclk_cntl_u {
726 unsigned long val : 32; 744 u32 val : 32;
727 struct pclk_cntl_t f; 745 struct pclk_cntl_t f;
728} __attribute__((packed)); 746} __attribute__((packed));
729 747
@@ -735,36 +753,176 @@ union pclk_cntl_u {
735#define TESTCLK_SRC_XTAL 0x06 753#define TESTCLK_SRC_XTAL 0x06
736 754
737struct clk_test_cntl_t { 755struct clk_test_cntl_t {
738 unsigned long testclk_sel : 4; 756 u32 testclk_sel : 4;
739 unsigned long : 3; 757 u32 : 3;
740 unsigned long start_check_freq : 1; 758 u32 start_check_freq : 1;
741 unsigned long tstcount_rst : 1; 759 u32 tstcount_rst : 1;
742 unsigned long : 15; 760 u32 : 15;
743 unsigned long test_count : 8; 761 u32 test_count : 8;
744} __attribute__((packed)); 762} __attribute__((packed));
745 763
746union clk_test_cntl_u { 764union clk_test_cntl_u {
747 unsigned long val : 32; 765 u32 val : 32;
748 struct clk_test_cntl_t f; 766 struct clk_test_cntl_t f;
749} __attribute__((packed)); 767} __attribute__((packed));
750 768
751struct pwrmgt_cntl_t { 769struct pwrmgt_cntl_t {
752 unsigned long pwm_enable : 1; 770 u32 pwm_enable : 1;
753 unsigned long : 1; 771 u32 : 1;
754 unsigned long pwm_mode_req : 2; 772 u32 pwm_mode_req : 2;
755 unsigned long pwm_wakeup_cond : 2; 773 u32 pwm_wakeup_cond : 2;
756 unsigned long pwm_fast_noml_hw_en : 1; 774 u32 pwm_fast_noml_hw_en : 1;
757 unsigned long pwm_noml_fast_hw_en : 1; 775 u32 pwm_noml_fast_hw_en : 1;
758 unsigned long pwm_fast_noml_cond : 4; 776 u32 pwm_fast_noml_cond : 4;
759 unsigned long pwm_noml_fast_cond : 4; 777 u32 pwm_noml_fast_cond : 4;
760 unsigned long pwm_idle_timer : 8; 778 u32 pwm_idle_timer : 8;
761 unsigned long pwm_busy_timer : 8; 779 u32 pwm_busy_timer : 8;
762} __attribute__((packed)); 780} __attribute__((packed));
763 781
764union pwrmgt_cntl_u { 782union pwrmgt_cntl_u {
765 unsigned long val : 32; 783 u32 val : 32;
766 struct pwrmgt_cntl_t f; 784 struct pwrmgt_cntl_t f;
767} __attribute__((packed)); 785} __attribute__((packed));
768 786
787#define SRC_DATATYPE_EQU_DST 3
788
789#define ROP3_SRCCOPY 0xcc
790#define ROP3_PATCOPY 0xf0
791
792#define GMC_BRUSH_SOLID_COLOR 13
793#define GMC_BRUSH_NONE 15
794
795#define DP_SRC_MEM_RECTANGULAR 2
796
797#define DP_OP_ROP 0
798
799struct dp_gui_master_cntl_t {
800 u32 gmc_src_pitch_offset_cntl : 1;
801 u32 gmc_dst_pitch_offset_cntl : 1;
802 u32 gmc_src_clipping : 1;
803 u32 gmc_dst_clipping : 1;
804 u32 gmc_brush_datatype : 4;
805 u32 gmc_dst_datatype : 4;
806 u32 gmc_src_datatype : 3;
807 u32 gmc_byte_pix_order : 1;
808 u32 gmc_default_sel : 1;
809 u32 gmc_rop3 : 8;
810 u32 gmc_dp_src_source : 3;
811 u32 gmc_clr_cmp_fcn_dis : 1;
812 u32 : 1;
813 u32 gmc_wr_msk_dis : 1;
814 u32 gmc_dp_op : 1;
815} __attribute__((packed));
816
817union dp_gui_master_cntl_u {
818 u32 val : 32;
819 struct dp_gui_master_cntl_t f;
820} __attribute__((packed));
821
822struct rbbm_status_t {
823 u32 cmdfifo_avail : 7;
824 u32 : 1;
825 u32 hirq_on_rbb : 1;
826 u32 cprq_on_rbb : 1;
827 u32 cfrq_on_rbb : 1;
828 u32 hirq_in_rtbuf : 1;
829 u32 cprq_in_rtbuf : 1;
830 u32 cfrq_in_rtbuf : 1;
831 u32 cf_pipe_busy : 1;
832 u32 eng_ev_busy : 1;
833 u32 cp_cmdstrm_busy : 1;
834 u32 e2_busy : 1;
835 u32 rb2d_busy : 1;
836 u32 rb3d_busy : 1;
837 u32 se_busy : 1;
838 u32 re_busy : 1;
839 u32 tam_busy : 1;
840 u32 tdm_busy : 1;
841 u32 pb_busy : 1;
842 u32 : 6;
843 u32 gui_active : 1;
844} __attribute__((packed));
845
846union rbbm_status_u {
847 u32 val : 32;
848 struct rbbm_status_t f;
849} __attribute__((packed));
850
851struct dp_datatype_t {
852 u32 dp_dst_datatype : 4;
853 u32 : 4;
854 u32 dp_brush_datatype : 4;
855 u32 dp_src2_type : 1;
856 u32 dp_src2_datatype : 3;
857 u32 dp_src_datatype : 3;
858 u32 : 11;
859 u32 dp_byte_pix_order : 1;
860 u32 : 1;
861} __attribute__((packed));
862
863union dp_datatype_u {
864 u32 val : 32;
865 struct dp_datatype_t f;
866} __attribute__((packed));
867
868struct dp_mix_t {
869 u32 : 8;
870 u32 dp_src_source : 3;
871 u32 dp_src2_source : 3;
872 u32 : 2;
873 u32 dp_rop3 : 8;
874 u32 dp_op : 1;
875 u32 : 7;
876} __attribute__((packed));
877
878union dp_mix_u {
879 u32 val : 32;
880 struct dp_mix_t f;
881} __attribute__((packed));
882
883struct eng_cntl_t {
884 u32 erc_reg_rd_ws : 1;
885 u32 erc_reg_wr_ws : 1;
886 u32 erc_idle_reg_wr : 1;
887 u32 dis_engine_triggers : 1;
888 u32 dis_rop_src_uses_dst_w_h : 1;
889 u32 dis_src_uses_dst_dirmaj : 1;
890 u32 : 6;
891 u32 force_3dclk_when_2dclk : 1;
892 u32 : 19;
893} __attribute__((packed));
894
895union eng_cntl_u {
896 u32 val : 32;
897 struct eng_cntl_t f;
898} __attribute__((packed));
899
900struct dp_cntl_t {
901 u32 dst_x_dir : 1;
902 u32 dst_y_dir : 1;
903 u32 src_x_dir : 1;
904 u32 src_y_dir : 1;
905 u32 dst_major_x : 1;
906 u32 src_major_x : 1;
907 u32 : 26;
908} __attribute__((packed));
909
910union dp_cntl_u {
911 u32 val : 32;
912 struct dp_cntl_t f;
913} __attribute__((packed));
914
915struct dp_cntl_dst_dir_t {
916 u32 : 15;
917 u32 dst_y_dir : 1;
918 u32 : 15;
919 u32 dst_x_dir : 1;
920} __attribute__((packed));
921
922union dp_cntl_dst_dir_u {
923 u32 val : 32;
924 struct dp_cntl_dst_dir_t f;
925} __attribute__((packed));
926
769#endif 927#endif
770 928
diff --git a/fs/Makefile b/fs/Makefile
index 080b3867be4d..83bf478e786b 100644
--- a/fs/Makefile
+++ b/fs/Makefile
@@ -10,7 +10,7 @@ obj-y := open.o read_write.o file_table.o buffer.o bio.o super.o \
10 ioctl.o readdir.o select.o fifo.o locks.o dcache.o inode.o \ 10 ioctl.o readdir.o select.o fifo.o locks.o dcache.o inode.o \
11 attr.o bad_inode.o file.o filesystems.o namespace.o aio.o \ 11 attr.o bad_inode.o file.o filesystems.o namespace.o aio.o \
12 seq_file.o xattr.o libfs.o fs-writeback.o mpage.o direct-io.o \ 12 seq_file.o xattr.o libfs.o fs-writeback.o mpage.o direct-io.o \
13 ioprio.o pnode.o drop_caches.o 13 ioprio.o pnode.o drop_caches.o splice.o sync.o
14 14
15obj-$(CONFIG_INOTIFY) += inotify.o 15obj-$(CONFIG_INOTIFY) += inotify.o
16obj-$(CONFIG_EPOLL) += eventpoll.o 16obj-$(CONFIG_EPOLL) += eventpoll.o
diff --git a/fs/char_dev.c b/fs/char_dev.c
index 4e1b849f912f..f3418f7a6e9d 100644
--- a/fs/char_dev.c
+++ b/fs/char_dev.c
@@ -15,6 +15,7 @@
15#include <linux/module.h> 15#include <linux/module.h>
16#include <linux/smp_lock.h> 16#include <linux/smp_lock.h>
17#include <linux/devfs_fs_kernel.h> 17#include <linux/devfs_fs_kernel.h>
18#include <linux/seq_file.h>
18 19
19#include <linux/kobject.h> 20#include <linux/kobject.h>
20#include <linux/kobj_map.h> 21#include <linux/kobj_map.h>
@@ -27,8 +28,6 @@
27 28
28static struct kobj_map *cdev_map; 29static struct kobj_map *cdev_map;
29 30
30#define MAX_PROBE_HASH 255 /* random */
31
32static DEFINE_MUTEX(chrdevs_lock); 31static DEFINE_MUTEX(chrdevs_lock);
33 32
34static struct char_device_struct { 33static struct char_device_struct {
@@ -39,93 +38,29 @@ static struct char_device_struct {
39 char name[64]; 38 char name[64];
40 struct file_operations *fops; 39 struct file_operations *fops;
41 struct cdev *cdev; /* will die */ 40 struct cdev *cdev; /* will die */
42} *chrdevs[MAX_PROBE_HASH]; 41} *chrdevs[CHRDEV_MAJOR_HASH_SIZE];
43 42
44/* index in the above */ 43/* index in the above */
45static inline int major_to_index(int major) 44static inline int major_to_index(int major)
46{ 45{
47 return major % MAX_PROBE_HASH; 46 return major % CHRDEV_MAJOR_HASH_SIZE;
48}
49
50struct chrdev_info {
51 int index;
52 struct char_device_struct *cd;
53};
54
55void *get_next_chrdev(void *dev)
56{
57 struct chrdev_info *info;
58
59 if (dev == NULL) {
60 info = kmalloc(sizeof(*info), GFP_KERNEL);
61 if (!info)
62 goto out;
63 info->index=0;
64 info->cd = chrdevs[info->index];
65 if (info->cd)
66 goto out;
67 } else {
68 info = dev;
69 }
70
71 while (info->index < ARRAY_SIZE(chrdevs)) {
72 if (info->cd)
73 info->cd = info->cd->next;
74 if (info->cd)
75 goto out;
76 /*
77 * No devices on this chain, move to the next
78 */
79 info->index++;
80 info->cd = (info->index < ARRAY_SIZE(chrdevs)) ?
81 chrdevs[info->index] : NULL;
82 if (info->cd)
83 goto out;
84 }
85
86out:
87 return info;
88}
89
90void *acquire_chrdev_list(void)
91{
92 mutex_lock(&chrdevs_lock);
93 return get_next_chrdev(NULL);
94}
95
96void release_chrdev_list(void *dev)
97{
98 mutex_unlock(&chrdevs_lock);
99 kfree(dev);
100} 47}
101 48
49#ifdef CONFIG_PROC_FS
102 50
103int count_chrdev_list(void) 51void chrdev_show(struct seq_file *f, off_t offset)
104{ 52{
105 struct char_device_struct *cd; 53 struct char_device_struct *cd;
106 int i, count;
107
108 count = 0;
109 54
110 for (i = 0; i < ARRAY_SIZE(chrdevs) ; i++) { 55 if (offset < CHRDEV_MAJOR_HASH_SIZE) {
111 for (cd = chrdevs[i]; cd; cd = cd->next) 56 mutex_lock(&chrdevs_lock);
112 count++; 57 for (cd = chrdevs[offset]; cd; cd = cd->next)
58 seq_printf(f, "%3d %s\n", cd->major, cd->name);
59 mutex_unlock(&chrdevs_lock);
113 } 60 }
114
115 return count;
116} 61}
117 62
118int get_chrdev_info(void *dev, int *major, char **name) 63#endif /* CONFIG_PROC_FS */
119{
120 struct chrdev_info *info = dev;
121
122 if (info->cd == NULL)
123 return 1;
124
125 *major = info->cd->major;
126 *name = info->cd->name;
127 return 0;
128}
129 64
130/* 65/*
131 * Register a single major with a specified minor range. 66 * Register a single major with a specified minor range.
diff --git a/fs/cifs/CHANGES b/fs/cifs/CHANGES
index cb68efba35db..8a2de038882e 100644
--- a/fs/cifs/CHANGES
+++ b/fs/cifs/CHANGES
@@ -1,3 +1,21 @@
1Version 1.42
2------------
3Fix slow oplock break when mounted to different servers at the same time and
4the tids match and we try to find matching fid on wrong server.
5
6Version 1.41
7------------
8Fix NTLMv2 security (can be enabled in /proc/fs/cifs) so customers can
9configure stronger authentication. Fix sfu symlinks so they can
10be followed (not just recognized). Fix wraparound of bcc on
11read responses when buffer size over 64K and also fix wrap of
12max smb buffer size when CIFSMaxBufSize over 64K. Fix oops in
13cifs_user_read and cifs_readpages (when EAGAIN on send of smb
14on socket is returned over and over). Add POSIX (advisory) byte range
15locking support (requires server with newest CIFS UNIX Extensions
16to the protocol implemented). Slow down negprot slightly in port 139
17RFC1001 case to give session_init time on buggy servers.
18
1Version 1.40 19Version 1.40
2------------ 20------------
3Use fsuid (fsgid) more consistently instead of uid (gid). Improve performance 21Use fsuid (fsgid) more consistently instead of uid (gid). Improve performance
diff --git a/fs/cifs/Makefile b/fs/cifs/Makefile
index 7384947a0f93..58c77254a23b 100644
--- a/fs/cifs/Makefile
+++ b/fs/cifs/Makefile
@@ -3,4 +3,4 @@
3# 3#
4obj-$(CONFIG_CIFS) += cifs.o 4obj-$(CONFIG_CIFS) += cifs.o
5 5
6cifs-objs := cifsfs.o cifssmb.o cifs_debug.o connect.o dir.o file.o inode.o link.o misc.o netmisc.o smbdes.o smbencrypt.o transport.o asn1.o md4.o md5.o cifs_unicode.o nterr.o xattr.o cifsencrypt.o fcntl.o readdir.o ioctl.o 6cifs-objs := cifsfs.o cifssmb.o cifs_debug.o connect.o dir.o file.o inode.o link.o misc.o netmisc.o smbdes.o smbencrypt.o transport.o asn1.o md4.o md5.o cifs_unicode.o nterr.o xattr.o cifsencrypt.o fcntl.o readdir.o ioctl.o ntlmssp.o
diff --git a/fs/cifs/README b/fs/cifs/README
index b0070d1b149d..b2b4d0803761 100644
--- a/fs/cifs/README
+++ b/fs/cifs/README
@@ -422,6 +422,13 @@ A partial list of the supported mount options follows:
422 nomapchars Do not translate any of these seven characters (default). 422 nomapchars Do not translate any of these seven characters (default).
423 nocase Request case insensitive path name matching (case 423 nocase Request case insensitive path name matching (case
424 sensitive is the default if the server suports it). 424 sensitive is the default if the server suports it).
425 posixpaths If CIFS Unix extensions are supported, attempt to
426 negotiate posix path name support which allows certain
427 characters forbidden in typical CIFS filenames, without
428 requiring remapping. (default)
429 noposixpaths If CIFS Unix extensions are supported, do not request
430 posix path name support (this may cause servers to
431 reject creatingfile with certain reserved characters).
425 nobrl Do not send byte range lock requests to the server. 432 nobrl Do not send byte range lock requests to the server.
426 This is necessary for certain applications that break 433 This is necessary for certain applications that break
427 with cifs style mandatory byte range locks (and most 434 with cifs style mandatory byte range locks (and most
diff --git a/fs/cifs/cifsencrypt.c b/fs/cifs/cifsencrypt.c
index a2c24858d40f..e7d63737e651 100644
--- a/fs/cifs/cifsencrypt.c
+++ b/fs/cifs/cifsencrypt.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * fs/cifs/cifsencrypt.c 2 * fs/cifs/cifsencrypt.c
3 * 3 *
4 * Copyright (C) International Business Machines Corp., 2005 4 * Copyright (C) International Business Machines Corp., 2005,2006
5 * Author(s): Steve French (sfrench@us.ibm.com) 5 * Author(s): Steve French (sfrench@us.ibm.com)
6 * 6 *
7 * This library is free software; you can redistribute it and/or modify 7 * This library is free software; you can redistribute it and/or modify
@@ -36,7 +36,8 @@
36extern void mdfour(unsigned char *out, unsigned char *in, int n); 36extern void mdfour(unsigned char *out, unsigned char *in, int n);
37extern void E_md4hash(const unsigned char *passwd, unsigned char *p16); 37extern void E_md4hash(const unsigned char *passwd, unsigned char *p16);
38 38
39static int cifs_calculate_signature(const struct smb_hdr * cifs_pdu, const char * key, char * signature) 39static int cifs_calculate_signature(const struct smb_hdr * cifs_pdu,
40 const char * key, char * signature)
40{ 41{
41 struct MD5Context context; 42 struct MD5Context context;
42 43
@@ -56,9 +57,6 @@ int cifs_sign_smb(struct smb_hdr * cifs_pdu, struct TCP_Server_Info * server,
56 int rc = 0; 57 int rc = 0;
57 char smb_signature[20]; 58 char smb_signature[20];
58 59
59 /* BB remember to initialize sequence number elsewhere and initialize mac_signing key elsewhere BB */
60 /* BB remember to add code to save expected sequence number in midQ entry BB */
61
62 if((cifs_pdu == NULL) || (server == NULL)) 60 if((cifs_pdu == NULL) || (server == NULL))
63 return -EINVAL; 61 return -EINVAL;
64 62
@@ -85,20 +83,33 @@ int cifs_sign_smb(struct smb_hdr * cifs_pdu, struct TCP_Server_Info * server,
85static int cifs_calc_signature2(const struct kvec * iov, int n_vec, 83static int cifs_calc_signature2(const struct kvec * iov, int n_vec,
86 const char * key, char * signature) 84 const char * key, char * signature)
87{ 85{
88 struct MD5Context context; 86 struct MD5Context context;
89 87 int i;
90 if((iov == NULL) || (signature == NULL))
91 return -EINVAL;
92 88
93 MD5Init(&context); 89 if((iov == NULL) || (signature == NULL))
94 MD5Update(&context,key,CIFS_SESSION_KEY_SIZE+16); 90 return -EINVAL;
95 91
96/* MD5Update(&context,cifs_pdu->Protocol,cifs_pdu->smb_buf_length); */ /* BB FIXME BB */ 92 MD5Init(&context);
93 MD5Update(&context,key,CIFS_SESSION_KEY_SIZE+16);
94 for(i=0;i<n_vec;i++) {
95 if(iov[i].iov_base == NULL) {
96 cERROR(1,("null iovec entry"));
97 return -EIO;
98 } else if(iov[i].iov_len == 0)
99 break; /* bail out if we are sent nothing to sign */
100 /* The first entry includes a length field (which does not get
101 signed that occupies the first 4 bytes before the header */
102 if(i==0) {
103 if (iov[0].iov_len <= 8 ) /* cmd field at offset 9 */
104 break; /* nothing to sign or corrupt header */
105 MD5Update(&context,iov[0].iov_base+4, iov[0].iov_len-4);
106 } else
107 MD5Update(&context,iov[i].iov_base, iov[i].iov_len);
108 }
97 109
98 MD5Final(signature,&context); 110 MD5Final(signature,&context);
99 111
100 return -EOPNOTSUPP; 112 return 0;
101/* return 0; */
102} 113}
103 114
104 115
@@ -259,4 +270,5 @@ void CalcNTLMv2_response(const struct cifsSesInfo * ses,char * v2_session_respon
259/* hmac_md5_update(v2_session_response+16)client thing,8,&context); */ /* BB fix */ 270/* hmac_md5_update(v2_session_response+16)client thing,8,&context); */ /* BB fix */
260 271
261 hmac_md5_final(v2_session_response,&context); 272 hmac_md5_final(v2_session_response,&context);
273 cifs_dump_mem("v2_sess_rsp: ", v2_session_response, 32); /* BB removeme BB */
262} 274}
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
index 4bbc544857bc..d4b713e5affb 100644
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -93,13 +93,10 @@ cifs_read_super(struct super_block *sb, void *data,
93 int rc = 0; 93 int rc = 0;
94 94
95 sb->s_flags |= MS_NODIRATIME; /* and probably even noatime */ 95 sb->s_flags |= MS_NODIRATIME; /* and probably even noatime */
96 sb->s_fs_info = kmalloc(sizeof(struct cifs_sb_info),GFP_KERNEL); 96 sb->s_fs_info = kzalloc(sizeof(struct cifs_sb_info),GFP_KERNEL);
97 cifs_sb = CIFS_SB(sb); 97 cifs_sb = CIFS_SB(sb);
98 if(cifs_sb == NULL) 98 if(cifs_sb == NULL)
99 return -ENOMEM; 99 return -ENOMEM;
100 else
101 memset(cifs_sb,0,sizeof(struct cifs_sb_info));
102
103 100
104 rc = cifs_mount(sb, cifs_sb, data, devname); 101 rc = cifs_mount(sb, cifs_sb, data, devname);
105 102
diff --git a/fs/cifs/cifsfs.h b/fs/cifs/cifsfs.h
index 74f405ae4da3..4e829dc672a6 100644
--- a/fs/cifs/cifsfs.h
+++ b/fs/cifs/cifsfs.h
@@ -99,5 +99,5 @@ extern ssize_t cifs_getxattr(struct dentry *, const char *, void *, size_t);
99extern ssize_t cifs_listxattr(struct dentry *, char *, size_t); 99extern ssize_t cifs_listxattr(struct dentry *, char *, size_t);
100extern int cifs_ioctl (struct inode * inode, struct file * filep, 100extern int cifs_ioctl (struct inode * inode, struct file * filep,
101 unsigned int command, unsigned long arg); 101 unsigned int command, unsigned long arg);
102#define CIFS_VERSION "1.40" 102#define CIFS_VERSION "1.42"
103#endif /* _CIFSFS_H */ 103#endif /* _CIFSFS_H */
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
index 7bed27601ce5..006eb33bff5f 100644
--- a/fs/cifs/cifsglob.h
+++ b/fs/cifs/cifsglob.h
@@ -1,7 +1,7 @@
1/* 1/*
2 * fs/cifs/cifsglob.h 2 * fs/cifs/cifsglob.h
3 * 3 *
4 * Copyright (C) International Business Machines Corp., 2002,2005 4 * Copyright (C) International Business Machines Corp., 2002,2006
5 * Author(s): Steve French (sfrench@us.ibm.com) 5 * Author(s): Steve French (sfrench@us.ibm.com)
6 * 6 *
7 * This library is free software; you can redistribute it and/or modify 7 * This library is free software; you can redistribute it and/or modify
@@ -430,6 +430,15 @@ struct dir_notify_req {
430#define CIFS_LARGE_BUFFER 2 430#define CIFS_LARGE_BUFFER 2
431#define CIFS_IOVEC 4 /* array of response buffers */ 431#define CIFS_IOVEC 4 /* array of response buffers */
432 432
433/* Type of session setup needed */
434#define CIFS_PLAINTEXT 0
435#define CIFS_LANMAN 1
436#define CIFS_NTLM 2
437#define CIFS_NTLMSSP_NEG 3
438#define CIFS_NTLMSSP_AUTH 4
439#define CIFS_SPNEGO_INIT 5
440#define CIFS_SPNEGO_TARG 6
441
433/* 442/*
434 ***************************************************************** 443 *****************************************************************
435 * All constants go here 444 * All constants go here
diff --git a/fs/cifs/cifspdu.h b/fs/cifs/cifspdu.h
index cc2471094ca5..b2233ac05bd2 100644
--- a/fs/cifs/cifspdu.h
+++ b/fs/cifs/cifspdu.h
@@ -859,7 +859,10 @@ typedef struct smb_com_lock_req {
859 LOCKING_ANDX_RANGE Locks[1]; 859 LOCKING_ANDX_RANGE Locks[1];
860} __attribute__((packed)) LOCK_REQ; 860} __attribute__((packed)) LOCK_REQ;
861 861
862 862/* lock type */
863#define CIFS_RDLCK 0
864#define CIFS_WRLCK 1
865#define CIFS_UNLCK 2
863typedef struct cifs_posix_lock { 866typedef struct cifs_posix_lock {
864 __le16 lock_type; /* 0 = Read, 1 = Write, 2 = Unlock */ 867 __le16 lock_type; /* 0 = Read, 1 = Write, 2 = Unlock */
865 __le16 lock_flags; /* 1 = Wait (only valid for setlock) */ 868 __le16 lock_flags; /* 1 = Wait (only valid for setlock) */
@@ -1786,7 +1789,13 @@ typedef struct {
1786#define CIFS_UNIX_POSIX_ACL_CAP 0x00000002 /* support getfacl/setfacl */ 1789#define CIFS_UNIX_POSIX_ACL_CAP 0x00000002 /* support getfacl/setfacl */
1787#define CIFS_UNIX_XATTR_CAP 0x00000004 /* support new namespace */ 1790#define CIFS_UNIX_XATTR_CAP 0x00000004 /* support new namespace */
1788#define CIFS_UNIX_EXTATTR_CAP 0x00000008 /* support chattr/chflag */ 1791#define CIFS_UNIX_EXTATTR_CAP 0x00000008 /* support chattr/chflag */
1789#define CIFS_UNIX_POSIX_PATHNAMES_CAP 0x00000010 /* Use POSIX pathnames on the wire. */ 1792#define CIFS_UNIX_POSIX_PATHNAMES_CAP 0x00000010 /* Allow POSIX path chars */
1793#ifdef CONFIG_CIFS_POSIX
1794#define CIFS_UNIX_CAP_MASK 0x0000001b
1795#else
1796#define CIFS_UNIX_CAP_MASK 0x00000013
1797#endif /* CONFIG_CIFS_POSIX */
1798
1790 1799
1791#define CIFS_POSIX_EXTENSIONS 0x00000010 /* support for new QFSInfo */ 1800#define CIFS_POSIX_EXTENSIONS 0x00000010 /* support for new QFSInfo */
1792 1801
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h
index 7b25463d3c14..2879ba343ca7 100644
--- a/fs/cifs/cifsproto.h
+++ b/fs/cifs/cifsproto.h
@@ -1,7 +1,7 @@
1/* 1/*
2 * fs/cifs/cifsproto.h 2 * fs/cifs/cifsproto.h
3 * 3 *
4 * Copyright (c) International Business Machines Corp., 2002,2005 4 * Copyright (c) International Business Machines Corp., 2002,2006
5 * Author(s): Steve French (sfrench@us.ibm.com) 5 * Author(s): Steve French (sfrench@us.ibm.com)
6 * 6 *
7 * This library is free software; you can redistribute it and/or modify 7 * This library is free software; you can redistribute it and/or modify
@@ -64,6 +64,14 @@ extern int map_smb_to_linux_error(struct smb_hdr *smb);
64extern void header_assemble(struct smb_hdr *, char /* command */ , 64extern void header_assemble(struct smb_hdr *, char /* command */ ,
65 const struct cifsTconInfo *, int /* length of 65 const struct cifsTconInfo *, int /* length of
66 fixed section (word count) in two byte units */); 66 fixed section (word count) in two byte units */);
67#ifdef CONFIG_CIFS_EXPERIMENTAL
68extern int small_smb_init_no_tc(const int smb_cmd, const int wct,
69 struct cifsSesInfo *ses,
70 void ** request_buf);
71extern int CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses,
72 const int stage, int * pNTLMv2_flg,
73 const struct nls_table *nls_cp);
74#endif
67extern __u16 GetNextMid(struct TCP_Server_Info *server); 75extern __u16 GetNextMid(struct TCP_Server_Info *server);
68extern struct oplock_q_entry * AllocOplockQEntry(struct inode *, u16, 76extern struct oplock_q_entry * AllocOplockQEntry(struct inode *, u16,
69 struct cifsTconInfo *); 77 struct cifsTconInfo *);
@@ -257,7 +265,10 @@ extern int CIFSSMBLock(const int xid, struct cifsTconInfo *tcon,
257 const __u64 offset, const __u32 numUnlock, 265 const __u64 offset, const __u32 numUnlock,
258 const __u32 numLock, const __u8 lockType, 266 const __u32 numLock, const __u8 lockType,
259 const int waitFlag); 267 const int waitFlag);
260 268extern int CIFSSMBPosixLock(const int xid, struct cifsTconInfo *tcon,
269 const __u16 smb_file_id, const int get_flag,
270 const __u64 len, const __u64 offset,
271 const __u16 lock_type, const int waitFlag);
261extern int CIFSSMBTDis(const int xid, struct cifsTconInfo *tcon); 272extern int CIFSSMBTDis(const int xid, struct cifsTconInfo *tcon);
262extern int CIFSSMBLogoff(const int xid, struct cifsSesInfo *ses); 273extern int CIFSSMBLogoff(const int xid, struct cifsSesInfo *ses);
263 274
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c
index a243fe2792d5..d705500aa283 100644
--- a/fs/cifs/cifssmb.c
+++ b/fs/cifs/cifssmb.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * fs/cifs/cifssmb.c 2 * fs/cifs/cifssmb.c
3 * 3 *
4 * Copyright (C) International Business Machines Corp., 2002,2005 4 * Copyright (C) International Business Machines Corp., 2002,2006
5 * Author(s): Steve French (sfrench@us.ibm.com) 5 * Author(s): Steve French (sfrench@us.ibm.com)
6 * 6 *
7 * Contains the routines for constructing the SMB PDUs themselves 7 * Contains the routines for constructing the SMB PDUs themselves
@@ -186,7 +186,35 @@ small_smb_init(int smb_command, int wct, struct cifsTconInfo *tcon,
186 cifs_stats_inc(&tcon->num_smbs_sent); 186 cifs_stats_inc(&tcon->num_smbs_sent);
187 187
188 return rc; 188 return rc;
189} 189}
190
191#ifdef CONFIG_CIFS_EXPERIMENTAL
192int
193small_smb_init_no_tc(const int smb_command, const int wct,
194 struct cifsSesInfo *ses, void **request_buf)
195{
196 int rc;
197 struct smb_hdr * buffer;
198
199 rc = small_smb_init(smb_command, wct, NULL, request_buf);
200 if(rc)
201 return rc;
202
203 buffer = (struct smb_hdr *)*request_buf;
204 buffer->Mid = GetNextMid(ses->server);
205 if (ses->capabilities & CAP_UNICODE)
206 buffer->Flags2 |= SMBFLG2_UNICODE;
207 if (ses->capabilities & CAP_STATUS32)
208 buffer->Flags2 |= SMBFLG2_ERR_STATUS;
209
210 /* uid, tid can stay at zero as set in header assemble */
211
212 /* BB add support for turning on the signing when
213 this function is used after 1st of session setup requests */
214
215 return rc;
216}
217#endif /* CONFIG_CIFS_EXPERIMENTAL */
190 218
191/* If the return code is zero, this function must fill in request_buf pointer */ 219/* If the return code is zero, this function must fill in request_buf pointer */
192static int 220static int
@@ -1042,7 +1070,7 @@ CIFSSMBRead(const int xid, struct cifsTconInfo *tcon,
1042 } 1070 }
1043 } 1071 }
1044 1072
1045 cifs_small_buf_release(pSMB); 1073/* cifs_small_buf_release(pSMB); */ /* Freed earlier now in SendReceive2 */
1046 if(*buf) { 1074 if(*buf) {
1047 if(resp_buf_type == CIFS_SMALL_BUFFER) 1075 if(resp_buf_type == CIFS_SMALL_BUFFER)
1048 cifs_small_buf_release(iov[0].iov_base); 1076 cifs_small_buf_release(iov[0].iov_base);
@@ -1246,7 +1274,7 @@ CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon,
1246 *nbytes += le16_to_cpu(pSMBr->Count); 1274 *nbytes += le16_to_cpu(pSMBr->Count);
1247 } 1275 }
1248 1276
1249 cifs_small_buf_release(pSMB); 1277/* cifs_small_buf_release(pSMB); */ /* Freed earlier now in SendReceive2 */
1250 if(resp_buf_type == CIFS_SMALL_BUFFER) 1278 if(resp_buf_type == CIFS_SMALL_BUFFER)
1251 cifs_small_buf_release(iov[0].iov_base); 1279 cifs_small_buf_release(iov[0].iov_base);
1252 else if(resp_buf_type == CIFS_LARGE_BUFFER) 1280 else if(resp_buf_type == CIFS_LARGE_BUFFER)
@@ -1325,6 +1353,85 @@ CIFSSMBLock(const int xid, struct cifsTconInfo *tcon,
1325} 1353}
1326 1354
1327int 1355int
1356CIFSSMBPosixLock(const int xid, struct cifsTconInfo *tcon,
1357 const __u16 smb_file_id, const int get_flag, const __u64 len,
1358 const __u64 lkoffset, const __u16 lock_type, const int waitFlag)
1359{
1360 struct smb_com_transaction2_sfi_req *pSMB = NULL;
1361 struct smb_com_transaction2_sfi_rsp *pSMBr = NULL;
1362 char *data_offset;
1363 struct cifs_posix_lock *parm_data;
1364 int rc = 0;
1365 int bytes_returned = 0;
1366 __u16 params, param_offset, offset, byte_count, count;
1367
1368 cFYI(1, ("Posix Lock"));
1369 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
1370
1371 if (rc)
1372 return rc;
1373
1374 pSMBr = (struct smb_com_transaction2_sfi_rsp *)pSMB;
1375
1376 params = 6;
1377 pSMB->MaxSetupCount = 0;
1378 pSMB->Reserved = 0;
1379 pSMB->Flags = 0;
1380 pSMB->Timeout = 0;
1381 pSMB->Reserved2 = 0;
1382 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
1383 offset = param_offset + params;
1384
1385 data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
1386
1387 count = sizeof(struct cifs_posix_lock);
1388 pSMB->MaxParameterCount = cpu_to_le16(2);
1389 pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find max SMB PDU from sess */
1390 pSMB->SetupCount = 1;
1391 pSMB->Reserved3 = 0;
1392 if(get_flag)
1393 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
1394 else
1395 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
1396 byte_count = 3 /* pad */ + params + count;
1397 pSMB->DataCount = cpu_to_le16(count);
1398 pSMB->ParameterCount = cpu_to_le16(params);
1399 pSMB->TotalDataCount = pSMB->DataCount;
1400 pSMB->TotalParameterCount = pSMB->ParameterCount;
1401 pSMB->ParameterOffset = cpu_to_le16(param_offset);
1402 parm_data = (struct cifs_posix_lock *)
1403 (((char *) &pSMB->hdr.Protocol) + offset);
1404
1405 parm_data->lock_type = cpu_to_le16(lock_type);
1406 if(waitFlag)
1407 parm_data->lock_flags = 1;
1408 parm_data->pid = cpu_to_le32(current->tgid);
1409 parm_data->start = lkoffset;
1410 parm_data->length = len; /* normalize negative numbers */
1411
1412 pSMB->DataOffset = cpu_to_le16(offset);
1413 pSMB->Fid = smb_file_id;
1414 pSMB->InformationLevel = cpu_to_le16(SMB_SET_POSIX_LOCK);
1415 pSMB->Reserved4 = 0;
1416 pSMB->hdr.smb_buf_length += byte_count;
1417 pSMB->ByteCount = cpu_to_le16(byte_count);
1418 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1419 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
1420 if (rc) {
1421 cFYI(1, ("Send error in Posix Lock = %d", rc));
1422 }
1423
1424 if (pSMB)
1425 cifs_small_buf_release(pSMB);
1426
1427 /* Note: On -EAGAIN error only caller can retry on handle based calls
1428 since file handle passed in no longer valid */
1429
1430 return rc;
1431}
1432
1433
1434int
1328CIFSSMBClose(const int xid, struct cifsTconInfo *tcon, int smb_file_id) 1435CIFSSMBClose(const int xid, struct cifsTconInfo *tcon, int smb_file_id)
1329{ 1436{
1330 int rc = 0; 1437 int rc = 0;
@@ -2578,7 +2685,7 @@ qsec_out:
2578 cifs_small_buf_release(iov[0].iov_base); 2685 cifs_small_buf_release(iov[0].iov_base);
2579 else if(buf_type == CIFS_LARGE_BUFFER) 2686 else if(buf_type == CIFS_LARGE_BUFFER)
2580 cifs_buf_release(iov[0].iov_base); 2687 cifs_buf_release(iov[0].iov_base);
2581 cifs_small_buf_release(pSMB); 2688/* cifs_small_buf_release(pSMB); */ /* Freed earlier now in SendReceive2 */
2582 return rc; 2689 return rc;
2583} 2690}
2584 2691
@@ -2954,7 +3061,8 @@ findFirstRetry:
2954 pSMB->TotalParameterCount = cpu_to_le16(params); 3061 pSMB->TotalParameterCount = cpu_to_le16(params);
2955 pSMB->ParameterCount = pSMB->TotalParameterCount; 3062 pSMB->ParameterCount = pSMB->TotalParameterCount;
2956 pSMB->ParameterOffset = cpu_to_le16( 3063 pSMB->ParameterOffset = cpu_to_le16(
2957 offsetof(struct smb_com_transaction2_ffirst_req, SearchAttributes) - 4); 3064 offsetof(struct smb_com_transaction2_ffirst_req, SearchAttributes)
3065 - 4);
2958 pSMB->DataCount = 0; 3066 pSMB->DataCount = 0;
2959 pSMB->DataOffset = 0; 3067 pSMB->DataOffset = 0;
2960 pSMB->SetupCount = 1; /* one byte, no need to make endian neutral */ 3068 pSMB->SetupCount = 1; /* one byte, no need to make endian neutral */
@@ -2977,12 +3085,12 @@ findFirstRetry:
2977 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 3085 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2978 cifs_stats_inc(&tcon->num_ffirst); 3086 cifs_stats_inc(&tcon->num_ffirst);
2979 3087
2980 if (rc) {/* BB add logic to retry regular search if Unix search rejected unexpectedly by server */ 3088 if (rc) {/* BB add logic to retry regular search if Unix search
3089 rejected unexpectedly by server */
2981 /* BB Add code to handle unsupported level rc */ 3090 /* BB Add code to handle unsupported level rc */
2982 cFYI(1, ("Error in FindFirst = %d", rc)); 3091 cFYI(1, ("Error in FindFirst = %d", rc));
2983 3092
2984 if (pSMB) 3093 cifs_buf_release(pSMB);
2985 cifs_buf_release(pSMB);
2986 3094
2987 /* BB eventually could optimize out free and realloc of buf */ 3095 /* BB eventually could optimize out free and realloc of buf */
2988 /* for this case */ 3096 /* for this case */
@@ -2998,6 +3106,7 @@ findFirstRetry:
2998 psrch_inf->unicode = FALSE; 3106 psrch_inf->unicode = FALSE;
2999 3107
3000 psrch_inf->ntwrk_buf_start = (char *)pSMBr; 3108 psrch_inf->ntwrk_buf_start = (char *)pSMBr;
3109 psrch_inf->smallBuf = 0;
3001 psrch_inf->srch_entries_start = 3110 psrch_inf->srch_entries_start =
3002 (char *) &pSMBr->hdr.Protocol + 3111 (char *) &pSMBr->hdr.Protocol +
3003 le16_to_cpu(pSMBr->t2.DataOffset); 3112 le16_to_cpu(pSMBr->t2.DataOffset);
@@ -3118,9 +3227,14 @@ int CIFSFindNext(const int xid, struct cifsTconInfo *tcon,
3118 parms = (T2_FNEXT_RSP_PARMS *)response_data; 3227 parms = (T2_FNEXT_RSP_PARMS *)response_data;
3119 response_data = (char *)&pSMBr->hdr.Protocol + 3228 response_data = (char *)&pSMBr->hdr.Protocol +
3120 le16_to_cpu(pSMBr->t2.DataOffset); 3229 le16_to_cpu(pSMBr->t2.DataOffset);
3121 cifs_buf_release(psrch_inf->ntwrk_buf_start); 3230 if(psrch_inf->smallBuf)
3231 cifs_small_buf_release(
3232 psrch_inf->ntwrk_buf_start);
3233 else
3234 cifs_buf_release(psrch_inf->ntwrk_buf_start);
3122 psrch_inf->srch_entries_start = response_data; 3235 psrch_inf->srch_entries_start = response_data;
3123 psrch_inf->ntwrk_buf_start = (char *)pSMB; 3236 psrch_inf->ntwrk_buf_start = (char *)pSMB;
3237 psrch_inf->smallBuf = 0;
3124 if(parms->EndofSearch) 3238 if(parms->EndofSearch)
3125 psrch_inf->endOfSearch = TRUE; 3239 psrch_inf->endOfSearch = TRUE;
3126 else 3240 else
@@ -3834,6 +3948,7 @@ CIFSSMBSetFSUnixInfo(const int xid, struct cifsTconInfo *tcon, __u64 cap)
3834 3948
3835 cFYI(1, ("In SETFSUnixInfo")); 3949 cFYI(1, ("In SETFSUnixInfo"));
3836SETFSUnixRetry: 3950SETFSUnixRetry:
3951 /* BB switch to small buf init to save memory */
3837 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, 3952 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3838 (void **) &pSMBr); 3953 (void **) &pSMBr);
3839 if (rc) 3954 if (rc)
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index 2a0c1f4ca0ae..0b86d5ca9014 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * fs/cifs/connect.c 2 * fs/cifs/connect.c
3 * 3 *
4 * Copyright (C) International Business Machines Corp., 2002,2005 4 * Copyright (C) International Business Machines Corp., 2002,2006
5 * Author(s): Steve French (sfrench@us.ibm.com) 5 * Author(s): Steve French (sfrench@us.ibm.com)
6 * 6 *
7 * This library is free software; you can redistribute it and/or modify 7 * This library is free software; you can redistribute it and/or modify
@@ -564,7 +564,7 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
564 564
565 565
566 dump_smb(smb_buffer, length); 566 dump_smb(smb_buffer, length);
567 if (checkSMB (smb_buffer, smb_buffer->Mid, total_read+4)) { 567 if (checkSMB(smb_buffer, smb_buffer->Mid, total_read+4)) {
568 cifs_dump_mem("Bad SMB: ", smb_buffer, 48); 568 cifs_dump_mem("Bad SMB: ", smb_buffer, 48);
569 continue; 569 continue;
570 } 570 }
@@ -1476,6 +1476,14 @@ ipv4_connect(struct sockaddr_in *psin_server, struct socket **csocket,
1476 rc = smb_send(*csocket, smb_buf, 0x44, 1476 rc = smb_send(*csocket, smb_buf, 0x44,
1477 (struct sockaddr *)psin_server); 1477 (struct sockaddr *)psin_server);
1478 kfree(ses_init_buf); 1478 kfree(ses_init_buf);
1479 msleep(1); /* RFC1001 layer in at least one server
1480 requires very short break before negprot
1481 presumably because not expecting negprot
1482 to follow so fast. This is a simple
1483 solution that works without
1484 complicating the code and causes no
1485 significant slowing down on mount
1486 for everyone else */
1479 } 1487 }
1480 /* else the negprot may still work without this 1488 /* else the negprot may still work without this
1481 even though malloc failed */ 1489 even though malloc failed */
@@ -1920,27 +1928,34 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
1920 cifs_sb->tcon = tcon; 1928 cifs_sb->tcon = tcon;
1921 tcon->ses = pSesInfo; 1929 tcon->ses = pSesInfo;
1922 1930
1923 /* do not care if following two calls succeed - informational only */ 1931 /* do not care if following two calls succeed - informational */
1924 CIFSSMBQFSDeviceInfo(xid, tcon); 1932 CIFSSMBQFSDeviceInfo(xid, tcon);
1925 CIFSSMBQFSAttributeInfo(xid, tcon); 1933 CIFSSMBQFSAttributeInfo(xid, tcon);
1934
1926 if (tcon->ses->capabilities & CAP_UNIX) { 1935 if (tcon->ses->capabilities & CAP_UNIX) {
1927 if(!CIFSSMBQFSUnixInfo(xid, tcon)) { 1936 if(!CIFSSMBQFSUnixInfo(xid, tcon)) {
1928 if(!volume_info.no_psx_acl) { 1937 __u64 cap =
1929 if(CIFS_UNIX_POSIX_ACL_CAP & 1938 le64_to_cpu(tcon->fsUnixInfo.Capability);
1930 le64_to_cpu(tcon->fsUnixInfo.Capability)) 1939 cap &= CIFS_UNIX_CAP_MASK;
1931 cFYI(1,("server negotiated posix acl support")); 1940 if(volume_info.no_psx_acl)
1932 sb->s_flags |= MS_POSIXACL; 1941 cap &= ~CIFS_UNIX_POSIX_ACL_CAP;
1942 else if(CIFS_UNIX_POSIX_ACL_CAP & cap) {
1943 cFYI(1,("negotiated posix acl support"));
1944 sb->s_flags |= MS_POSIXACL;
1933 } 1945 }
1934 1946
1935 /* Try and negotiate POSIX pathnames if we can. */ 1947 if(volume_info.posix_paths == 0)
1936 if (volume_info.posix_paths && (CIFS_UNIX_POSIX_PATHNAMES_CAP & 1948 cap &= ~CIFS_UNIX_POSIX_PATHNAMES_CAP;
1937 le64_to_cpu(tcon->fsUnixInfo.Capability))) { 1949 else if(cap & CIFS_UNIX_POSIX_PATHNAMES_CAP) {
1938 if (!CIFSSMBSetFSUnixInfo(xid, tcon, CIFS_UNIX_POSIX_PATHNAMES_CAP)) { 1950 cFYI(1,("negotiate posix pathnames"));
1939 cFYI(1,("negotiated posix pathnames support")); 1951 cifs_sb->mnt_cifs_flags |=
1940 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_POSIX_PATHS; 1952 CIFS_MOUNT_POSIX_PATHS;
1941 } else { 1953 }
1942 cFYI(1,("posix pathnames support requested but not supported")); 1954
1943 } 1955 cFYI(1,("Negotiate caps 0x%x",(int)cap));
1956
1957 if (CIFSSMBSetFSUnixInfo(xid, tcon, cap)) {
1958 cFYI(1,("setting capabilities failed"));
1944 } 1959 }
1945 } 1960 }
1946 } 1961 }
@@ -2278,6 +2293,8 @@ CIFSSpnegoSessSetup(unsigned int xid, struct cifsSesInfo *ses,
2278 smb_buffer->Mid = GetNextMid(ses->server); 2293 smb_buffer->Mid = GetNextMid(ses->server);
2279 pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC; 2294 pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC;
2280 pSMB->req.AndXCommand = 0xFF; 2295 pSMB->req.AndXCommand = 0xFF;
2296 if(ses->server->maxBuf > 64*1024)
2297 ses->server->maxBuf = (64*1023);
2281 pSMB->req.MaxBufferSize = cpu_to_le16(ses->server->maxBuf); 2298 pSMB->req.MaxBufferSize = cpu_to_le16(ses->server->maxBuf);
2282 pSMB->req.MaxMpxCount = cpu_to_le16(ses->server->maxReq); 2299 pSMB->req.MaxMpxCount = cpu_to_le16(ses->server->maxReq);
2283 2300
@@ -2525,7 +2542,7 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid,
2525 __u32 negotiate_flags, capabilities; 2542 __u32 negotiate_flags, capabilities;
2526 __u16 count; 2543 __u16 count;
2527 2544
2528 cFYI(1, ("In NTLMSSP sesssetup (negotiate) ")); 2545 cFYI(1, ("In NTLMSSP sesssetup (negotiate)"));
2529 if(ses == NULL) 2546 if(ses == NULL)
2530 return -EINVAL; 2547 return -EINVAL;
2531 domain = ses->domainName; 2548 domain = ses->domainName;
@@ -2575,7 +2592,8 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid,
2575 SecurityBlob->MessageType = NtLmNegotiate; 2592 SecurityBlob->MessageType = NtLmNegotiate;
2576 negotiate_flags = 2593 negotiate_flags =
2577 NTLMSSP_NEGOTIATE_UNICODE | NTLMSSP_NEGOTIATE_OEM | 2594 NTLMSSP_NEGOTIATE_UNICODE | NTLMSSP_NEGOTIATE_OEM |
2578 NTLMSSP_REQUEST_TARGET | NTLMSSP_NEGOTIATE_NTLM | 0x80000000 | 2595 NTLMSSP_REQUEST_TARGET | NTLMSSP_NEGOTIATE_NTLM |
2596 NTLMSSP_NEGOTIATE_56 |
2579 /* NTLMSSP_NEGOTIATE_ALWAYS_SIGN | */ NTLMSSP_NEGOTIATE_128; 2597 /* NTLMSSP_NEGOTIATE_ALWAYS_SIGN | */ NTLMSSP_NEGOTIATE_128;
2580 if(sign_CIFS_PDUs) 2598 if(sign_CIFS_PDUs)
2581 negotiate_flags |= NTLMSSP_NEGOTIATE_SIGN; 2599 negotiate_flags |= NTLMSSP_NEGOTIATE_SIGN;
@@ -2588,26 +2606,11 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid,
2588 SecurityBlob->WorkstationName.Length = 0; 2606 SecurityBlob->WorkstationName.Length = 0;
2589 SecurityBlob->WorkstationName.MaximumLength = 0; 2607 SecurityBlob->WorkstationName.MaximumLength = 0;
2590 2608
2591 if (domain == NULL) { 2609 /* Domain not sent on first Sesssetup in NTLMSSP, instead it is sent
2592 SecurityBlob->DomainName.Buffer = 0; 2610 along with username on auth request (ie the response to challenge) */
2593 SecurityBlob->DomainName.Length = 0; 2611 SecurityBlob->DomainName.Buffer = 0;
2594 SecurityBlob->DomainName.MaximumLength = 0; 2612 SecurityBlob->DomainName.Length = 0;
2595 } else { 2613 SecurityBlob->DomainName.MaximumLength = 0;
2596 __u16 len;
2597 negotiate_flags |= NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED;
2598 strncpy(bcc_ptr, domain, 63);
2599 len = strnlen(domain, 64);
2600 SecurityBlob->DomainName.MaximumLength =
2601 cpu_to_le16(len);
2602 SecurityBlob->DomainName.Buffer =
2603 cpu_to_le32((long) &SecurityBlob->
2604 DomainString -
2605 (long) &SecurityBlob->Signature);
2606 bcc_ptr += len;
2607 SecurityBlobLength += len;
2608 SecurityBlob->DomainName.Length =
2609 cpu_to_le16(len);
2610 }
2611 if (ses->capabilities & CAP_UNICODE) { 2614 if (ses->capabilities & CAP_UNICODE) {
2612 if ((long) bcc_ptr % 2) { 2615 if ((long) bcc_ptr % 2) {
2613 *bcc_ptr = 0; 2616 *bcc_ptr = 0;
@@ -2677,7 +2680,7 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid,
2677 SecurityBlob2->MessageType)); 2680 SecurityBlob2->MessageType));
2678 } else if (ses) { 2681 } else if (ses) {
2679 ses->Suid = smb_buffer_response->Uid; /* UID left in le format */ 2682 ses->Suid = smb_buffer_response->Uid; /* UID left in le format */
2680 cFYI(1, ("UID = %d ", ses->Suid)); 2683 cFYI(1, ("UID = %d", ses->Suid));
2681 if ((pSMBr->resp.hdr.WordCount == 3) 2684 if ((pSMBr->resp.hdr.WordCount == 3)
2682 || ((pSMBr->resp.hdr.WordCount == 4) 2685 || ((pSMBr->resp.hdr.WordCount == 4)
2683 && (blob_len < 2686 && (blob_len <
@@ -2685,17 +2688,17 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid,
2685 2688
2686 if (pSMBr->resp.hdr.WordCount == 4) { 2689 if (pSMBr->resp.hdr.WordCount == 4) {
2687 bcc_ptr += blob_len; 2690 bcc_ptr += blob_len;
2688 cFYI(1, 2691 cFYI(1, ("Security Blob Length %d",
2689 ("Security Blob Length %d ",
2690 blob_len)); 2692 blob_len));
2691 } 2693 }
2692 2694
2693 cFYI(1, ("NTLMSSP Challenge rcvd ")); 2695 cFYI(1, ("NTLMSSP Challenge rcvd"));
2694 2696
2695 memcpy(ses->server->cryptKey, 2697 memcpy(ses->server->cryptKey,
2696 SecurityBlob2->Challenge, 2698 SecurityBlob2->Challenge,
2697 CIFS_CRYPTO_KEY_SIZE); 2699 CIFS_CRYPTO_KEY_SIZE);
2698 if(SecurityBlob2->NegotiateFlags & cpu_to_le32(NTLMSSP_NEGOTIATE_NTLMV2)) 2700 if(SecurityBlob2->NegotiateFlags &
2701 cpu_to_le32(NTLMSSP_NEGOTIATE_NTLMV2))
2699 *pNTLMv2_flag = TRUE; 2702 *pNTLMv2_flag = TRUE;
2700 2703
2701 if((SecurityBlob2->NegotiateFlags & 2704 if((SecurityBlob2->NegotiateFlags &
@@ -2818,7 +2821,7 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid,
2818 bcc_ptr++; 2821 bcc_ptr++;
2819 } else 2822 } else
2820 cFYI(1, 2823 cFYI(1,
2821 ("Variable field of length %d extends beyond end of smb ", 2824 ("Variable field of length %d extends beyond end of smb",
2822 len)); 2825 len));
2823 } 2826 }
2824 } else { 2827 } else {
@@ -2830,7 +2833,7 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid,
2830 } 2833 }
2831 } else { 2834 } else {
2832 cERROR(1, 2835 cERROR(1,
2833 (" Invalid Word count %d: ", 2836 (" Invalid Word count %d:",
2834 smb_buffer_response->WordCount)); 2837 smb_buffer_response->WordCount));
2835 rc = -EIO; 2838 rc = -EIO;
2836 } 2839 }
@@ -3447,7 +3450,7 @@ int cifs_setup_session(unsigned int xid, struct cifsSesInfo *pSesInfo,
3447 if (extended_security 3450 if (extended_security
3448 && (pSesInfo->capabilities & CAP_EXTENDED_SECURITY) 3451 && (pSesInfo->capabilities & CAP_EXTENDED_SECURITY)
3449 && (pSesInfo->server->secType == NTLMSSP)) { 3452 && (pSesInfo->server->secType == NTLMSSP)) {
3450 cFYI(1, ("New style sesssetup ")); 3453 cFYI(1, ("New style sesssetup"));
3451 rc = CIFSSpnegoSessSetup(xid, pSesInfo, 3454 rc = CIFSSpnegoSessSetup(xid, pSesInfo,
3452 NULL /* security blob */, 3455 NULL /* security blob */,
3453 0 /* blob length */, 3456 0 /* blob length */,
@@ -3455,7 +3458,7 @@ int cifs_setup_session(unsigned int xid, struct cifsSesInfo *pSesInfo,
3455 } else if (extended_security 3458 } else if (extended_security
3456 && (pSesInfo->capabilities & CAP_EXTENDED_SECURITY) 3459 && (pSesInfo->capabilities & CAP_EXTENDED_SECURITY)
3457 && (pSesInfo->server->secType == RawNTLMSSP)) { 3460 && (pSesInfo->server->secType == RawNTLMSSP)) {
3458 cFYI(1, ("NTLMSSP sesssetup ")); 3461 cFYI(1, ("NTLMSSP sesssetup"));
3459 rc = CIFSNTLMSSPNegotiateSessSetup(xid, 3462 rc = CIFSNTLMSSPNegotiateSessSetup(xid,
3460 pSesInfo, 3463 pSesInfo,
3461 &ntlmv2_flag, 3464 &ntlmv2_flag,
diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c
index 632561dd9c50..1d0ca3eaaca5 100644
--- a/fs/cifs/dir.c
+++ b/fs/cifs/dir.c
@@ -48,13 +48,14 @@ build_path_from_dentry(struct dentry *direntry)
48 struct dentry *temp; 48 struct dentry *temp;
49 int namelen = 0; 49 int namelen = 0;
50 char *full_path; 50 char *full_path;
51 char dirsep = CIFS_DIR_SEP(CIFS_SB(direntry->d_sb)); 51 char dirsep;
52 52
53 if(direntry == NULL) 53 if(direntry == NULL)
54 return NULL; /* not much we can do if dentry is freed and 54 return NULL; /* not much we can do if dentry is freed and
55 we need to reopen the file after it was closed implicitly 55 we need to reopen the file after it was closed implicitly
56 when the server crashed */ 56 when the server crashed */
57 57
58 dirsep = CIFS_DIR_SEP(CIFS_SB(direntry->d_sb));
58cifs_bp_rename_retry: 59cifs_bp_rename_retry:
59 for (temp = direntry; !IS_ROOT(temp);) { 60 for (temp = direntry; !IS_ROOT(temp);) {
60 namelen += (1 + temp->d_name.len); 61 namelen += (1 + temp->d_name.len);
@@ -255,12 +256,10 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
255 CIFSSMBClose(xid, pTcon, fileHandle); 256 CIFSSMBClose(xid, pTcon, fileHandle);
256 } else if(newinode) { 257 } else if(newinode) {
257 pCifsFile = 258 pCifsFile =
258 kmalloc(sizeof (struct cifsFileInfo), GFP_KERNEL); 259 kzalloc(sizeof (struct cifsFileInfo), GFP_KERNEL);
259 260
260 if(pCifsFile == NULL) 261 if(pCifsFile == NULL)
261 goto cifs_create_out; 262 goto cifs_create_out;
262 memset((char *)pCifsFile, 0,
263 sizeof (struct cifsFileInfo));
264 pCifsFile->netfid = fileHandle; 263 pCifsFile->netfid = fileHandle;
265 pCifsFile->pid = current->tgid; 264 pCifsFile->pid = current->tgid;
266 pCifsFile->pInode = newinode; 265 pCifsFile->pInode = newinode;
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index fb49aef1f2ec..5c497c529772 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -555,7 +555,10 @@ int cifs_closedir(struct inode *inode, struct file *file)
555 if (ptmp) { 555 if (ptmp) {
556 cFYI(1, ("closedir free smb buf in srch struct")); 556 cFYI(1, ("closedir free smb buf in srch struct"));
557 pCFileStruct->srch_inf.ntwrk_buf_start = NULL; 557 pCFileStruct->srch_inf.ntwrk_buf_start = NULL;
558 cifs_buf_release(ptmp); 558 if(pCFileStruct->srch_inf.smallBuf)
559 cifs_small_buf_release(ptmp);
560 else
561 cifs_buf_release(ptmp);
559 } 562 }
560 ptmp = pCFileStruct->search_resume_name; 563 ptmp = pCFileStruct->search_resume_name;
561 if (ptmp) { 564 if (ptmp) {
@@ -574,13 +577,14 @@ int cifs_closedir(struct inode *inode, struct file *file)
574int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock) 577int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock)
575{ 578{
576 int rc, xid; 579 int rc, xid;
577 __u32 lockType = LOCKING_ANDX_LARGE_FILES;
578 __u32 numLock = 0; 580 __u32 numLock = 0;
579 __u32 numUnlock = 0; 581 __u32 numUnlock = 0;
580 __u64 length; 582 __u64 length;
581 int wait_flag = FALSE; 583 int wait_flag = FALSE;
582 struct cifs_sb_info *cifs_sb; 584 struct cifs_sb_info *cifs_sb;
583 struct cifsTconInfo *pTcon; 585 struct cifsTconInfo *pTcon;
586 __u16 netfid;
587 __u8 lockType = LOCKING_ANDX_LARGE_FILES;
584 588
585 length = 1 + pfLock->fl_end - pfLock->fl_start; 589 length = 1 + pfLock->fl_end - pfLock->fl_start;
586 rc = -EACCES; 590 rc = -EACCES;
@@ -592,11 +596,11 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock)
592 pfLock->fl_end)); 596 pfLock->fl_end));
593 597
594 if (pfLock->fl_flags & FL_POSIX) 598 if (pfLock->fl_flags & FL_POSIX)
595 cFYI(1, ("Posix ")); 599 cFYI(1, ("Posix"));
596 if (pfLock->fl_flags & FL_FLOCK) 600 if (pfLock->fl_flags & FL_FLOCK)
597 cFYI(1, ("Flock ")); 601 cFYI(1, ("Flock"));
598 if (pfLock->fl_flags & FL_SLEEP) { 602 if (pfLock->fl_flags & FL_SLEEP) {
599 cFYI(1, ("Blocking lock ")); 603 cFYI(1, ("Blocking lock"));
600 wait_flag = TRUE; 604 wait_flag = TRUE;
601 } 605 }
602 if (pfLock->fl_flags & FL_ACCESS) 606 if (pfLock->fl_flags & FL_ACCESS)
@@ -612,21 +616,23 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock)
612 cFYI(1, ("F_WRLCK ")); 616 cFYI(1, ("F_WRLCK "));
613 numLock = 1; 617 numLock = 1;
614 } else if (pfLock->fl_type == F_UNLCK) { 618 } else if (pfLock->fl_type == F_UNLCK) {
615 cFYI(1, ("F_UNLCK ")); 619 cFYI(1, ("F_UNLCK"));
616 numUnlock = 1; 620 numUnlock = 1;
621 /* Check if unlock includes more than
622 one lock range */
617 } else if (pfLock->fl_type == F_RDLCK) { 623 } else if (pfLock->fl_type == F_RDLCK) {
618 cFYI(1, ("F_RDLCK ")); 624 cFYI(1, ("F_RDLCK"));
619 lockType |= LOCKING_ANDX_SHARED_LOCK; 625 lockType |= LOCKING_ANDX_SHARED_LOCK;
620 numLock = 1; 626 numLock = 1;
621 } else if (pfLock->fl_type == F_EXLCK) { 627 } else if (pfLock->fl_type == F_EXLCK) {
622 cFYI(1, ("F_EXLCK ")); 628 cFYI(1, ("F_EXLCK"));
623 numLock = 1; 629 numLock = 1;
624 } else if (pfLock->fl_type == F_SHLCK) { 630 } else if (pfLock->fl_type == F_SHLCK) {
625 cFYI(1, ("F_SHLCK ")); 631 cFYI(1, ("F_SHLCK"));
626 lockType |= LOCKING_ANDX_SHARED_LOCK; 632 lockType |= LOCKING_ANDX_SHARED_LOCK;
627 numLock = 1; 633 numLock = 1;
628 } else 634 } else
629 cFYI(1, ("Unknown type of lock ")); 635 cFYI(1, ("Unknown type of lock"));
630 636
631 cifs_sb = CIFS_SB(file->f_dentry->d_sb); 637 cifs_sb = CIFS_SB(file->f_dentry->d_sb);
632 pTcon = cifs_sb->tcon; 638 pTcon = cifs_sb->tcon;
@@ -635,27 +641,41 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock)
635 FreeXid(xid); 641 FreeXid(xid);
636 return -EBADF; 642 return -EBADF;
637 } 643 }
644 netfid = ((struct cifsFileInfo *)file->private_data)->netfid;
645
638 646
647 /* BB add code here to normalize offset and length to
648 account for negative length which we can not accept over the
649 wire */
639 if (IS_GETLK(cmd)) { 650 if (IS_GETLK(cmd)) {
640 rc = CIFSSMBLock(xid, pTcon, 651 if(experimEnabled &&
641 ((struct cifsFileInfo *)file-> 652 (cifs_sb->tcon->ses->capabilities & CAP_UNIX) &&
642 private_data)->netfid, 653 (CIFS_UNIX_FCNTL_CAP &
643 length, 654 le64_to_cpu(cifs_sb->tcon->fsUnixInfo.Capability))) {
644 pfLock->fl_start, 0, 1, lockType, 655 int posix_lock_type;
645 0 /* wait flag */ ); 656 if(lockType & LOCKING_ANDX_SHARED_LOCK)
657 posix_lock_type = CIFS_RDLCK;
658 else
659 posix_lock_type = CIFS_WRLCK;
660 rc = CIFSSMBPosixLock(xid, pTcon, netfid, 1 /* get */,
661 length, pfLock->fl_start,
662 posix_lock_type, wait_flag);
663 FreeXid(xid);
664 return rc;
665 }
666
667 /* BB we could chain these into one lock request BB */
668 rc = CIFSSMBLock(xid, pTcon, netfid, length, pfLock->fl_start,
669 0, 1, lockType, 0 /* wait flag */ );
646 if (rc == 0) { 670 if (rc == 0) {
647 rc = CIFSSMBLock(xid, pTcon, 671 rc = CIFSSMBLock(xid, pTcon, netfid, length,
648 ((struct cifsFileInfo *) file->
649 private_data)->netfid,
650 length,
651 pfLock->fl_start, 1 /* numUnlock */ , 672 pfLock->fl_start, 1 /* numUnlock */ ,
652 0 /* numLock */ , lockType, 673 0 /* numLock */ , lockType,
653 0 /* wait flag */ ); 674 0 /* wait flag */ );
654 pfLock->fl_type = F_UNLCK; 675 pfLock->fl_type = F_UNLCK;
655 if (rc != 0) 676 if (rc != 0)
656 cERROR(1, ("Error unlocking previously locked " 677 cERROR(1, ("Error unlocking previously locked "
657 "range %d during test of lock ", 678 "range %d during test of lock", rc));
658 rc));
659 rc = 0; 679 rc = 0;
660 680
661 } else { 681 } else {
@@ -667,12 +687,30 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock)
667 FreeXid(xid); 687 FreeXid(xid);
668 return rc; 688 return rc;
669 } 689 }
670 690 if (experimEnabled &&
671 rc = CIFSSMBLock(xid, pTcon, 691 (cifs_sb->tcon->ses->capabilities & CAP_UNIX) &&
672 ((struct cifsFileInfo *) file->private_data)-> 692 (CIFS_UNIX_FCNTL_CAP &
673 netfid, length, 693 le64_to_cpu(cifs_sb->tcon->fsUnixInfo.Capability))) {
674 pfLock->fl_start, numUnlock, numLock, lockType, 694 int posix_lock_type;
675 wait_flag); 695 if(lockType & LOCKING_ANDX_SHARED_LOCK)
696 posix_lock_type = CIFS_RDLCK;
697 else
698 posix_lock_type = CIFS_WRLCK;
699
700 if(numUnlock == 1)
701 posix_lock_type = CIFS_UNLCK;
702 else if(numLock == 0) {
703 /* if no lock or unlock then nothing
704 to do since we do not know what it is */
705 FreeXid(xid);
706 return -EOPNOTSUPP;
707 }
708 rc = CIFSSMBPosixLock(xid, pTcon, netfid, 0 /* set */,
709 length, pfLock->fl_start,
710 posix_lock_type, wait_flag);
711 } else
712 rc = CIFSSMBLock(xid, pTcon, netfid, length, pfLock->fl_start,
713 numUnlock, numLock, lockType, wait_flag);
676 if (pfLock->fl_flags & FL_POSIX) 714 if (pfLock->fl_flags & FL_POSIX)
677 posix_lock_file_wait(file, pfLock); 715 posix_lock_file_wait(file, pfLock);
678 FreeXid(xid); 716 FreeXid(xid);
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
index 598eec9778f6..957ddd1571c6 100644
--- a/fs/cifs/inode.c
+++ b/fs/cifs/inode.c
@@ -565,11 +565,14 @@ int cifs_unlink(struct inode *inode, struct dentry *direntry)
565 struct cifsInodeInfo *cifsInode; 565 struct cifsInodeInfo *cifsInode;
566 FILE_BASIC_INFO *pinfo_buf; 566 FILE_BASIC_INFO *pinfo_buf;
567 567
568 cFYI(1, ("cifs_unlink, inode = 0x%p with ", inode)); 568 cFYI(1, ("cifs_unlink, inode = 0x%p", inode));
569 569
570 xid = GetXid(); 570 xid = GetXid();
571 571
572 cifs_sb = CIFS_SB(inode->i_sb); 572 if(inode)
573 cifs_sb = CIFS_SB(inode->i_sb);
574 else
575 cifs_sb = CIFS_SB(direntry->d_sb);
573 pTcon = cifs_sb->tcon; 576 pTcon = cifs_sb->tcon;
574 577
575 /* Unlink can be called from rename so we can not grab the sem here 578 /* Unlink can be called from rename so we can not grab the sem here
@@ -609,9 +612,8 @@ int cifs_unlink(struct inode *inode, struct dentry *direntry)
609 } 612 }
610 } else if (rc == -EACCES) { 613 } else if (rc == -EACCES) {
611 /* try only if r/o attribute set in local lookup data? */ 614 /* try only if r/o attribute set in local lookup data? */
612 pinfo_buf = kmalloc(sizeof(FILE_BASIC_INFO), GFP_KERNEL); 615 pinfo_buf = kzalloc(sizeof(FILE_BASIC_INFO), GFP_KERNEL);
613 if (pinfo_buf) { 616 if (pinfo_buf) {
614 memset(pinfo_buf, 0, sizeof(FILE_BASIC_INFO));
615 /* ATTRS set to normal clears r/o bit */ 617 /* ATTRS set to normal clears r/o bit */
616 pinfo_buf->Attributes = cpu_to_le32(ATTR_NORMAL); 618 pinfo_buf->Attributes = cpu_to_le32(ATTR_NORMAL);
617 if (!(pTcon->ses->flags & CIFS_SES_NT4)) 619 if (!(pTcon->ses->flags & CIFS_SES_NT4))
@@ -693,9 +695,11 @@ int cifs_unlink(struct inode *inode, struct dentry *direntry)
693 when needed */ 695 when needed */
694 direntry->d_inode->i_ctime = current_fs_time(inode->i_sb); 696 direntry->d_inode->i_ctime = current_fs_time(inode->i_sb);
695 } 697 }
696 inode->i_ctime = inode->i_mtime = current_fs_time(inode->i_sb); 698 if(inode) {
697 cifsInode = CIFS_I(inode); 699 inode->i_ctime = inode->i_mtime = current_fs_time(inode->i_sb);
698 cifsInode->time = 0; /* force revalidate of dir as well */ 700 cifsInode = CIFS_I(inode);
701 cifsInode->time = 0; /* force revalidate of dir as well */
702 }
699 703
700 kfree(full_path); 704 kfree(full_path);
701 FreeXid(xid); 705 FreeXid(xid);
@@ -1167,7 +1171,7 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
1167 nfid, npid, FALSE); 1171 nfid, npid, FALSE);
1168 atomic_dec(&open_file->wrtPending); 1172 atomic_dec(&open_file->wrtPending);
1169 cFYI(1,("SetFSize for attrs rc = %d", rc)); 1173 cFYI(1,("SetFSize for attrs rc = %d", rc));
1170 if(rc == -EINVAL) { 1174 if((rc == -EINVAL) || (rc == -EOPNOTSUPP)) {
1171 int bytes_written; 1175 int bytes_written;
1172 rc = CIFSSMBWrite(xid, pTcon, 1176 rc = CIFSSMBWrite(xid, pTcon,
1173 nfid, 0, attrs->ia_size, 1177 nfid, 0, attrs->ia_size,
@@ -1189,7 +1193,7 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
1189 cifs_sb->mnt_cifs_flags & 1193 cifs_sb->mnt_cifs_flags &
1190 CIFS_MOUNT_MAP_SPECIAL_CHR); 1194 CIFS_MOUNT_MAP_SPECIAL_CHR);
1191 cFYI(1, ("SetEOF by path (setattrs) rc = %d", rc)); 1195 cFYI(1, ("SetEOF by path (setattrs) rc = %d", rc));
1192 if(rc == -EINVAL) { 1196 if((rc == -EINVAL) || (rc == -EOPNOTSUPP)) {
1193 __u16 netfid; 1197 __u16 netfid;
1194 int oplock = FALSE; 1198 int oplock = FALSE;
1195 1199
diff --git a/fs/cifs/link.c b/fs/cifs/link.c
index 8d0da7c87c7b..9562f5bba65c 100644
--- a/fs/cifs/link.c
+++ b/fs/cifs/link.c
@@ -67,7 +67,7 @@ cifs_hardlink(struct dentry *old_file, struct inode *inode,
67 cifs_sb_target->local_nls, 67 cifs_sb_target->local_nls,
68 cifs_sb_target->mnt_cifs_flags & 68 cifs_sb_target->mnt_cifs_flags &
69 CIFS_MOUNT_MAP_SPECIAL_CHR); 69 CIFS_MOUNT_MAP_SPECIAL_CHR);
70 if(rc == -EIO) 70 if((rc == -EIO) || (rc == -EINVAL))
71 rc = -EOPNOTSUPP; 71 rc = -EOPNOTSUPP;
72 } 72 }
73 73
diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c
index 432ba15e2c2d..fafd056426e4 100644
--- a/fs/cifs/misc.c
+++ b/fs/cifs/misc.c
@@ -72,10 +72,9 @@ sesInfoAlloc(void)
72 struct cifsSesInfo *ret_buf; 72 struct cifsSesInfo *ret_buf;
73 73
74 ret_buf = 74 ret_buf =
75 (struct cifsSesInfo *) kmalloc(sizeof (struct cifsSesInfo), 75 (struct cifsSesInfo *) kzalloc(sizeof (struct cifsSesInfo),
76 GFP_KERNEL); 76 GFP_KERNEL);
77 if (ret_buf) { 77 if (ret_buf) {
78 memset(ret_buf, 0, sizeof (struct cifsSesInfo));
79 write_lock(&GlobalSMBSeslock); 78 write_lock(&GlobalSMBSeslock);
80 atomic_inc(&sesInfoAllocCount); 79 atomic_inc(&sesInfoAllocCount);
81 ret_buf->status = CifsNew; 80 ret_buf->status = CifsNew;
@@ -110,10 +109,9 @@ tconInfoAlloc(void)
110{ 109{
111 struct cifsTconInfo *ret_buf; 110 struct cifsTconInfo *ret_buf;
112 ret_buf = 111 ret_buf =
113 (struct cifsTconInfo *) kmalloc(sizeof (struct cifsTconInfo), 112 (struct cifsTconInfo *) kzalloc(sizeof (struct cifsTconInfo),
114 GFP_KERNEL); 113 GFP_KERNEL);
115 if (ret_buf) { 114 if (ret_buf) {
116 memset(ret_buf, 0, sizeof (struct cifsTconInfo));
117 write_lock(&GlobalSMBSeslock); 115 write_lock(&GlobalSMBSeslock);
118 atomic_inc(&tconInfoAllocCount); 116 atomic_inc(&tconInfoAllocCount);
119 list_add(&ret_buf->cifsConnectionList, 117 list_add(&ret_buf->cifsConnectionList,
@@ -423,9 +421,7 @@ checkSMB(struct smb_hdr *smb, __u16 mid, int length)
423{ 421{
424 __u32 len = smb->smb_buf_length; 422 __u32 len = smb->smb_buf_length;
425 __u32 clc_len; /* calculated length */ 423 __u32 clc_len; /* calculated length */
426 cFYI(0, 424 cFYI(0, ("checkSMB Length: 0x%x, smb_buf_length: 0x%x", length, len));
427 ("Entering checkSMB with Length: %x, smb_buf_length: %x",
428 length, len));
429 if (((unsigned int)length < 2 + sizeof (struct smb_hdr)) || 425 if (((unsigned int)length < 2 + sizeof (struct smb_hdr)) ||
430 (len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4)) { 426 (len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4)) {
431 if ((unsigned int)length < 2 + sizeof (struct smb_hdr)) { 427 if ((unsigned int)length < 2 + sizeof (struct smb_hdr)) {
@@ -433,29 +429,36 @@ checkSMB(struct smb_hdr *smb, __u16 mid, int length)
433 sizeof (struct smb_hdr) - 1) 429 sizeof (struct smb_hdr) - 1)
434 && (smb->Status.CifsError != 0)) { 430 && (smb->Status.CifsError != 0)) {
435 smb->WordCount = 0; 431 smb->WordCount = 0;
436 return 0; /* some error cases do not return wct and bcc */ 432 /* some error cases do not return wct and bcc */
433 return 0;
437 } else { 434 } else {
438 cERROR(1, ("Length less than smb header size")); 435 cERROR(1, ("Length less than smb header size"));
439 } 436 }
440
441 } 437 }
442 if (len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) 438 if (len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4)
443 cERROR(1, 439 cERROR(1, ("smb length greater than MaxBufSize, mid=%d",
444 ("smb_buf_length greater than MaxBufSize")); 440 smb->Mid));
445 cERROR(1,
446 ("bad smb detected. Illegal length. mid=%d",
447 smb->Mid));
448 return 1; 441 return 1;
449 } 442 }
450 443
451 if (checkSMBhdr(smb, mid)) 444 if (checkSMBhdr(smb, mid))
452 return 1; 445 return 1;
453 clc_len = smbCalcSize_LE(smb); 446 clc_len = smbCalcSize_LE(smb);
454 if ((4 + len != clc_len) 447
455 || (4 + len != (unsigned int)length)) { 448 if(4 + len != (unsigned int)length) {
456 cERROR(1, ("Calculated size 0x%x vs actual length 0x%x", 449 cERROR(1, ("Length read does not match RFC1001 length %d",len));
457 clc_len, 4 + len)); 450 return 1;
458 cERROR(1, ("bad smb size detected for Mid=%d", smb->Mid)); 451 }
452
453 if (4 + len != clc_len) {
454 /* check if bcc wrapped around for large read responses */
455 if((len > 64 * 1024) && (len > clc_len)) {
456 /* check if lengths match mod 64K */
457 if(((4 + len) & 0xFFFF) == (clc_len & 0xFFFF))
458 return 0; /* bcc wrapped */
459 }
460 cFYI(1, ("Calculated size %d vs length %d mismatch for mid %d",
461 clc_len, 4 + len, smb->Mid));
459 /* Windows XP can return a few bytes too much, presumably 462 /* Windows XP can return a few bytes too much, presumably
460 an illegal pad, at the end of byte range lock responses 463 an illegal pad, at the end of byte range lock responses
461 so we allow for that three byte pad, as long as actual 464 so we allow for that three byte pad, as long as actual
@@ -469,8 +472,11 @@ checkSMB(struct smb_hdr *smb, __u16 mid, int length)
469 wct and bcc to minimum size and drop the t2 parms and data */ 472 wct and bcc to minimum size and drop the t2 parms and data */
470 if((4+len > clc_len) && (len <= clc_len + 512)) 473 if((4+len > clc_len) && (len <= clc_len + 512))
471 return 0; 474 return 0;
472 else 475 else {
476 cERROR(1, ("RFC1001 size %d bigger than SMB for Mid=%d",
477 len, smb->Mid));
473 return 1; 478 return 1;
479 }
474 } 480 }
475 return 0; 481 return 0;
476} 482}
diff --git a/fs/cifs/ntlmssp.c b/fs/cifs/ntlmssp.c
new file mode 100644
index 000000000000..78866f925747
--- /dev/null
+++ b/fs/cifs/ntlmssp.c
@@ -0,0 +1,129 @@
1/*
2 * fs/cifs/ntlmssp.h
3 *
4 * Copyright (c) International Business Machines Corp., 2006
5 * Author(s): Steve French (sfrench@us.ibm.com)
6 *
7 * This library is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU Lesser General Public License as published
9 * by the Free Software Foundation; either version 2.1 of the License, or
10 * (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
15 * the GNU Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public License
18 * along with this library; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */
21
22#include "cifspdu.h"
23#include "cifsglob.h"
24#include "cifsproto.h"
25#include "cifs_unicode.h"
26#include "cifs_debug.h"
27#include "ntlmssp.h"
28#include "nterr.h"
29
30#ifdef CONFIG_CIFS_EXPERIMENTAL
31static __u32 cifs_ssetup_hdr(struct cifsSesInfo *ses, SESSION_SETUP_ANDX *pSMB)
32{
33 __u32 capabilities = 0;
34
35 /* init fields common to all four types of SessSetup */
36 /* note that header is initialized to zero in header_assemble */
37 pSMB->req.AndXCommand = 0xFF;
38 pSMB->req.MaxBufferSize = cpu_to_le16(ses->server->maxBuf);
39 pSMB->req.MaxMpxCount = cpu_to_le16(ses->server->maxReq);
40
41 /* Now no need to set SMBFLG_CASELESS or obsolete CANONICAL PATH */
42
43 /* BB verify whether signing required on neg or just on auth frame
44 (and NTLM case) */
45
46 capabilities = CAP_LARGE_FILES | CAP_NT_SMBS | CAP_LEVEL_II_OPLOCKS |
47 CAP_LARGE_WRITE_X | CAP_LARGE_READ_X;
48
49 if(ses->server->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
50 pSMB->req.hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
51
52 if (ses->capabilities & CAP_UNICODE) {
53 pSMB->req.hdr.Flags2 |= SMBFLG2_UNICODE;
54 capabilities |= CAP_UNICODE;
55 }
56 if (ses->capabilities & CAP_STATUS32) {
57 pSMB->req.hdr.Flags2 |= SMBFLG2_ERR_STATUS;
58 capabilities |= CAP_STATUS32;
59 }
60 if (ses->capabilities & CAP_DFS) {
61 pSMB->req.hdr.Flags2 |= SMBFLG2_DFS;
62 capabilities |= CAP_DFS;
63 }
64
65 /* BB check whether to init vcnum BB */
66 return capabilities;
67}
68int
69CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, const int type,
70 int * pNTLMv2_flg, const struct nls_table *nls_cp)
71{
72 int rc = 0;
73 int wct;
74 struct smb_hdr *smb_buffer;
75 char *bcc_ptr;
76 SESSION_SETUP_ANDX *pSMB;
77 __u32 capabilities;
78
79 if(ses == NULL)
80 return -EINVAL;
81
82 cFYI(1,("SStp type: %d",type));
83 if(type < CIFS_NTLM) {
84#ifndef CONFIG_CIFS_WEAK_PW_HASH
85 /* LANMAN and plaintext are less secure and off by default.
86 So we make this explicitly be turned on in kconfig (in the
87 build) and turned on at runtime (changed from the default)
88 in proc/fs/cifs or via mount parm. Unfortunately this is
89 needed for old Win (e.g. Win95), some obscure NAS and OS/2 */
90 return -EOPNOTSUPP;
91#endif
92 wct = 10; /* lanman 2 style sessionsetup */
93 } else if(type < CIFS_NTLMSSP_NEG)
94 wct = 13; /* old style NTLM sessionsetup */
95 else /* same size for negotiate or auth, NTLMSSP or extended security */
96 wct = 12;
97
98 rc = small_smb_init_no_tc(SMB_COM_SESSION_SETUP_ANDX, wct, ses,
99 (void **)&smb_buffer);
100 if(rc)
101 return rc;
102
103 pSMB = (SESSION_SETUP_ANDX *)smb_buffer;
104
105 capabilities = cifs_ssetup_hdr(ses, pSMB);
106 bcc_ptr = pByteArea(smb_buffer);
107 if(type > CIFS_NTLM) {
108 pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC;
109 capabilities |= CAP_EXTENDED_SECURITY;
110 pSMB->req.Capabilities = cpu_to_le32(capabilities);
111 /* BB set password lengths */
112 } else if(type < CIFS_NTLM) /* lanman */ {
113 /* no capabilities flags in old lanman negotiation */
114 /* pSMB->old_req.PasswordLength = */ /* BB fixme BB */
115 } else /* type CIFS_NTLM */ {
116 pSMB->req_no_secext.Capabilities = cpu_to_le32(capabilities);
117 pSMB->req_no_secext.CaseInsensitivePasswordLength =
118 cpu_to_le16(CIFS_SESSION_KEY_SIZE);
119 pSMB->req_no_secext.CaseSensitivePasswordLength =
120 cpu_to_le16(CIFS_SESSION_KEY_SIZE);
121 }
122
123
124/* rc = SendReceive2(xid, ses, iov, num_iovecs, &resp_buf_type, 0); */
125 /* SMB request buf freed in SendReceive2 */
126
127 return rc;
128}
129#endif /* CONFIG_CIFS_EXPERIMENTAL */
diff --git a/fs/cifs/ntlmssp.h b/fs/cifs/ntlmssp.h
index 803389b64a2c..d39b712a11c5 100644
--- a/fs/cifs/ntlmssp.h
+++ b/fs/cifs/ntlmssp.h
@@ -1,7 +1,7 @@
1/* 1/*
2 * fs/cifs/ntlmssp.h 2 * fs/cifs/ntlmssp.h
3 * 3 *
4 * Copyright (c) International Business Machines Corp., 2002 4 * Copyright (c) International Business Machines Corp., 2002,2006
5 * Author(s): Steve French (sfrench@us.ibm.com) 5 * Author(s): Steve French (sfrench@us.ibm.com)
6 * 6 *
7 * This library is free software; you can redistribute it and/or modify 7 * This library is free software; you can redistribute it and/or modify
diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c
index 488bd0d81dcf..2f6e2825571e 100644
--- a/fs/cifs/readdir.c
+++ b/fs/cifs/readdir.c
@@ -604,7 +604,12 @@ static int find_cifs_entry(const int xid, struct cifsTconInfo *pTcon,
604 cifsFile->search_resume_name = NULL; 604 cifsFile->search_resume_name = NULL;
605 if(cifsFile->srch_inf.ntwrk_buf_start) { 605 if(cifsFile->srch_inf.ntwrk_buf_start) {
606 cFYI(1,("freeing SMB ff cache buf on search rewind")); 606 cFYI(1,("freeing SMB ff cache buf on search rewind"));
607 cifs_buf_release(cifsFile->srch_inf.ntwrk_buf_start); 607 if(cifsFile->srch_inf.smallBuf)
608 cifs_small_buf_release(cifsFile->srch_inf.
609 ntwrk_buf_start);
610 else
611 cifs_buf_release(cifsFile->srch_inf.
612 ntwrk_buf_start);
608 } 613 }
609 rc = initiate_cifs_search(xid,file); 614 rc = initiate_cifs_search(xid,file);
610 if(rc) { 615 if(rc) {
diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c
index b12cb8a7da7c..3da80409466c 100644
--- a/fs/cifs/transport.c
+++ b/fs/cifs/transport.c
@@ -309,17 +309,16 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses,
309 309
310 *pRespBufType = CIFS_NO_BUFFER; /* no response buf yet */ 310 *pRespBufType = CIFS_NO_BUFFER; /* no response buf yet */
311 311
312 if (ses == NULL) { 312 if ((ses == NULL) || (ses->server == NULL)) {
313 cERROR(1,("Null smb session")); 313 cifs_small_buf_release(in_buf);
314 return -EIO; 314 cERROR(1,("Null session"));
315 }
316 if(ses->server == NULL) {
317 cERROR(1,("Null tcp session"));
318 return -EIO; 315 return -EIO;
319 } 316 }
320 317
321 if(ses->server->tcpStatus == CifsExiting) 318 if(ses->server->tcpStatus == CifsExiting) {
319 cifs_small_buf_release(in_buf);
322 return -ENOENT; 320 return -ENOENT;
321 }
323 322
324 /* Ensure that we do not send more than 50 overlapping requests 323 /* Ensure that we do not send more than 50 overlapping requests
325 to the same server. We may make this configurable later or 324 to the same server. We may make this configurable later or
@@ -346,6 +345,7 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses,
346 } else { 345 } else {
347 if(ses->server->tcpStatus == CifsExiting) { 346 if(ses->server->tcpStatus == CifsExiting) {
348 spin_unlock(&GlobalMid_Lock); 347 spin_unlock(&GlobalMid_Lock);
348 cifs_small_buf_release(in_buf);
349 return -ENOENT; 349 return -ENOENT;
350 } 350 }
351 351
@@ -385,6 +385,7 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses,
385 midQ = AllocMidQEntry(in_buf, ses); 385 midQ = AllocMidQEntry(in_buf, ses);
386 if (midQ == NULL) { 386 if (midQ == NULL) {
387 up(&ses->server->tcpSem); 387 up(&ses->server->tcpSem);
388 cifs_small_buf_release(in_buf);
388 /* If not lock req, update # of requests on wire to server */ 389 /* If not lock req, update # of requests on wire to server */
389 if(long_op < 3) { 390 if(long_op < 3) {
390 atomic_dec(&ses->server->inFlight); 391 atomic_dec(&ses->server->inFlight);
@@ -408,14 +409,18 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses,
408 if(rc < 0) { 409 if(rc < 0) {
409 DeleteMidQEntry(midQ); 410 DeleteMidQEntry(midQ);
410 up(&ses->server->tcpSem); 411 up(&ses->server->tcpSem);
412 cifs_small_buf_release(in_buf);
411 /* If not lock req, update # of requests on wire to server */ 413 /* If not lock req, update # of requests on wire to server */
412 if(long_op < 3) { 414 if(long_op < 3) {
413 atomic_dec(&ses->server->inFlight); 415 atomic_dec(&ses->server->inFlight);
414 wake_up(&ses->server->request_q); 416 wake_up(&ses->server->request_q);
415 } 417 }
416 return rc; 418 return rc;
417 } else 419 } else {
418 up(&ses->server->tcpSem); 420 up(&ses->server->tcpSem);
421 cifs_small_buf_release(in_buf);
422 }
423
419 if (long_op == -1) 424 if (long_op == -1)
420 goto cifs_no_response_exit2; 425 goto cifs_no_response_exit2;
421 else if (long_op == 2) /* writes past end of file can take loong time */ 426 else if (long_op == 2) /* writes past end of file can take loong time */
@@ -543,6 +548,7 @@ cifs_no_response_exit2:
543 548
544out_unlock2: 549out_unlock2:
545 up(&ses->server->tcpSem); 550 up(&ses->server->tcpSem);
551 cifs_small_buf_release(in_buf);
546 /* If not lock req, update # of requests on wire to server */ 552 /* If not lock req, update # of requests on wire to server */
547 if(long_op < 3) { 553 if(long_op < 3) {
548 atomic_dec(&ses->server->inFlight); 554 atomic_dec(&ses->server->inFlight);
diff --git a/fs/dcache.c b/fs/dcache.c
index 19458d399502..940d188e5d14 100644
--- a/fs/dcache.c
+++ b/fs/dcache.c
@@ -1101,6 +1101,32 @@ next:
1101} 1101}
1102 1102
1103/** 1103/**
1104 * d_hash_and_lookup - hash the qstr then search for a dentry
1105 * @dir: Directory to search in
1106 * @name: qstr of name we wish to find
1107 *
1108 * On hash failure or on lookup failure NULL is returned.
1109 */
1110struct dentry *d_hash_and_lookup(struct dentry *dir, struct qstr *name)
1111{
1112 struct dentry *dentry = NULL;
1113
1114 /*
1115 * Check for a fs-specific hash function. Note that we must
1116 * calculate the standard hash first, as the d_op->d_hash()
1117 * routine may choose to leave the hash value unchanged.
1118 */
1119 name->hash = full_name_hash(name->name, name->len);
1120 if (dir->d_op && dir->d_op->d_hash) {
1121 if (dir->d_op->d_hash(dir, name) < 0)
1122 goto out;
1123 }
1124 dentry = d_lookup(dir, name);
1125out:
1126 return dentry;
1127}
1128
1129/**
1104 * d_validate - verify dentry provided from insecure source 1130 * d_validate - verify dentry provided from insecure source
1105 * @dentry: The dentry alleged to be valid child of @dparent 1131 * @dentry: The dentry alleged to be valid child of @dparent
1106 * @dparent: The parent dentry (known to be valid) 1132 * @dparent: The parent dentry (known to be valid)
@@ -1172,11 +1198,11 @@ void d_delete(struct dentry * dentry)
1172 spin_lock(&dentry->d_lock); 1198 spin_lock(&dentry->d_lock);
1173 isdir = S_ISDIR(dentry->d_inode->i_mode); 1199 isdir = S_ISDIR(dentry->d_inode->i_mode);
1174 if (atomic_read(&dentry->d_count) == 1) { 1200 if (atomic_read(&dentry->d_count) == 1) {
1175 /* remove this and other inotify debug checks after 2.6.18 */
1176 dentry->d_flags &= ~DCACHE_INOTIFY_PARENT_WATCHED;
1177
1178 dentry_iput(dentry); 1201 dentry_iput(dentry);
1179 fsnotify_nameremove(dentry, isdir); 1202 fsnotify_nameremove(dentry, isdir);
1203
1204 /* remove this and other inotify debug checks after 2.6.18 */
1205 dentry->d_flags &= ~DCACHE_INOTIFY_PARENT_WATCHED;
1180 return; 1206 return;
1181 } 1207 }
1182 1208
@@ -1616,26 +1642,12 @@ ino_t find_inode_number(struct dentry *dir, struct qstr *name)
1616 struct dentry * dentry; 1642 struct dentry * dentry;
1617 ino_t ino = 0; 1643 ino_t ino = 0;
1618 1644
1619 /* 1645 dentry = d_hash_and_lookup(dir, name);
1620 * Check for a fs-specific hash function. Note that we must 1646 if (dentry) {
1621 * calculate the standard hash first, as the d_op->d_hash()
1622 * routine may choose to leave the hash value unchanged.
1623 */
1624 name->hash = full_name_hash(name->name, name->len);
1625 if (dir->d_op && dir->d_op->d_hash)
1626 {
1627 if (dir->d_op->d_hash(dir, name) != 0)
1628 goto out;
1629 }
1630
1631 dentry = d_lookup(dir, name);
1632 if (dentry)
1633 {
1634 if (dentry->d_inode) 1647 if (dentry->d_inode)
1635 ino = dentry->d_inode->i_ino; 1648 ino = dentry->d_inode->i_ino;
1636 dput(dentry); 1649 dput(dentry);
1637 } 1650 }
1638out:
1639 return ino; 1651 return ino;
1640} 1652}
1641 1653
diff --git a/fs/direct-io.c b/fs/direct-io.c
index 9d1d2aa73e42..910a8ed74b5d 100644
--- a/fs/direct-io.c
+++ b/fs/direct-io.c
@@ -524,8 +524,6 @@ static int get_more_blocks(struct dio *dio)
524 */ 524 */
525 ret = dio->page_errors; 525 ret = dio->page_errors;
526 if (ret == 0) { 526 if (ret == 0) {
527 map_bh->b_state = 0;
528 map_bh->b_size = 0;
529 BUG_ON(dio->block_in_file >= dio->final_block_in_request); 527 BUG_ON(dio->block_in_file >= dio->final_block_in_request);
530 fs_startblk = dio->block_in_file >> dio->blkfactor; 528 fs_startblk = dio->block_in_file >> dio->blkfactor;
531 dio_count = dio->final_block_in_request - dio->block_in_file; 529 dio_count = dio->final_block_in_request - dio->block_in_file;
@@ -534,6 +532,9 @@ static int get_more_blocks(struct dio *dio)
534 if (dio_count & blkmask) 532 if (dio_count & blkmask)
535 fs_count++; 533 fs_count++;
536 534
535 map_bh->b_state = 0;
536 map_bh->b_size = fs_count << dio->inode->i_blkbits;
537
537 create = dio->rw == WRITE; 538 create = dio->rw == WRITE;
538 if (dio->lock_type == DIO_LOCKING) { 539 if (dio->lock_type == DIO_LOCKING) {
539 if (dio->block_in_file < (i_size_read(dio->inode) >> 540 if (dio->block_in_file < (i_size_read(dio->inode) >>
@@ -542,13 +543,13 @@ static int get_more_blocks(struct dio *dio)
542 } else if (dio->lock_type == DIO_NO_LOCKING) { 543 } else if (dio->lock_type == DIO_NO_LOCKING) {
543 create = 0; 544 create = 0;
544 } 545 }
546
545 /* 547 /*
546 * For writes inside i_size we forbid block creations: only 548 * For writes inside i_size we forbid block creations: only
547 * overwrites are permitted. We fall back to buffered writes 549 * overwrites are permitted. We fall back to buffered writes
548 * at a higher level for inside-i_size block-instantiating 550 * at a higher level for inside-i_size block-instantiating
549 * writes. 551 * writes.
550 */ 552 */
551 map_bh->b_size = fs_count << dio->blkbits;
552 ret = (*dio->get_block)(dio->inode, fs_startblk, 553 ret = (*dio->get_block)(dio->inode, fs_startblk,
553 map_bh, create); 554 map_bh, create);
554 } 555 }
diff --git a/fs/ext2/file.c b/fs/ext2/file.c
index 509cceca04db..23e2c7ccec1d 100644
--- a/fs/ext2/file.c
+++ b/fs/ext2/file.c
@@ -53,6 +53,8 @@ const struct file_operations ext2_file_operations = {
53 .readv = generic_file_readv, 53 .readv = generic_file_readv,
54 .writev = generic_file_writev, 54 .writev = generic_file_writev,
55 .sendfile = generic_file_sendfile, 55 .sendfile = generic_file_sendfile,
56 .splice_read = generic_file_splice_read,
57 .splice_write = generic_file_splice_write,
56}; 58};
57 59
58#ifdef CONFIG_EXT2_FS_XIP 60#ifdef CONFIG_EXT2_FS_XIP
diff --git a/fs/ext3/file.c b/fs/ext3/file.c
index 783a796220bb..1efefb630ea9 100644
--- a/fs/ext3/file.c
+++ b/fs/ext3/file.c
@@ -119,6 +119,8 @@ const struct file_operations ext3_file_operations = {
119 .release = ext3_release_file, 119 .release = ext3_release_file,
120 .fsync = ext3_sync_file, 120 .fsync = ext3_sync_file,
121 .sendfile = generic_file_sendfile, 121 .sendfile = generic_file_sendfile,
122 .splice_read = generic_file_splice_read,
123 .splice_write = generic_file_splice_write,
122}; 124};
123 125
124struct inode_operations ext3_file_inode_operations = { 126struct inode_operations ext3_file_inode_operations = {
diff --git a/fs/hppfs/hppfs_kern.c b/fs/hppfs/hppfs_kern.c
index 2ba20cdb5baa..5e6363be246f 100644
--- a/fs/hppfs/hppfs_kern.c
+++ b/fs/hppfs/hppfs_kern.c
@@ -216,10 +216,10 @@ static struct dentry *hppfs_lookup(struct inode *ino, struct dentry *dentry,
216static struct inode_operations hppfs_file_iops = { 216static struct inode_operations hppfs_file_iops = {
217}; 217};
218 218
219static ssize_t read_proc(struct file *file, char *buf, ssize_t count, 219static ssize_t read_proc(struct file *file, char __user *buf, ssize_t count,
220 loff_t *ppos, int is_user) 220 loff_t *ppos, int is_user)
221{ 221{
222 ssize_t (*read)(struct file *, char *, size_t, loff_t *); 222 ssize_t (*read)(struct file *, char __user *, size_t, loff_t *);
223 ssize_t n; 223 ssize_t n;
224 224
225 read = file->f_dentry->d_inode->i_fop->read; 225 read = file->f_dentry->d_inode->i_fop->read;
@@ -236,7 +236,7 @@ static ssize_t read_proc(struct file *file, char *buf, ssize_t count,
236 return n; 236 return n;
237} 237}
238 238
239static ssize_t hppfs_read_file(int fd, char *buf, ssize_t count) 239static ssize_t hppfs_read_file(int fd, char __user *buf, ssize_t count)
240{ 240{
241 ssize_t n; 241 ssize_t n;
242 int cur, err; 242 int cur, err;
@@ -274,7 +274,7 @@ static ssize_t hppfs_read_file(int fd, char *buf, ssize_t count)
274 return n; 274 return n;
275} 275}
276 276
277static ssize_t hppfs_read(struct file *file, char *buf, size_t count, 277static ssize_t hppfs_read(struct file *file, char __user *buf, size_t count,
278 loff_t *ppos) 278 loff_t *ppos)
279{ 279{
280 struct hppfs_private *hppfs = file->private_data; 280 struct hppfs_private *hppfs = file->private_data;
@@ -313,12 +313,12 @@ static ssize_t hppfs_read(struct file *file, char *buf, size_t count,
313 return(count); 313 return(count);
314} 314}
315 315
316static ssize_t hppfs_write(struct file *file, const char *buf, size_t len, 316static ssize_t hppfs_write(struct file *file, const char __user *buf, size_t len,
317 loff_t *ppos) 317 loff_t *ppos)
318{ 318{
319 struct hppfs_private *data = file->private_data; 319 struct hppfs_private *data = file->private_data;
320 struct file *proc_file = data->proc_file; 320 struct file *proc_file = data->proc_file;
321 ssize_t (*write)(struct file *, const char *, size_t, loff_t *); 321 ssize_t (*write)(struct file *, const char __user *, size_t, loff_t *);
322 int err; 322 int err;
323 323
324 write = proc_file->f_dentry->d_inode->i_fop->write; 324 write = proc_file->f_dentry->d_inode->i_fop->write;
@@ -658,7 +658,7 @@ static struct super_operations hppfs_sbops = {
658 .statfs = hppfs_statfs, 658 .statfs = hppfs_statfs,
659}; 659};
660 660
661static int hppfs_readlink(struct dentry *dentry, char *buffer, int buflen) 661static int hppfs_readlink(struct dentry *dentry, char __user *buffer, int buflen)
662{ 662{
663 struct file *proc_file; 663 struct file *proc_file;
664 struct dentry *proc_dentry; 664 struct dentry *proc_dentry;
diff --git a/fs/locks.c b/fs/locks.c
index 4d9e71d43e7e..dda83d6cd48b 100644
--- a/fs/locks.c
+++ b/fs/locks.c
@@ -168,18 +168,9 @@ static void locks_release_private(struct file_lock *fl)
168/* Free a lock which is not in use. */ 168/* Free a lock which is not in use. */
169static void locks_free_lock(struct file_lock *fl) 169static void locks_free_lock(struct file_lock *fl)
170{ 170{
171 if (fl == NULL) { 171 BUG_ON(waitqueue_active(&fl->fl_wait));
172 BUG(); 172 BUG_ON(!list_empty(&fl->fl_block));
173 return; 173 BUG_ON(!list_empty(&fl->fl_link));
174 }
175 if (waitqueue_active(&fl->fl_wait))
176 panic("Attempting to free lock with active wait queue");
177
178 if (!list_empty(&fl->fl_block))
179 panic("Attempting to free lock with active block list");
180
181 if (!list_empty(&fl->fl_link))
182 panic("Attempting to free lock on active lock list");
183 174
184 locks_release_private(fl); 175 locks_release_private(fl);
185 kmem_cache_free(filelock_cache, fl); 176 kmem_cache_free(filelock_cache, fl);
@@ -735,8 +726,9 @@ EXPORT_SYMBOL(posix_locks_deadlock);
735 * at the head of the list, but that's secret knowledge known only to 726 * at the head of the list, but that's secret knowledge known only to
736 * flock_lock_file and posix_lock_file. 727 * flock_lock_file and posix_lock_file.
737 */ 728 */
738static int flock_lock_file(struct file *filp, struct file_lock *new_fl) 729static int flock_lock_file(struct file *filp, struct file_lock *request)
739{ 730{
731 struct file_lock *new_fl = NULL;
740 struct file_lock **before; 732 struct file_lock **before;
741 struct inode * inode = filp->f_dentry->d_inode; 733 struct inode * inode = filp->f_dentry->d_inode;
742 int error = 0; 734 int error = 0;
@@ -751,17 +743,19 @@ static int flock_lock_file(struct file *filp, struct file_lock *new_fl)
751 continue; 743 continue;
752 if (filp != fl->fl_file) 744 if (filp != fl->fl_file)
753 continue; 745 continue;
754 if (new_fl->fl_type == fl->fl_type) 746 if (request->fl_type == fl->fl_type)
755 goto out; 747 goto out;
756 found = 1; 748 found = 1;
757 locks_delete_lock(before); 749 locks_delete_lock(before);
758 break; 750 break;
759 } 751 }
760 unlock_kernel();
761 752
762 if (new_fl->fl_type == F_UNLCK) 753 if (request->fl_type == F_UNLCK)
763 return 0; 754 goto out;
764 755
756 new_fl = locks_alloc_lock();
757 if (new_fl == NULL)
758 goto out;
765 /* 759 /*
766 * If a higher-priority process was blocked on the old file lock, 760 * If a higher-priority process was blocked on the old file lock,
767 * give it the opportunity to lock the file. 761 * give it the opportunity to lock the file.
@@ -769,26 +763,27 @@ static int flock_lock_file(struct file *filp, struct file_lock *new_fl)
769 if (found) 763 if (found)
770 cond_resched(); 764 cond_resched();
771 765
772 lock_kernel();
773 for_each_lock(inode, before) { 766 for_each_lock(inode, before) {
774 struct file_lock *fl = *before; 767 struct file_lock *fl = *before;
775 if (IS_POSIX(fl)) 768 if (IS_POSIX(fl))
776 break; 769 break;
777 if (IS_LEASE(fl)) 770 if (IS_LEASE(fl))
778 continue; 771 continue;
779 if (!flock_locks_conflict(new_fl, fl)) 772 if (!flock_locks_conflict(request, fl))
780 continue; 773 continue;
781 error = -EAGAIN; 774 error = -EAGAIN;
782 if (new_fl->fl_flags & FL_SLEEP) { 775 if (request->fl_flags & FL_SLEEP)
783 locks_insert_block(fl, new_fl); 776 locks_insert_block(fl, request);
784 }
785 goto out; 777 goto out;
786 } 778 }
779 locks_copy_lock(new_fl, request);
787 locks_insert_lock(&inode->i_flock, new_fl); 780 locks_insert_lock(&inode->i_flock, new_fl);
788 error = 0; 781 new_fl = NULL;
789 782
790out: 783out:
791 unlock_kernel(); 784 unlock_kernel();
785 if (new_fl)
786 locks_free_lock(new_fl);
792 return error; 787 return error;
793} 788}
794 789
@@ -1569,9 +1564,7 @@ asmlinkage long sys_flock(unsigned int fd, unsigned int cmd)
1569 error = flock_lock_file_wait(filp, lock); 1564 error = flock_lock_file_wait(filp, lock);
1570 1565
1571 out_free: 1566 out_free:
1572 if (list_empty(&lock->fl_link)) { 1567 locks_free_lock(lock);
1573 locks_free_lock(lock);
1574 }
1575 1568
1576 out_putf: 1569 out_putf:
1577 fput(filp); 1570 fput(filp);
diff --git a/fs/msdos/namei.c b/fs/msdos/namei.c
index 626a367bcd81..5b76ccd19e3f 100644
--- a/fs/msdos/namei.c
+++ b/fs/msdos/namei.c
@@ -12,14 +12,6 @@
12#include <linux/msdos_fs.h> 12#include <linux/msdos_fs.h>
13#include <linux/smp_lock.h> 13#include <linux/smp_lock.h>
14 14
15/* MS-DOS "device special files" */
16static const unsigned char *reserved_names[] = {
17 "CON ", "PRN ", "NUL ", "AUX ",
18 "LPT1 ", "LPT2 ", "LPT3 ", "LPT4 ",
19 "COM1 ", "COM2 ", "COM3 ", "COM4 ",
20 NULL
21};
22
23/* Characters that are undesirable in an MS-DOS file name */ 15/* Characters that are undesirable in an MS-DOS file name */
24static unsigned char bad_chars[] = "*?<>|\""; 16static unsigned char bad_chars[] = "*?<>|\"";
25static unsigned char bad_if_strict_pc[] = "+=,; "; 17static unsigned char bad_if_strict_pc[] = "+=,; ";
@@ -40,7 +32,6 @@ static int msdos_format_name(const unsigned char *name, int len,
40 */ 32 */
41{ 33{
42 unsigned char *walk; 34 unsigned char *walk;
43 const unsigned char **reserved;
44 unsigned char c; 35 unsigned char c;
45 int space; 36 int space;
46 37
@@ -127,11 +118,7 @@ static int msdos_format_name(const unsigned char *name, int len,
127 } 118 }
128 while (walk - res < MSDOS_NAME) 119 while (walk - res < MSDOS_NAME)
129 *walk++ = ' '; 120 *walk++ = ' ';
130 if (!opts->atari) 121
131 /* GEMDOS is less stupid and has no reserved names */
132 for (reserved = reserved_names; *reserved; reserved++)
133 if (!strncmp(res, *reserved, 8))
134 return -EINVAL;
135 return 0; 122 return 0;
136} 123}
137 124
diff --git a/fs/namei.c b/fs/namei.c
index 22f6e8d16aa8..96723ae83c89 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -1254,7 +1254,7 @@ out:
1254 return dentry; 1254 return dentry;
1255} 1255}
1256 1256
1257struct dentry * lookup_hash(struct nameidata *nd) 1257static struct dentry *lookup_hash(struct nameidata *nd)
1258{ 1258{
1259 return __lookup_hash(&nd->last, nd->dentry, nd); 1259 return __lookup_hash(&nd->last, nd->dentry, nd);
1260} 1260}
@@ -2697,7 +2697,6 @@ EXPORT_SYMBOL(follow_up);
2697EXPORT_SYMBOL(get_write_access); /* binfmt_aout */ 2697EXPORT_SYMBOL(get_write_access); /* binfmt_aout */
2698EXPORT_SYMBOL(getname); 2698EXPORT_SYMBOL(getname);
2699EXPORT_SYMBOL(lock_rename); 2699EXPORT_SYMBOL(lock_rename);
2700EXPORT_SYMBOL(lookup_hash);
2701EXPORT_SYMBOL(lookup_one_len); 2700EXPORT_SYMBOL(lookup_one_len);
2702EXPORT_SYMBOL(page_follow_link_light); 2701EXPORT_SYMBOL(page_follow_link_light);
2703EXPORT_SYMBOL(page_put_link); 2702EXPORT_SYMBOL(page_put_link);
diff --git a/fs/partitions/mac.c b/fs/partitions/mac.c
index bb22cdd0cb14..813292f21210 100644
--- a/fs/partitions/mac.c
+++ b/fs/partitions/mac.c
@@ -12,6 +12,7 @@
12#include "mac.h" 12#include "mac.h"
13 13
14#ifdef CONFIG_PPC_PMAC 14#ifdef CONFIG_PPC_PMAC
15#include <asm/machdep.h>
15extern void note_bootable_part(dev_t dev, int part, int goodness); 16extern void note_bootable_part(dev_t dev, int part, int goodness);
16#endif 17#endif
17 18
@@ -79,7 +80,7 @@ int mac_partition(struct parsed_partitions *state, struct block_device *bdev)
79 * If this is the first bootable partition, tell the 80 * If this is the first bootable partition, tell the
80 * setup code, in case it wants to make this the root. 81 * setup code, in case it wants to make this the root.
81 */ 82 */
82 if (_machine == _MACH_Pmac) { 83 if (machine_is(powermac)) {
83 int goodness = 0; 84 int goodness = 0;
84 85
85 mac_fix_string(part->processor, 16); 86 mac_fix_string(part->processor, 16);
diff --git a/fs/pipe.c b/fs/pipe.c
index e2f4f1d9ffc2..109a102c150d 100644
--- a/fs/pipe.c
+++ b/fs/pipe.c
@@ -15,6 +15,7 @@
15#include <linux/pipe_fs_i.h> 15#include <linux/pipe_fs_i.h>
16#include <linux/uio.h> 16#include <linux/uio.h>
17#include <linux/highmem.h> 17#include <linux/highmem.h>
18#include <linux/pagemap.h>
18 19
19#include <asm/uaccess.h> 20#include <asm/uaccess.h>
20#include <asm/ioctls.h> 21#include <asm/ioctls.h>
@@ -94,11 +95,20 @@ static void anon_pipe_buf_release(struct pipe_inode_info *info, struct pipe_buff
94{ 95{
95 struct page *page = buf->page; 96 struct page *page = buf->page;
96 97
97 if (info->tmp_page) { 98 /*
98 __free_page(page); 99 * If nobody else uses this page, and we don't already have a
100 * temporary page, let's keep track of it as a one-deep
101 * allocation cache
102 */
103 if (page_count(page) == 1 && !info->tmp_page) {
104 info->tmp_page = page;
99 return; 105 return;
100 } 106 }
101 info->tmp_page = page; 107
108 /*
109 * Otherwise just release our reference to it
110 */
111 page_cache_release(page);
102} 112}
103 113
104static void *anon_pipe_buf_map(struct file *file, struct pipe_inode_info *info, struct pipe_buffer *buf) 114static void *anon_pipe_buf_map(struct file *file, struct pipe_inode_info *info, struct pipe_buffer *buf)
@@ -111,11 +121,19 @@ static void anon_pipe_buf_unmap(struct pipe_inode_info *info, struct pipe_buffer
111 kunmap(buf->page); 121 kunmap(buf->page);
112} 122}
113 123
124static int anon_pipe_buf_steal(struct pipe_inode_info *info,
125 struct pipe_buffer *buf)
126{
127 buf->stolen = 1;
128 return 0;
129}
130
114static struct pipe_buf_operations anon_pipe_buf_ops = { 131static struct pipe_buf_operations anon_pipe_buf_ops = {
115 .can_merge = 1, 132 .can_merge = 1,
116 .map = anon_pipe_buf_map, 133 .map = anon_pipe_buf_map,
117 .unmap = anon_pipe_buf_unmap, 134 .unmap = anon_pipe_buf_unmap,
118 .release = anon_pipe_buf_release, 135 .release = anon_pipe_buf_release,
136 .steal = anon_pipe_buf_steal,
119}; 137};
120 138
121static ssize_t 139static ssize_t
@@ -152,6 +170,11 @@ pipe_readv(struct file *filp, const struct iovec *_iov,
152 chars = total_len; 170 chars = total_len;
153 171
154 addr = ops->map(filp, info, buf); 172 addr = ops->map(filp, info, buf);
173 if (IS_ERR(addr)) {
174 if (!ret)
175 ret = PTR_ERR(addr);
176 break;
177 }
155 error = pipe_iov_copy_to_user(iov, addr + buf->offset, chars); 178 error = pipe_iov_copy_to_user(iov, addr + buf->offset, chars);
156 ops->unmap(info, buf); 179 ops->unmap(info, buf);
157 if (unlikely(error)) { 180 if (unlikely(error)) {
@@ -254,8 +277,16 @@ pipe_writev(struct file *filp, const struct iovec *_iov,
254 struct pipe_buf_operations *ops = buf->ops; 277 struct pipe_buf_operations *ops = buf->ops;
255 int offset = buf->offset + buf->len; 278 int offset = buf->offset + buf->len;
256 if (ops->can_merge && offset + chars <= PAGE_SIZE) { 279 if (ops->can_merge && offset + chars <= PAGE_SIZE) {
257 void *addr = ops->map(filp, info, buf); 280 void *addr;
258 int error = pipe_iov_copy_from_user(offset + addr, iov, chars); 281 int error;
282
283 addr = ops->map(filp, info, buf);
284 if (IS_ERR(addr)) {
285 error = PTR_ERR(addr);
286 goto out;
287 }
288 error = pipe_iov_copy_from_user(offset + addr, iov,
289 chars);
259 ops->unmap(info, buf); 290 ops->unmap(info, buf);
260 ret = error; 291 ret = error;
261 do_wakeup = 1; 292 do_wakeup = 1;
diff --git a/fs/proc/base.c b/fs/proc/base.c
index 8f1f49ceebec..a3a3eecef689 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -534,12 +534,15 @@ static int proc_oom_score(struct task_struct *task, char *buffer)
534 534
535/* If the process being read is separated by chroot from the reading process, 535/* If the process being read is separated by chroot from the reading process,
536 * don't let the reader access the threads. 536 * don't let the reader access the threads.
537 *
538 * note: this does dput(root) and mntput(vfsmnt) on exit.
537 */ 539 */
538static int proc_check_chroot(struct dentry *root, struct vfsmount *vfsmnt) 540static int proc_check_chroot(struct dentry *root, struct vfsmount *vfsmnt)
539{ 541{
540 struct dentry *de, *base; 542 struct dentry *de, *base;
541 struct vfsmount *our_vfsmnt, *mnt; 543 struct vfsmount *our_vfsmnt, *mnt;
542 int res = 0; 544 int res = 0;
545
543 read_lock(&current->fs->lock); 546 read_lock(&current->fs->lock);
544 our_vfsmnt = mntget(current->fs->rootmnt); 547 our_vfsmnt = mntget(current->fs->rootmnt);
545 base = dget(current->fs->root); 548 base = dget(current->fs->root);
@@ -549,11 +552,11 @@ static int proc_check_chroot(struct dentry *root, struct vfsmount *vfsmnt)
549 de = root; 552 de = root;
550 mnt = vfsmnt; 553 mnt = vfsmnt;
551 554
552 while (vfsmnt != our_vfsmnt) { 555 while (mnt != our_vfsmnt) {
553 if (vfsmnt == vfsmnt->mnt_parent) 556 if (mnt == mnt->mnt_parent)
554 goto out; 557 goto out;
555 de = vfsmnt->mnt_mountpoint; 558 de = mnt->mnt_mountpoint;
556 vfsmnt = vfsmnt->mnt_parent; 559 mnt = mnt->mnt_parent;
557 } 560 }
558 561
559 if (!is_subdir(de, base)) 562 if (!is_subdir(de, base))
@@ -564,7 +567,7 @@ exit:
564 dput(base); 567 dput(base);
565 mntput(our_vfsmnt); 568 mntput(our_vfsmnt);
566 dput(root); 569 dput(root);
567 mntput(mnt); 570 mntput(vfsmnt);
568 return res; 571 return res;
569out: 572out:
570 spin_unlock(&vfsmount_lock); 573 spin_unlock(&vfsmount_lock);
diff --git a/fs/proc/proc_devtree.c b/fs/proc/proc_devtree.c
index 596b4b4f1cc8..abdf068bc27f 100644
--- a/fs/proc/proc_devtree.c
+++ b/fs/proc/proc_devtree.c
@@ -52,7 +52,8 @@ static int property_read_proc(char *page, char **start, off_t off,
52 * Add a property to a node 52 * Add a property to a node
53 */ 53 */
54static struct proc_dir_entry * 54static struct proc_dir_entry *
55__proc_device_tree_add_prop(struct proc_dir_entry *de, struct property *pp) 55__proc_device_tree_add_prop(struct proc_dir_entry *de, struct property *pp,
56 const char *name)
56{ 57{
57 struct proc_dir_entry *ent; 58 struct proc_dir_entry *ent;
58 59
@@ -60,14 +61,14 @@ __proc_device_tree_add_prop(struct proc_dir_entry *de, struct property *pp)
60 * Unfortunately proc_register puts each new entry 61 * Unfortunately proc_register puts each new entry
61 * at the beginning of the list. So we rearrange them. 62 * at the beginning of the list. So we rearrange them.
62 */ 63 */
63 ent = create_proc_read_entry(pp->name, 64 ent = create_proc_read_entry(name,
64 strncmp(pp->name, "security-", 9) 65 strncmp(name, "security-", 9)
65 ? S_IRUGO : S_IRUSR, de, 66 ? S_IRUGO : S_IRUSR, de,
66 property_read_proc, pp); 67 property_read_proc, pp);
67 if (ent == NULL) 68 if (ent == NULL)
68 return NULL; 69 return NULL;
69 70
70 if (!strncmp(pp->name, "security-", 9)) 71 if (!strncmp(name, "security-", 9))
71 ent->size = 0; /* don't leak number of password chars */ 72 ent->size = 0; /* don't leak number of password chars */
72 else 73 else
73 ent->size = pp->length; 74 ent->size = pp->length;
@@ -78,7 +79,7 @@ __proc_device_tree_add_prop(struct proc_dir_entry *de, struct property *pp)
78 79
79void proc_device_tree_add_prop(struct proc_dir_entry *pde, struct property *prop) 80void proc_device_tree_add_prop(struct proc_dir_entry *pde, struct property *prop)
80{ 81{
81 __proc_device_tree_add_prop(pde, prop); 82 __proc_device_tree_add_prop(pde, prop, prop->name);
82} 83}
83 84
84void proc_device_tree_remove_prop(struct proc_dir_entry *pde, 85void proc_device_tree_remove_prop(struct proc_dir_entry *pde,
@@ -106,6 +107,69 @@ void proc_device_tree_update_prop(struct proc_dir_entry *pde,
106} 107}
107 108
108/* 109/*
110 * Various dodgy firmware might give us nodes and/or properties with
111 * conflicting names. That's generally ok, except for exporting via /proc,
112 * so munge names here to ensure they're unique.
113 */
114
115static int duplicate_name(struct proc_dir_entry *de, const char *name)
116{
117 struct proc_dir_entry *ent;
118 int found = 0;
119
120 spin_lock(&proc_subdir_lock);
121
122 for (ent = de->subdir; ent != NULL; ent = ent->next) {
123 if (strcmp(ent->name, name) == 0) {
124 found = 1;
125 break;
126 }
127 }
128
129 spin_unlock(&proc_subdir_lock);
130
131 return found;
132}
133
134static const char *fixup_name(struct device_node *np, struct proc_dir_entry *de,
135 const char *name)
136{
137 char *fixed_name;
138 int fixup_len = strlen(name) + 2 + 1; /* name + #x + \0 */
139 int i = 1, size;
140
141realloc:
142 fixed_name = kmalloc(fixup_len, GFP_KERNEL);
143 if (fixed_name == NULL) {
144 printk(KERN_ERR "device-tree: Out of memory trying to fixup "
145 "name \"%s\"\n", name);
146 return name;
147 }
148
149retry:
150 size = snprintf(fixed_name, fixup_len, "%s#%d", name, i);
151 size++; /* account for NULL */
152
153 if (size > fixup_len) {
154 /* We ran out of space, free and reallocate. */
155 kfree(fixed_name);
156 fixup_len = size;
157 goto realloc;
158 }
159
160 if (duplicate_name(de, fixed_name)) {
161 /* Multiple duplicates. Retry with a different offset. */
162 i++;
163 goto retry;
164 }
165
166 printk(KERN_WARNING "device-tree: Duplicate name in %s, "
167 "renamed to \"%s\"\n", np->full_name, fixed_name);
168
169 return fixed_name;
170}
171
172/*
109 * Process a node, adding entries for its children and its properties. 173 * Process a node, adding entries for its children and its properties.
110 */ 174 */
111void proc_device_tree_add_node(struct device_node *np, 175void proc_device_tree_add_node(struct device_node *np,
@@ -118,37 +182,30 @@ void proc_device_tree_add_node(struct device_node *np,
118 182
119 set_node_proc_entry(np, de); 183 set_node_proc_entry(np, de);
120 for (child = NULL; (child = of_get_next_child(np, child));) { 184 for (child = NULL; (child = of_get_next_child(np, child));) {
185 /* Use everything after the last slash, or the full name */
121 p = strrchr(child->full_name, '/'); 186 p = strrchr(child->full_name, '/');
122 if (!p) 187 if (!p)
123 p = child->full_name; 188 p = child->full_name;
124 else 189 else
125 ++p; 190 ++p;
191
192 if (duplicate_name(de, p))
193 p = fixup_name(np, de, p);
194
126 ent = proc_mkdir(p, de); 195 ent = proc_mkdir(p, de);
127 if (ent == 0) 196 if (ent == 0)
128 break; 197 break;
129 proc_device_tree_add_node(child, ent); 198 proc_device_tree_add_node(child, ent);
130 } 199 }
131 of_node_put(child); 200 of_node_put(child);
201
132 for (pp = np->properties; pp != 0; pp = pp->next) { 202 for (pp = np->properties; pp != 0; pp = pp->next) {
133 /* 203 p = pp->name;
134 * Yet another Apple device-tree bogosity: on some machines, 204
135 * they have properties & nodes with the same name. Those 205 if (duplicate_name(de, p))
136 * properties are quite unimportant for us though, thus we 206 p = fixup_name(np, de, p);
137 * simply "skip" them here, but we do have to check.
138 */
139 spin_lock(&proc_subdir_lock);
140 for (ent = de->subdir; ent != NULL; ent = ent->next)
141 if (!strcmp(ent->name, pp->name))
142 break;
143 spin_unlock(&proc_subdir_lock);
144 if (ent != NULL) {
145 printk(KERN_WARNING "device-tree: property \"%s\" name"
146 " conflicts with node in %s\n", pp->name,
147 np->full_name);
148 continue;
149 }
150 207
151 ent = __proc_device_tree_add_prop(de, pp); 208 ent = __proc_device_tree_add_prop(de, pp, p);
152 if (ent == 0) 209 if (ent == 0)
153 break; 210 break;
154 } 211 }
diff --git a/fs/proc/proc_misc.c b/fs/proc/proc_misc.c
index ef5a3323f4b5..5c10ea157425 100644
--- a/fs/proc/proc_misc.c
+++ b/fs/proc/proc_misc.c
@@ -249,144 +249,60 @@ static int cpuinfo_open(struct inode *inode, struct file *file)
249 return seq_open(file, &cpuinfo_op); 249 return seq_open(file, &cpuinfo_op);
250} 250}
251 251
252enum devinfo_states { 252static struct file_operations proc_cpuinfo_operations = {
253 CHR_HDR, 253 .open = cpuinfo_open,
254 CHR_LIST, 254 .read = seq_read,
255 BLK_HDR, 255 .llseek = seq_lseek,
256 BLK_LIST, 256 .release = seq_release,
257 DEVINFO_DONE
258};
259
260struct devinfo_state {
261 void *chrdev;
262 void *blkdev;
263 unsigned int num_records;
264 unsigned int cur_record;
265 enum devinfo_states state;
266}; 257};
267 258
268static void *devinfo_start(struct seq_file *f, loff_t *pos) 259static int devinfo_show(struct seq_file *f, void *v)
269{ 260{
270 struct devinfo_state *info = f->private; 261 int i = *(loff_t *) v;
271 262
272 if (*pos) { 263 if (i < CHRDEV_MAJOR_HASH_SIZE) {
273 if ((info) && (*pos <= info->num_records)) 264 if (i == 0)
274 return info; 265 seq_printf(f, "Character devices:\n");
275 return NULL; 266 chrdev_show(f, i);
267 } else {
268 i -= CHRDEV_MAJOR_HASH_SIZE;
269 if (i == 0)
270 seq_printf(f, "\nBlock devices:\n");
271 blkdev_show(f, i);
276 } 272 }
277 info = kmalloc(sizeof(*info), GFP_KERNEL); 273 return 0;
278 f->private = info;
279 info->chrdev = acquire_chrdev_list();
280 info->blkdev = acquire_blkdev_list();
281 info->state = CHR_HDR;
282 info->num_records = count_chrdev_list();
283 info->num_records += count_blkdev_list();
284 info->num_records += 2; /* Character and Block headers */
285 *pos = 1;
286 info->cur_record = *pos;
287 return info;
288} 274}
289 275
290static void *devinfo_next(struct seq_file *f, void *v, loff_t *pos) 276static void *devinfo_start(struct seq_file *f, loff_t *pos)
291{ 277{
292 int idummy; 278 if (*pos < (BLKDEV_MAJOR_HASH_SIZE + CHRDEV_MAJOR_HASH_SIZE))
293 char *ndummy; 279 return pos;
294 struct devinfo_state *info = f->private; 280 return NULL;
295
296 switch (info->state) {
297 case CHR_HDR:
298 info->state = CHR_LIST;
299 (*pos)++;
300 /*fallthrough*/
301 case CHR_LIST:
302 if (get_chrdev_info(info->chrdev,&idummy,&ndummy)) {
303 /*
304 * The character dev list is complete
305 */
306 info->state = BLK_HDR;
307 } else {
308 info->chrdev = get_next_chrdev(info->chrdev);
309 }
310 (*pos)++;
311 break;
312 case BLK_HDR:
313 info->state = BLK_LIST;
314 (*pos)++;
315 /*fallthrough*/
316 case BLK_LIST:
317 if (get_blkdev_info(info->blkdev,&idummy,&ndummy)) {
318 /*
319 * The block dev list is complete
320 */
321 info->state = DEVINFO_DONE;
322 } else {
323 info->blkdev = get_next_blkdev(info->blkdev);
324 }
325 (*pos)++;
326 break;
327 case DEVINFO_DONE:
328 (*pos)++;
329 info->cur_record = *pos;
330 info = NULL;
331 break;
332 default:
333 break;
334 }
335 if (info)
336 info->cur_record = *pos;
337 return info;
338} 281}
339 282
340static void devinfo_stop(struct seq_file *f, void *v) 283static void *devinfo_next(struct seq_file *f, void *v, loff_t *pos)
341{ 284{
342 struct devinfo_state *info = f->private; 285 (*pos)++;
343 286 if (*pos >= (BLKDEV_MAJOR_HASH_SIZE + CHRDEV_MAJOR_HASH_SIZE))
344 if (info) { 287 return NULL;
345 release_chrdev_list(info->chrdev); 288 return pos;
346 release_blkdev_list(info->blkdev);
347 f->private = NULL;
348 kfree(info);
349 }
350} 289}
351 290
352static int devinfo_show(struct seq_file *f, void *arg) 291static void devinfo_stop(struct seq_file *f, void *v)
353{ 292{
354 int major; 293 /* Nothing to do */
355 char *name;
356 struct devinfo_state *info = f->private;
357
358 switch(info->state) {
359 case CHR_HDR:
360 seq_printf(f,"Character devices:\n");
361 /* fallthrough */
362 case CHR_LIST:
363 if (!get_chrdev_info(info->chrdev,&major,&name))
364 seq_printf(f,"%3d %s\n",major,name);
365 break;
366 case BLK_HDR:
367 seq_printf(f,"\nBlock devices:\n");
368 /* fallthrough */
369 case BLK_LIST:
370 if (!get_blkdev_info(info->blkdev,&major,&name))
371 seq_printf(f,"%3d %s\n",major,name);
372 break;
373 default:
374 break;
375 }
376
377 return 0;
378} 294}
379 295
380static struct seq_operations devinfo_op = { 296static struct seq_operations devinfo_ops = {
381 .start = devinfo_start, 297 .start = devinfo_start,
382 .next = devinfo_next, 298 .next = devinfo_next,
383 .stop = devinfo_stop, 299 .stop = devinfo_stop,
384 .show = devinfo_show, 300 .show = devinfo_show
385}; 301};
386 302
387static int devinfo_open(struct inode *inode, struct file *file) 303static int devinfo_open(struct inode *inode, struct file *filp)
388{ 304{
389 return seq_open(file, &devinfo_op); 305 return seq_open(filp, &devinfo_ops);
390} 306}
391 307
392static struct file_operations proc_devinfo_operations = { 308static struct file_operations proc_devinfo_operations = {
@@ -396,13 +312,6 @@ static struct file_operations proc_devinfo_operations = {
396 .release = seq_release, 312 .release = seq_release,
397}; 313};
398 314
399static struct file_operations proc_cpuinfo_operations = {
400 .open = cpuinfo_open,
401 .read = seq_read,
402 .llseek = seq_lseek,
403 .release = seq_release,
404};
405
406extern struct seq_operations vmstat_op; 315extern struct seq_operations vmstat_op;
407static int vmstat_open(struct inode *inode, struct file *file) 316static int vmstat_open(struct inode *inode, struct file *file)
408{ 317{
diff --git a/fs/reiserfs/file.c b/fs/reiserfs/file.c
index 010094d14da6..cf6e1cf40351 100644
--- a/fs/reiserfs/file.c
+++ b/fs/reiserfs/file.c
@@ -1576,6 +1576,8 @@ const struct file_operations reiserfs_file_operations = {
1576 .sendfile = generic_file_sendfile, 1576 .sendfile = generic_file_sendfile,
1577 .aio_read = generic_file_aio_read, 1577 .aio_read = generic_file_aio_read,
1578 .aio_write = reiserfs_aio_write, 1578 .aio_write = reiserfs_aio_write,
1579 .splice_read = generic_file_splice_read,
1580 .splice_write = generic_file_splice_write,
1579}; 1581};
1580 1582
1581struct inode_operations reiserfs_file_inode_operations = { 1583struct inode_operations reiserfs_file_inode_operations = {
diff --git a/fs/select.c b/fs/select.c
index b3a3a1326af6..071660fa7b01 100644
--- a/fs/select.c
+++ b/fs/select.c
@@ -314,7 +314,7 @@ static int core_sys_select(int n, fd_set __user *inp, fd_set __user *outp,
314 int ret, size, max_fdset; 314 int ret, size, max_fdset;
315 struct fdtable *fdt; 315 struct fdtable *fdt;
316 /* Allocate small arguments on the stack to save memory and be faster */ 316 /* Allocate small arguments on the stack to save memory and be faster */
317 char stack_fds[SELECT_STACK_ALLOC]; 317 long stack_fds[SELECT_STACK_ALLOC/sizeof(long)];
318 318
319 ret = -EINVAL; 319 ret = -EINVAL;
320 if (n < 0) 320 if (n < 0)
@@ -639,8 +639,10 @@ int do_sys_poll(struct pollfd __user *ufds, unsigned int nfds, s64 *timeout)
639 struct poll_list *walk; 639 struct poll_list *walk;
640 struct fdtable *fdt; 640 struct fdtable *fdt;
641 int max_fdset; 641 int max_fdset;
642 /* Allocate small arguments on the stack to save memory and be faster */ 642 /* Allocate small arguments on the stack to save memory and be
643 char stack_pps[POLL_STACK_ALLOC]; 643 faster - use long to make sure the buffer is aligned properly
644 on 64 bit archs to avoid unaligned access */
645 long stack_pps[POLL_STACK_ALLOC/sizeof(long)];
644 struct poll_list *stack_pp = NULL; 646 struct poll_list *stack_pp = NULL;
645 647
646 /* Do a sanity check on nfds ... */ 648 /* Do a sanity check on nfds ... */
diff --git a/fs/splice.c b/fs/splice.c
new file mode 100644
index 000000000000..7c2bbf18d7a7
--- /dev/null
+++ b/fs/splice.c
@@ -0,0 +1,663 @@
1/*
2 * "splice": joining two ropes together by interweaving their strands.
3 *
4 * This is the "extended pipe" functionality, where a pipe is used as
5 * an arbitrary in-memory buffer. Think of a pipe as a small kernel
6 * buffer that you can use to transfer data from one end to the other.
7 *
8 * The traditional unix read/write is extended with a "splice()" operation
9 * that transfers data buffers to or from a pipe buffer.
10 *
11 * Named by Larry McVoy, original implementation from Linus, extended by
12 * Jens to support splicing to files and fixing the initial implementation
13 * bugs.
14 *
15 * Copyright (C) 2005 Jens Axboe <axboe@suse.de>
16 * Copyright (C) 2005 Linus Torvalds <torvalds@osdl.org>
17 *
18 */
19#include <linux/fs.h>
20#include <linux/file.h>
21#include <linux/pagemap.h>
22#include <linux/pipe_fs_i.h>
23#include <linux/mm_inline.h>
24#include <linux/swap.h>
25#include <linux/module.h>
26
27/*
28 * Passed to the actors
29 */
30struct splice_desc {
31 unsigned int len, total_len; /* current and remaining length */
32 unsigned int flags; /* splice flags */
33 struct file *file; /* file to read/write */
34 loff_t pos; /* file position */
35};
36
37static int page_cache_pipe_buf_steal(struct pipe_inode_info *info,
38 struct pipe_buffer *buf)
39{
40 struct page *page = buf->page;
41
42 WARN_ON(!PageLocked(page));
43 WARN_ON(!PageUptodate(page));
44
45 if (!remove_mapping(page_mapping(page), page))
46 return 1;
47
48 if (PageLRU(page)) {
49 struct zone *zone = page_zone(page);
50
51 spin_lock_irq(&zone->lru_lock);
52 BUG_ON(!PageLRU(page));
53 __ClearPageLRU(page);
54 del_page_from_lru(zone, page);
55 spin_unlock_irq(&zone->lru_lock);
56 }
57
58 buf->stolen = 1;
59 return 0;
60}
61
62static void page_cache_pipe_buf_release(struct pipe_inode_info *info,
63 struct pipe_buffer *buf)
64{
65 page_cache_release(buf->page);
66 buf->page = NULL;
67 buf->stolen = 0;
68}
69
70static void *page_cache_pipe_buf_map(struct file *file,
71 struct pipe_inode_info *info,
72 struct pipe_buffer *buf)
73{
74 struct page *page = buf->page;
75
76 lock_page(page);
77
78 if (!PageUptodate(page)) {
79 unlock_page(page);
80 return ERR_PTR(-EIO);
81 }
82
83 if (!page->mapping) {
84 unlock_page(page);
85 return ERR_PTR(-ENODATA);
86 }
87
88 return kmap(buf->page);
89}
90
91static void page_cache_pipe_buf_unmap(struct pipe_inode_info *info,
92 struct pipe_buffer *buf)
93{
94 if (!buf->stolen)
95 unlock_page(buf->page);
96 kunmap(buf->page);
97}
98
99static struct pipe_buf_operations page_cache_pipe_buf_ops = {
100 .can_merge = 0,
101 .map = page_cache_pipe_buf_map,
102 .unmap = page_cache_pipe_buf_unmap,
103 .release = page_cache_pipe_buf_release,
104 .steal = page_cache_pipe_buf_steal,
105};
106
107static ssize_t move_to_pipe(struct inode *inode, struct page **pages,
108 int nr_pages, unsigned long offset,
109 unsigned long len)
110{
111 struct pipe_inode_info *info;
112 int ret, do_wakeup, i;
113
114 ret = 0;
115 do_wakeup = 0;
116 i = 0;
117
118 mutex_lock(PIPE_MUTEX(*inode));
119
120 info = inode->i_pipe;
121 for (;;) {
122 int bufs;
123
124 if (!PIPE_READERS(*inode)) {
125 send_sig(SIGPIPE, current, 0);
126 if (!ret)
127 ret = -EPIPE;
128 break;
129 }
130
131 bufs = info->nrbufs;
132 if (bufs < PIPE_BUFFERS) {
133 int newbuf = (info->curbuf + bufs) & (PIPE_BUFFERS - 1);
134 struct pipe_buffer *buf = info->bufs + newbuf;
135 struct page *page = pages[i++];
136 unsigned long this_len;
137
138 this_len = PAGE_CACHE_SIZE - offset;
139 if (this_len > len)
140 this_len = len;
141
142 buf->page = page;
143 buf->offset = offset;
144 buf->len = this_len;
145 buf->ops = &page_cache_pipe_buf_ops;
146 info->nrbufs = ++bufs;
147 do_wakeup = 1;
148
149 ret += this_len;
150 len -= this_len;
151 offset = 0;
152 if (!--nr_pages)
153 break;
154 if (!len)
155 break;
156 if (bufs < PIPE_BUFFERS)
157 continue;
158
159 break;
160 }
161
162 if (signal_pending(current)) {
163 if (!ret)
164 ret = -ERESTARTSYS;
165 break;
166 }
167
168 if (do_wakeup) {
169 wake_up_interruptible_sync(PIPE_WAIT(*inode));
170 kill_fasync(PIPE_FASYNC_READERS(*inode), SIGIO,
171 POLL_IN);
172 do_wakeup = 0;
173 }
174
175 PIPE_WAITING_WRITERS(*inode)++;
176 pipe_wait(inode);
177 PIPE_WAITING_WRITERS(*inode)--;
178 }
179
180 mutex_unlock(PIPE_MUTEX(*inode));
181
182 if (do_wakeup) {
183 wake_up_interruptible(PIPE_WAIT(*inode));
184 kill_fasync(PIPE_FASYNC_READERS(*inode), SIGIO, POLL_IN);
185 }
186
187 while (i < nr_pages)
188 page_cache_release(pages[i++]);
189
190 return ret;
191}
192
193static int __generic_file_splice_read(struct file *in, struct inode *pipe,
194 size_t len)
195{
196 struct address_space *mapping = in->f_mapping;
197 unsigned int offset, nr_pages;
198 struct page *pages[PIPE_BUFFERS], *shadow[PIPE_BUFFERS];
199 struct page *page;
200 pgoff_t index, pidx;
201 int i, j;
202
203 index = in->f_pos >> PAGE_CACHE_SHIFT;
204 offset = in->f_pos & ~PAGE_CACHE_MASK;
205 nr_pages = (len + offset + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
206
207 if (nr_pages > PIPE_BUFFERS)
208 nr_pages = PIPE_BUFFERS;
209
210 /*
211 * initiate read-ahead on this page range
212 */
213 do_page_cache_readahead(mapping, in, index, nr_pages);
214
215 /*
216 * Get as many pages from the page cache as possible..
217 * Start IO on the page cache entries we create (we
218 * can assume that any pre-existing ones we find have
219 * already had IO started on them).
220 */
221 i = find_get_pages(mapping, index, nr_pages, pages);
222
223 /*
224 * common case - we found all pages and they are contiguous,
225 * kick them off
226 */
227 if (i && (pages[i - 1]->index == index + i - 1))
228 goto splice_them;
229
230 /*
231 * fill shadow[] with pages at the right locations, so we only
232 * have to fill holes
233 */
234 memset(shadow, 0, i * sizeof(struct page *));
235 for (j = 0, pidx = index; j < i; pidx++, j++)
236 shadow[pages[j]->index - pidx] = pages[j];
237
238 /*
239 * now fill in the holes
240 */
241 for (i = 0, pidx = index; i < nr_pages; pidx++, i++) {
242 int error;
243
244 if (shadow[i])
245 continue;
246
247 /*
248 * no page there, look one up / create it
249 */
250 page = find_or_create_page(mapping, pidx,
251 mapping_gfp_mask(mapping));
252 if (!page)
253 break;
254
255 if (PageUptodate(page))
256 unlock_page(page);
257 else {
258 error = mapping->a_ops->readpage(in, page);
259
260 if (unlikely(error)) {
261 page_cache_release(page);
262 break;
263 }
264 }
265 shadow[i] = page;
266 }
267
268 if (!i) {
269 for (i = 0; i < nr_pages; i++) {
270 if (shadow[i])
271 page_cache_release(shadow[i]);
272 }
273 return 0;
274 }
275
276 memcpy(pages, shadow, i * sizeof(struct page *));
277
278 /*
279 * Now we splice them into the pipe..
280 */
281splice_them:
282 return move_to_pipe(pipe, pages, i, offset, len);
283}
284
285ssize_t generic_file_splice_read(struct file *in, struct inode *pipe,
286 size_t len, unsigned int flags)
287{
288 ssize_t spliced;
289 int ret;
290
291 ret = 0;
292 spliced = 0;
293 while (len) {
294 ret = __generic_file_splice_read(in, pipe, len);
295
296 if (ret <= 0)
297 break;
298
299 in->f_pos += ret;
300 len -= ret;
301 spliced += ret;
302 }
303
304 if (spliced)
305 return spliced;
306
307 return ret;
308}
309
310/*
311 * Send 'len' bytes to socket from 'file' at position 'pos' using sendpage().
312 */
313static int pipe_to_sendpage(struct pipe_inode_info *info,
314 struct pipe_buffer *buf, struct splice_desc *sd)
315{
316 struct file *file = sd->file;
317 loff_t pos = sd->pos;
318 unsigned int offset;
319 ssize_t ret;
320 void *ptr;
321
322 /*
323 * sub-optimal, but we are limited by the pipe ->map. we don't
324 * need a kmap'ed buffer here, we just want to make sure we
325 * have the page pinned if the pipe page originates from the
326 * page cache
327 */
328 ptr = buf->ops->map(file, info, buf);
329 if (IS_ERR(ptr))
330 return PTR_ERR(ptr);
331
332 offset = pos & ~PAGE_CACHE_MASK;
333
334 ret = file->f_op->sendpage(file, buf->page, offset, sd->len, &pos,
335 sd->len < sd->total_len);
336
337 buf->ops->unmap(info, buf);
338 if (ret == sd->len)
339 return 0;
340
341 return -EIO;
342}
343
344/*
345 * This is a little more tricky than the file -> pipe splicing. There are
346 * basically three cases:
347 *
348 * - Destination page already exists in the address space and there
349 * are users of it. For that case we have no other option that
350 * copying the data. Tough luck.
351 * - Destination page already exists in the address space, but there
352 * are no users of it. Make sure it's uptodate, then drop it. Fall
353 * through to last case.
354 * - Destination page does not exist, we can add the pipe page to
355 * the page cache and avoid the copy.
356 *
357 * For now we just do the slower thing and always copy pages over, it's
358 * easier than migrating pages from the pipe to the target file. For the
359 * case of doing file | file splicing, the migrate approach had some LRU
360 * nastiness...
361 */
362static int pipe_to_file(struct pipe_inode_info *info, struct pipe_buffer *buf,
363 struct splice_desc *sd)
364{
365 struct file *file = sd->file;
366 struct address_space *mapping = file->f_mapping;
367 unsigned int offset;
368 struct page *page;
369 pgoff_t index;
370 char *src;
371 int ret;
372
373 /*
374 * after this, page will be locked and unmapped
375 */
376 src = buf->ops->map(file, info, buf);
377 if (IS_ERR(src))
378 return PTR_ERR(src);
379
380 index = sd->pos >> PAGE_CACHE_SHIFT;
381 offset = sd->pos & ~PAGE_CACHE_MASK;
382
383 /*
384 * reuse buf page, if SPLICE_F_MOVE is set
385 */
386 if (sd->flags & SPLICE_F_MOVE) {
387 if (buf->ops->steal(info, buf))
388 goto find_page;
389
390 page = buf->page;
391 if (add_to_page_cache_lru(page, mapping, index,
392 mapping_gfp_mask(mapping)))
393 goto find_page;
394 } else {
395find_page:
396 ret = -ENOMEM;
397 page = find_or_create_page(mapping, index,
398 mapping_gfp_mask(mapping));
399 if (!page)
400 goto out;
401
402 /*
403 * If the page is uptodate, it is also locked. If it isn't
404 * uptodate, we can mark it uptodate if we are filling the
405 * full page. Otherwise we need to read it in first...
406 */
407 if (!PageUptodate(page)) {
408 if (sd->len < PAGE_CACHE_SIZE) {
409 ret = mapping->a_ops->readpage(file, page);
410 if (unlikely(ret))
411 goto out;
412
413 lock_page(page);
414
415 if (!PageUptodate(page)) {
416 /*
417 * page got invalidated, repeat
418 */
419 if (!page->mapping) {
420 unlock_page(page);
421 page_cache_release(page);
422 goto find_page;
423 }
424 ret = -EIO;
425 goto out;
426 }
427 } else {
428 WARN_ON(!PageLocked(page));
429 SetPageUptodate(page);
430 }
431 }
432 }
433
434 ret = mapping->a_ops->prepare_write(file, page, 0, sd->len);
435 if (ret)
436 goto out;
437
438 if (!buf->stolen) {
439 char *dst = kmap_atomic(page, KM_USER0);
440
441 memcpy(dst + offset, src + buf->offset, sd->len);
442 flush_dcache_page(page);
443 kunmap_atomic(dst, KM_USER0);
444 }
445
446 ret = mapping->a_ops->commit_write(file, page, 0, sd->len);
447 if (ret < 0)
448 goto out;
449
450 set_page_dirty(page);
451 ret = write_one_page(page, 0);
452out:
453 if (ret < 0)
454 unlock_page(page);
455 if (!buf->stolen)
456 page_cache_release(page);
457 buf->ops->unmap(info, buf);
458 return ret;
459}
460
461typedef int (splice_actor)(struct pipe_inode_info *, struct pipe_buffer *,
462 struct splice_desc *);
463
464static ssize_t move_from_pipe(struct inode *inode, struct file *out,
465 size_t len, unsigned int flags,
466 splice_actor *actor)
467{
468 struct pipe_inode_info *info;
469 int ret, do_wakeup, err;
470 struct splice_desc sd;
471
472 ret = 0;
473 do_wakeup = 0;
474
475 sd.total_len = len;
476 sd.flags = flags;
477 sd.file = out;
478 sd.pos = out->f_pos;
479
480 mutex_lock(PIPE_MUTEX(*inode));
481
482 info = inode->i_pipe;
483 for (;;) {
484 int bufs = info->nrbufs;
485
486 if (bufs) {
487 int curbuf = info->curbuf;
488 struct pipe_buffer *buf = info->bufs + curbuf;
489 struct pipe_buf_operations *ops = buf->ops;
490
491 sd.len = buf->len;
492 if (sd.len > sd.total_len)
493 sd.len = sd.total_len;
494
495 err = actor(info, buf, &sd);
496 if (err) {
497 if (!ret && err != -ENODATA)
498 ret = err;
499
500 break;
501 }
502
503 ret += sd.len;
504 buf->offset += sd.len;
505 buf->len -= sd.len;
506 if (!buf->len) {
507 buf->ops = NULL;
508 ops->release(info, buf);
509 curbuf = (curbuf + 1) & (PIPE_BUFFERS - 1);
510 info->curbuf = curbuf;
511 info->nrbufs = --bufs;
512 do_wakeup = 1;
513 }
514
515 sd.pos += sd.len;
516 sd.total_len -= sd.len;
517 if (!sd.total_len)
518 break;
519 }
520
521 if (bufs)
522 continue;
523 if (!PIPE_WRITERS(*inode))
524 break;
525 if (!PIPE_WAITING_WRITERS(*inode)) {
526 if (ret)
527 break;
528 }
529
530 if (signal_pending(current)) {
531 if (!ret)
532 ret = -ERESTARTSYS;
533 break;
534 }
535
536 if (do_wakeup) {
537 wake_up_interruptible_sync(PIPE_WAIT(*inode));
538 kill_fasync(PIPE_FASYNC_WRITERS(*inode),SIGIO,POLL_OUT);
539 do_wakeup = 0;
540 }
541
542 pipe_wait(inode);
543 }
544
545 mutex_unlock(PIPE_MUTEX(*inode));
546
547 if (do_wakeup) {
548 wake_up_interruptible(PIPE_WAIT(*inode));
549 kill_fasync(PIPE_FASYNC_WRITERS(*inode), SIGIO, POLL_OUT);
550 }
551
552 mutex_lock(&out->f_mapping->host->i_mutex);
553 out->f_pos = sd.pos;
554 mutex_unlock(&out->f_mapping->host->i_mutex);
555 return ret;
556
557}
558
559ssize_t generic_file_splice_write(struct inode *inode, struct file *out,
560 size_t len, unsigned int flags)
561{
562 return move_from_pipe(inode, out, len, flags, pipe_to_file);
563}
564
565ssize_t generic_splice_sendpage(struct inode *inode, struct file *out,
566 size_t len, unsigned int flags)
567{
568 return move_from_pipe(inode, out, len, flags, pipe_to_sendpage);
569}
570
571EXPORT_SYMBOL(generic_file_splice_write);
572EXPORT_SYMBOL(generic_file_splice_read);
573
574static long do_splice_from(struct inode *pipe, struct file *out, size_t len,
575 unsigned int flags)
576{
577 loff_t pos;
578 int ret;
579
580 if (!out->f_op || !out->f_op->splice_write)
581 return -EINVAL;
582
583 if (!(out->f_mode & FMODE_WRITE))
584 return -EBADF;
585
586 pos = out->f_pos;
587 ret = rw_verify_area(WRITE, out, &pos, len);
588 if (unlikely(ret < 0))
589 return ret;
590
591 return out->f_op->splice_write(pipe, out, len, flags);
592}
593
594static long do_splice_to(struct file *in, struct inode *pipe, size_t len,
595 unsigned int flags)
596{
597 loff_t pos, isize, left;
598 int ret;
599
600 if (!in->f_op || !in->f_op->splice_read)
601 return -EINVAL;
602
603 if (!(in->f_mode & FMODE_READ))
604 return -EBADF;
605
606 pos = in->f_pos;
607 ret = rw_verify_area(READ, in, &pos, len);
608 if (unlikely(ret < 0))
609 return ret;
610
611 isize = i_size_read(in->f_mapping->host);
612 if (unlikely(in->f_pos >= isize))
613 return 0;
614
615 left = isize - in->f_pos;
616 if (left < len)
617 len = left;
618
619 return in->f_op->splice_read(in, pipe, len, flags);
620}
621
622static long do_splice(struct file *in, struct file *out, size_t len,
623 unsigned int flags)
624{
625 struct inode *pipe;
626
627 pipe = in->f_dentry->d_inode;
628 if (pipe->i_pipe)
629 return do_splice_from(pipe, out, len, flags);
630
631 pipe = out->f_dentry->d_inode;
632 if (pipe->i_pipe)
633 return do_splice_to(in, pipe, len, flags);
634
635 return -EINVAL;
636}
637
638asmlinkage long sys_splice(int fdin, int fdout, size_t len, unsigned int flags)
639{
640 long error;
641 struct file *in, *out;
642 int fput_in, fput_out;
643
644 if (unlikely(!len))
645 return 0;
646
647 error = -EBADF;
648 in = fget_light(fdin, &fput_in);
649 if (in) {
650 if (in->f_mode & FMODE_READ) {
651 out = fget_light(fdout, &fput_out);
652 if (out) {
653 if (out->f_mode & FMODE_WRITE)
654 error = do_splice(in, out, len, flags);
655 fput_light(out, fput_out);
656 }
657 }
658
659 fput_light(in, fput_in);
660 }
661
662 return error;
663}
diff --git a/fs/sync.c b/fs/sync.c
new file mode 100644
index 000000000000..8616006d2094
--- /dev/null
+++ b/fs/sync.c
@@ -0,0 +1,164 @@
1/*
2 * High-level sync()-related operations
3 */
4
5#include <linux/kernel.h>
6#include <linux/file.h>
7#include <linux/fs.h>
8#include <linux/module.h>
9#include <linux/writeback.h>
10#include <linux/syscalls.h>
11#include <linux/linkage.h>
12#include <linux/pagemap.h>
13
14#define VALID_FLAGS (SYNC_FILE_RANGE_WAIT_BEFORE|SYNC_FILE_RANGE_WRITE| \
15 SYNC_FILE_RANGE_WAIT_AFTER)
16
17/*
18 * sys_sync_file_range() permits finely controlled syncing over a segment of
19 * a file in the range offset .. (offset+nbytes-1) inclusive. If nbytes is
20 * zero then sys_sync_file_range() will operate from offset out to EOF.
21 *
22 * The flag bits are:
23 *
24 * SYNC_FILE_RANGE_WAIT_BEFORE: wait upon writeout of all pages in the range
25 * before performing the write.
26 *
27 * SYNC_FILE_RANGE_WRITE: initiate writeout of all those dirty pages in the
28 * range which are not presently under writeback.
29 *
30 * SYNC_FILE_RANGE_WAIT_AFTER: wait upon writeout of all pages in the range
31 * after performing the write.
32 *
33 * Useful combinations of the flag bits are:
34 *
35 * SYNC_FILE_RANGE_WAIT_BEFORE|SYNC_FILE_RANGE_WRITE: ensures that all pages
36 * in the range which were dirty on entry to sys_sync_file_range() are placed
37 * under writeout. This is a start-write-for-data-integrity operation.
38 *
39 * SYNC_FILE_RANGE_WRITE: start writeout of all dirty pages in the range which
40 * are not presently under writeout. This is an asynchronous flush-to-disk
41 * operation. Not suitable for data integrity operations.
42 *
43 * SYNC_FILE_RANGE_WAIT_BEFORE (or SYNC_FILE_RANGE_WAIT_AFTER): wait for
44 * completion of writeout of all pages in the range. This will be used after an
45 * earlier SYNC_FILE_RANGE_WAIT_BEFORE|SYNC_FILE_RANGE_WRITE operation to wait
46 * for that operation to complete and to return the result.
47 *
48 * SYNC_FILE_RANGE_WAIT_BEFORE|SYNC_FILE_RANGE_WRITE|SYNC_FILE_RANGE_WAIT_AFTER:
49 * a traditional sync() operation. This is a write-for-data-integrity operation
50 * which will ensure that all pages in the range which were dirty on entry to
51 * sys_sync_file_range() are committed to disk.
52 *
53 *
54 * SYNC_FILE_RANGE_WAIT_BEFORE and SYNC_FILE_RANGE_WAIT_AFTER will detect any
55 * I/O errors or ENOSPC conditions and will return those to the caller, after
56 * clearing the EIO and ENOSPC flags in the address_space.
57 *
58 * It should be noted that none of these operations write out the file's
59 * metadata. So unless the application is strictly performing overwrites of
60 * already-instantiated disk blocks, there are no guarantees here that the data
61 * will be available after a crash.
62 */
63asmlinkage long sys_sync_file_range(int fd, loff_t offset, loff_t nbytes,
64 int flags)
65{
66 int ret;
67 struct file *file;
68 loff_t endbyte; /* inclusive */
69 int fput_needed;
70 umode_t i_mode;
71
72 ret = -EINVAL;
73 if (flags & ~VALID_FLAGS)
74 goto out;
75
76 endbyte = offset + nbytes;
77
78 if ((s64)offset < 0)
79 goto out;
80 if ((s64)endbyte < 0)
81 goto out;
82 if (endbyte < offset)
83 goto out;
84
85 if (sizeof(pgoff_t) == 4) {
86 if (offset >= (0x100000000ULL << PAGE_CACHE_SHIFT)) {
87 /*
88 * The range starts outside a 32 bit machine's
89 * pagecache addressing capabilities. Let it "succeed"
90 */
91 ret = 0;
92 goto out;
93 }
94 if (endbyte >= (0x100000000ULL << PAGE_CACHE_SHIFT)) {
95 /*
96 * Out to EOF
97 */
98 nbytes = 0;
99 }
100 }
101
102 if (nbytes == 0)
103 endbyte = -1;
104 else
105 endbyte--; /* inclusive */
106
107 ret = -EBADF;
108 file = fget_light(fd, &fput_needed);
109 if (!file)
110 goto out;
111
112 i_mode = file->f_dentry->d_inode->i_mode;
113 ret = -ESPIPE;
114 if (!S_ISREG(i_mode) && !S_ISBLK(i_mode) && !S_ISDIR(i_mode) &&
115 !S_ISLNK(i_mode))
116 goto out_put;
117
118 ret = do_sync_file_range(file, offset, endbyte, flags);
119out_put:
120 fput_light(file, fput_needed);
121out:
122 return ret;
123}
124
125/*
126 * `endbyte' is inclusive
127 */
128int do_sync_file_range(struct file *file, loff_t offset, loff_t endbyte,
129 int flags)
130{
131 int ret;
132 struct address_space *mapping;
133
134 mapping = file->f_mapping;
135 if (!mapping) {
136 ret = -EINVAL;
137 goto out;
138 }
139
140 ret = 0;
141 if (flags & SYNC_FILE_RANGE_WAIT_BEFORE) {
142 ret = wait_on_page_writeback_range(mapping,
143 offset >> PAGE_CACHE_SHIFT,
144 endbyte >> PAGE_CACHE_SHIFT);
145 if (ret < 0)
146 goto out;
147 }
148
149 if (flags & SYNC_FILE_RANGE_WRITE) {
150 ret = __filemap_fdatawrite_range(mapping, offset, endbyte,
151 WB_SYNC_NONE);
152 if (ret < 0)
153 goto out;
154 }
155
156 if (flags & SYNC_FILE_RANGE_WAIT_AFTER) {
157 ret = wait_on_page_writeback_range(mapping,
158 offset >> PAGE_CACHE_SHIFT,
159 endbyte >> PAGE_CACHE_SHIFT);
160 }
161out:
162 return ret;
163}
164EXPORT_SYMBOL_GPL(do_sync_file_range);
diff --git a/fs/vfat/namei.c b/fs/vfat/namei.c
index ef46939c0c1a..a56cec3be5f0 100644
--- a/fs/vfat/namei.c
+++ b/fs/vfat/namei.c
@@ -185,24 +185,6 @@ static int vfat_valid_longname(const unsigned char *name, unsigned int len)
185 return -EINVAL; 185 return -EINVAL;
186 if (len >= 256) 186 if (len >= 256)
187 return -ENAMETOOLONG; 187 return -ENAMETOOLONG;
188
189 /* MS-DOS "device special files" */
190 if (len == 3 || (len > 3 && name[3] == '.')) { /* basename == 3 */
191 if (!strnicmp(name, "aux", 3) ||
192 !strnicmp(name, "con", 3) ||
193 !strnicmp(name, "nul", 3) ||
194 !strnicmp(name, "prn", 3))
195 return -EINVAL;
196 }
197 if (len == 4 || (len > 4 && name[4] == '.')) { /* basename == 4 */
198 /* "com1", "com2", ... */
199 if ('1' <= name[3] && name[3] <= '9') {
200 if (!strnicmp(name, "com", 3) ||
201 !strnicmp(name, "lpt", 3))
202 return -EINVAL;
203 }
204 }
205
206 return 0; 188 return 0;
207} 189}
208 190
diff --git a/fs/xfs/linux-2.6/mrlock.h b/fs/xfs/linux-2.6/mrlock.h
index 16b44c3c2362..1b262b790d9c 100644
--- a/fs/xfs/linux-2.6/mrlock.h
+++ b/fs/xfs/linux-2.6/mrlock.h
@@ -79,7 +79,7 @@ static inline void mrdemote(mrlock_t *mrp)
79 * Debug-only routine, without some platform-specific asm code, we can 79 * Debug-only routine, without some platform-specific asm code, we can
80 * now only answer requests regarding whether we hold the lock for write 80 * now only answer requests regarding whether we hold the lock for write
81 * (reader state is outside our visibility, we only track writer state). 81 * (reader state is outside our visibility, we only track writer state).
82 * Note: means !ismrlocked would give false positivies, so don't do that. 82 * Note: means !ismrlocked would give false positives, so don't do that.
83 */ 83 */
84static inline int ismrlocked(mrlock_t *mrp, int type) 84static inline int ismrlocked(mrlock_t *mrp, int type)
85{ 85{
diff --git a/fs/xfs/linux-2.6/xfs_aops.c b/fs/xfs/linux-2.6/xfs_aops.c
index c02f7c5b7462..6cbbd165c60d 100644
--- a/fs/xfs/linux-2.6/xfs_aops.c
+++ b/fs/xfs/linux-2.6/xfs_aops.c
@@ -372,7 +372,7 @@ static inline int bio_add_buffer(struct bio *bio, struct buffer_head *bh)
372 * assumes that all buffers on the page are started at the same time. 372 * assumes that all buffers on the page are started at the same time.
373 * 373 *
374 * The fix is two passes across the ioend list - one to start writeback on the 374 * The fix is two passes across the ioend list - one to start writeback on the
375 * bufferheads, and then the second one submit them for I/O. 375 * buffer_heads, and then submit them for I/O on the second pass.
376 */ 376 */
377STATIC void 377STATIC void
378xfs_submit_ioend( 378xfs_submit_ioend(
@@ -699,7 +699,7 @@ xfs_convert_page(
699 699
700 /* 700 /*
701 * page_dirty is initially a count of buffers on the page before 701 * page_dirty is initially a count of buffers on the page before
702 * EOF and is decrememted as we move each into a cleanable state. 702 * EOF and is decremented as we move each into a cleanable state.
703 * 703 *
704 * Derivation: 704 * Derivation:
705 * 705 *
@@ -842,7 +842,7 @@ xfs_cluster_write(
842 * page if possible. 842 * page if possible.
843 * The bh->b_state's cannot know if any of the blocks or which block for 843 * The bh->b_state's cannot know if any of the blocks or which block for
844 * that matter are dirty due to mmap writes, and therefore bh uptodate is 844 * that matter are dirty due to mmap writes, and therefore bh uptodate is
845 * only vaild if the page itself isn't completely uptodate. Some layers 845 * only valid if the page itself isn't completely uptodate. Some layers
846 * may clear the page dirty flag prior to calling write page, under the 846 * may clear the page dirty flag prior to calling write page, under the
847 * assumption the entire page will be written out; by not writing out the 847 * assumption the entire page will be written out; by not writing out the
848 * whole page the page can be reused before all valid dirty data is 848 * whole page the page can be reused before all valid dirty data is
@@ -892,7 +892,7 @@ xfs_page_state_convert(
892 892
893 /* 893 /*
894 * page_dirty is initially a count of buffers on the page before 894 * page_dirty is initially a count of buffers on the page before
895 * EOF and is decrememted as we move each into a cleanable state. 895 * EOF and is decremented as we move each into a cleanable state.
896 * 896 *
897 * Derivation: 897 * Derivation:
898 * 898 *
@@ -1223,10 +1223,9 @@ free_buffers:
1223} 1223}
1224 1224
1225STATIC int 1225STATIC int
1226__xfs_get_block( 1226__xfs_get_blocks(
1227 struct inode *inode, 1227 struct inode *inode,
1228 sector_t iblock, 1228 sector_t iblock,
1229 unsigned long blocks,
1230 struct buffer_head *bh_result, 1229 struct buffer_head *bh_result,
1231 int create, 1230 int create,
1232 int direct, 1231 int direct,
@@ -1236,22 +1235,17 @@ __xfs_get_block(
1236 xfs_iomap_t iomap; 1235 xfs_iomap_t iomap;
1237 xfs_off_t offset; 1236 xfs_off_t offset;
1238 ssize_t size; 1237 ssize_t size;
1239 int retpbbm = 1; 1238 int niomap = 1;
1240 int error; 1239 int error;
1241 1240
1242 offset = (xfs_off_t)iblock << inode->i_blkbits; 1241 offset = (xfs_off_t)iblock << inode->i_blkbits;
1243 if (blocks) 1242 ASSERT(bh_result->b_size >= (1 << inode->i_blkbits));
1244 size = (ssize_t) min_t(xfs_off_t, LONG_MAX, 1243 size = bh_result->b_size;
1245 (xfs_off_t)blocks << inode->i_blkbits);
1246 else
1247 size = 1 << inode->i_blkbits;
1248
1249 VOP_BMAP(vp, offset, size, 1244 VOP_BMAP(vp, offset, size,
1250 create ? flags : BMAPI_READ, &iomap, &retpbbm, error); 1245 create ? flags : BMAPI_READ, &iomap, &niomap, error);
1251 if (error) 1246 if (error)
1252 return -error; 1247 return -error;
1253 1248 if (niomap == 0)
1254 if (retpbbm == 0)
1255 return 0; 1249 return 0;
1256 1250
1257 if (iomap.iomap_bn != IOMAP_DADDR_NULL) { 1251 if (iomap.iomap_bn != IOMAP_DADDR_NULL) {
@@ -1271,12 +1265,16 @@ __xfs_get_block(
1271 } 1265 }
1272 } 1266 }
1273 1267
1274 /* If this is a realtime file, data might be on a new device */ 1268 /*
1269 * If this is a realtime file, data may be on a different device.
1270 * to that pointed to from the buffer_head b_bdev currently.
1271 */
1275 bh_result->b_bdev = iomap.iomap_target->bt_bdev; 1272 bh_result->b_bdev = iomap.iomap_target->bt_bdev;
1276 1273
1277 /* If we previously allocated a block out beyond eof and 1274 /*
1278 * we are now coming back to use it then we will need to 1275 * If we previously allocated a block out beyond eof and we are
1279 * flag it as new even if it has a disk address. 1276 * now coming back to use it then we will need to flag it as new
1277 * even if it has a disk address.
1280 */ 1278 */
1281 if (create && 1279 if (create &&
1282 ((!buffer_mapped(bh_result) && !buffer_uptodate(bh_result)) || 1280 ((!buffer_mapped(bh_result) && !buffer_uptodate(bh_result)) ||
@@ -1292,26 +1290,24 @@ __xfs_get_block(
1292 } 1290 }
1293 } 1291 }
1294 1292
1295 if (blocks) { 1293 if (direct || size > (1 << inode->i_blkbits)) {
1296 ASSERT(iomap.iomap_bsize - iomap.iomap_delta > 0); 1294 ASSERT(iomap.iomap_bsize - iomap.iomap_delta > 0);
1297 offset = min_t(xfs_off_t, 1295 offset = min_t(xfs_off_t,
1298 iomap.iomap_bsize - iomap.iomap_delta, 1296 iomap.iomap_bsize - iomap.iomap_delta, size);
1299 (xfs_off_t)blocks << inode->i_blkbits); 1297 bh_result->b_size = (ssize_t)min_t(xfs_off_t, LONG_MAX, offset);
1300 bh_result->b_size = (u32) min_t(xfs_off_t, UINT_MAX, offset);
1301 } 1298 }
1302 1299
1303 return 0; 1300 return 0;
1304} 1301}
1305 1302
1306int 1303int
1307xfs_get_block( 1304xfs_get_blocks(
1308 struct inode *inode, 1305 struct inode *inode,
1309 sector_t iblock, 1306 sector_t iblock,
1310 struct buffer_head *bh_result, 1307 struct buffer_head *bh_result,
1311 int create) 1308 int create)
1312{ 1309{
1313 return __xfs_get_block(inode, iblock, 1310 return __xfs_get_blocks(inode, iblock,
1314 bh_result->b_size >> inode->i_blkbits,
1315 bh_result, create, 0, BMAPI_WRITE); 1311 bh_result, create, 0, BMAPI_WRITE);
1316} 1312}
1317 1313
@@ -1322,8 +1318,7 @@ xfs_get_blocks_direct(
1322 struct buffer_head *bh_result, 1318 struct buffer_head *bh_result,
1323 int create) 1319 int create)
1324{ 1320{
1325 return __xfs_get_block(inode, iblock, 1321 return __xfs_get_blocks(inode, iblock,
1326 bh_result->b_size >> inode->i_blkbits,
1327 bh_result, create, 1, BMAPI_WRITE|BMAPI_DIRECT); 1322 bh_result, create, 1, BMAPI_WRITE|BMAPI_DIRECT);
1328} 1323}
1329 1324
@@ -1339,9 +1334,9 @@ xfs_end_io_direct(
1339 /* 1334 /*
1340 * Non-NULL private data means we need to issue a transaction to 1335 * Non-NULL private data means we need to issue a transaction to
1341 * convert a range from unwritten to written extents. This needs 1336 * convert a range from unwritten to written extents. This needs
1342 * to happen from process contect but aio+dio I/O completion 1337 * to happen from process context but aio+dio I/O completion
1343 * happens from irq context so we need to defer it to a workqueue. 1338 * happens from irq context so we need to defer it to a workqueue.
1344 * This is not nessecary for synchronous direct I/O, but we do 1339 * This is not necessary for synchronous direct I/O, but we do
1345 * it anyway to keep the code uniform and simpler. 1340 * it anyway to keep the code uniform and simpler.
1346 * 1341 *
1347 * The core direct I/O code might be changed to always call the 1342 * The core direct I/O code might be changed to always call the
@@ -1358,7 +1353,7 @@ xfs_end_io_direct(
1358 } 1353 }
1359 1354
1360 /* 1355 /*
1361 * blockdev_direct_IO can return an error even afer the I/O 1356 * blockdev_direct_IO can return an error even after the I/O
1362 * completion handler was called. Thus we need to protect 1357 * completion handler was called. Thus we need to protect
1363 * against double-freeing. 1358 * against double-freeing.
1364 */ 1359 */
@@ -1405,7 +1400,7 @@ xfs_vm_prepare_write(
1405 unsigned int from, 1400 unsigned int from,
1406 unsigned int to) 1401 unsigned int to)
1407{ 1402{
1408 return block_prepare_write(page, from, to, xfs_get_block); 1403 return block_prepare_write(page, from, to, xfs_get_blocks);
1409} 1404}
1410 1405
1411STATIC sector_t 1406STATIC sector_t
@@ -1422,7 +1417,7 @@ xfs_vm_bmap(
1422 VOP_RWLOCK(vp, VRWLOCK_READ); 1417 VOP_RWLOCK(vp, VRWLOCK_READ);
1423 VOP_FLUSH_PAGES(vp, (xfs_off_t)0, -1, 0, FI_REMAPF, error); 1418 VOP_FLUSH_PAGES(vp, (xfs_off_t)0, -1, 0, FI_REMAPF, error);
1424 VOP_RWUNLOCK(vp, VRWLOCK_READ); 1419 VOP_RWUNLOCK(vp, VRWLOCK_READ);
1425 return generic_block_bmap(mapping, block, xfs_get_block); 1420 return generic_block_bmap(mapping, block, xfs_get_blocks);
1426} 1421}
1427 1422
1428STATIC int 1423STATIC int
@@ -1430,7 +1425,7 @@ xfs_vm_readpage(
1430 struct file *unused, 1425 struct file *unused,
1431 struct page *page) 1426 struct page *page)
1432{ 1427{
1433 return mpage_readpage(page, xfs_get_block); 1428 return mpage_readpage(page, xfs_get_blocks);
1434} 1429}
1435 1430
1436STATIC int 1431STATIC int
@@ -1440,7 +1435,7 @@ xfs_vm_readpages(
1440 struct list_head *pages, 1435 struct list_head *pages,
1441 unsigned nr_pages) 1436 unsigned nr_pages)
1442{ 1437{
1443 return mpage_readpages(mapping, pages, nr_pages, xfs_get_block); 1438 return mpage_readpages(mapping, pages, nr_pages, xfs_get_blocks);
1444} 1439}
1445 1440
1446STATIC void 1441STATIC void
diff --git a/fs/xfs/linux-2.6/xfs_aops.h b/fs/xfs/linux-2.6/xfs_aops.h
index 795699f121d2..60716543c68b 100644
--- a/fs/xfs/linux-2.6/xfs_aops.h
+++ b/fs/xfs/linux-2.6/xfs_aops.h
@@ -41,6 +41,6 @@ typedef struct xfs_ioend {
41} xfs_ioend_t; 41} xfs_ioend_t;
42 42
43extern struct address_space_operations xfs_address_space_operations; 43extern struct address_space_operations xfs_address_space_operations;
44extern int xfs_get_block(struct inode *, sector_t, struct buffer_head *, int); 44extern int xfs_get_blocks(struct inode *, sector_t, struct buffer_head *, int);
45 45
46#endif /* __XFS_IOPS_H__ */ 46#endif /* __XFS_IOPS_H__ */
diff --git a/fs/xfs/linux-2.6/xfs_export.h b/fs/xfs/linux-2.6/xfs_export.h
index e5b0559700a4..e794ca4efc76 100644
--- a/fs/xfs/linux-2.6/xfs_export.h
+++ b/fs/xfs/linux-2.6/xfs_export.h
@@ -54,7 +54,7 @@
54 * Note, the NFS filehandle also includes an fsid portion which 54 * Note, the NFS filehandle also includes an fsid portion which
55 * may have an inode number in it. That number is hardcoded to 55 * may have an inode number in it. That number is hardcoded to
56 * 32bits and there is no way for XFS to intercept it. In 56 * 32bits and there is no way for XFS to intercept it. In
57 * practice this means when exporting an XFS filesytem with 64bit 57 * practice this means when exporting an XFS filesystem with 64bit
58 * inodes you should either export the mountpoint (rather than 58 * inodes you should either export the mountpoint (rather than
59 * a subdirectory) or use the "fsid" export option. 59 * a subdirectory) or use the "fsid" export option.
60 */ 60 */
diff --git a/fs/xfs/linux-2.6/xfs_ioctl32.c b/fs/xfs/linux-2.6/xfs_ioctl32.c
index b6321abd9a81..251bfe451a3f 100644
--- a/fs/xfs/linux-2.6/xfs_ioctl32.c
+++ b/fs/xfs/linux-2.6/xfs_ioctl32.c
@@ -72,7 +72,7 @@ xfs_ioctl32_flock(
72 copy_in_user(&p->l_pid, &p32->l_pid, sizeof(u32)) || 72 copy_in_user(&p->l_pid, &p32->l_pid, sizeof(u32)) ||
73 copy_in_user(&p->l_pad, &p32->l_pad, 4*sizeof(u32))) 73 copy_in_user(&p->l_pad, &p32->l_pad, 4*sizeof(u32)))
74 return -EFAULT; 74 return -EFAULT;
75 75
76 return (unsigned long)p; 76 return (unsigned long)p;
77} 77}
78 78
@@ -107,11 +107,15 @@ xfs_ioctl32_bulkstat(
107#endif 107#endif
108 108
109STATIC long 109STATIC long
110xfs_compat_ioctl(int mode, struct file *f, unsigned cmd, unsigned long arg) 110xfs_compat_ioctl(
111 int mode,
112 struct file *file,
113 unsigned cmd,
114 unsigned long arg)
111{ 115{
116 struct inode *inode = file->f_dentry->d_inode;
117 vnode_t *vp = vn_from_inode(inode);
112 int error; 118 int error;
113 struct inode *inode = f->f_dentry->d_inode;
114 vnode_t *vp = vn_to_inode(inode);
115 119
116 switch (cmd) { 120 switch (cmd) {
117 case XFS_IOC_DIOINFO: 121 case XFS_IOC_DIOINFO:
@@ -189,7 +193,7 @@ xfs_compat_ioctl(int mode, struct file *f, unsigned cmd, unsigned long arg)
189 return -ENOIOCTLCMD; 193 return -ENOIOCTLCMD;
190 } 194 }
191 195
192 VOP_IOCTL(vp, inode, f, mode, cmd, (void __user *)arg, error); 196 VOP_IOCTL(vp, inode, file, mode, cmd, (void __user *)arg, error);
193 VMODIFY(vp); 197 VMODIFY(vp);
194 198
195 return error; 199 return error;
@@ -197,18 +201,18 @@ xfs_compat_ioctl(int mode, struct file *f, unsigned cmd, unsigned long arg)
197 201
198long 202long
199xfs_file_compat_ioctl( 203xfs_file_compat_ioctl(
200 struct file *f, 204 struct file *file,
201 unsigned cmd, 205 unsigned cmd,
202 unsigned long arg) 206 unsigned long arg)
203{ 207{
204 return xfs_compat_ioctl(0, f, cmd, arg); 208 return xfs_compat_ioctl(0, file, cmd, arg);
205} 209}
206 210
207long 211long
208xfs_file_compat_invis_ioctl( 212xfs_file_compat_invis_ioctl(
209 struct file *f, 213 struct file *file,
210 unsigned cmd, 214 unsigned cmd,
211 unsigned long arg) 215 unsigned long arg)
212{ 216{
213 return xfs_compat_ioctl(IO_INVIS, f, cmd, arg); 217 return xfs_compat_ioctl(IO_INVIS, file, cmd, arg);
214} 218}
diff --git a/fs/xfs/linux-2.6/xfs_iops.c b/fs/xfs/linux-2.6/xfs_iops.c
index af487437bd7e..149237304fb6 100644
--- a/fs/xfs/linux-2.6/xfs_iops.c
+++ b/fs/xfs/linux-2.6/xfs_iops.c
@@ -708,7 +708,7 @@ STATIC void
708xfs_vn_truncate( 708xfs_vn_truncate(
709 struct inode *inode) 709 struct inode *inode)
710{ 710{
711 block_truncate_page(inode->i_mapping, inode->i_size, xfs_get_block); 711 block_truncate_page(inode->i_mapping, inode->i_size, xfs_get_blocks);
712} 712}
713 713
714STATIC int 714STATIC int
diff --git a/fs/xfs/linux-2.6/xfs_lrw.c b/fs/xfs/linux-2.6/xfs_lrw.c
index 0169360475c4..84ddf1893894 100644
--- a/fs/xfs/linux-2.6/xfs_lrw.c
+++ b/fs/xfs/linux-2.6/xfs_lrw.c
@@ -681,7 +681,7 @@ start:
681 eventsent = 1; 681 eventsent = 1;
682 682
683 /* 683 /*
684 * The iolock was dropped and reaquired in XFS_SEND_DATA 684 * The iolock was dropped and reacquired in XFS_SEND_DATA
685 * so we have to recheck the size when appending. 685 * so we have to recheck the size when appending.
686 * We will only "goto start;" once, since having sent the 686 * We will only "goto start;" once, since having sent the
687 * event prevents another call to XFS_SEND_DATA, which is 687 * event prevents another call to XFS_SEND_DATA, which is
diff --git a/fs/xfs/linux-2.6/xfs_vfs.h b/fs/xfs/linux-2.6/xfs_vfs.h
index 8fed356db055..841200c03092 100644
--- a/fs/xfs/linux-2.6/xfs_vfs.h
+++ b/fs/xfs/linux-2.6/xfs_vfs.h
@@ -92,7 +92,7 @@ typedef enum {
92#define SYNC_FSDATA 0x0020 /* flush fs data (e.g. superblocks) */ 92#define SYNC_FSDATA 0x0020 /* flush fs data (e.g. superblocks) */
93#define SYNC_REFCACHE 0x0040 /* prune some of the nfs ref cache */ 93#define SYNC_REFCACHE 0x0040 /* prune some of the nfs ref cache */
94#define SYNC_REMOUNT 0x0080 /* remount readonly, no dummy LRs */ 94#define SYNC_REMOUNT 0x0080 /* remount readonly, no dummy LRs */
95#define SYNC_QUIESCE 0x0100 /* quiesce fileystem for a snapshot */ 95#define SYNC_QUIESCE 0x0100 /* quiesce filesystem for a snapshot */
96 96
97typedef int (*vfs_mount_t)(bhv_desc_t *, 97typedef int (*vfs_mount_t)(bhv_desc_t *,
98 struct xfs_mount_args *, struct cred *); 98 struct xfs_mount_args *, struct cred *);
diff --git a/fs/xfs/quota/xfs_dquot_item.c b/fs/xfs/quota/xfs_dquot_item.c
index e4e5f05b841b..546f48af882a 100644
--- a/fs/xfs/quota/xfs_dquot_item.c
+++ b/fs/xfs/quota/xfs_dquot_item.c
@@ -221,7 +221,7 @@ xfs_qm_dqunpin_wait(
221 * as possible. 221 * as possible.
222 * 222 *
223 * We must not be holding the AIL_LOCK at this point. Calling incore() to 223 * We must not be holding the AIL_LOCK at this point. Calling incore() to
224 * search the buffercache can be a time consuming thing, and AIL_LOCK is a 224 * search the buffer cache can be a time consuming thing, and AIL_LOCK is a
225 * spinlock. 225 * spinlock.
226 */ 226 */
227STATIC void 227STATIC void
diff --git a/fs/xfs/quota/xfs_qm.c b/fs/xfs/quota/xfs_qm.c
index 1fb757ef3f41..73c1e5e80c07 100644
--- a/fs/xfs/quota/xfs_qm.c
+++ b/fs/xfs/quota/xfs_qm.c
@@ -289,7 +289,7 @@ xfs_qm_rele_quotafs_ref(
289 289
290/* 290/*
291 * This is called at mount time from xfs_mountfs to initialize the quotainfo 291 * This is called at mount time from xfs_mountfs to initialize the quotainfo
292 * structure and start the global quotamanager (xfs_Gqm) if it hasn't done 292 * structure and start the global quota manager (xfs_Gqm) if it hasn't done
293 * so already. Note that the superblock has not been read in yet. 293 * so already. Note that the superblock has not been read in yet.
294 */ 294 */
295void 295void
@@ -807,7 +807,7 @@ xfs_qm_dqattach_one(
807 * Given a udquot and gdquot, attach a ptr to the group dquot in the 807 * Given a udquot and gdquot, attach a ptr to the group dquot in the
808 * udquot as a hint for future lookups. The idea sounds simple, but the 808 * udquot as a hint for future lookups. The idea sounds simple, but the
809 * execution isn't, because the udquot might have a group dquot attached 809 * execution isn't, because the udquot might have a group dquot attached
810 * already and getting rid of that gets us into lock ordering contraints. 810 * already and getting rid of that gets us into lock ordering constraints.
811 * The process is complicated more by the fact that the dquots may or may not 811 * The process is complicated more by the fact that the dquots may or may not
812 * be locked on entry. 812 * be locked on entry.
813 */ 813 */
@@ -1094,10 +1094,10 @@ xfs_qm_sync(
1094 } 1094 }
1095 /* 1095 /*
1096 * If we can't grab the flush lock then if the caller 1096 * If we can't grab the flush lock then if the caller
1097 * really wanted us to give this our best shot, 1097 * really wanted us to give this our best shot, so
1098 * see if we can give a push to the buffer before we wait 1098 * see if we can give a push to the buffer before we wait
1099 * on the flush lock. At this point, we know that 1099 * on the flush lock. At this point, we know that
1100 * eventhough the dquot is being flushed, 1100 * even though the dquot is being flushed,
1101 * it has (new) dirty data. 1101 * it has (new) dirty data.
1102 */ 1102 */
1103 xfs_qm_dqflock_pushbuf_wait(dqp); 1103 xfs_qm_dqflock_pushbuf_wait(dqp);
@@ -1491,7 +1491,7 @@ xfs_qm_reset_dqcounts(
1491 /* 1491 /*
1492 * Do a sanity check, and if needed, repair the dqblk. Don't 1492 * Do a sanity check, and if needed, repair the dqblk. Don't
1493 * output any warnings because it's perfectly possible to 1493 * output any warnings because it's perfectly possible to
1494 * find unitialized dquot blks. See comment in xfs_qm_dqcheck. 1494 * find uninitialised dquot blks. See comment in xfs_qm_dqcheck.
1495 */ 1495 */
1496 (void) xfs_qm_dqcheck(ddq, id+j, type, XFS_QMOPT_DQREPAIR, 1496 (void) xfs_qm_dqcheck(ddq, id+j, type, XFS_QMOPT_DQREPAIR,
1497 "xfs_quotacheck"); 1497 "xfs_quotacheck");
@@ -1580,7 +1580,7 @@ xfs_qm_dqiterate(
1580 1580
1581 error = 0; 1581 error = 0;
1582 /* 1582 /*
1583 * This looks racey, but we can't keep an inode lock across a 1583 * This looks racy, but we can't keep an inode lock across a
1584 * trans_reserve. But, this gets called during quotacheck, and that 1584 * trans_reserve. But, this gets called during quotacheck, and that
1585 * happens only at mount time which is single threaded. 1585 * happens only at mount time which is single threaded.
1586 */ 1586 */
@@ -1824,7 +1824,7 @@ xfs_qm_dqusage_adjust(
1824 * we have to start from the beginning anyway. 1824 * we have to start from the beginning anyway.
1825 * Once we're done, we'll log all the dquot bufs. 1825 * Once we're done, we'll log all the dquot bufs.
1826 * 1826 *
1827 * The *QUOTA_ON checks below may look pretty racey, but quotachecks 1827 * The *QUOTA_ON checks below may look pretty racy, but quotachecks
1828 * and quotaoffs don't race. (Quotachecks happen at mount time only). 1828 * and quotaoffs don't race. (Quotachecks happen at mount time only).
1829 */ 1829 */
1830 if (XFS_IS_UQUOTA_ON(mp)) { 1830 if (XFS_IS_UQUOTA_ON(mp)) {
diff --git a/fs/xfs/quota/xfs_qm_syscalls.c b/fs/xfs/quota/xfs_qm_syscalls.c
index 676884394aae..c55db463bbf2 100644
--- a/fs/xfs/quota/xfs_qm_syscalls.c
+++ b/fs/xfs/quota/xfs_qm_syscalls.c
@@ -912,7 +912,7 @@ xfs_qm_export_dquot(
912 912
913 /* 913 /*
914 * Internally, we don't reset all the timers when quota enforcement 914 * Internally, we don't reset all the timers when quota enforcement
915 * gets turned off. No need to confuse the userlevel code, 915 * gets turned off. No need to confuse the user level code,
916 * so return zeroes in that case. 916 * so return zeroes in that case.
917 */ 917 */
918 if (! XFS_IS_QUOTA_ENFORCED(mp)) { 918 if (! XFS_IS_QUOTA_ENFORCED(mp)) {
diff --git a/fs/xfs/quota/xfs_trans_dquot.c b/fs/xfs/quota/xfs_trans_dquot.c
index 3290975d31f7..d8e131ec0aa8 100644
--- a/fs/xfs/quota/xfs_trans_dquot.c
+++ b/fs/xfs/quota/xfs_trans_dquot.c
@@ -804,7 +804,7 @@ xfs_trans_reserve_quota_bydquots(
804 } 804 }
805 805
806 /* 806 /*
807 * Didnt change anything critical, so, no need to log 807 * Didn't change anything critical, so, no need to log
808 */ 808 */
809 return (0); 809 return (0);
810} 810}
diff --git a/fs/xfs/xfs_acl.c b/fs/xfs/xfs_acl.c
index 4ff0f4e41c61..2539af34eb63 100644
--- a/fs/xfs/xfs_acl.c
+++ b/fs/xfs/xfs_acl.c
@@ -395,7 +395,7 @@ xfs_acl_allow_set(
395 * The access control process to determine the access permission: 395 * The access control process to determine the access permission:
396 * if uid == file owner id, use the file owner bits. 396 * if uid == file owner id, use the file owner bits.
397 * if gid == file owner group id, use the file group bits. 397 * if gid == file owner group id, use the file group bits.
398 * scan ACL for a maching user or group, and use matched entry 398 * scan ACL for a matching user or group, and use matched entry
399 * permission. Use total permissions of all matching group entries, 399 * permission. Use total permissions of all matching group entries,
400 * until all acl entries are exhausted. The final permission produced 400 * until all acl entries are exhausted. The final permission produced
401 * by matching acl entry or entries needs to be & with group permission. 401 * by matching acl entry or entries needs to be & with group permission.
diff --git a/fs/xfs/xfs_ag.h b/fs/xfs/xfs_ag.h
index a96e2ffce0cc..dc2361dd740a 100644
--- a/fs/xfs/xfs_ag.h
+++ b/fs/xfs/xfs_ag.h
@@ -179,7 +179,7 @@ typedef struct xfs_perag
179{ 179{
180 char pagf_init; /* this agf's entry is initialized */ 180 char pagf_init; /* this agf's entry is initialized */
181 char pagi_init; /* this agi's entry is initialized */ 181 char pagi_init; /* this agi's entry is initialized */
182 char pagf_metadata; /* the agf is prefered to be metadata */ 182 char pagf_metadata; /* the agf is preferred to be metadata */
183 char pagi_inodeok; /* The agi is ok for inodes */ 183 char pagi_inodeok; /* The agi is ok for inodes */
184 __uint8_t pagf_levels[XFS_BTNUM_AGF]; 184 __uint8_t pagf_levels[XFS_BTNUM_AGF];
185 /* # of levels in bno & cnt btree */ 185 /* # of levels in bno & cnt btree */
diff --git a/fs/xfs/xfs_alloc.c b/fs/xfs/xfs_alloc.c
index f4328e1e2a74..64ee07db0d5e 100644
--- a/fs/xfs/xfs_alloc.c
+++ b/fs/xfs/xfs_alloc.c
@@ -511,7 +511,7 @@ STATIC void
511xfs_alloc_trace_busy( 511xfs_alloc_trace_busy(
512 char *name, /* function tag string */ 512 char *name, /* function tag string */
513 char *str, /* additional string */ 513 char *str, /* additional string */
514 xfs_mount_t *mp, /* file system mount poing */ 514 xfs_mount_t *mp, /* file system mount point */
515 xfs_agnumber_t agno, /* allocation group number */ 515 xfs_agnumber_t agno, /* allocation group number */
516 xfs_agblock_t agbno, /* a.g. relative block number */ 516 xfs_agblock_t agbno, /* a.g. relative block number */
517 xfs_extlen_t len, /* length of extent */ 517 xfs_extlen_t len, /* length of extent */
@@ -1843,7 +1843,7 @@ xfs_alloc_fix_freelist(
1843 } else 1843 } else
1844 agbp = NULL; 1844 agbp = NULL;
1845 1845
1846 /* If this is a metadata prefered pag and we are user data 1846 /* If this is a metadata preferred pag and we are user data
1847 * then try somewhere else if we are not being asked to 1847 * then try somewhere else if we are not being asked to
1848 * try harder at this point 1848 * try harder at this point
1849 */ 1849 */
@@ -2458,7 +2458,7 @@ error0:
2458/* 2458/*
2459 * AG Busy list management 2459 * AG Busy list management
2460 * The busy list contains block ranges that have been freed but whose 2460 * The busy list contains block ranges that have been freed but whose
2461 * transacations have not yet hit disk. If any block listed in a busy 2461 * transactions have not yet hit disk. If any block listed in a busy
2462 * list is reused, the transaction that freed it must be forced to disk 2462 * list is reused, the transaction that freed it must be forced to disk
2463 * before continuing to use the block. 2463 * before continuing to use the block.
2464 * 2464 *
diff --git a/fs/xfs/xfs_alloc.h b/fs/xfs/xfs_alloc.h
index 3546dea27b7d..2d1f8928b267 100644
--- a/fs/xfs/xfs_alloc.h
+++ b/fs/xfs/xfs_alloc.h
@@ -68,7 +68,7 @@ typedef struct xfs_alloc_arg {
68 xfs_alloctype_t otype; /* original allocation type */ 68 xfs_alloctype_t otype; /* original allocation type */
69 char wasdel; /* set if allocation was prev delayed */ 69 char wasdel; /* set if allocation was prev delayed */
70 char wasfromfl; /* set if allocation is from freelist */ 70 char wasfromfl; /* set if allocation is from freelist */
71 char isfl; /* set if is freelist blocks - !actg */ 71 char isfl; /* set if is freelist blocks - !acctg */
72 char userdata; /* set if this is user data */ 72 char userdata; /* set if this is user data */
73} xfs_alloc_arg_t; 73} xfs_alloc_arg_t;
74 74
diff --git a/fs/xfs/xfs_attr.c b/fs/xfs/xfs_attr.c
index 093fac476bda..b6e1e02bbb28 100644
--- a/fs/xfs/xfs_attr.c
+++ b/fs/xfs/xfs_attr.c
@@ -294,7 +294,7 @@ xfs_attr_set_int(xfs_inode_t *dp, const char *name, int namelen,
294 xfs_trans_ihold(args.trans, dp); 294 xfs_trans_ihold(args.trans, dp);
295 295
296 /* 296 /*
297 * If the attribute list is non-existant or a shortform list, 297 * If the attribute list is non-existent or a shortform list,
298 * upgrade it to a single-leaf-block attribute list. 298 * upgrade it to a single-leaf-block attribute list.
299 */ 299 */
300 if ((dp->i_d.di_aformat == XFS_DINODE_FMT_LOCAL) || 300 if ((dp->i_d.di_aformat == XFS_DINODE_FMT_LOCAL) ||
@@ -1584,7 +1584,7 @@ out:
1584 * Fill in the disk block numbers in the state structure for the buffers 1584 * Fill in the disk block numbers in the state structure for the buffers
1585 * that are attached to the state structure. 1585 * that are attached to the state structure.
1586 * This is done so that we can quickly reattach ourselves to those buffers 1586 * This is done so that we can quickly reattach ourselves to those buffers
1587 * after some set of transaction commit's has released these buffers. 1587 * after some set of transaction commits have released these buffers.
1588 */ 1588 */
1589STATIC int 1589STATIC int
1590xfs_attr_fillstate(xfs_da_state_t *state) 1590xfs_attr_fillstate(xfs_da_state_t *state)
@@ -1631,7 +1631,7 @@ xfs_attr_fillstate(xfs_da_state_t *state)
1631/* 1631/*
1632 * Reattach the buffers to the state structure based on the disk block 1632 * Reattach the buffers to the state structure based on the disk block
1633 * numbers stored in the state structure. 1633 * numbers stored in the state structure.
1634 * This is done after some set of transaction commit's has released those 1634 * This is done after some set of transaction commits have released those
1635 * buffers from our grip. 1635 * buffers from our grip.
1636 */ 1636 */
1637STATIC int 1637STATIC int
diff --git a/fs/xfs/xfs_attr_leaf.c b/fs/xfs/xfs_attr_leaf.c
index 717682747bd2..9462be86aa14 100644
--- a/fs/xfs/xfs_attr_leaf.c
+++ b/fs/xfs/xfs_attr_leaf.c
@@ -524,7 +524,7 @@ xfs_attr_shortform_compare(const void *a, const void *b)
524 524
525/* 525/*
526 * Copy out entries of shortform attribute lists for attr_list(). 526 * Copy out entries of shortform attribute lists for attr_list().
527 * Shortform atrtribute lists are not stored in hashval sorted order. 527 * Shortform attribute lists are not stored in hashval sorted order.
528 * If the output buffer is not large enough to hold them all, then we 528 * If the output buffer is not large enough to hold them all, then we
529 * we have to calculate each entries' hashvalue and sort them before 529 * we have to calculate each entries' hashvalue and sort them before
530 * we can begin returning them to the user. 530 * we can begin returning them to the user.
@@ -1541,7 +1541,7 @@ xfs_attr_leaf_toosmall(xfs_da_state_t *state, int *action)
1541 /* 1541 /*
1542 * Check for the degenerate case of the block being empty. 1542 * Check for the degenerate case of the block being empty.
1543 * If the block is empty, we'll simply delete it, no need to 1543 * If the block is empty, we'll simply delete it, no need to
1544 * coalesce it with a sibling block. We choose (aribtrarily) 1544 * coalesce it with a sibling block. We choose (arbitrarily)
1545 * to merge with the forward block unless it is NULL. 1545 * to merge with the forward block unless it is NULL.
1546 */ 1546 */
1547 if (count == 0) { 1547 if (count == 0) {
diff --git a/fs/xfs/xfs_behavior.c b/fs/xfs/xfs_behavior.c
index 9880adae3938..f4fe3715a803 100644
--- a/fs/xfs/xfs_behavior.c
+++ b/fs/xfs/xfs_behavior.c
@@ -31,7 +31,7 @@
31 * The behavior chain is ordered based on the 'position' number which 31 * The behavior chain is ordered based on the 'position' number which
32 * lives in the first field of the ops vector (higher numbers first). 32 * lives in the first field of the ops vector (higher numbers first).
33 * 33 *
34 * Attemps to insert duplicate ops result in an EINVAL return code. 34 * Attempts to insert duplicate ops result in an EINVAL return code.
35 * Otherwise, return 0 to indicate success. 35 * Otherwise, return 0 to indicate success.
36 */ 36 */
37int 37int
@@ -84,7 +84,7 @@ bhv_insert(bhv_head_t *bhp, bhv_desc_t *bdp)
84 84
85/* 85/*
86 * Remove a behavior descriptor from a position in a behavior chain; 86 * Remove a behavior descriptor from a position in a behavior chain;
87 * the postition is guaranteed not to be the first position. 87 * the position is guaranteed not to be the first position.
88 * Should only be called by the bhv_remove() macro. 88 * Should only be called by the bhv_remove() macro.
89 */ 89 */
90void 90void
diff --git a/fs/xfs/xfs_behavior.h b/fs/xfs/xfs_behavior.h
index 2cd89bb5ab10..1d8ff103201c 100644
--- a/fs/xfs/xfs_behavior.h
+++ b/fs/xfs/xfs_behavior.h
@@ -39,7 +39,7 @@
39 * behaviors is synchronized with operations-in-progress (oip's) so that 39 * behaviors is synchronized with operations-in-progress (oip's) so that
40 * the oip's always see a consistent view of the chain. 40 * the oip's always see a consistent view of the chain.
41 * 41 *
42 * The term "interpostion" is used to refer to the act of inserting 42 * The term "interposition" is used to refer to the act of inserting
43 * a behavior such that it interposes on (i.e., is inserted in front 43 * a behavior such that it interposes on (i.e., is inserted in front
44 * of) a particular other behavior. A key example of this is when a 44 * of) a particular other behavior. A key example of this is when a
45 * system implementing distributed single system image wishes to 45 * system implementing distributed single system image wishes to
@@ -51,7 +51,7 @@
51 * 51 *
52 * Behavior synchronization is logic which is necessary under certain 52 * Behavior synchronization is logic which is necessary under certain
53 * circumstances that there is no conflict between ongoing operations 53 * circumstances that there is no conflict between ongoing operations
54 * traversing the behavior chain and those dunamically modifying the 54 * traversing the behavior chain and those dynamically modifying the
55 * behavior chain. Because behavior synchronization adds extra overhead 55 * behavior chain. Because behavior synchronization adds extra overhead
56 * to virtual operation invocation, we want to restrict, as much as 56 * to virtual operation invocation, we want to restrict, as much as
57 * we can, the requirement for this extra code, to those situations 57 * we can, the requirement for this extra code, to those situations
diff --git a/fs/xfs/xfs_bmap.c b/fs/xfs/xfs_bmap.c
index 2d702e4a74a3..d384e489705f 100644
--- a/fs/xfs/xfs_bmap.c
+++ b/fs/xfs/xfs_bmap.c
@@ -3467,113 +3467,6 @@ done:
3467 return error; 3467 return error;
3468} 3468}
3469 3469
3470xfs_bmbt_rec_t * /* pointer to found extent entry */
3471xfs_bmap_do_search_extents(
3472 xfs_bmbt_rec_t *base, /* base of extent list */
3473 xfs_extnum_t lastx, /* last extent index used */
3474 xfs_extnum_t nextents, /* number of file extents */
3475 xfs_fileoff_t bno, /* block number searched for */
3476 int *eofp, /* out: end of file found */
3477 xfs_extnum_t *lastxp, /* out: last extent index */
3478 xfs_bmbt_irec_t *gotp, /* out: extent entry found */
3479 xfs_bmbt_irec_t *prevp) /* out: previous extent entry found */
3480{
3481 xfs_bmbt_rec_t *ep; /* extent list entry pointer */
3482 xfs_bmbt_irec_t got; /* extent list entry, decoded */
3483 int high; /* high index of binary search */
3484 int low; /* low index of binary search */
3485
3486 /*
3487 * Initialize the extent entry structure to catch access to
3488 * uninitialized br_startblock field.
3489 */
3490 got.br_startoff = 0xffa5a5a5a5a5a5a5LL;
3491 got.br_blockcount = 0xa55a5a5a5a5a5a5aLL;
3492 got.br_state = XFS_EXT_INVALID;
3493
3494#if XFS_BIG_BLKNOS
3495 got.br_startblock = 0xffffa5a5a5a5a5a5LL;
3496#else
3497 got.br_startblock = 0xffffa5a5;
3498#endif
3499
3500 if (lastx != NULLEXTNUM && lastx < nextents)
3501 ep = base + lastx;
3502 else
3503 ep = NULL;
3504 prevp->br_startoff = NULLFILEOFF;
3505 if (ep && bno >= (got.br_startoff = xfs_bmbt_get_startoff(ep)) &&
3506 bno < got.br_startoff +
3507 (got.br_blockcount = xfs_bmbt_get_blockcount(ep)))
3508 *eofp = 0;
3509 else if (ep && lastx < nextents - 1 &&
3510 bno >= (got.br_startoff = xfs_bmbt_get_startoff(ep + 1)) &&
3511 bno < got.br_startoff +
3512 (got.br_blockcount = xfs_bmbt_get_blockcount(ep + 1))) {
3513 lastx++;
3514 ep++;
3515 *eofp = 0;
3516 } else if (nextents == 0)
3517 *eofp = 1;
3518 else if (bno == 0 &&
3519 (got.br_startoff = xfs_bmbt_get_startoff(base)) == 0) {
3520 ep = base;
3521 lastx = 0;
3522 got.br_blockcount = xfs_bmbt_get_blockcount(ep);
3523 *eofp = 0;
3524 } else {
3525 low = 0;
3526 high = nextents - 1;
3527 /* binary search the extents array */
3528 while (low <= high) {
3529 XFS_STATS_INC(xs_cmp_exlist);
3530 lastx = (low + high) >> 1;
3531 ep = base + lastx;
3532 got.br_startoff = xfs_bmbt_get_startoff(ep);
3533 got.br_blockcount = xfs_bmbt_get_blockcount(ep);
3534 if (bno < got.br_startoff)
3535 high = lastx - 1;
3536 else if (bno >= got.br_startoff + got.br_blockcount)
3537 low = lastx + 1;
3538 else {
3539 got.br_startblock = xfs_bmbt_get_startblock(ep);
3540 got.br_state = xfs_bmbt_get_state(ep);
3541 *eofp = 0;
3542 *lastxp = lastx;
3543 *gotp = got;
3544 return ep;
3545 }
3546 }
3547 if (bno >= got.br_startoff + got.br_blockcount) {
3548 lastx++;
3549 if (lastx == nextents) {
3550 *eofp = 1;
3551 got.br_startblock = xfs_bmbt_get_startblock(ep);
3552 got.br_state = xfs_bmbt_get_state(ep);
3553 *prevp = got;
3554 ep = NULL;
3555 } else {
3556 *eofp = 0;
3557 xfs_bmbt_get_all(ep, prevp);
3558 ep++;
3559 got.br_startoff = xfs_bmbt_get_startoff(ep);
3560 got.br_blockcount = xfs_bmbt_get_blockcount(ep);
3561 }
3562 } else {
3563 *eofp = 0;
3564 if (ep > base)
3565 xfs_bmbt_get_all(ep - 1, prevp);
3566 }
3567 }
3568 if (ep) {
3569 got.br_startblock = xfs_bmbt_get_startblock(ep);
3570 got.br_state = xfs_bmbt_get_state(ep);
3571 }
3572 *lastxp = lastx;
3573 *gotp = got;
3574 return ep;
3575}
3576
3577/* 3470/*
3578 * Search the extent records for the entry containing block bno. 3471 * Search the extent records for the entry containing block bno.
3579 * If bno lies in a hole, point to the next entry. If bno lies 3472 * If bno lies in a hole, point to the next entry. If bno lies
diff --git a/fs/xfs/xfs_bmap.h b/fs/xfs/xfs_bmap.h
index 011ccaa9a1c0..f83399c89ce3 100644
--- a/fs/xfs/xfs_bmap.h
+++ b/fs/xfs/xfs_bmap.h
@@ -362,14 +362,6 @@ xfs_bmbt_rec_t *
362xfs_bmap_search_multi_extents(struct xfs_ifork *, xfs_fileoff_t, int *, 362xfs_bmap_search_multi_extents(struct xfs_ifork *, xfs_fileoff_t, int *,
363 xfs_extnum_t *, xfs_bmbt_irec_t *, xfs_bmbt_irec_t *); 363 xfs_extnum_t *, xfs_bmbt_irec_t *, xfs_bmbt_irec_t *);
364 364
365/*
366 * Search an extent list for the extent which includes block
367 * bno.
368 */
369xfs_bmbt_rec_t *xfs_bmap_do_search_extents(xfs_bmbt_rec_t *,
370 xfs_extnum_t, xfs_extnum_t, xfs_fileoff_t, int *,
371 xfs_extnum_t *, xfs_bmbt_irec_t *, xfs_bmbt_irec_t *);
372
373#endif /* __KERNEL__ */ 365#endif /* __KERNEL__ */
374 366
375#endif /* __XFS_BMAP_H__ */ 367#endif /* __XFS_BMAP_H__ */
diff --git a/fs/xfs/xfs_buf_item.c b/fs/xfs/xfs_buf_item.c
index 07e2324152b1..5fed15682dda 100644
--- a/fs/xfs/xfs_buf_item.c
+++ b/fs/xfs/xfs_buf_item.c
@@ -98,12 +98,12 @@ xfs_buf_item_flush_log_debug(
98} 98}
99 99
100/* 100/*
101 * This function is called to verify that our caller's have logged 101 * This function is called to verify that our callers have logged
102 * all the bytes that they changed. 102 * all the bytes that they changed.
103 * 103 *
104 * It does this by comparing the original copy of the buffer stored in 104 * It does this by comparing the original copy of the buffer stored in
105 * the buf log item's bli_orig array to the current copy of the buffer 105 * the buf log item's bli_orig array to the current copy of the buffer
106 * and ensuring that all bytes which miscompare are set in the bli_logged 106 * and ensuring that all bytes which mismatch are set in the bli_logged
107 * array of the buf log item. 107 * array of the buf log item.
108 */ 108 */
109STATIC void 109STATIC void
diff --git a/fs/xfs/xfs_cap.h b/fs/xfs/xfs_cap.h
index 433ec537f9bd..d0035c6e9514 100644
--- a/fs/xfs/xfs_cap.h
+++ b/fs/xfs/xfs_cap.h
@@ -38,7 +38,7 @@ typedef struct xfs_cap_set {
38/* 38/*
39 * For Linux, we take the bitfields directly from capability.h 39 * For Linux, we take the bitfields directly from capability.h
40 * and no longer attempt to keep this attribute ondisk compatible 40 * and no longer attempt to keep this attribute ondisk compatible
41 * with IRIX. Since this attribute is only set on exectuables, 41 * with IRIX. Since this attribute is only set on executables,
42 * it just doesn't make much sense to try. We do use a different 42 * it just doesn't make much sense to try. We do use a different
43 * named attribute though, to avoid confusion. 43 * named attribute though, to avoid confusion.
44 */ 44 */
diff --git a/fs/xfs/xfs_da_btree.c b/fs/xfs/xfs_da_btree.c
index 4bae3a76c678..8988b9051175 100644
--- a/fs/xfs/xfs_da_btree.c
+++ b/fs/xfs/xfs_da_btree.c
@@ -840,7 +840,7 @@ xfs_da_node_toosmall(xfs_da_state_t *state, int *action)
840 /* 840 /*
841 * Check for the degenerate case of the block being empty. 841 * Check for the degenerate case of the block being empty.
842 * If the block is empty, we'll simply delete it, no need to 842 * If the block is empty, we'll simply delete it, no need to
843 * coalesce it with a sibling block. We choose (aribtrarily) 843 * coalesce it with a sibling block. We choose (arbitrarily)
844 * to merge with the forward block unless it is NULL. 844 * to merge with the forward block unless it is NULL.
845 */ 845 */
846 if (count == 0) { 846 if (count == 0) {
diff --git a/fs/xfs/xfs_dir2_block.c b/fs/xfs/xfs_dir2_block.c
index bd5cee6aa51a..972ded595476 100644
--- a/fs/xfs/xfs_dir2_block.c
+++ b/fs/xfs/xfs_dir2_block.c
@@ -533,7 +533,7 @@ xfs_dir2_block_getdents(
533 533
534 /* 534 /*
535 * Reached the end of the block. 535 * Reached the end of the block.
536 * Set the offset to a nonexistent block 1 and return. 536 * Set the offset to a non-existent block 1 and return.
537 */ 537 */
538 *eofp = 1; 538 *eofp = 1;
539 539
diff --git a/fs/xfs/xfs_dir2_leaf.c b/fs/xfs/xfs_dir2_leaf.c
index 08648b18265c..0f5e2f2ce6ec 100644
--- a/fs/xfs/xfs_dir2_leaf.c
+++ b/fs/xfs/xfs_dir2_leaf.c
@@ -515,7 +515,7 @@ xfs_dir2_leaf_addname(
515 ASSERT(be32_to_cpu(leaf->ents[highstale].address) == 515 ASSERT(be32_to_cpu(leaf->ents[highstale].address) ==
516 XFS_DIR2_NULL_DATAPTR); 516 XFS_DIR2_NULL_DATAPTR);
517 /* 517 /*
518 * Copy entries down to copver the stale entry 518 * Copy entries down to cover the stale entry
519 * and make room for the new entry. 519 * and make room for the new entry.
520 */ 520 */
521 if (highstale - index > 0) 521 if (highstale - index > 0)
diff --git a/fs/xfs/xfs_dir2_node.c b/fs/xfs/xfs_dir2_node.c
index af556f16a0c7..ac511ab9c52d 100644
--- a/fs/xfs/xfs_dir2_node.c
+++ b/fs/xfs/xfs_dir2_node.c
@@ -830,7 +830,7 @@ xfs_dir2_leafn_rebalance(
830 state->inleaf = 1; 830 state->inleaf = 1;
831 blk2->index = 0; 831 blk2->index = 0;
832 cmn_err(CE_ALERT, 832 cmn_err(CE_ALERT,
833 "xfs_dir2_leafn_rebalance: picked the wrong leaf? reverting orignal leaf: " 833 "xfs_dir2_leafn_rebalance: picked the wrong leaf? reverting original leaf: "
834 "blk1->index %d\n", 834 "blk1->index %d\n",
835 blk1->index); 835 blk1->index);
836 } 836 }
diff --git a/fs/xfs/xfs_dir_leaf.c b/fs/xfs/xfs_dir_leaf.c
index ee88751c3be6..6d711869262f 100644
--- a/fs/xfs/xfs_dir_leaf.c
+++ b/fs/xfs/xfs_dir_leaf.c
@@ -1341,7 +1341,7 @@ xfs_dir_leaf_toosmall(xfs_da_state_t *state, int *action)
1341 /* 1341 /*
1342 * Check for the degenerate case of the block being empty. 1342 * Check for the degenerate case of the block being empty.
1343 * If the block is empty, we'll simply delete it, no need to 1343 * If the block is empty, we'll simply delete it, no need to
1344 * coalesce it with a sibling block. We choose (aribtrarily) 1344 * coalesce it with a sibling block. We choose (arbitrarily)
1345 * to merge with the forward block unless it is NULL. 1345 * to merge with the forward block unless it is NULL.
1346 */ 1346 */
1347 if (count == 0) { 1347 if (count == 0) {
diff --git a/fs/xfs/xfs_fsops.c b/fs/xfs/xfs_fsops.c
index 56caa88713ab..dfa3527b20a7 100644
--- a/fs/xfs/xfs_fsops.c
+++ b/fs/xfs/xfs_fsops.c
@@ -477,7 +477,7 @@ xfs_fs_counts(
477 * 477 *
478 * xfs_reserve_blocks is called to set m_resblks 478 * xfs_reserve_blocks is called to set m_resblks
479 * in the in-core mount table. The number of unused reserved blocks 479 * in the in-core mount table. The number of unused reserved blocks
480 * is kept in m_resbls_avail. 480 * is kept in m_resblks_avail.
481 * 481 *
482 * Reserve the requested number of blocks if available. Otherwise return 482 * Reserve the requested number of blocks if available. Otherwise return
483 * as many as possible to satisfy the request. The actual number 483 * as many as possible to satisfy the request. The actual number
diff --git a/fs/xfs/xfs_ialloc.c b/fs/xfs/xfs_ialloc.c
index 0024892841a3..4eeb856183b1 100644
--- a/fs/xfs/xfs_ialloc.c
+++ b/fs/xfs/xfs_ialloc.c
@@ -136,7 +136,7 @@ xfs_ialloc_ag_alloc(
136 int ninodes; /* num inodes per buf */ 136 int ninodes; /* num inodes per buf */
137 xfs_agino_t thisino; /* current inode number, for loop */ 137 xfs_agino_t thisino; /* current inode number, for loop */
138 int version; /* inode version number to use */ 138 int version; /* inode version number to use */
139 int isaligned; /* inode allocation at stripe unit */ 139 int isaligned = 0; /* inode allocation at stripe unit */
140 /* boundary */ 140 /* boundary */
141 141
142 args.tp = tp; 142 args.tp = tp;
@@ -152,47 +152,75 @@ xfs_ialloc_ag_alloc(
152 return XFS_ERROR(ENOSPC); 152 return XFS_ERROR(ENOSPC);
153 args.minlen = args.maxlen = XFS_IALLOC_BLOCKS(args.mp); 153 args.minlen = args.maxlen = XFS_IALLOC_BLOCKS(args.mp);
154 /* 154 /*
155 * Set the alignment for the allocation. 155 * First try to allocate inodes contiguous with the last-allocated
156 * If stripe alignment is turned on then align at stripe unit 156 * chunk of inodes. If the filesystem is striped, this will fill
157 * boundary. 157 * an entire stripe unit with inodes.
158 * If the cluster size is smaller than a filesystem block 158 */
159 * then we're doing I/O for inodes in filesystem block size pieces,
160 * so don't need alignment anyway.
161 */
162 isaligned = 0;
163 if (args.mp->m_sinoalign) {
164 ASSERT(!(args.mp->m_flags & XFS_MOUNT_NOALIGN));
165 args.alignment = args.mp->m_dalign;
166 isaligned = 1;
167 } else if (XFS_SB_VERSION_HASALIGN(&args.mp->m_sb) &&
168 args.mp->m_sb.sb_inoalignmt >=
169 XFS_B_TO_FSBT(args.mp, XFS_INODE_CLUSTER_SIZE(args.mp)))
170 args.alignment = args.mp->m_sb.sb_inoalignmt;
171 else
172 args.alignment = 1;
173 agi = XFS_BUF_TO_AGI(agbp); 159 agi = XFS_BUF_TO_AGI(agbp);
174 /* 160 newino = be32_to_cpu(agi->agi_newino);
175 * Need to figure out where to allocate the inode blocks. 161 if(likely(newino != NULLAGINO)) {
176 * Ideally they should be spaced out through the a.g. 162 args.agbno = XFS_AGINO_TO_AGBNO(args.mp, newino) +
177 * For now, just allocate blocks up front. 163 XFS_IALLOC_BLOCKS(args.mp);
178 */ 164 args.fsbno = XFS_AGB_TO_FSB(args.mp,
179 args.agbno = be32_to_cpu(agi->agi_root); 165 be32_to_cpu(agi->agi_seqno), args.agbno);
180 args.fsbno = XFS_AGB_TO_FSB(args.mp, be32_to_cpu(agi->agi_seqno), 166 args.type = XFS_ALLOCTYPE_THIS_BNO;
181 args.agbno); 167 args.mod = args.total = args.wasdel = args.isfl =
182 /* 168 args.userdata = args.minalignslop = 0;
183 * Allocate a fixed-size extent of inodes. 169 args.prod = 1;
184 */ 170 args.alignment = 1;
185 args.type = XFS_ALLOCTYPE_NEAR_BNO; 171 /*
186 args.mod = args.total = args.wasdel = args.isfl = args.userdata = 172 * Allow space for the inode btree to split.
187 args.minalignslop = 0; 173 */
188 args.prod = 1; 174 args.minleft = XFS_IN_MAXLEVELS(args.mp) - 1;
189 /* 175 if ((error = xfs_alloc_vextent(&args)))
190 * Allow space for the inode btree to split. 176 return error;
191 */ 177 } else
192 args.minleft = XFS_IN_MAXLEVELS(args.mp) - 1; 178 args.fsbno = NULLFSBLOCK;
193 if ((error = xfs_alloc_vextent(&args)))
194 return error;
195 179
180 if (unlikely(args.fsbno == NULLFSBLOCK)) {
181 /*
182 * Set the alignment for the allocation.
183 * If stripe alignment is turned on then align at stripe unit
184 * boundary.
185 * If the cluster size is smaller than a filesystem block
186 * then we're doing I/O for inodes in filesystem block size
187 * pieces, so don't need alignment anyway.
188 */
189 isaligned = 0;
190 if (args.mp->m_sinoalign) {
191 ASSERT(!(args.mp->m_flags & XFS_MOUNT_NOALIGN));
192 args.alignment = args.mp->m_dalign;
193 isaligned = 1;
194 } else if (XFS_SB_VERSION_HASALIGN(&args.mp->m_sb) &&
195 args.mp->m_sb.sb_inoalignmt >=
196 XFS_B_TO_FSBT(args.mp,
197 XFS_INODE_CLUSTER_SIZE(args.mp)))
198 args.alignment = args.mp->m_sb.sb_inoalignmt;
199 else
200 args.alignment = 1;
201 /*
202 * Need to figure out where to allocate the inode blocks.
203 * Ideally they should be spaced out through the a.g.
204 * For now, just allocate blocks up front.
205 */
206 args.agbno = be32_to_cpu(agi->agi_root);
207 args.fsbno = XFS_AGB_TO_FSB(args.mp,
208 be32_to_cpu(agi->agi_seqno), args.agbno);
209 /*
210 * Allocate a fixed-size extent of inodes.
211 */
212 args.type = XFS_ALLOCTYPE_NEAR_BNO;
213 args.mod = args.total = args.wasdel = args.isfl =
214 args.userdata = args.minalignslop = 0;
215 args.prod = 1;
216 /*
217 * Allow space for the inode btree to split.
218 */
219 args.minleft = XFS_IN_MAXLEVELS(args.mp) - 1;
220 if ((error = xfs_alloc_vextent(&args)))
221 return error;
222 }
223
196 /* 224 /*
197 * If stripe alignment is turned on, then try again with cluster 225 * If stripe alignment is turned on, then try again with cluster
198 * alignment. 226 * alignment.
@@ -1023,7 +1051,7 @@ xfs_difree(
1023 rec.ir_freecount++; 1051 rec.ir_freecount++;
1024 1052
1025 /* 1053 /*
1026 * When an inode cluster is free, it becomes elgible for removal 1054 * When an inode cluster is free, it becomes eligible for removal
1027 */ 1055 */
1028 if ((mp->m_flags & XFS_MOUNT_IDELETE) && 1056 if ((mp->m_flags & XFS_MOUNT_IDELETE) &&
1029 (rec.ir_freecount == XFS_IALLOC_INODES(mp))) { 1057 (rec.ir_freecount == XFS_IALLOC_INODES(mp))) {
diff --git a/fs/xfs/xfs_iget.c b/fs/xfs/xfs_iget.c
index 3ce35a6f700b..bb33113eef9f 100644
--- a/fs/xfs/xfs_iget.c
+++ b/fs/xfs/xfs_iget.c
@@ -509,7 +509,7 @@ retry:
509 } else { 509 } else {
510 /* 510 /*
511 * If the inode is not fully constructed due to 511 * If the inode is not fully constructed due to
512 * filehandle mistmatches wait for the inode to go 512 * filehandle mismatches wait for the inode to go
513 * away and try again. 513 * away and try again.
514 * 514 *
515 * iget_locked will call __wait_on_freeing_inode 515 * iget_locked will call __wait_on_freeing_inode
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c
index 88a517fad07b..48146bdc6bdd 100644
--- a/fs/xfs/xfs_inode.c
+++ b/fs/xfs/xfs_inode.c
@@ -160,7 +160,7 @@ xfs_inotobp(
160 xfs_dinode_t *dip; 160 xfs_dinode_t *dip;
161 161
162 /* 162 /*
163 * Call the space managment code to find the location of the 163 * Call the space management code to find the location of the
164 * inode on disk. 164 * inode on disk.
165 */ 165 */
166 imap.im_blkno = 0; 166 imap.im_blkno = 0;
@@ -837,7 +837,7 @@ xfs_dic2xflags(
837 837
838/* 838/*
839 * Given a mount structure and an inode number, return a pointer 839 * Given a mount structure and an inode number, return a pointer
840 * to a newly allocated in-core inode coresponding to the given 840 * to a newly allocated in-core inode corresponding to the given
841 * inode number. 841 * inode number.
842 * 842 *
843 * Initialize the inode's attributes and extent pointers if it 843 * Initialize the inode's attributes and extent pointers if it
@@ -2723,7 +2723,7 @@ xfs_ipin(
2723/* 2723/*
2724 * Decrement the pin count of the given inode, and wake up 2724 * Decrement the pin count of the given inode, and wake up
2725 * anyone in xfs_iwait_unpin() if the count goes to 0. The 2725 * anyone in xfs_iwait_unpin() if the count goes to 0. The
2726 * inode must have been previoulsy pinned with a call to xfs_ipin(). 2726 * inode must have been previously pinned with a call to xfs_ipin().
2727 */ 2727 */
2728void 2728void
2729xfs_iunpin( 2729xfs_iunpin(
@@ -3690,7 +3690,7 @@ void
3690xfs_iext_add( 3690xfs_iext_add(
3691 xfs_ifork_t *ifp, /* inode fork pointer */ 3691 xfs_ifork_t *ifp, /* inode fork pointer */
3692 xfs_extnum_t idx, /* index to begin adding exts */ 3692 xfs_extnum_t idx, /* index to begin adding exts */
3693 int ext_diff) /* nubmer of extents to add */ 3693 int ext_diff) /* number of extents to add */
3694{ 3694{
3695 int byte_diff; /* new bytes being added */ 3695 int byte_diff; /* new bytes being added */
3696 int new_size; /* size of extents after adding */ 3696 int new_size; /* size of extents after adding */
@@ -4038,7 +4038,7 @@ xfs_iext_remove_indirect(
4038 xfs_extnum_t ext_diff; /* extents to remove in current list */ 4038 xfs_extnum_t ext_diff; /* extents to remove in current list */
4039 xfs_extnum_t nex1; /* number of extents before idx */ 4039 xfs_extnum_t nex1; /* number of extents before idx */
4040 xfs_extnum_t nex2; /* extents after idx + count */ 4040 xfs_extnum_t nex2; /* extents after idx + count */
4041 int nlists; /* entries in indirecton array */ 4041 int nlists; /* entries in indirection array */
4042 int page_idx = idx; /* index in target extent list */ 4042 int page_idx = idx; /* index in target extent list */
4043 4043
4044 ASSERT(ifp->if_flags & XFS_IFEXTIREC); 4044 ASSERT(ifp->if_flags & XFS_IFEXTIREC);
@@ -4291,9 +4291,9 @@ xfs_iext_bno_to_ext(
4291 xfs_filblks_t blockcount = 0; /* number of blocks in extent */ 4291 xfs_filblks_t blockcount = 0; /* number of blocks in extent */
4292 xfs_bmbt_rec_t *ep = NULL; /* pointer to target extent */ 4292 xfs_bmbt_rec_t *ep = NULL; /* pointer to target extent */
4293 xfs_ext_irec_t *erp = NULL; /* indirection array pointer */ 4293 xfs_ext_irec_t *erp = NULL; /* indirection array pointer */
4294 int high; /* upper boundry in search */ 4294 int high; /* upper boundary in search */
4295 xfs_extnum_t idx = 0; /* index of target extent */ 4295 xfs_extnum_t idx = 0; /* index of target extent */
4296 int low; /* lower boundry in search */ 4296 int low; /* lower boundary in search */
4297 xfs_extnum_t nextents; /* number of file extents */ 4297 xfs_extnum_t nextents; /* number of file extents */
4298 xfs_fileoff_t startoff = 0; /* start offset of extent */ 4298 xfs_fileoff_t startoff = 0; /* start offset of extent */
4299 4299
diff --git a/fs/xfs/xfs_inode_item.c b/fs/xfs/xfs_inode_item.c
index 36aa1fcb90a5..7497a481b2f5 100644
--- a/fs/xfs/xfs_inode_item.c
+++ b/fs/xfs/xfs_inode_item.c
@@ -580,7 +580,7 @@ xfs_inode_item_unpin_remove(
580 * been or is in the process of being flushed, then (ideally) we'd like to 580 * been or is in the process of being flushed, then (ideally) we'd like to
581 * see if the inode's buffer is still incore, and if so give it a nudge. 581 * see if the inode's buffer is still incore, and if so give it a nudge.
582 * We delay doing so until the pushbuf routine, though, to avoid holding 582 * We delay doing so until the pushbuf routine, though, to avoid holding
583 * the AIL lock across a call to the blackhole which is the buffercache. 583 * the AIL lock across a call to the blackhole which is the buffer cache.
584 * Also we don't want to sleep in any device strategy routines, which can happen 584 * Also we don't want to sleep in any device strategy routines, which can happen
585 * if we do the subsequent bawrite in here. 585 * if we do the subsequent bawrite in here.
586 */ 586 */
diff --git a/fs/xfs/xfs_itable.c b/fs/xfs/xfs_itable.c
index 32247b6bfee7..94068d014f27 100644
--- a/fs/xfs/xfs_itable.c
+++ b/fs/xfs/xfs_itable.c
@@ -272,7 +272,7 @@ xfs_bulkstat(
272 size_t statstruct_size, /* sizeof struct filling */ 272 size_t statstruct_size, /* sizeof struct filling */
273 char __user *ubuffer, /* buffer with inode stats */ 273 char __user *ubuffer, /* buffer with inode stats */
274 int flags, /* defined in xfs_itable.h */ 274 int flags, /* defined in xfs_itable.h */
275 int *done) /* 1 if there're more stats to get */ 275 int *done) /* 1 if there are more stats to get */
276{ 276{
277 xfs_agblock_t agbno=0;/* allocation group block number */ 277 xfs_agblock_t agbno=0;/* allocation group block number */
278 xfs_buf_t *agbp; /* agi header buffer */ 278 xfs_buf_t *agbp; /* agi header buffer */
@@ -676,7 +676,7 @@ xfs_bulkstat_single(
676 xfs_mount_t *mp, /* mount point for filesystem */ 676 xfs_mount_t *mp, /* mount point for filesystem */
677 xfs_ino_t *lastinop, /* inode to return */ 677 xfs_ino_t *lastinop, /* inode to return */
678 char __user *buffer, /* buffer with inode stats */ 678 char __user *buffer, /* buffer with inode stats */
679 int *done) /* 1 if there're more stats to get */ 679 int *done) /* 1 if there are more stats to get */
680{ 680{
681 int count; /* count value for bulkstat call */ 681 int count; /* count value for bulkstat call */
682 int error; /* return value */ 682 int error; /* return value */
diff --git a/fs/xfs/xfs_itable.h b/fs/xfs/xfs_itable.h
index 047d834ed210..11eb4e1b18c4 100644
--- a/fs/xfs/xfs_itable.h
+++ b/fs/xfs/xfs_itable.h
@@ -60,7 +60,7 @@ xfs_bulkstat(
60 size_t statstruct_size,/* sizeof struct that we're filling */ 60 size_t statstruct_size,/* sizeof struct that we're filling */
61 char __user *ubuffer,/* buffer with inode stats */ 61 char __user *ubuffer,/* buffer with inode stats */
62 int flags, /* flag to control access method */ 62 int flags, /* flag to control access method */
63 int *done); /* 1 if there're more stats to get */ 63 int *done); /* 1 if there are more stats to get */
64 64
65int 65int
66xfs_bulkstat_single( 66xfs_bulkstat_single(
diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c
index 9176995160ed..32e841d2f26d 100644
--- a/fs/xfs/xfs_log.c
+++ b/fs/xfs/xfs_log.c
@@ -59,7 +59,7 @@ STATIC xlog_t * xlog_alloc_log(xfs_mount_t *mp,
59 int num_bblks); 59 int num_bblks);
60STATIC int xlog_space_left(xlog_t *log, int cycle, int bytes); 60STATIC int xlog_space_left(xlog_t *log, int cycle, int bytes);
61STATIC int xlog_sync(xlog_t *log, xlog_in_core_t *iclog); 61STATIC int xlog_sync(xlog_t *log, xlog_in_core_t *iclog);
62STATIC void xlog_unalloc_log(xlog_t *log); 62STATIC void xlog_dealloc_log(xlog_t *log);
63STATIC int xlog_write(xfs_mount_t *mp, xfs_log_iovec_t region[], 63STATIC int xlog_write(xfs_mount_t *mp, xfs_log_iovec_t region[],
64 int nentries, xfs_log_ticket_t tic, 64 int nentries, xfs_log_ticket_t tic,
65 xfs_lsn_t *start_lsn, 65 xfs_lsn_t *start_lsn,
@@ -304,7 +304,7 @@ xfs_log_done(xfs_mount_t *mp,
304 if ((ticket->t_flags & XLOG_TIC_PERM_RESERV) == 0 || 304 if ((ticket->t_flags & XLOG_TIC_PERM_RESERV) == 0 ||
305 (flags & XFS_LOG_REL_PERM_RESERV)) { 305 (flags & XFS_LOG_REL_PERM_RESERV)) {
306 /* 306 /*
307 * Release ticket if not permanent reservation or a specifc 307 * Release ticket if not permanent reservation or a specific
308 * request has been made to release a permanent reservation. 308 * request has been made to release a permanent reservation.
309 */ 309 */
310 xlog_trace_loggrant(log, ticket, "xfs_log_done: (non-permanent)"); 310 xlog_trace_loggrant(log, ticket, "xfs_log_done: (non-permanent)");
@@ -511,7 +511,7 @@ xfs_log_mount(xfs_mount_t *mp,
511 vfsp->vfs_flag |= VFS_RDONLY; 511 vfsp->vfs_flag |= VFS_RDONLY;
512 if (error) { 512 if (error) {
513 cmn_err(CE_WARN, "XFS: log mount/recovery failed: error %d", error); 513 cmn_err(CE_WARN, "XFS: log mount/recovery failed: error %d", error);
514 xlog_unalloc_log(mp->m_log); 514 xlog_dealloc_log(mp->m_log);
515 return error; 515 return error;
516 } 516 }
517 } 517 }
@@ -667,7 +667,7 @@ xfs_log_unmount_write(xfs_mount_t *mp)
667 * 667 *
668 * Go through the motions of sync'ing and releasing 668 * Go through the motions of sync'ing and releasing
669 * the iclog, even though no I/O will actually happen, 669 * the iclog, even though no I/O will actually happen,
670 * we need to wait for other log I/O's that may already 670 * we need to wait for other log I/Os that may already
671 * be in progress. Do this as a separate section of 671 * be in progress. Do this as a separate section of
672 * code so we'll know if we ever get stuck here that 672 * code so we'll know if we ever get stuck here that
673 * we're in this odd situation of trying to unmount 673 * we're in this odd situation of trying to unmount
@@ -704,7 +704,7 @@ xfs_log_unmount_write(xfs_mount_t *mp)
704void 704void
705xfs_log_unmount_dealloc(xfs_mount_t *mp) 705xfs_log_unmount_dealloc(xfs_mount_t *mp)
706{ 706{
707 xlog_unalloc_log(mp->m_log); 707 xlog_dealloc_log(mp->m_log);
708} 708}
709 709
710/* 710/*
@@ -1492,7 +1492,7 @@ xlog_sync(xlog_t *log,
1492 ASSERT(XFS_BUF_ADDR(bp) <= log->l_logBBsize-1); 1492 ASSERT(XFS_BUF_ADDR(bp) <= log->l_logBBsize-1);
1493 ASSERT(XFS_BUF_ADDR(bp) + BTOBB(count) <= log->l_logBBsize); 1493 ASSERT(XFS_BUF_ADDR(bp) + BTOBB(count) <= log->l_logBBsize);
1494 1494
1495 /* account for internal log which does't start at block #0 */ 1495 /* account for internal log which doesn't start at block #0 */
1496 XFS_BUF_SET_ADDR(bp, XFS_BUF_ADDR(bp) + log->l_logBBstart); 1496 XFS_BUF_SET_ADDR(bp, XFS_BUF_ADDR(bp) + log->l_logBBstart);
1497 XFS_BUF_WRITE(bp); 1497 XFS_BUF_WRITE(bp);
1498 if ((error = XFS_bwrite(bp))) { 1498 if ((error = XFS_bwrite(bp))) {
@@ -1506,10 +1506,10 @@ xlog_sync(xlog_t *log,
1506 1506
1507 1507
1508/* 1508/*
1509 * Unallocate a log structure 1509 * Deallocate a log structure
1510 */ 1510 */
1511void 1511void
1512xlog_unalloc_log(xlog_t *log) 1512xlog_dealloc_log(xlog_t *log)
1513{ 1513{
1514 xlog_in_core_t *iclog, *next_iclog; 1514 xlog_in_core_t *iclog, *next_iclog;
1515 xlog_ticket_t *tic, *next_tic; 1515 xlog_ticket_t *tic, *next_tic;
@@ -1539,7 +1539,7 @@ xlog_unalloc_log(xlog_t *log)
1539 if ((log->l_ticket_cnt != log->l_ticket_tcnt) && 1539 if ((log->l_ticket_cnt != log->l_ticket_tcnt) &&
1540 !XLOG_FORCED_SHUTDOWN(log)) { 1540 !XLOG_FORCED_SHUTDOWN(log)) {
1541 xfs_fs_cmn_err(CE_WARN, log->l_mp, 1541 xfs_fs_cmn_err(CE_WARN, log->l_mp,
1542 "xlog_unalloc_log: (cnt: %d, total: %d)", 1542 "xlog_dealloc_log: (cnt: %d, total: %d)",
1543 log->l_ticket_cnt, log->l_ticket_tcnt); 1543 log->l_ticket_cnt, log->l_ticket_tcnt);
1544 /* ASSERT(log->l_ticket_cnt == log->l_ticket_tcnt); */ 1544 /* ASSERT(log->l_ticket_cnt == log->l_ticket_tcnt); */
1545 1545
@@ -1562,7 +1562,7 @@ xlog_unalloc_log(xlog_t *log)
1562#endif 1562#endif
1563 log->l_mp->m_log = NULL; 1563 log->l_mp->m_log = NULL;
1564 kmem_free(log, sizeof(xlog_t)); 1564 kmem_free(log, sizeof(xlog_t));
1565} /* xlog_unalloc_log */ 1565} /* xlog_dealloc_log */
1566 1566
1567/* 1567/*
1568 * Update counters atomically now that memcpy is done. 1568 * Update counters atomically now that memcpy is done.
@@ -2829,7 +2829,7 @@ xlog_state_release_iclog(xlog_t *log,
2829 2829
2830 /* 2830 /*
2831 * We let the log lock go, so it's possible that we hit a log I/O 2831 * We let the log lock go, so it's possible that we hit a log I/O
2832 * error or someother SHUTDOWN condition that marks the iclog 2832 * error or some other SHUTDOWN condition that marks the iclog
2833 * as XLOG_STATE_IOERROR before the bwrite. However, we know that 2833 * as XLOG_STATE_IOERROR before the bwrite. However, we know that
2834 * this iclog has consistent data, so we ignore IOERROR 2834 * this iclog has consistent data, so we ignore IOERROR
2835 * flags after this point. 2835 * flags after this point.
diff --git a/fs/xfs/xfs_log.h b/fs/xfs/xfs_log.h
index 4b2ac88dbb83..eacb3d4987f2 100644
--- a/fs/xfs/xfs_log.h
+++ b/fs/xfs/xfs_log.h
@@ -27,7 +27,7 @@
27 27
28#ifdef __KERNEL__ 28#ifdef __KERNEL__
29/* 29/*
30 * By comparing each compnent, we don't have to worry about extra 30 * By comparing each component, we don't have to worry about extra
31 * endian issues in treating two 32 bit numbers as one 64 bit number 31 * endian issues in treating two 32 bit numbers as one 64 bit number
32 */ 32 */
33static inline xfs_lsn_t _lsn_cmp(xfs_lsn_t lsn1, xfs_lsn_t lsn2) 33static inline xfs_lsn_t _lsn_cmp(xfs_lsn_t lsn1, xfs_lsn_t lsn2)
diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c
index add13f507ed2..1f0016b0b4ec 100644
--- a/fs/xfs/xfs_log_recover.c
+++ b/fs/xfs/xfs_log_recover.c
@@ -583,7 +583,7 @@ xlog_find_head(
583 * x | x ... | x - 1 | x 583 * x | x ... | x - 1 | x
584 * Another case that fits this picture would be 584 * Another case that fits this picture would be
585 * x | x + 1 | x ... | x 585 * x | x + 1 | x ... | x
586 * In this case the head really is somwhere at the end of the 586 * In this case the head really is somewhere at the end of the
587 * log, as one of the latest writes at the beginning was 587 * log, as one of the latest writes at the beginning was
588 * incomplete. 588 * incomplete.
589 * One more case is 589 * One more case is
@@ -2799,7 +2799,7 @@ xlog_recover_do_trans(
2799 * we don't need to worry about the block number being 2799 * we don't need to worry about the block number being
2800 * truncated in > 1 TB buffers because in user-land, 2800 * truncated in > 1 TB buffers because in user-land,
2801 * we're now n32 or 64-bit so xfs_daddr_t is 64-bits so 2801 * we're now n32 or 64-bit so xfs_daddr_t is 64-bits so
2802 * the blkno's will get through the user-mode buffer 2802 * the blknos will get through the user-mode buffer
2803 * cache properly. The only bad case is o32 kernels 2803 * cache properly. The only bad case is o32 kernels
2804 * where xfs_daddr_t is 32-bits but mount will warn us 2804 * where xfs_daddr_t is 32-bits but mount will warn us
2805 * off a > 1 TB filesystem before we get here. 2805 * off a > 1 TB filesystem before we get here.
diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c
index 20e8abc16d18..72e7e78bfff8 100644
--- a/fs/xfs/xfs_mount.c
+++ b/fs/xfs/xfs_mount.c
@@ -393,7 +393,7 @@ xfs_initialize_perag(
393 break; 393 break;
394 } 394 }
395 395
396 /* This ag is prefered for inodes */ 396 /* This ag is preferred for inodes */
397 pag = &mp->m_perag[index]; 397 pag = &mp->m_perag[index];
398 pag->pagi_inodeok = 1; 398 pag->pagi_inodeok = 1;
399 if (index < max_metadata) 399 if (index < max_metadata)
@@ -1728,7 +1728,7 @@ xfs_mount_log_sbunit(
1728 * We cannot use the hotcpu_register() function because it does 1728 * We cannot use the hotcpu_register() function because it does
1729 * not allow notifier instances. We need a notifier per filesystem 1729 * not allow notifier instances. We need a notifier per filesystem
1730 * as we need to be able to identify the filesystem to balance 1730 * as we need to be able to identify the filesystem to balance
1731 * the counters out. This is acheived by having a notifier block 1731 * the counters out. This is achieved by having a notifier block
1732 * embedded in the xfs_mount_t and doing pointer magic to get the 1732 * embedded in the xfs_mount_t and doing pointer magic to get the
1733 * mount pointer from the notifier block address. 1733 * mount pointer from the notifier block address.
1734 */ 1734 */
diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h
index ebd73960e9db..66cbee79864e 100644
--- a/fs/xfs/xfs_mount.h
+++ b/fs/xfs/xfs_mount.h
@@ -379,7 +379,7 @@ typedef struct xfs_mount {
379#endif 379#endif
380 int m_dalign; /* stripe unit */ 380 int m_dalign; /* stripe unit */
381 int m_swidth; /* stripe width */ 381 int m_swidth; /* stripe width */
382 int m_sinoalign; /* stripe unit inode alignmnt */ 382 int m_sinoalign; /* stripe unit inode alignment */
383 int m_attr_magicpct;/* 37% of the blocksize */ 383 int m_attr_magicpct;/* 37% of the blocksize */
384 int m_dir_magicpct; /* 37% of the dir blocksize */ 384 int m_dir_magicpct; /* 37% of the dir blocksize */
385 __uint8_t m_mk_sharedro; /* mark shared ro on unmount */ 385 __uint8_t m_mk_sharedro; /* mark shared ro on unmount */
diff --git a/fs/xfs/xfs_quota.h b/fs/xfs/xfs_quota.h
index 82a08baf437b..4f6a034de7f7 100644
--- a/fs/xfs/xfs_quota.h
+++ b/fs/xfs/xfs_quota.h
@@ -31,7 +31,7 @@
31typedef __uint32_t xfs_dqid_t; 31typedef __uint32_t xfs_dqid_t;
32 32
33/* 33/*
34 * Eventhough users may not have quota limits occupying all 64-bits, 34 * Even though users may not have quota limits occupying all 64-bits,
35 * they may need 64-bit accounting. Hence, 64-bit quota-counters, 35 * they may need 64-bit accounting. Hence, 64-bit quota-counters,
36 * and quota-limits. This is a waste in the common case, but hey ... 36 * and quota-limits. This is a waste in the common case, but hey ...
37 */ 37 */
@@ -246,7 +246,7 @@ typedef struct xfs_qoff_logformat {
246#ifdef __KERNEL__ 246#ifdef __KERNEL__
247/* 247/*
248 * This check is done typically without holding the inode lock; 248 * This check is done typically without holding the inode lock;
249 * that may seem racey, but it is harmless in the context that it is used. 249 * that may seem racy, but it is harmless in the context that it is used.
250 * The inode cannot go inactive as long a reference is kept, and 250 * The inode cannot go inactive as long a reference is kept, and
251 * therefore if dquot(s) were attached, they'll stay consistent. 251 * therefore if dquot(s) were attached, they'll stay consistent.
252 * If, for example, the ownership of the inode changes while 252 * If, for example, the ownership of the inode changes while
diff --git a/fs/xfs/xfs_trans.c b/fs/xfs/xfs_trans.c
index 2918956553a5..8d056cef5d1f 100644
--- a/fs/xfs/xfs_trans.c
+++ b/fs/xfs/xfs_trans.c
@@ -490,7 +490,7 @@ xfs_trans_mod_sb(
490 case XFS_TRANS_SB_RES_FREXTENTS: 490 case XFS_TRANS_SB_RES_FREXTENTS:
491 /* 491 /*
492 * The allocation has already been applied to the 492 * The allocation has already been applied to the
493 * in-core superblocks's counter. This should only 493 * in-core superblock's counter. This should only
494 * be applied to the on-disk superblock. 494 * be applied to the on-disk superblock.
495 */ 495 */
496 ASSERT(delta < 0); 496 ASSERT(delta < 0);
@@ -611,7 +611,7 @@ xfs_trans_apply_sb_deltas(
611 611
612 if (whole) 612 if (whole)
613 /* 613 /*
614 * Log the whole thing, the fields are discontiguous. 614 * Log the whole thing, the fields are noncontiguous.
615 */ 615 */
616 xfs_trans_log_buf(tp, bp, 0, sizeof(xfs_sb_t) - 1); 616 xfs_trans_log_buf(tp, bp, 0, sizeof(xfs_sb_t) - 1);
617 else 617 else
@@ -669,7 +669,7 @@ xfs_trans_unreserve_and_mod_sb(
669 /* 669 /*
670 * Apply any superblock modifications to the in-core version. 670 * Apply any superblock modifications to the in-core version.
671 * The t_res_fdblocks_delta and t_res_frextents_delta fields are 671 * The t_res_fdblocks_delta and t_res_frextents_delta fields are
672 * explicity NOT applied to the in-core superblock. 672 * explicitly NOT applied to the in-core superblock.
673 * The idea is that that has already been done. 673 * The idea is that that has already been done.
674 */ 674 */
675 if (tp->t_flags & XFS_TRANS_SB_DIRTY) { 675 if (tp->t_flags & XFS_TRANS_SB_DIRTY) {
diff --git a/fs/xfs/xfs_trans.h b/fs/xfs/xfs_trans.h
index e48befa4e337..100d9a4b38ee 100644
--- a/fs/xfs/xfs_trans.h
+++ b/fs/xfs/xfs_trans.h
@@ -354,7 +354,7 @@ typedef struct xfs_trans {
354 xfs_lsn_t t_commit_lsn; /* log seq num of end of 354 xfs_lsn_t t_commit_lsn; /* log seq num of end of
355 * transaction. */ 355 * transaction. */
356 struct xfs_mount *t_mountp; /* ptr to fs mount struct */ 356 struct xfs_mount *t_mountp; /* ptr to fs mount struct */
357 struct xfs_dquot_acct *t_dqinfo; /* accting info for dquots */ 357 struct xfs_dquot_acct *t_dqinfo; /* acctg info for dquots */
358 xfs_trans_callback_t t_callback; /* transaction callback */ 358 xfs_trans_callback_t t_callback; /* transaction callback */
359 void *t_callarg; /* callback arg */ 359 void *t_callarg; /* callback arg */
360 unsigned int t_flags; /* misc flags */ 360 unsigned int t_flags; /* misc flags */
diff --git a/fs/xfs/xfs_trans_inode.c b/fs/xfs/xfs_trans_inode.c
index e341409172d2..7c5894d59f81 100644
--- a/fs/xfs/xfs_trans_inode.c
+++ b/fs/xfs/xfs_trans_inode.c
@@ -272,7 +272,7 @@ xfs_trans_log_inode(
272 * This is to coordinate with the xfs_iflush() and xfs_iflush_done() 272 * This is to coordinate with the xfs_iflush() and xfs_iflush_done()
273 * routines in the eventual clearing of the ilf_fields bits. 273 * routines in the eventual clearing of the ilf_fields bits.
274 * See the big comment in xfs_iflush() for an explanation of 274 * See the big comment in xfs_iflush() for an explanation of
275 * this coorination mechanism. 275 * this coordination mechanism.
276 */ 276 */
277 flags |= ip->i_itemp->ili_last_fields; 277 flags |= ip->i_itemp->ili_last_fields;
278 ip->i_itemp->ili_format.ilf_fields |= flags; 278 ip->i_itemp->ili_format.ilf_fields |= flags;
diff --git a/fs/xfs/xfs_vfsops.c b/fs/xfs/xfs_vfsops.c
index d4ec4dfaf19c..504d2a80747a 100644
--- a/fs/xfs/xfs_vfsops.c
+++ b/fs/xfs/xfs_vfsops.c
@@ -880,10 +880,10 @@ xfs_statvfs(
880 * determine if they should be flushed sync, async, or 880 * determine if they should be flushed sync, async, or
881 * delwri. 881 * delwri.
882 * SYNC_CLOSE - This flag is passed when the system is being 882 * SYNC_CLOSE - This flag is passed when the system is being
883 * unmounted. We should sync and invalidate everthing. 883 * unmounted. We should sync and invalidate everything.
884 * SYNC_FSDATA - This indicates that the caller would like to make 884 * SYNC_FSDATA - This indicates that the caller would like to make
885 * sure the superblock is safe on disk. We can ensure 885 * sure the superblock is safe on disk. We can ensure
886 * this by simply makeing sure the log gets flushed 886 * this by simply making sure the log gets flushed
887 * if SYNC_BDFLUSH is set, and by actually writing it 887 * if SYNC_BDFLUSH is set, and by actually writing it
888 * out otherwise. 888 * out otherwise.
889 * 889 *
@@ -908,7 +908,7 @@ xfs_sync(
908 * 908 *
909 * This routine supports all of the flags defined for the generic VFS_SYNC 909 * This routine supports all of the flags defined for the generic VFS_SYNC
910 * interface as explained above under xfs_sync. In the interests of not 910 * interface as explained above under xfs_sync. In the interests of not
911 * changing interfaces within the 6.5 family, additional internallly- 911 * changing interfaces within the 6.5 family, additional internally-
912 * required functions are specified within a separate xflags parameter, 912 * required functions are specified within a separate xflags parameter,
913 * only available by calling this routine. 913 * only available by calling this routine.
914 * 914 *
@@ -1090,7 +1090,7 @@ xfs_sync_inodes(
1090 * If this is just vfs_sync() or pflushd() calling 1090 * If this is just vfs_sync() or pflushd() calling
1091 * then we can skip inodes for which it looks like 1091 * then we can skip inodes for which it looks like
1092 * there is nothing to do. Since we don't have the 1092 * there is nothing to do. Since we don't have the
1093 * inode locked this is racey, but these are periodic 1093 * inode locked this is racy, but these are periodic
1094 * calls so it doesn't matter. For the others we want 1094 * calls so it doesn't matter. For the others we want
1095 * to know for sure, so we at least try to lock them. 1095 * to know for sure, so we at least try to lock them.
1096 */ 1096 */
@@ -1429,7 +1429,7 @@ xfs_sync_inodes(
1429 * 1429 *
1430 * This routine supports all of the flags defined for the generic VFS_SYNC 1430 * This routine supports all of the flags defined for the generic VFS_SYNC
1431 * interface as explained above under xfs_sync. In the interests of not 1431 * interface as explained above under xfs_sync. In the interests of not
1432 * changing interfaces within the 6.5 family, additional internallly- 1432 * changing interfaces within the 6.5 family, additional internally-
1433 * required functions are specified within a separate xflags parameter, 1433 * required functions are specified within a separate xflags parameter,
1434 * only available by calling this routine. 1434 * only available by calling this routine.
1435 * 1435 *
diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c
index 0f0a64e81db9..de49601919c1 100644
--- a/fs/xfs/xfs_vnodeops.c
+++ b/fs/xfs/xfs_vnodeops.c
@@ -848,7 +848,7 @@ xfs_setattr(
848 * If this is a synchronous mount, make sure that the 848 * If this is a synchronous mount, make sure that the
849 * transaction goes to disk before returning to the user. 849 * transaction goes to disk before returning to the user.
850 * This is slightly sub-optimal in that truncates require 850 * This is slightly sub-optimal in that truncates require
851 * two sync transactions instead of one for wsync filesytems. 851 * two sync transactions instead of one for wsync filesystems.
852 * One for the truncate and one for the timestamps since we 852 * One for the truncate and one for the timestamps since we
853 * don't want to change the timestamps unless we're sure the 853 * don't want to change the timestamps unless we're sure the
854 * truncate worked. Truncates are less than 1% of the laddis 854 * truncate worked. Truncates are less than 1% of the laddis
@@ -1170,7 +1170,7 @@ xfs_fsync(
1170 1170
1171 /* 1171 /*
1172 * If this inode is on the RT dev we need to flush that 1172 * If this inode is on the RT dev we need to flush that
1173 * cache aswell. 1173 * cache as well.
1174 */ 1174 */
1175 if (ip->i_d.di_flags & XFS_DIFLAG_REALTIME) 1175 if (ip->i_d.di_flags & XFS_DIFLAG_REALTIME)
1176 xfs_blkdev_issue_flush(ip->i_mount->m_rtdev_targp); 1176 xfs_blkdev_issue_flush(ip->i_mount->m_rtdev_targp);
@@ -1380,7 +1380,7 @@ xfs_inactive_symlink_rmt(
1380 */ 1380 */
1381 ntp = xfs_trans_dup(tp); 1381 ntp = xfs_trans_dup(tp);
1382 /* 1382 /*
1383 * Commit the transaction containing extent freeing and EFD's. 1383 * Commit the transaction containing extent freeing and EFDs.
1384 * If we get an error on the commit here or on the reserve below, 1384 * If we get an error on the commit here or on the reserve below,
1385 * we need to unlock the inode since the new transaction doesn't 1385 * we need to unlock the inode since the new transaction doesn't
1386 * have the inode attached. 1386 * have the inode attached.
@@ -2023,7 +2023,7 @@ xfs_create(
2023 XFS_QM_DQRELE(mp, gdqp); 2023 XFS_QM_DQRELE(mp, gdqp);
2024 2024
2025 /* 2025 /*
2026 * Propogate the fact that the vnode changed after the 2026 * Propagate the fact that the vnode changed after the
2027 * xfs_inode locks have been released. 2027 * xfs_inode locks have been released.
2028 */ 2028 */
2029 VOP_VNODE_CHANGE(vp, VCHANGE_FLAGS_TRUNCATED, 3); 2029 VOP_VNODE_CHANGE(vp, VCHANGE_FLAGS_TRUNCATED, 3);
@@ -2370,7 +2370,7 @@ xfs_remove(
2370 * for a log reservation. Since we'll have to wait for the 2370 * for a log reservation. Since we'll have to wait for the
2371 * inactive code to complete before returning from xfs_iget, 2371 * inactive code to complete before returning from xfs_iget,
2372 * we need to make sure that we don't have log space reserved 2372 * we need to make sure that we don't have log space reserved
2373 * when we call xfs_iget. Instead we get an unlocked referece 2373 * when we call xfs_iget. Instead we get an unlocked reference
2374 * to the inode before getting our log reservation. 2374 * to the inode before getting our log reservation.
2375 */ 2375 */
2376 error = xfs_get_dir_entry(dentry, &ip); 2376 error = xfs_get_dir_entry(dentry, &ip);
@@ -3020,7 +3020,7 @@ xfs_rmdir(
3020 * for a log reservation. Since we'll have to wait for the 3020 * for a log reservation. Since we'll have to wait for the
3021 * inactive code to complete before returning from xfs_iget, 3021 * inactive code to complete before returning from xfs_iget,
3022 * we need to make sure that we don't have log space reserved 3022 * we need to make sure that we don't have log space reserved
3023 * when we call xfs_iget. Instead we get an unlocked referece 3023 * when we call xfs_iget. Instead we get an unlocked reference
3024 * to the inode before getting our log reservation. 3024 * to the inode before getting our log reservation.
3025 */ 3025 */
3026 error = xfs_get_dir_entry(dentry, &cdp); 3026 error = xfs_get_dir_entry(dentry, &cdp);
diff --git a/include/asm-arm/arch-ixp23xx/uncompress.h b/include/asm-arm/arch-ixp23xx/uncompress.h
index 62623fa9b2f7..013575e6a9a1 100644
--- a/include/asm-arm/arch-ixp23xx/uncompress.h
+++ b/include/asm-arm/arch-ixp23xx/uncompress.h
@@ -16,26 +16,21 @@
16 16
17#define UART_BASE ((volatile u32 *)IXP23XX_UART1_PHYS) 17#define UART_BASE ((volatile u32 *)IXP23XX_UART1_PHYS)
18 18
19static __inline__ void putc(char c) 19static inline void putc(char c)
20{ 20{
21 int j; 21 int j;
22 22
23 for (j = 0; j < 0x1000; j++) { 23 for (j = 0; j < 0x1000; j++) {
24 if (UART_BASE[UART_LSR] & UART_LSR_THRE) 24 if (UART_BASE[UART_LSR] & UART_LSR_THRE)
25 break; 25 break;
26 barrier();
26 } 27 }
27 28
28 UART_BASE[UART_TX] = c; 29 UART_BASE[UART_TX] = c;
29} 30}
30 31
31static void putstr(const char *s) 32static inline void flush(void)
32{ 33{
33 while (*s) {
34 putc(*s);
35 if (*s == '\n')
36 putc('\r');
37 s++;
38 }
39} 34}
40 35
41#define arch_decomp_setup() 36#define arch_decomp_setup()
diff --git a/include/asm-arm/arch-pxa/pxa-regs.h b/include/asm-arm/arch-pxa/pxa-regs.h
index 1409c5bd703f..c8f53a71c076 100644
--- a/include/asm-arm/arch-pxa/pxa-regs.h
+++ b/include/asm-arm/arch-pxa/pxa-regs.h
@@ -485,7 +485,7 @@
485#define SACR1_ENLBF (1 << 5) /* Enable Loopback */ 485#define SACR1_ENLBF (1 << 5) /* Enable Loopback */
486#define SACR1_DRPL (1 << 4) /* Disable Replaying Function */ 486#define SACR1_DRPL (1 << 4) /* Disable Replaying Function */
487#define SACR1_DREC (1 << 3) /* Disable Recording Function */ 487#define SACR1_DREC (1 << 3) /* Disable Recording Function */
488#define SACR1_AMSL (1 << 1) /* Specify Alternate Mode */ 488#define SACR1_AMSL (1 << 0) /* Specify Alternate Mode */
489 489
490#define SASR0_I2SOFF (1 << 7) /* Controller Status */ 490#define SASR0_I2SOFF (1 << 7) /* Controller Status */
491#define SASR0_ROR (1 << 6) /* Rx FIFO Overrun */ 491#define SASR0_ROR (1 << 6) /* Rx FIFO Overrun */
diff --git a/include/asm-arm/arch-pxa/sharpsl.h b/include/asm-arm/arch-pxa/sharpsl.h
index 0b43495d24b4..94cb4982af82 100644
--- a/include/asm-arm/arch-pxa/sharpsl.h
+++ b/include/asm-arm/arch-pxa/sharpsl.h
@@ -27,6 +27,8 @@ struct corgits_machinfo {
27 */ 27 */
28struct corgibl_machinfo { 28struct corgibl_machinfo {
29 int max_intensity; 29 int max_intensity;
30 int default_intensity;
31 int limit_mask;
30 void (*set_bl_intensity)(int intensity); 32 void (*set_bl_intensity)(int intensity);
31}; 33};
32extern void corgibl_limit_intensity(int limit); 34extern void corgibl_limit_intensity(int limit);
diff --git a/include/asm-arm/unistd.h b/include/asm-arm/unistd.h
index 8f331bbd39a8..65ac305c2d45 100644
--- a/include/asm-arm/unistd.h
+++ b/include/asm-arm/unistd.h
@@ -308,8 +308,6 @@
308#define __NR_mq_notify (__NR_SYSCALL_BASE+278) 308#define __NR_mq_notify (__NR_SYSCALL_BASE+278)
309#define __NR_mq_getsetattr (__NR_SYSCALL_BASE+279) 309#define __NR_mq_getsetattr (__NR_SYSCALL_BASE+279)
310#define __NR_waitid (__NR_SYSCALL_BASE+280) 310#define __NR_waitid (__NR_SYSCALL_BASE+280)
311
312#if defined(__ARM_EABI__) /* reserve these for un-muxing socketcall */
313#define __NR_socket (__NR_SYSCALL_BASE+281) 311#define __NR_socket (__NR_SYSCALL_BASE+281)
314#define __NR_bind (__NR_SYSCALL_BASE+282) 312#define __NR_bind (__NR_SYSCALL_BASE+282)
315#define __NR_connect (__NR_SYSCALL_BASE+283) 313#define __NR_connect (__NR_SYSCALL_BASE+283)
@@ -327,9 +325,6 @@
327#define __NR_getsockopt (__NR_SYSCALL_BASE+295) 325#define __NR_getsockopt (__NR_SYSCALL_BASE+295)
328#define __NR_sendmsg (__NR_SYSCALL_BASE+296) 326#define __NR_sendmsg (__NR_SYSCALL_BASE+296)
329#define __NR_recvmsg (__NR_SYSCALL_BASE+297) 327#define __NR_recvmsg (__NR_SYSCALL_BASE+297)
330#endif
331
332#if defined(__ARM_EABI__) /* reserve these for un-muxing ipc */
333#define __NR_semop (__NR_SYSCALL_BASE+298) 328#define __NR_semop (__NR_SYSCALL_BASE+298)
334#define __NR_semget (__NR_SYSCALL_BASE+299) 329#define __NR_semget (__NR_SYSCALL_BASE+299)
335#define __NR_semctl (__NR_SYSCALL_BASE+300) 330#define __NR_semctl (__NR_SYSCALL_BASE+300)
@@ -341,16 +336,10 @@
341#define __NR_shmdt (__NR_SYSCALL_BASE+306) 336#define __NR_shmdt (__NR_SYSCALL_BASE+306)
342#define __NR_shmget (__NR_SYSCALL_BASE+307) 337#define __NR_shmget (__NR_SYSCALL_BASE+307)
343#define __NR_shmctl (__NR_SYSCALL_BASE+308) 338#define __NR_shmctl (__NR_SYSCALL_BASE+308)
344#endif
345
346#define __NR_add_key (__NR_SYSCALL_BASE+309) 339#define __NR_add_key (__NR_SYSCALL_BASE+309)
347#define __NR_request_key (__NR_SYSCALL_BASE+310) 340#define __NR_request_key (__NR_SYSCALL_BASE+310)
348#define __NR_keyctl (__NR_SYSCALL_BASE+311) 341#define __NR_keyctl (__NR_SYSCALL_BASE+311)
349
350#if defined(__ARM_EABI__) /* reserved for un-muxing ipc */
351#define __NR_semtimedop (__NR_SYSCALL_BASE+312) 342#define __NR_semtimedop (__NR_SYSCALL_BASE+312)
352#endif
353
354#define __NR_vserver (__NR_SYSCALL_BASE+313) 343#define __NR_vserver (__NR_SYSCALL_BASE+313)
355#define __NR_ioprio_set (__NR_SYSCALL_BASE+314) 344#define __NR_ioprio_set (__NR_SYSCALL_BASE+314)
356#define __NR_ioprio_get (__NR_SYSCALL_BASE+315) 345#define __NR_ioprio_get (__NR_SYSCALL_BASE+315)
diff --git a/include/asm-generic/local.h b/include/asm-generic/local.h
index de4614840c2c..9291c24f5819 100644
--- a/include/asm-generic/local.h
+++ b/include/asm-generic/local.h
@@ -7,8 +7,15 @@
7#include <asm/atomic.h> 7#include <asm/atomic.h>
8#include <asm/types.h> 8#include <asm/types.h>
9 9
10/* An unsigned long type for operations which are atomic for a single 10/*
11 * CPU. Usually used in combination with per-cpu variables. */ 11 * A signed long type for operations which are atomic for a single CPU.
12 * Usually used in combination with per-cpu variables.
13 *
14 * This is the default implementation, which uses atomic_long_t. Which is
15 * rather pointless. The whole point behind local_t is that some processors
16 * can perform atomic adds and subtracts in a manner which is atomic wrt IRQs
17 * running on this CPU. local_t allows exploitation of such capabilities.
18 */
12 19
13/* Implement in terms of atomics. */ 20/* Implement in terms of atomics. */
14 21
@@ -20,7 +27,7 @@ typedef struct
20 27
21#define LOCAL_INIT(i) { ATOMIC_LONG_INIT(i) } 28#define LOCAL_INIT(i) { ATOMIC_LONG_INIT(i) }
22 29
23#define local_read(l) ((unsigned long)atomic_long_read(&(l)->a)) 30#define local_read(l) atomic_long_read(&(l)->a)
24#define local_set(l,i) atomic_long_set((&(l)->a),(i)) 31#define local_set(l,i) atomic_long_set((&(l)->a),(i))
25#define local_inc(l) atomic_long_inc(&(l)->a) 32#define local_inc(l) atomic_long_inc(&(l)->a)
26#define local_dec(l) atomic_long_dec(&(l)->a) 33#define local_dec(l) atomic_long_dec(&(l)->a)
diff --git a/include/asm-generic/mutex-dec.h b/include/asm-generic/mutex-dec.h
index 40c6d1f86598..29c6ac34e236 100644
--- a/include/asm-generic/mutex-dec.h
+++ b/include/asm-generic/mutex-dec.h
@@ -17,13 +17,14 @@
17 * it wasn't 1 originally. This function MUST leave the value lower than 17 * it wasn't 1 originally. This function MUST leave the value lower than
18 * 1 even when the "1" assertion wasn't true. 18 * 1 even when the "1" assertion wasn't true.
19 */ 19 */
20#define __mutex_fastpath_lock(count, fail_fn) \ 20static inline void
21do { \ 21__mutex_fastpath_lock(atomic_t *count, fastcall void (*fail_fn)(atomic_t *))
22 if (unlikely(atomic_dec_return(count) < 0)) \ 22{
23 fail_fn(count); \ 23 if (unlikely(atomic_dec_return(count) < 0))
24 else \ 24 fail_fn(count);
25 smp_mb(); \ 25 else
26} while (0) 26 smp_mb();
27}
27 28
28/** 29/**
29 * __mutex_fastpath_lock_retval - try to take the lock by moving the count 30 * __mutex_fastpath_lock_retval - try to take the lock by moving the count
@@ -36,7 +37,7 @@ do { \
36 * or anything the slow path function returns. 37 * or anything the slow path function returns.
37 */ 38 */
38static inline int 39static inline int
39__mutex_fastpath_lock_retval(atomic_t *count, int (*fail_fn)(atomic_t *)) 40__mutex_fastpath_lock_retval(atomic_t *count, fastcall int (*fail_fn)(atomic_t *))
40{ 41{
41 if (unlikely(atomic_dec_return(count) < 0)) 42 if (unlikely(atomic_dec_return(count) < 0))
42 return fail_fn(count); 43 return fail_fn(count);
@@ -59,12 +60,13 @@ __mutex_fastpath_lock_retval(atomic_t *count, int (*fail_fn)(atomic_t *))
59 * __mutex_slowpath_needs_to_unlock() macro needs to return 1, it needs 60 * __mutex_slowpath_needs_to_unlock() macro needs to return 1, it needs
60 * to return 0 otherwise. 61 * to return 0 otherwise.
61 */ 62 */
62#define __mutex_fastpath_unlock(count, fail_fn) \ 63static inline void
63do { \ 64__mutex_fastpath_unlock(atomic_t *count, fastcall void (*fail_fn)(atomic_t *))
64 smp_mb(); \ 65{
65 if (unlikely(atomic_inc_return(count) <= 0)) \ 66 smp_mb();
66 fail_fn(count); \ 67 if (unlikely(atomic_inc_return(count) <= 0))
67} while (0) 68 fail_fn(count);
69}
68 70
69#define __mutex_slowpath_needs_to_unlock() 1 71#define __mutex_slowpath_needs_to_unlock() 1
70 72
diff --git a/include/asm-generic/mutex-xchg.h b/include/asm-generic/mutex-xchg.h
index 1d24f47e6c48..32a2100c1aeb 100644
--- a/include/asm-generic/mutex-xchg.h
+++ b/include/asm-generic/mutex-xchg.h
@@ -3,7 +3,7 @@
3 * 3 *
4 * Generic implementation of the mutex fastpath, based on xchg(). 4 * Generic implementation of the mutex fastpath, based on xchg().
5 * 5 *
6 * NOTE: An xchg based implementation is less optimal than an atomic 6 * NOTE: An xchg based implementation might be less optimal than an atomic
7 * decrement/increment based implementation. If your architecture 7 * decrement/increment based implementation. If your architecture
8 * has a reasonable atomic dec/inc then you should probably use 8 * has a reasonable atomic dec/inc then you should probably use
9 * asm-generic/mutex-dec.h instead, or you could open-code an 9 * asm-generic/mutex-dec.h instead, or you could open-code an
@@ -22,14 +22,14 @@
22 * wasn't 1 originally. This function MUST leave the value lower than 1 22 * wasn't 1 originally. This function MUST leave the value lower than 1
23 * even when the "1" assertion wasn't true. 23 * even when the "1" assertion wasn't true.
24 */ 24 */
25#define __mutex_fastpath_lock(count, fail_fn) \ 25static inline void
26do { \ 26__mutex_fastpath_lock(atomic_t *count, fastcall void (*fail_fn)(atomic_t *))
27 if (unlikely(atomic_xchg(count, 0) != 1)) \ 27{
28 fail_fn(count); \ 28 if (unlikely(atomic_xchg(count, 0) != 1))
29 else \ 29 fail_fn(count);
30 smp_mb(); \ 30 else
31} while (0) 31 smp_mb();
32 32}
33 33
34/** 34/**
35 * __mutex_fastpath_lock_retval - try to take the lock by moving the count 35 * __mutex_fastpath_lock_retval - try to take the lock by moving the count
@@ -42,7 +42,7 @@ do { \
42 * or anything the slow path function returns 42 * or anything the slow path function returns
43 */ 43 */
44static inline int 44static inline int
45__mutex_fastpath_lock_retval(atomic_t *count, int (*fail_fn)(atomic_t *)) 45__mutex_fastpath_lock_retval(atomic_t *count, fastcall int (*fail_fn)(atomic_t *))
46{ 46{
47 if (unlikely(atomic_xchg(count, 0) != 1)) 47 if (unlikely(atomic_xchg(count, 0) != 1))
48 return fail_fn(count); 48 return fail_fn(count);
@@ -64,12 +64,13 @@ __mutex_fastpath_lock_retval(atomic_t *count, int (*fail_fn)(atomic_t *))
64 * __mutex_slowpath_needs_to_unlock() macro needs to return 1, it needs 64 * __mutex_slowpath_needs_to_unlock() macro needs to return 1, it needs
65 * to return 0 otherwise. 65 * to return 0 otherwise.
66 */ 66 */
67#define __mutex_fastpath_unlock(count, fail_fn) \ 67static inline void
68do { \ 68__mutex_fastpath_unlock(atomic_t *count, fastcall void (*fail_fn)(atomic_t *))
69 smp_mb(); \ 69{
70 if (unlikely(atomic_xchg(count, 1) != 0)) \ 70 smp_mb();
71 fail_fn(count); \ 71 if (unlikely(atomic_xchg(count, 1) != 0))
72} while (0) 72 fail_fn(count);
73}
73 74
74#define __mutex_slowpath_needs_to_unlock() 0 75#define __mutex_slowpath_needs_to_unlock() 0
75 76
diff --git a/include/asm-i386/apicdef.h b/include/asm-i386/apicdef.h
index 03185cef8e0a..5e4a35af2921 100644
--- a/include/asm-i386/apicdef.h
+++ b/include/asm-i386/apicdef.h
@@ -37,6 +37,7 @@
37#define APIC_SPIV_FOCUS_DISABLED (1<<9) 37#define APIC_SPIV_FOCUS_DISABLED (1<<9)
38#define APIC_SPIV_APIC_ENABLED (1<<8) 38#define APIC_SPIV_APIC_ENABLED (1<<8)
39#define APIC_ISR 0x100 39#define APIC_ISR 0x100
40#define APIC_ISR_NR 0x8 /* Number of 32 bit ISR registers. */
40#define APIC_TMR 0x180 41#define APIC_TMR 0x180
41#define APIC_IRR 0x200 42#define APIC_IRR 0x200
42#define APIC_ESR 0x280 43#define APIC_ESR 0x280
diff --git a/include/asm-i386/floppy.h b/include/asm-i386/floppy.h
index 79727afb94c9..03403045c182 100644
--- a/include/asm-i386/floppy.h
+++ b/include/asm-i386/floppy.h
@@ -56,7 +56,6 @@ static irqreturn_t floppy_hardint(int irq, void *dev_id, struct pt_regs * regs)
56 register unsigned char st; 56 register unsigned char st;
57 57
58#undef TRACE_FLPY_INT 58#undef TRACE_FLPY_INT
59#define NO_FLOPPY_ASSEMBLER
60 59
61#ifdef TRACE_FLPY_INT 60#ifdef TRACE_FLPY_INT
62 static int calls=0; 61 static int calls=0;
@@ -71,38 +70,6 @@ static irqreturn_t floppy_hardint(int irq, void *dev_id, struct pt_regs * regs)
71 bytes = virtual_dma_count; 70 bytes = virtual_dma_count;
72#endif 71#endif
73 72
74#ifndef NO_FLOPPY_ASSEMBLER
75 __asm__ (
76 "testl %1,%1"
77 "je 3f"
78"1: inb %w4,%b0"
79 "andb $160,%b0"
80 "cmpb $160,%b0"
81 "jne 2f"
82 "incw %w4"
83 "testl %3,%3"
84 "jne 4f"
85 "inb %w4,%b0"
86 "movb %0,(%2)"
87 "jmp 5f"
88"4: movb (%2),%0"
89 "outb %b0,%w4"
90"5: decw %w4"
91 "outb %0,$0x80"
92 "decl %1"
93 "incl %2"
94 "testl %1,%1"
95 "jne 1b"
96"3: inb %w4,%b0"
97"2: "
98 : "=a" ((char) st),
99 "=c" ((long) virtual_dma_count),
100 "=S" ((long) virtual_dma_addr)
101 : "b" ((long) virtual_dma_mode),
102 "d" ((short) virtual_dma_port+4),
103 "1" ((long) virtual_dma_count),
104 "2" ((long) virtual_dma_addr));
105#else
106 { 73 {
107 register int lcount; 74 register int lcount;
108 register char *lptr; 75 register char *lptr;
@@ -122,7 +89,6 @@ static irqreturn_t floppy_hardint(int irq, void *dev_id, struct pt_regs * regs)
122 virtual_dma_addr = lptr; 89 virtual_dma_addr = lptr;
123 st = inb(virtual_dma_port+4); 90 st = inb(virtual_dma_port+4);
124 } 91 }
125#endif
126 92
127#ifdef TRACE_FLPY_INT 93#ifdef TRACE_FLPY_INT
128 calls++; 94 calls++;
diff --git a/include/asm-i386/local.h b/include/asm-i386/local.h
index 0177da80dde3..e67fa08260fe 100644
--- a/include/asm-i386/local.h
+++ b/include/asm-i386/local.h
@@ -5,7 +5,7 @@
5 5
6typedef struct 6typedef struct
7{ 7{
8 volatile unsigned long counter; 8 volatile long counter;
9} local_t; 9} local_t;
10 10
11#define LOCAL_INIT(i) { (i) } 11#define LOCAL_INIT(i) { (i) }
@@ -29,7 +29,7 @@ static __inline__ void local_dec(local_t *v)
29 :"m" (v->counter)); 29 :"m" (v->counter));
30} 30}
31 31
32static __inline__ void local_add(unsigned long i, local_t *v) 32static __inline__ void local_add(long i, local_t *v)
33{ 33{
34 __asm__ __volatile__( 34 __asm__ __volatile__(
35 "addl %1,%0" 35 "addl %1,%0"
@@ -37,7 +37,7 @@ static __inline__ void local_add(unsigned long i, local_t *v)
37 :"ir" (i), "m" (v->counter)); 37 :"ir" (i), "m" (v->counter));
38} 38}
39 39
40static __inline__ void local_sub(unsigned long i, local_t *v) 40static __inline__ void local_sub(long i, local_t *v)
41{ 41{
42 __asm__ __volatile__( 42 __asm__ __volatile__(
43 "subl %1,%0" 43 "subl %1,%0"
diff --git a/include/asm-i386/unistd.h b/include/asm-i386/unistd.h
index 014e3562895b..2e7f3e257fdd 100644
--- a/include/asm-i386/unistd.h
+++ b/include/asm-i386/unistd.h
@@ -318,8 +318,10 @@
318#define __NR_unshare 310 318#define __NR_unshare 310
319#define __NR_set_robust_list 311 319#define __NR_set_robust_list 311
320#define __NR_get_robust_list 312 320#define __NR_get_robust_list 312
321#define __NR_sys_splice 313
322#define __NR_sys_sync_file_range 314
321 323
322#define NR_syscalls 313 324#define NR_syscalls 315
323 325
324/* 326/*
325 * user-visible error numbers are in the range -1 - -128: see 327 * user-visible error numbers are in the range -1 - -128: see
diff --git a/include/asm-ia64/asmmacro.h b/include/asm-ia64/asmmacro.h
index d4cec32083d8..edf2cebb2969 100644
--- a/include/asm-ia64/asmmacro.h
+++ b/include/asm-ia64/asmmacro.h
@@ -38,6 +38,10 @@ name:
38 38
39/* 39/*
40 * Helper macros for accessing user memory. 40 * Helper macros for accessing user memory.
41 *
42 * When adding any new .section/.previous entries here, make sure to
43 * also add it to the DISCARD section in arch/ia64/kernel/gate.lds.S or
44 * unpleasant things will happen.
41 */ 45 */
42 46
43 .section "__ex_table", "a" // declare section & section attributes 47 .section "__ex_table", "a" // declare section & section attributes
diff --git a/include/asm-ia64/pal.h b/include/asm-ia64/pal.h
index 4e7e6f23b08c..37e52a2836b0 100644
--- a/include/asm-ia64/pal.h
+++ b/include/asm-ia64/pal.h
@@ -68,6 +68,7 @@
68#define PAL_SHUTDOWN 40 /* enter processor shutdown state */ 68#define PAL_SHUTDOWN 40 /* enter processor shutdown state */
69#define PAL_PREFETCH_VISIBILITY 41 /* Make Processor Prefetches Visible */ 69#define PAL_PREFETCH_VISIBILITY 41 /* Make Processor Prefetches Visible */
70#define PAL_LOGICAL_TO_PHYSICAL 42 /* returns information on logical to physical processor mapping */ 70#define PAL_LOGICAL_TO_PHYSICAL 42 /* returns information on logical to physical processor mapping */
71#define PAL_CACHE_SHARED_INFO 43 /* returns information on caches shared by logical processor */
71 72
72#define PAL_COPY_PAL 256 /* relocate PAL procedures and PAL PMI */ 73#define PAL_COPY_PAL 256 /* relocate PAL procedures and PAL PMI */
73#define PAL_HALT_INFO 257 /* return the low power capabilities of processor */ 74#define PAL_HALT_INFO 257 /* return the low power capabilities of processor */
@@ -130,7 +131,7 @@ typedef u64 pal_cache_line_state_t;
130#define PAL_CACHE_LINE_STATE_MODIFIED 3 /* Modified */ 131#define PAL_CACHE_LINE_STATE_MODIFIED 3 /* Modified */
131 132
132typedef struct pal_freq_ratio { 133typedef struct pal_freq_ratio {
133 u64 den : 32, num : 32; /* numerator & denominator */ 134 u32 den, num; /* numerator & denominator */
134} itc_ratio, proc_ratio; 135} itc_ratio, proc_ratio;
135 136
136typedef union pal_cache_config_info_1_s { 137typedef union pal_cache_config_info_1_s {
@@ -151,10 +152,10 @@ typedef union pal_cache_config_info_1_s {
151 152
152typedef union pal_cache_config_info_2_s { 153typedef union pal_cache_config_info_2_s {
153 struct { 154 struct {
154 u64 cache_size : 32, /*cache size in bytes*/ 155 u32 cache_size; /*cache size in bytes*/
155 156
156 157
157 alias_boundary : 8, /* 39-32 aliased addr 158 u32 alias_boundary : 8, /* 39-32 aliased addr
158 * separation for max 159 * separation for max
159 * performance. 160 * performance.
160 */ 161 */
@@ -1647,6 +1648,33 @@ ia64_pal_logical_to_phys(u64 proc_number, pal_logical_to_physical_t *mapping)
1647 1648
1648 return iprv.status; 1649 return iprv.status;
1649} 1650}
1651
1652typedef struct pal_cache_shared_info_s
1653{
1654 u64 num_shared;
1655 pal_proc_n_log_info1_t ppli1;
1656 pal_proc_n_log_info2_t ppli2;
1657} pal_cache_shared_info_t;
1658
1659/* Get information on logical to physical processor mappings. */
1660static inline s64
1661ia64_pal_cache_shared_info(u64 level,
1662 u64 type,
1663 u64 proc_number,
1664 pal_cache_shared_info_t *info)
1665{
1666 struct ia64_pal_retval iprv;
1667
1668 PAL_CALL(iprv, PAL_CACHE_SHARED_INFO, level, type, proc_number);
1669
1670 if (iprv.status == PAL_STATUS_SUCCESS) {
1671 info->num_shared = iprv.v0;
1672 info->ppli1.ppli1_data = iprv.v1;
1673 info->ppli2.ppli2_data = iprv.v2;
1674 }
1675
1676 return iprv.status;
1677}
1650#endif /* __ASSEMBLY__ */ 1678#endif /* __ASSEMBLY__ */
1651 1679
1652#endif /* _ASM_IA64_PAL_H */ 1680#endif /* _ASM_IA64_PAL_H */
diff --git a/include/asm-ia64/unistd.h b/include/asm-ia64/unistd.h
index 019956c613e4..36070c1014d8 100644
--- a/include/asm-ia64/unistd.h
+++ b/include/asm-ia64/unistd.h
@@ -285,12 +285,13 @@
285#define __NR_faccessat 1293 285#define __NR_faccessat 1293
286/* 1294, 1295 reserved for pselect/ppoll */ 286/* 1294, 1295 reserved for pselect/ppoll */
287#define __NR_unshare 1296 287#define __NR_unshare 1296
288#define __NR_splice 1297
288 289
289#ifdef __KERNEL__ 290#ifdef __KERNEL__
290 291
291#include <linux/config.h> 292#include <linux/config.h>
292 293
293#define NR_syscalls 273 /* length of syscall table */ 294#define NR_syscalls 274 /* length of syscall table */
294 295
295#define __ARCH_WANT_SYS_RT_SIGACTION 296#define __ARCH_WANT_SYS_RT_SIGACTION
296 297
diff --git a/include/asm-parisc/atomic.h b/include/asm-parisc/atomic.h
index 4dc7253ff5d0..403ea97316cf 100644
--- a/include/asm-parisc/atomic.h
+++ b/include/asm-parisc/atomic.h
@@ -210,6 +210,8 @@ static __inline__ int atomic_read(const atomic_t *v)
210 210
211#define atomic_dec_and_test(v) (atomic_dec_return(v) == 0) 211#define atomic_dec_and_test(v) (atomic_dec_return(v) == 0)
212 212
213#define atomic_sub_and_test(i,v) (atomic_sub_return((i),(v)) == 0)
214
213#define ATOMIC_INIT(i) ((atomic_t) { (i) }) 215#define ATOMIC_INIT(i) ((atomic_t) { (i) })
214 216
215#define smp_mb__before_atomic_dec() smp_mb() 217#define smp_mb__before_atomic_dec() smp_mb()
@@ -267,6 +269,7 @@ atomic64_read(const atomic64_t *v)
267 269
268#define atomic64_inc_and_test(v) (atomic64_inc_return(v) == 0) 270#define atomic64_inc_and_test(v) (atomic64_inc_return(v) == 0)
269#define atomic64_dec_and_test(v) (atomic64_dec_return(v) == 0) 271#define atomic64_dec_and_test(v) (atomic64_dec_return(v) == 0)
272#define atomic64_sub_and_test(i,v) (atomic64_sub_return((i),(v)) == 0)
270 273
271#endif /* __LP64__ */ 274#endif /* __LP64__ */
272 275
diff --git a/include/asm-parisc/cache.h b/include/asm-parisc/cache.h
index ae50f8e12eed..c831665473cb 100644
--- a/include/asm-parisc/cache.h
+++ b/include/asm-parisc/cache.h
@@ -48,7 +48,7 @@ extern void flush_user_icache_range_asm(unsigned long, unsigned long);
48extern void flush_kernel_icache_range_asm(unsigned long, unsigned long); 48extern void flush_kernel_icache_range_asm(unsigned long, unsigned long);
49extern void flush_user_dcache_range_asm(unsigned long, unsigned long); 49extern void flush_user_dcache_range_asm(unsigned long, unsigned long);
50extern void flush_kernel_dcache_range_asm(unsigned long, unsigned long); 50extern void flush_kernel_dcache_range_asm(unsigned long, unsigned long);
51extern void flush_kernel_dcache_page(void *); 51extern void flush_kernel_dcache_page_asm(void *);
52extern void flush_kernel_icache_page(void *); 52extern void flush_kernel_icache_page(void *);
53extern void disable_sr_hashing(void); /* turns off space register hashing */ 53extern void disable_sr_hashing(void); /* turns off space register hashing */
54extern void disable_sr_hashing_asm(int); /* low level support for above */ 54extern void disable_sr_hashing_asm(int); /* low level support for above */
diff --git a/include/asm-parisc/cacheflush.h b/include/asm-parisc/cacheflush.h
index c53af9ff41b5..76b6b7d6046a 100644
--- a/include/asm-parisc/cacheflush.h
+++ b/include/asm-parisc/cacheflush.h
@@ -62,7 +62,7 @@ extern void flush_dcache_page(struct page *page);
62#define flush_dcache_mmap_unlock(mapping) \ 62#define flush_dcache_mmap_unlock(mapping) \
63 write_unlock_irq(&(mapping)->tree_lock) 63 write_unlock_irq(&(mapping)->tree_lock)
64 64
65#define flush_icache_page(vma,page) do { flush_kernel_dcache_page(page_address(page)); flush_kernel_icache_page(page_address(page)); } while (0) 65#define flush_icache_page(vma,page) do { flush_kernel_dcache_page(page); flush_kernel_icache_page(page_address(page)); } while (0)
66 66
67#define flush_icache_range(s,e) do { flush_kernel_dcache_range_asm(s,e); flush_kernel_icache_range_asm(s,e); } while (0) 67#define flush_icache_range(s,e) do { flush_kernel_dcache_range_asm(s,e); flush_kernel_icache_range_asm(s,e); } while (0)
68 68
@@ -184,6 +184,21 @@ flush_cache_page(struct vm_area_struct *vma, unsigned long vmaddr, unsigned long
184 184
185} 185}
186 186
187static inline void
188flush_anon_page(struct page *page, unsigned long vmaddr)
189{
190 if (PageAnon(page))
191 flush_user_dcache_page(vmaddr);
192}
193#define ARCH_HAS_FLUSH_ANON_PAGE
194
195static inline void
196flush_kernel_dcache_page(struct page *page)
197{
198 flush_kernel_dcache_page_asm(page_address(page));
199}
200#define ARCH_HAS_FLUSH_KERNEL_DCACHE_PAGE
201
187#ifdef CONFIG_DEBUG_RODATA 202#ifdef CONFIG_DEBUG_RODATA
188void mark_rodata_ro(void); 203void mark_rodata_ro(void);
189#endif 204#endif
diff --git a/include/asm-parisc/io.h b/include/asm-parisc/io.h
index be0c7234a6da..29da31194b91 100644
--- a/include/asm-parisc/io.h
+++ b/include/asm-parisc/io.h
@@ -25,35 +25,11 @@ extern unsigned long parisc_vmerge_max_size;
25 * eg dev->hpa or 0xfee00000. 25 * eg dev->hpa or 0xfee00000.
26 */ 26 */
27 27
28#ifdef CONFIG_DEBUG_IOREMAP
29#ifdef CONFIG_64BIT
30#define NYBBLE_SHIFT 60
31#else
32#define NYBBLE_SHIFT 28
33#endif
34extern void gsc_bad_addr(unsigned long addr);
35extern void __raw_bad_addr(const volatile void __iomem *addr);
36#define gsc_check_addr(addr) \
37 if ((addr >> NYBBLE_SHIFT) != 0xf) { \
38 gsc_bad_addr(addr); \
39 addr |= 0xfUL << NYBBLE_SHIFT; \
40 }
41#define __raw_check_addr(addr) \
42 if (((unsigned long)addr >> NYBBLE_SHIFT) != 0xe) \
43 __raw_bad_addr(addr); \
44 addr = (void __iomem *)((unsigned long)addr | (0xfUL << NYBBLE_SHIFT));
45#else
46#define gsc_check_addr(addr)
47#define __raw_check_addr(addr)
48#endif
49
50static inline unsigned char gsc_readb(unsigned long addr) 28static inline unsigned char gsc_readb(unsigned long addr)
51{ 29{
52 long flags; 30 long flags;
53 unsigned char ret; 31 unsigned char ret;
54 32
55 gsc_check_addr(addr);
56
57 __asm__ __volatile__( 33 __asm__ __volatile__(
58 " rsm 2,%0\n" 34 " rsm 2,%0\n"
59 " ldbx 0(%2),%1\n" 35 " ldbx 0(%2),%1\n"
@@ -68,8 +44,6 @@ static inline unsigned short gsc_readw(unsigned long addr)
68 long flags; 44 long flags;
69 unsigned short ret; 45 unsigned short ret;
70 46
71 gsc_check_addr(addr);
72
73 __asm__ __volatile__( 47 __asm__ __volatile__(
74 " rsm 2,%0\n" 48 " rsm 2,%0\n"
75 " ldhx 0(%2),%1\n" 49 " ldhx 0(%2),%1\n"
@@ -83,8 +57,6 @@ static inline unsigned int gsc_readl(unsigned long addr)
83{ 57{
84 u32 ret; 58 u32 ret;
85 59
86 gsc_check_addr(addr);
87
88 __asm__ __volatile__( 60 __asm__ __volatile__(
89 " ldwax 0(%1),%0\n" 61 " ldwax 0(%1),%0\n"
90 : "=r" (ret) : "r" (addr) ); 62 : "=r" (ret) : "r" (addr) );
@@ -95,7 +67,6 @@ static inline unsigned int gsc_readl(unsigned long addr)
95static inline unsigned long long gsc_readq(unsigned long addr) 67static inline unsigned long long gsc_readq(unsigned long addr)
96{ 68{
97 unsigned long long ret; 69 unsigned long long ret;
98 gsc_check_addr(addr);
99 70
100#ifdef __LP64__ 71#ifdef __LP64__
101 __asm__ __volatile__( 72 __asm__ __volatile__(
@@ -112,8 +83,6 @@ static inline unsigned long long gsc_readq(unsigned long addr)
112static inline void gsc_writeb(unsigned char val, unsigned long addr) 83static inline void gsc_writeb(unsigned char val, unsigned long addr)
113{ 84{
114 long flags; 85 long flags;
115 gsc_check_addr(addr);
116
117 __asm__ __volatile__( 86 __asm__ __volatile__(
118 " rsm 2,%0\n" 87 " rsm 2,%0\n"
119 " stbs %1,0(%2)\n" 88 " stbs %1,0(%2)\n"
@@ -124,8 +93,6 @@ static inline void gsc_writeb(unsigned char val, unsigned long addr)
124static inline void gsc_writew(unsigned short val, unsigned long addr) 93static inline void gsc_writew(unsigned short val, unsigned long addr)
125{ 94{
126 long flags; 95 long flags;
127 gsc_check_addr(addr);
128
129 __asm__ __volatile__( 96 __asm__ __volatile__(
130 " rsm 2,%0\n" 97 " rsm 2,%0\n"
131 " sths %1,0(%2)\n" 98 " sths %1,0(%2)\n"
@@ -135,8 +102,6 @@ static inline void gsc_writew(unsigned short val, unsigned long addr)
135 102
136static inline void gsc_writel(unsigned int val, unsigned long addr) 103static inline void gsc_writel(unsigned int val, unsigned long addr)
137{ 104{
138 gsc_check_addr(addr);
139
140 __asm__ __volatile__( 105 __asm__ __volatile__(
141 " stwas %0,0(%1)\n" 106 " stwas %0,0(%1)\n"
142 : : "r" (val), "r" (addr) ); 107 : : "r" (val), "r" (addr) );
@@ -144,8 +109,6 @@ static inline void gsc_writel(unsigned int val, unsigned long addr)
144 109
145static inline void gsc_writeq(unsigned long long val, unsigned long addr) 110static inline void gsc_writeq(unsigned long long val, unsigned long addr)
146{ 111{
147 gsc_check_addr(addr);
148
149#ifdef __LP64__ 112#ifdef __LP64__
150 __asm__ __volatile__( 113 __asm__ __volatile__(
151 " stda %0,0(%1)\n" 114 " stda %0,0(%1)\n"
@@ -180,14 +143,7 @@ extern inline void * ioremap_nocache(unsigned long offset, unsigned long size)
180 143
181extern void iounmap(void __iomem *addr); 144extern void iounmap(void __iomem *addr);
182 145
183/*
184 * USE_HPPA_IOREMAP is the magic flag to enable or disable real ioremap()
185 * functionality. It's currently disabled because it may not work on some
186 * machines.
187 */
188#define USE_HPPA_IOREMAP 0
189 146
190#if USE_HPPA_IOREMAP
191static inline unsigned char __raw_readb(const volatile void __iomem *addr) 147static inline unsigned char __raw_readb(const volatile void __iomem *addr)
192{ 148{
193 return (*(volatile unsigned char __force *) (addr)); 149 return (*(volatile unsigned char __force *) (addr));
@@ -221,57 +177,6 @@ static inline void __raw_writeq(unsigned long long b, volatile void __iomem *add
221{ 177{
222 *(volatile unsigned long long __force *) addr = b; 178 *(volatile unsigned long long __force *) addr = b;
223} 179}
224#else /* !USE_HPPA_IOREMAP */
225static inline unsigned char __raw_readb(const volatile void __iomem *addr)
226{
227 __raw_check_addr(addr);
228
229 return gsc_readb((unsigned long) addr);
230}
231static inline unsigned short __raw_readw(const volatile void __iomem *addr)
232{
233 __raw_check_addr(addr);
234
235 return gsc_readw((unsigned long) addr);
236}
237static inline unsigned int __raw_readl(const volatile void __iomem *addr)
238{
239 __raw_check_addr(addr);
240
241 return gsc_readl((unsigned long) addr);
242}
243static inline unsigned long long __raw_readq(const volatile void __iomem *addr)
244{
245 __raw_check_addr(addr);
246
247 return gsc_readq((unsigned long) addr);
248}
249
250static inline void __raw_writeb(unsigned char b, volatile void __iomem *addr)
251{
252 __raw_check_addr(addr);
253
254 gsc_writeb(b, (unsigned long) addr);
255}
256static inline void __raw_writew(unsigned short b, volatile void __iomem *addr)
257{
258 __raw_check_addr(addr);
259
260 gsc_writew(b, (unsigned long) addr);
261}
262static inline void __raw_writel(unsigned int b, volatile void __iomem *addr)
263{
264 __raw_check_addr(addr);
265
266 gsc_writel(b, (unsigned long) addr);
267}
268static inline void __raw_writeq(unsigned long long b, volatile void __iomem *addr)
269{
270 __raw_check_addr(addr);
271
272 gsc_writeq(b, (unsigned long) addr);
273}
274#endif /* !USE_HPPA_IOREMAP */
275 180
276/* readb can never be const, so use __fswab instead of le*_to_cpu */ 181/* readb can never be const, so use __fswab instead of le*_to_cpu */
277#define readb(addr) __raw_readb(addr) 182#define readb(addr) __raw_readb(addr)
diff --git a/include/asm-parisc/local.h b/include/asm-parisc/local.h
index 892b3b2c4962..d0f550912755 100644
--- a/include/asm-parisc/local.h
+++ b/include/asm-parisc/local.h
@@ -4,16 +4,16 @@
4#include <linux/percpu.h> 4#include <linux/percpu.h>
5#include <asm/atomic.h> 5#include <asm/atomic.h>
6 6
7typedef atomic_t local_t; 7typedef atomic_long_t local_t;
8 8
9#define LOCAL_INIT(i) ATOMIC_INIT(i) 9#define LOCAL_INIT(i) ATOMIC_LONG_INIT(i)
10#define local_read(v) atomic_read(v) 10#define local_read(v) atomic_long_read(v)
11#define local_set(v,i) atomic_set(v,i) 11#define local_set(v,i) atomic_long_set(v,i)
12 12
13#define local_inc(v) atomic_inc(v) 13#define local_inc(v) atomic_long_inc(v)
14#define local_dec(v) atomic_dec(v) 14#define local_dec(v) atomic_long_dec(v)
15#define local_add(i, v) atomic_add(i, v) 15#define local_add(i, v) atomic_long_add(i, v)
16#define local_sub(i, v) atomic_sub(i, v) 16#define local_sub(i, v) atomic_long_sub(i, v)
17 17
18#define __local_inc(v) ((v)->counter++) 18#define __local_inc(v) ((v)->counter++)
19#define __local_dec(v) ((v)->counter--) 19#define __local_dec(v) ((v)->counter--)
diff --git a/include/asm-parisc/page.h b/include/asm-parisc/page.h
index 9f303c0c3cd7..45e02aa5bf4b 100644
--- a/include/asm-parisc/page.h
+++ b/include/asm-parisc/page.h
@@ -26,7 +26,7 @@ static inline void
26copy_user_page(void *vto, void *vfrom, unsigned long vaddr, struct page *pg) 26copy_user_page(void *vto, void *vfrom, unsigned long vaddr, struct page *pg)
27{ 27{
28 copy_user_page_asm(vto, vfrom); 28 copy_user_page_asm(vto, vfrom);
29 flush_kernel_dcache_page(vto); 29 flush_kernel_dcache_page_asm(vto);
30 /* XXX: ppc flushes icache too, should we? */ 30 /* XXX: ppc flushes icache too, should we? */
31} 31}
32 32
@@ -40,14 +40,19 @@ clear_user_page(void *page, unsigned long vaddr, struct page *pg)
40/* 40/*
41 * These are used to make use of C type-checking.. 41 * These are used to make use of C type-checking..
42 */ 42 */
43#ifdef __LP64__ 43#define STRICT_MM_TYPECHECKS
44typedef struct { unsigned long pte; } pte_t; 44#ifdef STRICT_MM_TYPECHECKS
45#else 45typedef struct { unsigned long pte;
46typedef struct { 46#if !defined(CONFIG_64BIT)
47 unsigned long pte; 47 unsigned long future_flags;
48 unsigned long flags; 48 /* XXX: it's possible to remove future_flags and change BITS_PER_PTE_ENTRY
49} pte_t; 49 to 2, but then strangely the identical 32bit kernel boots on a
50 c3000(pa20), but not any longer on a 715(pa11).
51 Still investigating... HelgeD.
52 */
50#endif 53#endif
54} pte_t; /* either 32 or 64bit */
55
51/* NOTE: even on 64 bits, these entries are __u32 because we allocate 56/* NOTE: even on 64 bits, these entries are __u32 because we allocate
52 * the pmd and pgd in ZONE_DMA (i.e. under 4GB) */ 57 * the pmd and pgd in ZONE_DMA (i.e. under 4GB) */
53typedef struct { __u32 pmd; } pmd_t; 58typedef struct { __u32 pmd; } pmd_t;
@@ -55,25 +60,44 @@ typedef struct { __u32 pgd; } pgd_t;
55typedef struct { unsigned long pgprot; } pgprot_t; 60typedef struct { unsigned long pgprot; } pgprot_t;
56 61
57#define pte_val(x) ((x).pte) 62#define pte_val(x) ((x).pte)
58#ifdef __LP64__
59#define pte_flags(x) (*(__u32 *)&((x).pte))
60#else
61#define pte_flags(x) ((x).flags)
62#endif
63
64/* These do not work lvalues, so make sure we don't use them as such. */ 63/* These do not work lvalues, so make sure we don't use them as such. */
65#define pmd_val(x) ((x).pmd + 0) 64#define pmd_val(x) ((x).pmd + 0)
66#define pgd_val(x) ((x).pgd + 0) 65#define pgd_val(x) ((x).pgd + 0)
67#define pgprot_val(x) ((x).pgprot) 66#define pgprot_val(x) ((x).pgprot)
68 67
69#define __pmd_val_set(x,n) (x).pmd = (n)
70#define __pgd_val_set(x,n) (x).pgd = (n)
71
72#define __pte(x) ((pte_t) { (x) } ) 68#define __pte(x) ((pte_t) { (x) } )
73#define __pmd(x) ((pmd_t) { (x) } ) 69#define __pmd(x) ((pmd_t) { (x) } )
74#define __pgd(x) ((pgd_t) { (x) } ) 70#define __pgd(x) ((pgd_t) { (x) } )
75#define __pgprot(x) ((pgprot_t) { (x) } ) 71#define __pgprot(x) ((pgprot_t) { (x) } )
76 72
73#define __pmd_val_set(x,n) (x).pmd = (n)
74#define __pgd_val_set(x,n) (x).pgd = (n)
75
76#else
77/*
78 * .. while these make it easier on the compiler
79 */
80typedef unsigned long pte_t;
81typedef __u32 pmd_t;
82typedef __u32 pgd_t;
83typedef unsigned long pgprot_t;
84
85#define pte_val(x) (x)
86#define pmd_val(x) (x)
87#define pgd_val(x) (x)
88#define pgprot_val(x) (x)
89
90#define __pte(x) (x)
91#define __pmd(x) (x)
92#define __pgd(x) (x)
93#define __pgprot(x) (x)
94
95#define __pmd_val_set(x,n) (x) = (n)
96#define __pgd_val_set(x,n) (x) = (n)
97
98#endif /* STRICT_MM_TYPECHECKS */
99
100
77typedef struct __physmem_range { 101typedef struct __physmem_range {
78 unsigned long start_pfn; 102 unsigned long start_pfn;
79 unsigned long pages; /* PAGE_SIZE pages */ 103 unsigned long pages; /* PAGE_SIZE pages */
diff --git a/include/asm-parisc/pci.h b/include/asm-parisc/pci.h
index fe7f6a2f5aa7..77bbafb7f73e 100644
--- a/include/asm-parisc/pci.h
+++ b/include/asm-parisc/pci.h
@@ -289,4 +289,9 @@ static inline void pcibios_add_platform_entries(struct pci_dev *dev)
289{ 289{
290} 290}
291 291
292static inline void pcibios_penalize_isa_irq(int irq, int active)
293{
294 /* We don't need to penalize isa irq's */
295}
296
292#endif /* __ASM_PARISC_PCI_H */ 297#endif /* __ASM_PARISC_PCI_H */
diff --git a/include/asm-parisc/pdc_chassis.h b/include/asm-parisc/pdc_chassis.h
index adac9ac2743f..a609273dc6bf 100644
--- a/include/asm-parisc/pdc_chassis.h
+++ b/include/asm-parisc/pdc_chassis.h
@@ -6,9 +6,8 @@
6 * 6 *
7 * 7 *
8 * This program is free software; you can redistribute it and/or modify 8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by 9 * it under the terms of the GNU General Public License, version 2, as
10 * the Free Software Foundation; either version 2, or (at your option) 10 * published by the Free Software Foundation.
11 * any later version.
12 * 11 *
13 * This program is distributed in the hope that it will be useful, 12 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
diff --git a/include/asm-parisc/spinlock.h b/include/asm-parisc/spinlock.h
index 16c2ac075fc5..a93960e232cf 100644
--- a/include/asm-parisc/spinlock.h
+++ b/include/asm-parisc/spinlock.h
@@ -134,14 +134,22 @@ static __inline__ int __raw_write_trylock(raw_rwlock_t *rw)
134 return 1; 134 return 1;
135} 135}
136 136
137static __inline__ int __raw_is_read_locked(raw_rwlock_t *rw) 137/*
138 * read_can_lock - would read_trylock() succeed?
139 * @lock: the rwlock in question.
140 */
141static __inline__ int __raw_read_can_lock(raw_rwlock_t *rw)
138{ 142{
139 return rw->counter > 0; 143 return rw->counter >= 0;
140} 144}
141 145
142static __inline__ int __raw_is_write_locked(raw_rwlock_t *rw) 146/*
147 * write_can_lock - would write_trylock() succeed?
148 * @lock: the rwlock in question.
149 */
150static __inline__ int __raw_write_can_lock(raw_rwlock_t *rw)
143{ 151{
144 return rw->counter < 0; 152 return !rw->counter;
145} 153}
146 154
147#endif /* __ASM_SPINLOCK_H */ 155#endif /* __ASM_SPINLOCK_H */
diff --git a/include/asm-parisc/thread_info.h b/include/asm-parisc/thread_info.h
index ac32f140b83a..f2f83b04cd8b 100644
--- a/include/asm-parisc/thread_info.h
+++ b/include/asm-parisc/thread_info.h
@@ -49,7 +49,8 @@ struct thread_info {
49 49
50#endif /* !__ASSEMBLY */ 50#endif /* !__ASSEMBLY */
51 51
52#define PREEMPT_ACTIVE 0x10000000 52#define PREEMPT_ACTIVE_BIT 28
53#define PREEMPT_ACTIVE (1 << PREEMPT_ACTIVE_BIT)
53 54
54/* 55/*
55 * thread information flags 56 * thread information flags
diff --git a/include/asm-powerpc/bug.h b/include/asm-powerpc/bug.h
index 99817a802ca4..f44b529e3298 100644
--- a/include/asm-powerpc/bug.h
+++ b/include/asm-powerpc/bug.h
@@ -30,34 +30,60 @@ struct bug_entry *find_bug(unsigned long bugaddr);
30 30
31#ifdef CONFIG_BUG 31#ifdef CONFIG_BUG
32 32
33/*
34 * BUG_ON() and WARN_ON() do their best to cooperate with compile-time
35 * optimisations. However depending on the complexity of the condition
36 * some compiler versions may not produce optimal results.
37 */
38
33#define BUG() do { \ 39#define BUG() do { \
34 __asm__ __volatile__( \ 40 __asm__ __volatile__( \
35 "1: twi 31,0,0\n" \ 41 "1: twi 31,0,0\n" \
36 ".section __bug_table,\"a\"\n" \ 42 ".section __bug_table,\"a\"\n" \
37 "\t"PPC_LONG" 1b,%0,%1,%2\n" \ 43 "\t"PPC_LONG" 1b,%0,%1,%2\n" \
38 ".previous" \ 44 ".previous" \
39 : : "i" (__LINE__), "i" (__FILE__), "i" (__FUNCTION__)); \ 45 : : "i" (__LINE__), "i" (__FILE__), "i" (__FUNCTION__)); \
40} while (0) 46} while (0)
41 47
42#define BUG_ON(x) do { \ 48#define BUG_ON(x) do { \
43 __asm__ __volatile__( \ 49 if (__builtin_constant_p(x)) { \
50 if (x) \
51 BUG(); \
52 } else { \
53 __asm__ __volatile__( \
44 "1: "PPC_TLNEI" %0,0\n" \ 54 "1: "PPC_TLNEI" %0,0\n" \
45 ".section __bug_table,\"a\"\n" \ 55 ".section __bug_table,\"a\"\n" \
46 "\t"PPC_LONG" 1b,%1,%2,%3\n" \ 56 "\t"PPC_LONG" 1b,%1,%2,%3\n" \
47 ".previous" \ 57 ".previous" \
48 : : "r" ((long)(x)), "i" (__LINE__), \ 58 : : "r" ((long)(x)), "i" (__LINE__), \
49 "i" (__FILE__), "i" (__FUNCTION__)); \ 59 "i" (__FILE__), "i" (__FUNCTION__)); \
60 } \
50} while (0) 61} while (0)
51 62
52#define WARN_ON(x) do { \ 63#define __WARN() do { \
53 __asm__ __volatile__( \ 64 __asm__ __volatile__( \
65 "1: twi 31,0,0\n" \
66 ".section __bug_table,\"a\"\n" \
67 "\t"PPC_LONG" 1b,%0,%1,%2\n" \
68 ".previous" \
69 : : "i" (__LINE__ + BUG_WARNING_TRAP), \
70 "i" (__FILE__), "i" (__FUNCTION__)); \
71} while (0)
72
73#define WARN_ON(x) do { \
74 if (__builtin_constant_p(x)) { \
75 if (x) \
76 __WARN(); \
77 } else { \
78 __asm__ __volatile__( \
54 "1: "PPC_TLNEI" %0,0\n" \ 79 "1: "PPC_TLNEI" %0,0\n" \
55 ".section __bug_table,\"a\"\n" \ 80 ".section __bug_table,\"a\"\n" \
56 "\t"PPC_LONG" 1b,%1,%2,%3\n" \ 81 "\t"PPC_LONG" 1b,%1,%2,%3\n" \
57 ".previous" \ 82 ".previous" \
58 : : "r" ((long)(x)), \ 83 : : "r" ((long)(x)), \
59 "i" (__LINE__ + BUG_WARNING_TRAP), \ 84 "i" (__LINE__ + BUG_WARNING_TRAP), \
60 "i" (__FILE__), "i" (__FUNCTION__)); \ 85 "i" (__FILE__), "i" (__FUNCTION__)); \
86 } \
61} while (0) 87} while (0)
62 88
63#define HAVE_ARCH_BUG 89#define HAVE_ARCH_BUG
diff --git a/include/asm-powerpc/cputable.h b/include/asm-powerpc/cputable.h
index fe45f6f3a4be..4321483cce51 100644
--- a/include/asm-powerpc/cputable.h
+++ b/include/asm-powerpc/cputable.h
@@ -188,153 +188,154 @@ extern void do_cpu_ftr_fixups(unsigned long offset);
188 !defined(CONFIG_POWER3) && !defined(CONFIG_POWER4) && \ 188 !defined(CONFIG_POWER3) && !defined(CONFIG_POWER4) && \
189 !defined(CONFIG_BOOKE)) 189 !defined(CONFIG_BOOKE))
190 190
191enum { 191#define CPU_FTRS_PPC601 (CPU_FTR_COMMON | CPU_FTR_601 | CPU_FTR_HPTE_TABLE)
192 CPU_FTRS_PPC601 = CPU_FTR_COMMON | CPU_FTR_601 | CPU_FTR_HPTE_TABLE, 192#define CPU_FTRS_603 (CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE | \
193 CPU_FTRS_603 = CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE | 193 CPU_FTR_MAYBE_CAN_DOZE | CPU_FTR_USE_TB | \
194 CPU_FTR_MAYBE_CAN_DOZE | CPU_FTR_USE_TB | 194 CPU_FTR_MAYBE_CAN_NAP)
195 CPU_FTR_MAYBE_CAN_NAP, 195#define CPU_FTRS_604 (CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE | \
196 CPU_FTRS_604 = CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE | 196 CPU_FTR_USE_TB | CPU_FTR_604_PERF_MON | CPU_FTR_HPTE_TABLE)
197 CPU_FTR_USE_TB | CPU_FTR_604_PERF_MON | CPU_FTR_HPTE_TABLE, 197#define CPU_FTRS_740_NOTAU (CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE | \
198 CPU_FTRS_740_NOTAU = CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE | 198 CPU_FTR_MAYBE_CAN_DOZE | CPU_FTR_USE_TB | CPU_FTR_L2CR | \
199 CPU_FTR_MAYBE_CAN_DOZE | CPU_FTR_USE_TB | CPU_FTR_L2CR | 199 CPU_FTR_HPTE_TABLE | CPU_FTR_MAYBE_CAN_NAP)
200 CPU_FTR_HPTE_TABLE | CPU_FTR_MAYBE_CAN_NAP, 200#define CPU_FTRS_740 (CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE | \
201 CPU_FTRS_740 = CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE | 201 CPU_FTR_MAYBE_CAN_DOZE | CPU_FTR_USE_TB | CPU_FTR_L2CR | \
202 CPU_FTR_MAYBE_CAN_DOZE | CPU_FTR_USE_TB | CPU_FTR_L2CR | 202 CPU_FTR_TAU | CPU_FTR_HPTE_TABLE | CPU_FTR_MAYBE_CAN_NAP)
203 CPU_FTR_TAU | CPU_FTR_HPTE_TABLE | CPU_FTR_MAYBE_CAN_NAP, 203#define CPU_FTRS_750 (CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE | \
204 CPU_FTRS_750 = CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE | 204 CPU_FTR_MAYBE_CAN_DOZE | CPU_FTR_USE_TB | CPU_FTR_L2CR | \
205 CPU_FTR_MAYBE_CAN_DOZE | CPU_FTR_USE_TB | CPU_FTR_L2CR | 205 CPU_FTR_TAU | CPU_FTR_HPTE_TABLE | CPU_FTR_MAYBE_CAN_NAP)
206 CPU_FTR_TAU | CPU_FTR_HPTE_TABLE | CPU_FTR_MAYBE_CAN_NAP, 206#define CPU_FTRS_750FX1 (CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE | \
207 CPU_FTRS_750FX1 = CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE | 207 CPU_FTR_MAYBE_CAN_DOZE | CPU_FTR_USE_TB | CPU_FTR_L2CR | \
208 CPU_FTR_MAYBE_CAN_DOZE | CPU_FTR_USE_TB | CPU_FTR_L2CR | 208 CPU_FTR_TAU | CPU_FTR_HPTE_TABLE | CPU_FTR_MAYBE_CAN_NAP | \
209 CPU_FTR_TAU | CPU_FTR_HPTE_TABLE | CPU_FTR_MAYBE_CAN_NAP | 209 CPU_FTR_DUAL_PLL_750FX | CPU_FTR_NO_DPM)
210 CPU_FTR_DUAL_PLL_750FX | CPU_FTR_NO_DPM, 210#define CPU_FTRS_750FX2 (CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE | \
211 CPU_FTRS_750FX2 = CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE | 211 CPU_FTR_MAYBE_CAN_DOZE | CPU_FTR_USE_TB | CPU_FTR_L2CR | \
212 CPU_FTR_MAYBE_CAN_DOZE | CPU_FTR_USE_TB | CPU_FTR_L2CR | 212 CPU_FTR_TAU | CPU_FTR_HPTE_TABLE | CPU_FTR_MAYBE_CAN_NAP | \
213 CPU_FTR_TAU | CPU_FTR_HPTE_TABLE | CPU_FTR_MAYBE_CAN_NAP | 213 CPU_FTR_NO_DPM)
214 CPU_FTR_NO_DPM, 214#define CPU_FTRS_750FX (CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE | \
215 CPU_FTRS_750FX = CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE | 215 CPU_FTR_MAYBE_CAN_DOZE | CPU_FTR_USE_TB | CPU_FTR_L2CR | \
216 CPU_FTR_MAYBE_CAN_DOZE | CPU_FTR_USE_TB | CPU_FTR_L2CR | 216 CPU_FTR_TAU | CPU_FTR_HPTE_TABLE | CPU_FTR_MAYBE_CAN_NAP | \
217 CPU_FTR_TAU | CPU_FTR_HPTE_TABLE | CPU_FTR_MAYBE_CAN_NAP | 217 CPU_FTR_DUAL_PLL_750FX | CPU_FTR_HAS_HIGH_BATS)
218 CPU_FTR_DUAL_PLL_750FX | CPU_FTR_HAS_HIGH_BATS, 218#define CPU_FTRS_750GX (CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_MAYBE_CAN_DOZE | \
219 CPU_FTRS_750GX = CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_MAYBE_CAN_DOZE | 219 CPU_FTR_USE_TB | CPU_FTR_L2CR | CPU_FTR_TAU | \
220 CPU_FTR_USE_TB | CPU_FTR_L2CR | CPU_FTR_TAU | 220 CPU_FTR_HPTE_TABLE | CPU_FTR_MAYBE_CAN_NAP | \
221 CPU_FTR_HPTE_TABLE | CPU_FTR_MAYBE_CAN_NAP | 221 CPU_FTR_DUAL_PLL_750FX | CPU_FTR_HAS_HIGH_BATS)
222 CPU_FTR_DUAL_PLL_750FX | CPU_FTR_HAS_HIGH_BATS, 222#define CPU_FTRS_7400_NOTAU (CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE | \
223 CPU_FTRS_7400_NOTAU = CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE | 223 CPU_FTR_MAYBE_CAN_DOZE | CPU_FTR_USE_TB | CPU_FTR_L2CR | \
224 CPU_FTR_MAYBE_CAN_DOZE | CPU_FTR_USE_TB | CPU_FTR_L2CR | 224 CPU_FTR_ALTIVEC_COMP | CPU_FTR_HPTE_TABLE | \
225 CPU_FTR_ALTIVEC_COMP | CPU_FTR_HPTE_TABLE | 225 CPU_FTR_MAYBE_CAN_NAP)
226 CPU_FTR_MAYBE_CAN_NAP, 226#define CPU_FTRS_7400 (CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE | \
227 CPU_FTRS_7400 = CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE | 227 CPU_FTR_MAYBE_CAN_DOZE | CPU_FTR_USE_TB | CPU_FTR_L2CR | \
228 CPU_FTR_MAYBE_CAN_DOZE | CPU_FTR_USE_TB | CPU_FTR_L2CR | 228 CPU_FTR_TAU | CPU_FTR_ALTIVEC_COMP | CPU_FTR_HPTE_TABLE | \
229 CPU_FTR_TAU | CPU_FTR_ALTIVEC_COMP | CPU_FTR_HPTE_TABLE | 229 CPU_FTR_MAYBE_CAN_NAP)
230 CPU_FTR_MAYBE_CAN_NAP, 230#define CPU_FTRS_7450_20 (CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE | \
231 CPU_FTRS_7450_20 = CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE | 231 CPU_FTR_USE_TB | CPU_FTR_L2CR | CPU_FTR_ALTIVEC_COMP | \
232 CPU_FTR_USE_TB | CPU_FTR_L2CR | CPU_FTR_ALTIVEC_COMP | 232 CPU_FTR_L3CR | CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 | \
233 CPU_FTR_L3CR | CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 | 233 CPU_FTR_NEED_COHERENT)
234 CPU_FTR_NEED_COHERENT, 234#define CPU_FTRS_7450_21 (CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE | \
235 CPU_FTRS_7450_21 = CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE | 235 CPU_FTR_USE_TB | \
236 CPU_FTR_USE_TB | 236 CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_L2CR | CPU_FTR_ALTIVEC_COMP | \
237 CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_L2CR | CPU_FTR_ALTIVEC_COMP | 237 CPU_FTR_L3CR | CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 | \
238 CPU_FTR_L3CR | CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 | 238 CPU_FTR_NAP_DISABLE_L2_PR | CPU_FTR_L3_DISABLE_NAP | \
239 CPU_FTR_NAP_DISABLE_L2_PR | CPU_FTR_L3_DISABLE_NAP | 239 CPU_FTR_NEED_COHERENT)
240 CPU_FTR_NEED_COHERENT, 240#define CPU_FTRS_7450_23 (CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE | \
241 CPU_FTRS_7450_23 = CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE | 241 CPU_FTR_USE_TB | \
242 CPU_FTR_USE_TB | 242 CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_L2CR | CPU_FTR_ALTIVEC_COMP | \
243 CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_L2CR | CPU_FTR_ALTIVEC_COMP | 243 CPU_FTR_L3CR | CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 | \
244 CPU_FTR_L3CR | CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 | 244 CPU_FTR_NAP_DISABLE_L2_PR | CPU_FTR_NEED_COHERENT)
245 CPU_FTR_NAP_DISABLE_L2_PR | CPU_FTR_NEED_COHERENT, 245#define CPU_FTRS_7455_1 (CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE | \
246 CPU_FTRS_7455_1 = CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE | 246 CPU_FTR_USE_TB | \
247 CPU_FTR_USE_TB | 247 CPU_FTR_L2CR | CPU_FTR_ALTIVEC_COMP | CPU_FTR_L3CR | \
248 CPU_FTR_L2CR | CPU_FTR_ALTIVEC_COMP | CPU_FTR_L3CR | 248 CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 | CPU_FTR_HAS_HIGH_BATS | \
249 CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 | CPU_FTR_HAS_HIGH_BATS | 249 CPU_FTR_NEED_COHERENT)
250 CPU_FTR_NEED_COHERENT, 250#define CPU_FTRS_7455_20 (CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE | \
251 CPU_FTRS_7455_20 = CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE | 251 CPU_FTR_USE_TB | \
252 CPU_FTR_USE_TB | 252 CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_L2CR | CPU_FTR_ALTIVEC_COMP | \
253 CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_L2CR | CPU_FTR_ALTIVEC_COMP | 253 CPU_FTR_L3CR | CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 | \
254 CPU_FTR_L3CR | CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 | 254 CPU_FTR_NAP_DISABLE_L2_PR | CPU_FTR_L3_DISABLE_NAP | \
255 CPU_FTR_NAP_DISABLE_L2_PR | CPU_FTR_L3_DISABLE_NAP | 255 CPU_FTR_NEED_COHERENT | CPU_FTR_HAS_HIGH_BATS)
256 CPU_FTR_NEED_COHERENT | CPU_FTR_HAS_HIGH_BATS, 256#define CPU_FTRS_7455 (CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE | \
257 CPU_FTRS_7455 = CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE | 257 CPU_FTR_USE_TB | \
258 CPU_FTR_USE_TB | 258 CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_L2CR | CPU_FTR_ALTIVEC_COMP | \
259 CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_L2CR | CPU_FTR_ALTIVEC_COMP | 259 CPU_FTR_L3CR | CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 | \
260 CPU_FTR_L3CR | CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 | 260 CPU_FTR_NAP_DISABLE_L2_PR | CPU_FTR_HAS_HIGH_BATS | \
261 CPU_FTR_NAP_DISABLE_L2_PR | CPU_FTR_HAS_HIGH_BATS | 261 CPU_FTR_NEED_COHERENT)
262 CPU_FTR_NEED_COHERENT, 262#define CPU_FTRS_7447_10 (CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE | \
263 CPU_FTRS_7447_10 = CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE | 263 CPU_FTR_USE_TB | \
264 CPU_FTR_USE_TB | 264 CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_L2CR | CPU_FTR_ALTIVEC_COMP | \
265 CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_L2CR | CPU_FTR_ALTIVEC_COMP | 265 CPU_FTR_L3CR | CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 | \
266 CPU_FTR_L3CR | CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 | 266 CPU_FTR_NAP_DISABLE_L2_PR | CPU_FTR_HAS_HIGH_BATS | \
267 CPU_FTR_NAP_DISABLE_L2_PR | CPU_FTR_HAS_HIGH_BATS | 267 CPU_FTR_NEED_COHERENT | CPU_FTR_NO_BTIC)
268 CPU_FTR_NEED_COHERENT | CPU_FTR_NO_BTIC, 268#define CPU_FTRS_7447 (CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE | \
269 CPU_FTRS_7447 = CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE | 269 CPU_FTR_USE_TB | \
270 CPU_FTR_USE_TB | 270 CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_L2CR | CPU_FTR_ALTIVEC_COMP | \
271 CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_L2CR | CPU_FTR_ALTIVEC_COMP | 271 CPU_FTR_L3CR | CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 | \
272 CPU_FTR_L3CR | CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 | 272 CPU_FTR_NAP_DISABLE_L2_PR | CPU_FTR_HAS_HIGH_BATS | \
273 CPU_FTR_NAP_DISABLE_L2_PR | CPU_FTR_HAS_HIGH_BATS | 273 CPU_FTR_NEED_COHERENT)
274 CPU_FTR_NEED_COHERENT, 274#define CPU_FTRS_7447A (CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE | \
275 CPU_FTRS_7447A = CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE | 275 CPU_FTR_USE_TB | \
276 CPU_FTR_USE_TB | 276 CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_L2CR | CPU_FTR_ALTIVEC_COMP | \
277 CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_L2CR | CPU_FTR_ALTIVEC_COMP | 277 CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 | \
278 CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 | 278 CPU_FTR_NAP_DISABLE_L2_PR | CPU_FTR_HAS_HIGH_BATS | \
279 CPU_FTR_NAP_DISABLE_L2_PR | CPU_FTR_HAS_HIGH_BATS | 279 CPU_FTR_NEED_COHERENT)
280 CPU_FTR_NEED_COHERENT, 280#define CPU_FTRS_82XX (CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE | \
281 CPU_FTRS_82XX = CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE | 281 CPU_FTR_MAYBE_CAN_DOZE | CPU_FTR_USE_TB)
282 CPU_FTR_MAYBE_CAN_DOZE | CPU_FTR_USE_TB, 282#define CPU_FTRS_G2_LE (CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_MAYBE_CAN_DOZE | \
283 CPU_FTRS_G2_LE = CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_MAYBE_CAN_DOZE | 283 CPU_FTR_USE_TB | CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_HAS_HIGH_BATS)
284 CPU_FTR_USE_TB | CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_HAS_HIGH_BATS, 284#define CPU_FTRS_E300 (CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_MAYBE_CAN_DOZE | \
285 CPU_FTRS_E300 = CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_MAYBE_CAN_DOZE | 285 CPU_FTR_USE_TB | CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_HAS_HIGH_BATS | \
286 CPU_FTR_USE_TB | CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_HAS_HIGH_BATS | 286 CPU_FTR_COMMON)
287 CPU_FTR_COMMON, 287#define CPU_FTRS_CLASSIC32 (CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE | \
288 CPU_FTRS_CLASSIC32 = CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE | 288 CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE)
289 CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE, 289#define CPU_FTRS_POWER3_32 (CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE | \
290 CPU_FTRS_POWER3_32 = CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE | 290 CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE)
291 CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE, 291#define CPU_FTRS_POWER4_32 (CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE | \
292 CPU_FTRS_POWER4_32 = CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE | 292 CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | CPU_FTR_NODSISRALIGN)
293 CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | CPU_FTR_NODSISRALIGN, 293#define CPU_FTRS_970_32 (CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE | \
294 CPU_FTRS_970_32 = CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE | 294 CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | CPU_FTR_ALTIVEC_COMP | \
295 CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE | CPU_FTR_ALTIVEC_COMP | 295 CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_NODSISRALIGN)
296 CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_NODSISRALIGN, 296#define CPU_FTRS_8XX (CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB)
297 CPU_FTRS_8XX = CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB, 297#define CPU_FTRS_40X (CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | \
298 CPU_FTRS_40X = CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | 298 CPU_FTR_NODSISRALIGN)
299 CPU_FTR_NODSISRALIGN, 299#define CPU_FTRS_44X (CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | \
300 CPU_FTRS_44X = CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | 300 CPU_FTR_NODSISRALIGN)
301 CPU_FTR_NODSISRALIGN, 301#define CPU_FTRS_E200 (CPU_FTR_USE_TB | CPU_FTR_NODSISRALIGN)
302 CPU_FTRS_E200 = CPU_FTR_USE_TB | CPU_FTR_NODSISRALIGN, 302#define CPU_FTRS_E500 (CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | \
303 CPU_FTRS_E500 = CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | 303 CPU_FTR_NODSISRALIGN)
304 CPU_FTR_NODSISRALIGN, 304#define CPU_FTRS_E500_2 (CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | \
305 CPU_FTRS_E500_2 = CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | 305 CPU_FTR_BIG_PHYS | CPU_FTR_NODSISRALIGN)
306 CPU_FTR_BIG_PHYS | CPU_FTR_NODSISRALIGN, 306#define CPU_FTRS_GENERIC_32 (CPU_FTR_COMMON | CPU_FTR_NODSISRALIGN)
307 CPU_FTRS_GENERIC_32 = CPU_FTR_COMMON | CPU_FTR_NODSISRALIGN,
308#ifdef __powerpc64__ 307#ifdef __powerpc64__
309 CPU_FTRS_POWER3 = CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | 308#define CPU_FTRS_POWER3 (CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | \
310 CPU_FTR_HPTE_TABLE | CPU_FTR_IABR, 309 CPU_FTR_HPTE_TABLE | CPU_FTR_IABR)
311 CPU_FTRS_RS64 = CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | 310#define CPU_FTRS_RS64 (CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | \
312 CPU_FTR_HPTE_TABLE | CPU_FTR_IABR | 311 CPU_FTR_HPTE_TABLE | CPU_FTR_IABR | \
313 CPU_FTR_MMCRA | CPU_FTR_CTRL, 312 CPU_FTR_MMCRA | CPU_FTR_CTRL)
314 CPU_FTRS_POWER4 = CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | 313#define CPU_FTRS_POWER4 (CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | \
315 CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_MMCRA, 314 CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_MMCRA)
316 CPU_FTRS_PPC970 = CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | 315#define CPU_FTRS_PPC970 (CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | \
317 CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2 | 316 CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2 | \
318 CPU_FTR_ALTIVEC_COMP | CPU_FTR_CAN_NAP | CPU_FTR_MMCRA, 317 CPU_FTR_ALTIVEC_COMP | CPU_FTR_CAN_NAP | CPU_FTR_MMCRA)
319 CPU_FTRS_POWER5 = CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | 318#define CPU_FTRS_POWER5 (CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | \
320 CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2 | 319 CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2 | \
321 CPU_FTR_MMCRA | CPU_FTR_SMT | 320 CPU_FTR_MMCRA | CPU_FTR_SMT | \
322 CPU_FTR_COHERENT_ICACHE | CPU_FTR_LOCKLESS_TLBIE | 321 CPU_FTR_COHERENT_ICACHE | CPU_FTR_LOCKLESS_TLBIE | \
323 CPU_FTR_MMCRA_SIHV | CPU_FTR_PURR, 322 CPU_FTR_MMCRA_SIHV | CPU_FTR_PURR)
324 CPU_FTRS_CELL = CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | 323#define CPU_FTRS_CELL (CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | \
325 CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2 | 324 CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2 | \
326 CPU_FTR_ALTIVEC_COMP | CPU_FTR_MMCRA | CPU_FTR_SMT | 325 CPU_FTR_ALTIVEC_COMP | CPU_FTR_MMCRA | CPU_FTR_SMT | \
327 CPU_FTR_CTRL | CPU_FTR_PAUSE_ZERO, 326 CPU_FTR_CTRL | CPU_FTR_PAUSE_ZERO)
328 CPU_FTRS_COMPATIBLE = CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | 327#define CPU_FTRS_COMPATIBLE (CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | \
329 CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2, 328 CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2)
330#endif 329#endif
331 330
332 CPU_FTRS_POSSIBLE =
333#ifdef __powerpc64__ 331#ifdef __powerpc64__
334 CPU_FTRS_POWER3 | CPU_FTRS_RS64 | CPU_FTRS_POWER4 | 332#define CPU_FTRS_POSSIBLE \
335 CPU_FTRS_PPC970 | CPU_FTRS_POWER5 | CPU_FTRS_CELL | 333 (CPU_FTRS_POWER3 | CPU_FTRS_RS64 | CPU_FTRS_POWER4 | \
336 CPU_FTR_CI_LARGE_PAGE | 334 CPU_FTRS_PPC970 | CPU_FTRS_POWER5 | CPU_FTRS_CELL | \
335 CPU_FTR_CI_LARGE_PAGE)
337#else 336#else
337enum {
338 CPU_FTRS_POSSIBLE =
338#if CLASSIC_PPC 339#if CLASSIC_PPC
339 CPU_FTRS_PPC601 | CPU_FTRS_603 | CPU_FTRS_604 | CPU_FTRS_740_NOTAU | 340 CPU_FTRS_PPC601 | CPU_FTRS_603 | CPU_FTRS_604 | CPU_FTRS_740_NOTAU |
340 CPU_FTRS_740 | CPU_FTRS_750 | CPU_FTRS_750FX1 | 341 CPU_FTRS_740 | CPU_FTRS_750 | CPU_FTRS_750FX1 |
@@ -368,14 +369,18 @@ enum {
368#ifdef CONFIG_E500 369#ifdef CONFIG_E500
369 CPU_FTRS_E500 | CPU_FTRS_E500_2 | 370 CPU_FTRS_E500 | CPU_FTRS_E500_2 |
370#endif 371#endif
371#endif /* __powerpc64__ */
372 0, 372 0,
373};
374#endif /* __powerpc64__ */
373 375
374 CPU_FTRS_ALWAYS =
375#ifdef __powerpc64__ 376#ifdef __powerpc64__
376 CPU_FTRS_POWER3 & CPU_FTRS_RS64 & CPU_FTRS_POWER4 & 377#define CPU_FTRS_ALWAYS \
377 CPU_FTRS_PPC970 & CPU_FTRS_POWER5 & CPU_FTRS_CELL & 378 (CPU_FTRS_POWER3 & CPU_FTRS_RS64 & CPU_FTRS_POWER4 & \
379 CPU_FTRS_PPC970 & CPU_FTRS_POWER5 & CPU_FTRS_CELL & \
380 CPU_FTRS_POSSIBLE)
378#else 381#else
382enum {
383 CPU_FTRS_ALWAYS =
379#if CLASSIC_PPC 384#if CLASSIC_PPC
380 CPU_FTRS_PPC601 & CPU_FTRS_603 & CPU_FTRS_604 & CPU_FTRS_740_NOTAU & 385 CPU_FTRS_PPC601 & CPU_FTRS_603 & CPU_FTRS_604 & CPU_FTRS_740_NOTAU &
381 CPU_FTRS_740 & CPU_FTRS_750 & CPU_FTRS_750FX1 & 386 CPU_FTRS_740 & CPU_FTRS_750 & CPU_FTRS_750FX1 &
@@ -409,9 +414,9 @@ enum {
409#ifdef CONFIG_E500 414#ifdef CONFIG_E500
410 CPU_FTRS_E500 & CPU_FTRS_E500_2 & 415 CPU_FTRS_E500 & CPU_FTRS_E500_2 &
411#endif 416#endif
412#endif /* __powerpc64__ */
413 CPU_FTRS_POSSIBLE, 417 CPU_FTRS_POSSIBLE,
414}; 418};
419#endif /* __powerpc64__ */
415 420
416static inline int cpu_has_feature(unsigned long feature) 421static inline int cpu_has_feature(unsigned long feature)
417{ 422{
diff --git a/include/asm-powerpc/firmware.h b/include/asm-powerpc/firmware.h
index ce3788224ed0..77069df92bf8 100644
--- a/include/asm-powerpc/firmware.h
+++ b/include/asm-powerpc/firmware.h
@@ -82,13 +82,11 @@ enum {
82/* This is used to identify firmware features which are available 82/* This is used to identify firmware features which are available
83 * to the kernel. 83 * to the kernel.
84 */ 84 */
85extern unsigned long ppc64_firmware_features; 85extern unsigned long powerpc_firmware_features;
86 86
87static inline unsigned long firmware_has_feature(unsigned long feature) 87#define firmware_has_feature(feature) \
88{ 88 ((FW_FEATURE_ALWAYS & (feature)) || \
89 return (FW_FEATURE_ALWAYS & feature) || 89 (FW_FEATURE_POSSIBLE & powerpc_firmware_features & (feature)))
90 (FW_FEATURE_POSSIBLE & ppc64_firmware_features & feature);
91}
92 90
93extern void system_reset_fwnmi(void); 91extern void system_reset_fwnmi(void);
94extern void machine_check_fwnmi(void); 92extern void machine_check_fwnmi(void);
diff --git a/include/asm-powerpc/floppy.h b/include/asm-powerpc/floppy.h
index e258778ca429..608164c39efb 100644
--- a/include/asm-powerpc/floppy.h
+++ b/include/asm-powerpc/floppy.h
@@ -35,6 +35,7 @@
35#ifdef CONFIG_PCI 35#ifdef CONFIG_PCI
36 36
37#include <linux/pci.h> 37#include <linux/pci.h>
38#include <asm/ppc-pci.h> /* for ppc64_isabridge_dev */
38 39
39#define fd_dma_setup(addr,size,mode,io) powerpc_fd_dma_setup(addr,size,mode,io) 40#define fd_dma_setup(addr,size,mode,io) powerpc_fd_dma_setup(addr,size,mode,io)
40 41
@@ -52,12 +53,12 @@ static __inline__ int powerpc_fd_dma_setup(char *addr, unsigned long size,
52 if (bus_addr 53 if (bus_addr
53 && (addr != prev_addr || size != prev_size || dir != prev_dir)) { 54 && (addr != prev_addr || size != prev_size || dir != prev_dir)) {
54 /* different from last time -- unmap prev */ 55 /* different from last time -- unmap prev */
55 pci_unmap_single(NULL, bus_addr, prev_size, prev_dir); 56 pci_unmap_single(ppc64_isabridge_dev, bus_addr, prev_size, prev_dir);
56 bus_addr = 0; 57 bus_addr = 0;
57 } 58 }
58 59
59 if (!bus_addr) /* need to map it */ 60 if (!bus_addr) /* need to map it */
60 bus_addr = pci_map_single(NULL, addr, size, dir); 61 bus_addr = pci_map_single(ppc64_isabridge_dev, addr, size, dir);
61 62
62 /* remember this one as prev */ 63 /* remember this one as prev */
63 prev_addr = addr; 64 prev_addr = addr;
diff --git a/include/asm-powerpc/hvcall.h b/include/asm-powerpc/hvcall.h
index 38ca9ad6110d..b72c04f3f551 100644
--- a/include/asm-powerpc/hvcall.h
+++ b/include/asm-powerpc/hvcall.h
@@ -9,6 +9,7 @@
9#define H_Closed 2 /* Resource closed */ 9#define H_Closed 2 /* Resource closed */
10#define H_Constrained 4 /* Resource request constrained to max allowed */ 10#define H_Constrained 4 /* Resource request constrained to max allowed */
11#define H_InProgress 14 /* Kind of like busy */ 11#define H_InProgress 14 /* Kind of like busy */
12#define H_Pending 17 /* returned from H_POLL_PENDING */
12#define H_Continue 18 /* Returned from H_Join on success */ 13#define H_Continue 18 /* Returned from H_Join on success */
13#define H_LongBusyStartRange 9900 /* Start of long busy range */ 14#define H_LongBusyStartRange 9900 /* Start of long busy range */
14#define H_LongBusyOrder1msec 9900 /* Long busy, hint that 1msec is a good time to retry */ 15#define H_LongBusyOrder1msec 9900 /* Long busy, hint that 1msec is a good time to retry */
diff --git a/include/asm-powerpc/hvconsole.h b/include/asm-powerpc/hvconsole.h
index 34daf7b9b62f..35ea69e8121f 100644
--- a/include/asm-powerpc/hvconsole.h
+++ b/include/asm-powerpc/hvconsole.h
@@ -24,28 +24,18 @@
24#ifdef __KERNEL__ 24#ifdef __KERNEL__
25 25
26/* 26/*
27 * This is the max number of console adapters that can/will be found as 27 * PSeries firmware will only send/recv up to 16 bytes of character data per
28 * console devices on first stage console init. Any number beyond this range 28 * hcall.
29 * can't be used as a console device but is still a valid tty device.
30 */ 29 */
31#define MAX_NR_HVC_CONSOLES 16 30#define MAX_VIO_PUT_CHARS 16
31#define SIZE_VIO_GET_CHARS 16
32 32
33/* implemented by a low level driver */ 33/*
34struct hv_ops { 34 * Vio firmware always attempts to fetch MAX_VIO_GET_CHARS chars. The 'count'
35 int (*get_chars)(uint32_t vtermno, char *buf, int count); 35 * parm is included to conform to put_chars() function pointer template
36 int (*put_chars)(uint32_t vtermno, const char *buf, int count); 36 */
37};
38extern int hvc_get_chars(uint32_t vtermno, char *buf, int count); 37extern int hvc_get_chars(uint32_t vtermno, char *buf, int count);
39extern int hvc_put_chars(uint32_t vtermno, const char *buf, int count); 38extern int hvc_put_chars(uint32_t vtermno, const char *buf, int count);
40 39
41struct hvc_struct;
42
43/* Register a vterm and a slot index for use as a console (console_init) */
44extern int hvc_instantiate(uint32_t vtermno, int index, struct hv_ops *ops);
45/* register a vterm for hvc tty operation (module_init or hotplug add) */
46extern struct hvc_struct * __devinit hvc_alloc(uint32_t vtermno, int irq,
47 struct hv_ops *ops);
48/* remove a vterm from hvc tty operation (modele_exit or hotplug remove) */
49extern int __devexit hvc_remove(struct hvc_struct *hp);
50#endif /* __KERNEL__ */ 40#endif /* __KERNEL__ */
51#endif /* _PPC64_HVCONSOLE_H */ 41#endif /* _PPC64_HVCONSOLE_H */
diff --git a/include/asm-powerpc/machdep.h b/include/asm-powerpc/machdep.h
index 5348b820788c..5ed847680754 100644
--- a/include/asm-powerpc/machdep.h
+++ b/include/asm-powerpc/machdep.h
@@ -47,6 +47,7 @@ struct smp_ops_t {
47#endif 47#endif
48 48
49struct machdep_calls { 49struct machdep_calls {
50 char *name;
50#ifdef CONFIG_PPC64 51#ifdef CONFIG_PPC64
51 void (*hpte_invalidate)(unsigned long slot, 52 void (*hpte_invalidate)(unsigned long slot,
52 unsigned long va, 53 unsigned long va,
@@ -85,9 +86,9 @@ struct machdep_calls {
85 void (*iommu_dev_setup)(struct pci_dev *dev); 86 void (*iommu_dev_setup)(struct pci_dev *dev);
86 void (*iommu_bus_setup)(struct pci_bus *bus); 87 void (*iommu_bus_setup)(struct pci_bus *bus);
87 void (*irq_bus_setup)(struct pci_bus *bus); 88 void (*irq_bus_setup)(struct pci_bus *bus);
88#endif 89#endif /* CONFIG_PPC64 */
89 90
90 int (*probe)(int platform); 91 int (*probe)(void);
91 void (*setup_arch)(void); 92 void (*setup_arch)(void);
92 void (*init_early)(void); 93 void (*init_early)(void);
93 /* Optional, may be NULL. */ 94 /* Optional, may be NULL. */
@@ -158,6 +159,12 @@ struct machdep_calls {
158 /* Idle loop for this platform, leave empty for default idle loop */ 159 /* Idle loop for this platform, leave empty for default idle loop */
159 void (*idle_loop)(void); 160 void (*idle_loop)(void);
160 161
162 /*
163 * Function for waiting for work with reduced power in idle loop;
164 * called with interrupts disabled.
165 */
166 void (*power_save)(void);
167
161 /* Function to enable performance monitor counters for this 168 /* Function to enable performance monitor counters for this
162 platform, called once per cpu. */ 169 platform, called once per cpu. */
163 void (*enable_pmcs)(void); 170 void (*enable_pmcs)(void);
@@ -170,13 +177,6 @@ struct machdep_calls {
170 May be NULL. */ 177 May be NULL. */
171 void (*init)(void); 178 void (*init)(void);
172 179
173 void (*idle)(void);
174 void (*power_save)(void);
175
176 void (*heartbeat)(void);
177 unsigned long heartbeat_reset;
178 unsigned long heartbeat_count;
179
180 void (*setup_io_mappings)(void); 180 void (*setup_io_mappings)(void);
181 181
182 void (*early_serial_map)(void); 182 void (*early_serial_map)(void);
@@ -208,8 +208,6 @@ struct machdep_calls {
208 /* Called at then very end of pcibios_init() */ 208 /* Called at then very end of pcibios_init() */
209 void (*pcibios_after_init)(void); 209 void (*pcibios_after_init)(void);
210 210
211 /* this is for modules, since _machine can be a define -- Cort */
212 int ppc_machine;
213#endif /* CONFIG_PPC32 */ 211#endif /* CONFIG_PPC32 */
214 212
215 /* Called to shutdown machine specific hardware not already controlled 213 /* Called to shutdown machine specific hardware not already controlled
@@ -242,10 +240,29 @@ struct machdep_calls {
242#endif /* CONFIG_KEXEC */ 240#endif /* CONFIG_KEXEC */
243}; 241};
244 242
245extern void default_idle(void); 243extern void power4_idle(void);
246extern void native_idle(void); 244extern void ppc6xx_idle(void);
247 245
246/*
247 * ppc_md contains a copy of the machine description structure for the
248 * current platform. machine_id contains the initial address where the
249 * description was found during boot.
250 */
248extern struct machdep_calls ppc_md; 251extern struct machdep_calls ppc_md;
252extern struct machdep_calls *machine_id;
253
254#define __machine_desc __attribute__ ((__section__ (".machine.desc")))
255
256#define define_machine(name) struct machdep_calls mach_##name __machine_desc =
257#define machine_is(name) \
258 ({ \
259 extern struct machdep_calls mach_##name \
260 __attribute__((weak)); \
261 machine_id == &mach_##name; \
262 })
263
264extern void probe_machine(void);
265
249extern char cmd_line[COMMAND_LINE_SIZE]; 266extern char cmd_line[COMMAND_LINE_SIZE];
250 267
251#ifdef CONFIG_PPC_PMAC 268#ifdef CONFIG_PPC_PMAC
diff --git a/include/asm-powerpc/oprofile_impl.h b/include/asm-powerpc/oprofile_impl.h
index 338e6a7cff4a..5b33994cd488 100644
--- a/include/asm-powerpc/oprofile_impl.h
+++ b/include/asm-powerpc/oprofile_impl.h
@@ -17,9 +17,6 @@
17 17
18/* Per-counter configuration as set via oprofilefs. */ 18/* Per-counter configuration as set via oprofilefs. */
19struct op_counter_config { 19struct op_counter_config {
20#ifdef __powerpc64__
21 unsigned long valid;
22#endif
23 unsigned long enabled; 20 unsigned long enabled;
24 unsigned long event; 21 unsigned long event;
25 unsigned long count; 22 unsigned long count;
@@ -38,9 +35,6 @@ struct op_system_config {
38#endif 35#endif
39 unsigned long enable_kernel; 36 unsigned long enable_kernel;
40 unsigned long enable_user; 37 unsigned long enable_user;
41#ifdef CONFIG_PPC64
42 unsigned long backtrace_spinlocks;
43#endif
44}; 38};
45 39
46/* Per-arch configuration */ 40/* Per-arch configuration */
@@ -56,17 +50,12 @@ struct op_powerpc_model {
56 int num_counters; 50 int num_counters;
57}; 51};
58 52
59#ifdef CONFIG_FSL_BOOKE
60extern struct op_powerpc_model op_model_fsl_booke; 53extern struct op_powerpc_model op_model_fsl_booke;
61#else /* Otherwise, it's classic */
62
63#ifdef CONFIG_PPC64
64extern struct op_powerpc_model op_model_rs64; 54extern struct op_powerpc_model op_model_rs64;
65extern struct op_powerpc_model op_model_power4; 55extern struct op_powerpc_model op_model_power4;
66
67#else /* Otherwise, CONFIG_PPC32 */
68extern struct op_powerpc_model op_model_7450; 56extern struct op_powerpc_model op_model_7450;
69#endif 57
58#ifndef CONFIG_FSL_BOOKE
70 59
71/* All the classic PPC parts use these */ 60/* All the classic PPC parts use these */
72static inline unsigned int ctr_read(unsigned int i) 61static inline unsigned int ctr_read(unsigned int i)
@@ -134,5 +123,7 @@ static inline void ctr_write(unsigned int i, unsigned int val)
134} 123}
135#endif /* !CONFIG_FSL_BOOKE */ 124#endif /* !CONFIG_FSL_BOOKE */
136 125
126extern void op_powerpc_backtrace(struct pt_regs * const regs, unsigned int depth);
127
137#endif /* __KERNEL__ */ 128#endif /* __KERNEL__ */
138#endif /* _ASM_POWERPC_OPROFILE_IMPL_H */ 129#endif /* _ASM_POWERPC_OPROFILE_IMPL_H */
diff --git a/include/asm-powerpc/paca.h b/include/asm-powerpc/paca.h
index 4465b95ebef0..706325f99a84 100644
--- a/include/asm-powerpc/paca.h
+++ b/include/asm-powerpc/paca.h
@@ -105,5 +105,7 @@ struct paca_struct {
105 105
106extern struct paca_struct paca[]; 106extern struct paca_struct paca[];
107 107
108void setup_boot_paca(void);
109
108#endif /* __KERNEL__ */ 110#endif /* __KERNEL__ */
109#endif /* _ASM_POWERPC_PACA_H */ 111#endif /* _ASM_POWERPC_PACA_H */
diff --git a/include/asm-powerpc/percpu.h b/include/asm-powerpc/percpu.h
index 464301cd0d03..184a7a4d2fdf 100644
--- a/include/asm-powerpc/percpu.h
+++ b/include/asm-powerpc/percpu.h
@@ -27,7 +27,7 @@
27#define percpu_modcopy(pcpudst, src, size) \ 27#define percpu_modcopy(pcpudst, src, size) \
28do { \ 28do { \
29 unsigned int __i; \ 29 unsigned int __i; \
30 for_each_cpu(__i) \ 30 for_each_possible_cpu(__i) \
31 memcpy((pcpudst)+__per_cpu_offset(__i), \ 31 memcpy((pcpudst)+__per_cpu_offset(__i), \
32 (src), (size)); \ 32 (src), (size)); \
33} while (0) 33} while (0)
diff --git a/include/asm-powerpc/pmac_feature.h b/include/asm-powerpc/pmac_feature.h
index 3221628130c4..d3599cc9aa74 100644
--- a/include/asm-powerpc/pmac_feature.h
+++ b/include/asm-powerpc/pmac_feature.h
@@ -305,7 +305,7 @@ extern void pmac_feature_init(void);
305extern void pmac_set_early_video_resume(void (*proc)(void *data), void *data); 305extern void pmac_set_early_video_resume(void (*proc)(void *data), void *data);
306extern void pmac_call_early_video_resume(void); 306extern void pmac_call_early_video_resume(void);
307 307
308#define PMAC_FTR_DEF(x) ((_MACH_Pmac << 16) | (x)) 308#define PMAC_FTR_DEF(x) ((0x6660000) | (x))
309 309
310/* The AGP driver registers itself here */ 310/* The AGP driver registers itself here */
311extern void pmac_register_agp_pm(struct pci_dev *bridge, 311extern void pmac_register_agp_pm(struct pci_dev *bridge,
diff --git a/include/asm-powerpc/processor.h b/include/asm-powerpc/processor.h
index 1c64a211cf19..93f83efeb310 100644
--- a/include/asm-powerpc/processor.h
+++ b/include/asm-powerpc/processor.h
@@ -22,22 +22,6 @@
22 * -- BenH. 22 * -- BenH.
23 */ 23 */
24 24
25/* Platforms codes (to be obsoleted) */
26#define PLATFORM_PSERIES 0x0100
27#define PLATFORM_PSERIES_LPAR 0x0101
28#define PLATFORM_ISERIES_LPAR 0x0201
29#define PLATFORM_LPAR 0x0001
30#define PLATFORM_POWERMAC 0x0400
31#define PLATFORM_MAPLE 0x0500
32#define PLATFORM_PREP 0x0600
33#define PLATFORM_CHRP 0x0700
34#define PLATFORM_CELL 0x1000
35
36/* Compat platform codes for 32 bits */
37#define _MACH_prep PLATFORM_PREP
38#define _MACH_Pmac PLATFORM_POWERMAC
39#define _MACH_chrp PLATFORM_CHRP
40
41/* PREP sub-platform types see residual.h for these */ 25/* PREP sub-platform types see residual.h for these */
42#define _PREP_Motorola 0x01 /* motorola prep */ 26#define _PREP_Motorola 0x01 /* motorola prep */
43#define _PREP_Firm 0x02 /* firmworks prep */ 27#define _PREP_Firm 0x02 /* firmworks prep */
@@ -49,18 +33,14 @@
49#define _CHRP_IBM 0x05 /* IBM chrp, the longtrail and longtrail 2 */ 33#define _CHRP_IBM 0x05 /* IBM chrp, the longtrail and longtrail 2 */
50#define _CHRP_Pegasos 0x06 /* Genesi/bplan's Pegasos and Pegasos2 */ 34#define _CHRP_Pegasos 0x06 /* Genesi/bplan's Pegasos and Pegasos2 */
51 35
52#ifdef __KERNEL__ 36#if defined(__KERNEL__) && defined(CONFIG_PPC32)
53#define platform_is_pseries() (_machine == PLATFORM_PSERIES || \
54 _machine == PLATFORM_PSERIES_LPAR)
55 37
56#if defined(CONFIG_PPC_MULTIPLATFORM) 38extern int _chrp_type;
57extern int _machine;
58 39
59#ifdef CONFIG_PPC32 40#ifdef CONFIG_PPC_PREP
60 41
61/* what kind of prep workstation we are */ 42/* what kind of prep workstation we are */
62extern int _prep_type; 43extern int _prep_type;
63extern int _chrp_type;
64 44
65/* 45/*
66 * This is used to identify the board type from a given PReP board 46 * This is used to identify the board type from a given PReP board
@@ -70,17 +50,14 @@ extern int _chrp_type;
70extern unsigned char ucBoardRev; 50extern unsigned char ucBoardRev;
71extern unsigned char ucBoardRevMaj, ucBoardRevMin; 51extern unsigned char ucBoardRevMaj, ucBoardRevMin;
72 52
73#endif /* CONFIG_PPC32 */ 53#endif /* CONFIG_PPC_PREP */
74 54
75#elif defined(CONFIG_PPC_ISERIES) 55#ifndef CONFIG_PPC_MULTIPLATFORM
76/*
77 * iSeries is soon to become MULTIPLATFORM hopefully ...
78 */
79#define _machine PLATFORM_ISERIES_LPAR
80#else
81#define _machine 0 56#define _machine 0
82#endif /* CONFIG_PPC_MULTIPLATFORM */ 57#endif /* CONFIG_PPC_MULTIPLATFORM */
83#endif /* __KERNEL__ */ 58
59#endif /* defined(__KERNEL__) && defined(CONFIG_PPC32) */
60
84/* 61/*
85 * Default implementation of macro that returns current 62 * Default implementation of macro that returns current
86 * instruction pointer ("program counter"). 63 * instruction pointer ("program counter").
@@ -251,6 +228,10 @@ static inline unsigned long __pack_fe01(unsigned int fpmode)
251#define cpu_relax() barrier() 228#define cpu_relax() barrier()
252#endif 229#endif
253 230
231/* Check that a certain kernel stack pointer is valid in task_struct p */
232int validate_sp(unsigned long sp, struct task_struct *p,
233 unsigned long nbytes);
234
254/* 235/*
255 * Prefetch macros. 236 * Prefetch macros.
256 */ 237 */
diff --git a/include/asm-powerpc/prom.h b/include/asm-powerpc/prom.h
index 782e13a070a1..97ef1cd71a4d 100644
--- a/include/asm-powerpc/prom.h
+++ b/include/asm-powerpc/prom.h
@@ -149,12 +149,14 @@ extern struct device_node *of_node_get(struct device_node *node);
149extern void of_node_put(struct device_node *node); 149extern void of_node_put(struct device_node *node);
150 150
151/* For scanning the flat device-tree at boot time */ 151/* For scanning the flat device-tree at boot time */
152int __init of_scan_flat_dt(int (*it)(unsigned long node, 152extern int __init of_scan_flat_dt(int (*it)(unsigned long node,
153 const char *uname, int depth, 153 const char *uname, int depth,
154 void *data), 154 void *data),
155 void *data); 155 void *data);
156void* __init of_get_flat_dt_prop(unsigned long node, const char *name, 156extern void* __init of_get_flat_dt_prop(unsigned long node, const char *name,
157 unsigned long *size); 157 unsigned long *size);
158extern int __init of_flat_dt_is_compatible(unsigned long node, const char *name);
159extern unsigned long __init of_get_flat_dt_root(void);
158 160
159/* For updating the device tree at runtime */ 161/* For updating the device tree at runtime */
160extern void of_attach_node(struct device_node *); 162extern void of_attach_node(struct device_node *);
diff --git a/include/asm-powerpc/reg.h b/include/asm-powerpc/reg.h
index 72bfe3af0460..bd467bf5cf5a 100644
--- a/include/asm-powerpc/reg.h
+++ b/include/asm-powerpc/reg.h
@@ -622,6 +622,10 @@ extern void ppc64_runlatch_off(void);
622extern unsigned long scom970_read(unsigned int address); 622extern unsigned long scom970_read(unsigned int address);
623extern void scom970_write(unsigned int address, unsigned long value); 623extern void scom970_write(unsigned int address, unsigned long value);
624 624
625#else
626#define ppc64_runlatch_on()
627#define ppc64_runlatch_off()
628
625#endif /* CONFIG_PPC64 */ 629#endif /* CONFIG_PPC64 */
626 630
627#define __get_SP() ({unsigned long sp; \ 631#define __get_SP() ({unsigned long sp; \
diff --git a/include/asm-powerpc/smp.h b/include/asm-powerpc/smp.h
index 98581e5a8279..4a716f707cf6 100644
--- a/include/asm-powerpc/smp.h
+++ b/include/asm-powerpc/smp.h
@@ -29,7 +29,6 @@
29#endif 29#endif
30 30
31extern int boot_cpuid; 31extern int boot_cpuid;
32extern int boot_cpuid_phys;
33 32
34extern void cpu_die(void); 33extern void cpu_die(void);
35 34
@@ -99,6 +98,7 @@ extern void smp_release_cpus(void);
99#else 98#else
100/* 32-bit */ 99/* 32-bit */
101#ifndef CONFIG_SMP 100#ifndef CONFIG_SMP
101extern int boot_cpuid_phys;
102#define get_hard_smp_processor_id(cpu) boot_cpuid_phys 102#define get_hard_smp_processor_id(cpu) boot_cpuid_phys
103#define set_hard_smp_processor_id(cpu, phys) 103#define set_hard_smp_processor_id(cpu, phys)
104#endif 104#endif
diff --git a/include/asm-powerpc/spu.h b/include/asm-powerpc/spu.h
index 38bacf2f6e0c..f431d8b0b651 100644
--- a/include/asm-powerpc/spu.h
+++ b/include/asm-powerpc/spu.h
@@ -110,6 +110,7 @@ struct spu {
110 char *name; 110 char *name;
111 unsigned long local_store_phys; 111 unsigned long local_store_phys;
112 u8 *local_store; 112 u8 *local_store;
113 unsigned long problem_phys;
113 struct spu_problem __iomem *problem; 114 struct spu_problem __iomem *problem;
114 struct spu_priv1 __iomem *priv1; 115 struct spu_priv1 __iomem *priv1;
115 struct spu_priv2 __iomem *priv2; 116 struct spu_priv2 __iomem *priv2;
@@ -137,6 +138,7 @@ struct spu {
137 void (* wbox_callback)(struct spu *spu); 138 void (* wbox_callback)(struct spu *spu);
138 void (* ibox_callback)(struct spu *spu); 139 void (* ibox_callback)(struct spu *spu);
139 void (* stop_callback)(struct spu *spu); 140 void (* stop_callback)(struct spu *spu);
141 void (* mfc_callback)(struct spu *spu);
140 142
141 char irq_c0[8]; 143 char irq_c0[8];
142 char irq_c1[8]; 144 char irq_c1[8];
@@ -149,6 +151,14 @@ int spu_irq_class_0_bottom(struct spu *spu);
149int spu_irq_class_1_bottom(struct spu *spu); 151int spu_irq_class_1_bottom(struct spu *spu);
150void spu_irq_setaffinity(struct spu *spu, int cpu); 152void spu_irq_setaffinity(struct spu *spu, int cpu);
151 153
154/* system callbacks from the SPU */
155struct spu_syscall_block {
156 u64 nr_ret;
157 u64 parm[6];
158};
159extern long spu_sys_callback(struct spu_syscall_block *s);
160
161/* syscalls implemented in spufs */
152extern struct spufs_calls { 162extern struct spufs_calls {
153 asmlinkage long (*create_thread)(const char __user *name, 163 asmlinkage long (*create_thread)(const char __user *name,
154 unsigned int flags, mode_t mode); 164 unsigned int flags, mode_t mode);
@@ -399,7 +409,6 @@ struct spu_priv1 {
399#define SPU_GET_REVISION_BITS(vr) (vr & SPU_REVISION_BITS) 409#define SPU_GET_REVISION_BITS(vr) (vr & SPU_REVISION_BITS)
400 u8 pad_0x28_0x100[0x100 - 0x28]; /* 0x28 */ 410 u8 pad_0x28_0x100[0x100 - 0x28]; /* 0x28 */
401 411
402
403 /* Interrupt Area */ 412 /* Interrupt Area */
404 u64 int_mask_RW[3]; /* 0x100 */ 413 u64 int_mask_RW[3]; /* 0x100 */
405#define CLASS0_ENABLE_DMA_ALIGNMENT_INTR 0x1L 414#define CLASS0_ENABLE_DMA_ALIGNMENT_INTR 0x1L
diff --git a/include/asm-powerpc/syscalls.h b/include/asm-powerpc/syscalls.h
new file mode 100644
index 000000000000..c2fe79d4f90f
--- /dev/null
+++ b/include/asm-powerpc/syscalls.h
@@ -0,0 +1,58 @@
1#ifndef __ASM_POWERPC_SYSCALLS_H
2#define __ASM_POWERPC_SYSCALLS_H
3#ifdef __KERNEL__
4
5#include <linux/compiler.h>
6#include <linux/linkage.h>
7#include <linux/types.h>
8#include <asm/signal.h>
9
10struct new_utsname;
11struct pt_regs;
12struct rtas_args;
13struct sigaction;
14
15asmlinkage unsigned long sys_mmap(unsigned long addr, size_t len,
16 unsigned long prot, unsigned long flags,
17 unsigned long fd, off_t offset);
18asmlinkage unsigned long sys_mmap2(unsigned long addr, size_t len,
19 unsigned long prot, unsigned long flags,
20 unsigned long fd, unsigned long pgoff);
21asmlinkage int sys_execve(unsigned long a0, unsigned long a1,
22 unsigned long a2, unsigned long a3, unsigned long a4,
23 unsigned long a5, struct pt_regs *regs);
24asmlinkage int sys_clone(unsigned long clone_flags, unsigned long usp,
25 int __user *parent_tidp, void __user *child_threadptr,
26 int __user *child_tidp, int p6, struct pt_regs *regs);
27asmlinkage int sys_fork(unsigned long p1, unsigned long p2,
28 unsigned long p3, unsigned long p4, unsigned long p5,
29 unsigned long p6, struct pt_regs *regs);
30asmlinkage int sys_vfork(unsigned long p1, unsigned long p2,
31 unsigned long p3, unsigned long p4, unsigned long p5,
32 unsigned long p6, struct pt_regs *regs);
33asmlinkage int sys_pipe(int __user *fildes);
34asmlinkage long sys_rt_sigaction(int sig,
35 const struct sigaction __user *act,
36 struct sigaction __user *oact, size_t sigsetsize);
37asmlinkage int sys_ipc(uint call, int first, unsigned long second,
38 long third, void __user *ptr, long fifth);
39asmlinkage long ppc64_personality(unsigned long personality);
40asmlinkage int ppc_rtas(struct rtas_args __user *uargs);
41asmlinkage time_t sys64_time(time_t __user * tloc);
42asmlinkage long ppc_newuname(struct new_utsname __user * name);
43
44asmlinkage long sys_rt_sigsuspend(sigset_t __user *unewset,
45 size_t sigsetsize);
46
47#ifndef __powerpc64__
48asmlinkage long sys_sigaltstack(const stack_t __user *uss,
49 stack_t __user *uoss, int r5, int r6, int r7, int r8,
50 struct pt_regs *regs);
51#else /* __powerpc64__ */
52asmlinkage long sys_sigaltstack(const stack_t __user *uss,
53 stack_t __user *uoss, unsigned long r5, unsigned long r6,
54 unsigned long r7, unsigned long r8, struct pt_regs *regs);
55#endif /* __powerpc64__ */
56
57#endif /* __KERNEL__ */
58#endif /* __ASM_POWERPC_SYSCALLS_H */
diff --git a/include/asm-powerpc/system.h b/include/asm-powerpc/system.h
index 65f5a7b2646b..d075725bf444 100644
--- a/include/asm-powerpc/system.h
+++ b/include/asm-powerpc/system.h
@@ -365,8 +365,11 @@ __cmpxchg(volatile void *ptr, unsigned long old, unsigned long new,
365 * powers of 2 writes until it reaches sufficient alignment). 365 * powers of 2 writes until it reaches sufficient alignment).
366 * 366 *
367 * Based on this we disable the IP header alignment in network drivers. 367 * Based on this we disable the IP header alignment in network drivers.
368 * We also modify NET_SKB_PAD to be a cacheline in size, thus maintaining
369 * cacheline alignment of buffers.
368 */ 370 */
369#define NET_IP_ALIGN 0 371#define NET_IP_ALIGN 0
372#define NET_SKB_PAD L1_CACHE_BYTES
370#endif 373#endif
371 374
372#define arch_align_stack(x) (x) 375#define arch_align_stack(x) (x)
diff --git a/include/asm-powerpc/unistd.h b/include/asm-powerpc/unistd.h
index 35556993f066..536ba0873052 100644
--- a/include/asm-powerpc/unistd.h
+++ b/include/asm-powerpc/unistd.h
@@ -301,8 +301,9 @@
301#define __NR_pselect6 280 301#define __NR_pselect6 280
302#define __NR_ppoll 281 302#define __NR_ppoll 281
303#define __NR_unshare 282 303#define __NR_unshare 282
304#define __NR_splice 283
304 305
305#define __NR_syscalls 283 306#define __NR_syscalls 284
306 307
307#ifdef __KERNEL__ 308#ifdef __KERNEL__
308#define __NR__exit __NR_exit 309#define __NR__exit __NR_exit
@@ -425,6 +426,7 @@ type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5, type6 arg6
425#include <linux/types.h> 426#include <linux/types.h>
426#include <linux/compiler.h> 427#include <linux/compiler.h>
427#include <linux/linkage.h> 428#include <linux/linkage.h>
429#include <asm/syscalls.h>
428 430
429#define __ARCH_WANT_IPC_PARSE_VERSION 431#define __ARCH_WANT_IPC_PARSE_VERSION
430#define __ARCH_WANT_OLD_READDIR 432#define __ARCH_WANT_OLD_READDIR
@@ -460,44 +462,10 @@ type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5, type6 arg6
460 * System call prototypes. 462 * System call prototypes.
461 */ 463 */
462#ifdef __KERNEL_SYSCALLS__ 464#ifdef __KERNEL_SYSCALLS__
463extern pid_t setsid(void);
464extern int write(int fd, const char *buf, off_t count);
465extern int read(int fd, char *buf, off_t count);
466extern off_t lseek(int fd, off_t offset, int count);
467extern int dup(int fd);
468extern int execve(const char *file, char **argv, char **envp); 465extern int execve(const char *file, char **argv, char **envp);
469extern int open(const char *file, int flag, int mode);
470extern int close(int fd);
471extern pid_t waitpid(pid_t pid, int *wait_stat, int options);
472#endif /* __KERNEL_SYSCALLS__ */ 466#endif /* __KERNEL_SYSCALLS__ */
473 467
474/* 468/*
475 * Functions that implement syscalls.
476 */
477unsigned long sys_mmap(unsigned long addr, size_t len, unsigned long prot,
478 unsigned long flags, unsigned long fd, off_t offset);
479unsigned long sys_mmap2(unsigned long addr, size_t len,
480 unsigned long prot, unsigned long flags,
481 unsigned long fd, unsigned long pgoff);
482struct pt_regs;
483int sys_execve(unsigned long a0, unsigned long a1, unsigned long a2,
484 unsigned long a3, unsigned long a4, unsigned long a5,
485 struct pt_regs *regs);
486int sys_clone(unsigned long clone_flags, unsigned long usp,
487 int __user *parent_tidp, void __user *child_threadptr,
488 int __user *child_tidp, int p6, struct pt_regs *regs);
489int sys_fork(unsigned long p1, unsigned long p2, unsigned long p3,
490 unsigned long p4, unsigned long p5, unsigned long p6,
491 struct pt_regs *regs);
492int sys_vfork(unsigned long p1, unsigned long p2, unsigned long p3,
493 unsigned long p4, unsigned long p5, unsigned long p6,
494 struct pt_regs *regs);
495int sys_pipe(int __user *fildes);
496struct sigaction;
497long sys_rt_sigaction(int sig, const struct sigaction __user *act,
498 struct sigaction __user *oact, size_t sigsetsize);
499
500/*
501 * "Conditional" syscalls 469 * "Conditional" syscalls
502 * 470 *
503 * What we want is __attribute__((weak,alias("sys_ni_syscall"))), 471 * What we want is __attribute__((weak,alias("sys_ni_syscall"))),
diff --git a/include/asm-powerpc/vdso_datapage.h b/include/asm-powerpc/vdso_datapage.h
index 7aa92086c3fb..8a94f0eba5e9 100644
--- a/include/asm-powerpc/vdso_datapage.h
+++ b/include/asm-powerpc/vdso_datapage.h
@@ -55,6 +55,9 @@ struct vdso_data {
55 __u32 minor; /* Minor number 0x14 */ 55 __u32 minor; /* Minor number 0x14 */
56 } version; 56 } version;
57 57
58 /* Note about the platform flags: it now only contains the lpar
59 * bit. The actual platform number is dead and burried
60 */
58 __u32 platform; /* Platform flags 0x18 */ 61 __u32 platform; /* Platform flags 0x18 */
59 __u32 processor; /* Processor type 0x1C */ 62 __u32 processor; /* Processor type 0x1C */
60 __u64 processorCount; /* # of physical processors 0x20 */ 63 __u64 processorCount; /* # of physical processors 0x20 */
diff --git a/include/asm-ppc/machdep.h b/include/asm-ppc/machdep.h
index a3e8a45e45a9..e1a0a7b213d7 100644
--- a/include/asm-ppc/machdep.h
+++ b/include/asm-ppc/machdep.h
@@ -19,6 +19,18 @@ struct pci_dev;
19struct seq_file; 19struct seq_file;
20struct file; 20struct file;
21 21
22/*
23 * This is for compatibility with ARCH=powerpc.
24 */
25#define machine_is(x) __MACHINE_IS_##x
26#define __MACHINE_IS_powermac 0
27#define __MACHINE_IS_chrp 0
28#ifdef CONFIG_PPC_PREP
29#define __MACHINE_IS_prep 1
30#else
31#define __MACHINE_IS_prep 0
32#endif
33
22/* We export this macro for external modules like Alsa to know if 34/* We export this macro for external modules like Alsa to know if
23 * ppc_md.feature_call is implemented or not 35 * ppc_md.feature_call is implemented or not
24 */ 36 */
@@ -44,7 +56,7 @@ struct machdep_calls {
44 void (*power_off)(void); 56 void (*power_off)(void);
45 void (*halt)(void); 57 void (*halt)(void);
46 58
47 void (*idle)(void); 59 void (*idle_loop)(void);
48 void (*power_save)(void); 60 void (*power_save)(void);
49 61
50 long (*time_init)(void); /* Optional, may be NULL */ 62 long (*time_init)(void); /* Optional, may be NULL */
@@ -104,9 +116,6 @@ struct machdep_calls {
104 unsigned long size, 116 unsigned long size,
105 pgprot_t vma_prot); 117 pgprot_t vma_prot);
106 118
107 /* this is for modules, since _machine can be a define -- Cort */
108 int ppc_machine;
109
110 /* Motherboard/chipset features. This is a kind of general purpose 119 /* Motherboard/chipset features. This is a kind of general purpose
111 * hook used to control some machine specific features (like reset 120 * hook used to control some machine specific features (like reset
112 * lines, chip power control, etc...). 121 * lines, chip power control, etc...).
diff --git a/include/asm-ppc/mpc52xx.h b/include/asm-ppc/mpc52xx.h
index 6167f74635f7..7e9842805a28 100644
--- a/include/asm-ppc/mpc52xx.h
+++ b/include/asm-ppc/mpc52xx.h
@@ -355,6 +355,7 @@ struct mpc52xx_xlb {
355 u32 snoop_window; /* XLB + 0x70 */ 355 u32 snoop_window; /* XLB + 0x70 */
356}; 356};
357 357
358#define MPC52xx_XLB_CFG_PLDIS (1 << 31)
358#define MPC52xx_XLB_CFG_SNOOP (1 << 15) 359#define MPC52xx_XLB_CFG_SNOOP (1 << 15)
359 360
360/* Clock Distribution control */ 361/* Clock Distribution control */
@@ -427,6 +428,9 @@ extern void mpc52xx_calibrate_decr(void);
427 428
428extern void mpc52xx_find_bridges(void); 429extern void mpc52xx_find_bridges(void);
429 430
431extern void mpc52xx_setup_cpu(void);
432
433
430 434
431 /* Matching of PSC function */ 435 /* Matching of PSC function */
432struct mpc52xx_psc_func { 436struct mpc52xx_psc_func {
diff --git a/include/asm-ppc/pgtable.h b/include/asm-ppc/pgtable.h
index e1c62da12e74..570b355162fa 100644
--- a/include/asm-ppc/pgtable.h
+++ b/include/asm-ppc/pgtable.h
@@ -837,7 +837,8 @@ static inline int io_remap_pfn_range(struct vm_area_struct *vma,
837 */ 837 */
838#define pgtable_cache_init() do { } while (0) 838#define pgtable_cache_init() do { } while (0)
839 839
840extern int get_pteptr(struct mm_struct *mm, unsigned long addr, pte_t **ptep); 840extern int get_pteptr(struct mm_struct *mm, unsigned long addr, pte_t **ptep,
841 pmd_t **pmdp);
841 842
842#include <asm-generic/pgtable.h> 843#include <asm-generic/pgtable.h>
843 844
diff --git a/include/asm-ppc/prom.h b/include/asm-ppc/prom.h
index 6d431d6fb022..adc5ae784924 100644
--- a/include/asm-ppc/prom.h
+++ b/include/asm-ppc/prom.h
@@ -8,126 +8,19 @@
8#ifndef _PPC_PROM_H 8#ifndef _PPC_PROM_H
9#define _PPC_PROM_H 9#define _PPC_PROM_H
10 10
11#include <linux/config.h> 11/* This is used in arch/ppc/mm/mem_pieces.h */
12#include <linux/types.h>
13
14typedef u32 phandle;
15typedef u32 ihandle;
16
17struct address_range {
18 unsigned int space;
19 unsigned int address;
20 unsigned int size;
21};
22
23struct interrupt_info {
24 int line;
25 int sense; /* +ve/-ve logic, edge or level, etc. */
26};
27
28struct reg_property { 12struct reg_property {
29 unsigned int address; 13 unsigned int address;
30 unsigned int size; 14 unsigned int size;
31}; 15};
32 16
33struct property {
34 char *name;
35 int length;
36 unsigned char *value;
37 struct property *next;
38};
39
40/*
41 * Note: don't change this structure for now or you'll break BootX !
42 */
43struct device_node {
44 char *name;
45 char *type;
46 phandle node;
47 int n_addrs;
48 struct address_range *addrs;
49 int n_intrs;
50 struct interrupt_info *intrs;
51 char *full_name;
52 struct property *properties;
53 struct device_node *parent;
54 struct device_node *child;
55 struct device_node *sibling;
56 struct device_node *next; /* next device of same type */
57 struct device_node *allnext; /* next in list of all nodes */
58};
59
60struct prom_args;
61typedef void (*prom_entry)(struct prom_args *);
62
63/* OBSOLETE: Old style node lookup */
64extern struct device_node *find_devices(const char *name);
65extern struct device_node *find_type_devices(const char *type);
66extern struct device_node *find_path_device(const char *path);
67extern struct device_node *find_compatible_devices(const char *type,
68 const char *compat);
69extern struct device_node *find_all_nodes(void);
70
71/* New style node lookup */
72extern struct device_node *of_find_node_by_name(struct device_node *from,
73 const char *name);
74extern struct device_node *of_find_node_by_type(struct device_node *from,
75 const char *type);
76extern struct device_node *of_find_compatible_node(struct device_node *from,
77 const char *type, const char *compat);
78extern struct device_node *of_find_node_by_path(const char *path);
79extern struct device_node *of_find_all_nodes(struct device_node *prev);
80extern struct device_node *of_get_parent(const struct device_node *node);
81extern struct device_node *of_get_next_child(const struct device_node *node,
82 struct device_node *prev);
83extern struct device_node *of_node_get(struct device_node *node);
84extern void of_node_put(struct device_node *node);
85
86/* Other Prototypes */
87extern void abort(void);
88extern unsigned long prom_init(int, int, prom_entry);
89extern void prom_print(const char *msg);
90extern void relocate_nodes(void);
91extern void finish_device_tree(void);
92extern int device_is_compatible(struct device_node *device, const char *);
93extern int machine_is_compatible(const char *compat);
94extern unsigned char *get_property(struct device_node *node, const char *name,
95 int *lenp);
96extern int prom_add_property(struct device_node* np, struct property* prop);
97extern void prom_get_irq_senses(unsigned char *, int, int);
98extern int prom_n_addr_cells(struct device_node* np);
99extern int prom_n_size_cells(struct device_node* np);
100
101extern struct resource*
102request_OF_resource(struct device_node* node, int index, const char* name_postfix);
103extern int release_OF_resource(struct device_node* node, int index);
104
105extern void print_properties(struct device_node *node);
106extern int call_rtas(const char *service, int nargs, int nret,
107 unsigned long *outputs, ...);
108
109/* 17/*
110 * PCI <-> OF matching functions 18 * These macros assist in performing the address calculations that we
111 */ 19 * need to do to access data when the kernel is running at an address
112struct pci_bus; 20 * that is different from the address that the kernel is linked at.
113struct pci_dev; 21 * The reloc_offset() function returns the difference between these
114extern int pci_device_from_OF_node(struct device_node *node, 22 * two addresses and the macros simplify the process of adding or
115 u8* bus, u8* devfn); 23 * subtracting this offset to/from pointer values.
116extern struct device_node* pci_busdev_to_OF_node(struct pci_bus *, int);
117extern struct device_node* pci_device_to_OF_node(struct pci_dev *);
118extern void pci_create_OF_bus_map(void);
119
120/*
121 * When we call back to the Open Firmware client interface, we usually
122 * have to do that before the kernel is relocated to its final location
123 * (this is because we can't use OF after we have overwritten the
124 * exception vectors with our exception handlers). These macros assist
125 * in performing the address calculations that we need to do to access
126 * data when the kernel is running at an address that is different from
127 * the address that the kernel is linked at. The reloc_offset() function
128 * returns the difference between these two addresses and the macros
129 * simplify the process of adding or subtracting this offset to/from
130 * pointer values. See arch/ppc/kernel/prom.c for how these are used.
131 */ 24 */
132extern unsigned long reloc_offset(void); 25extern unsigned long reloc_offset(void);
133extern unsigned long add_reloc_offset(unsigned long); 26extern unsigned long add_reloc_offset(unsigned long);
@@ -136,45 +29,12 @@ extern unsigned long sub_reloc_offset(unsigned long);
136#define PTRRELOC(x) ((typeof(x))add_reloc_offset((unsigned long)(x))) 29#define PTRRELOC(x) ((typeof(x))add_reloc_offset((unsigned long)(x)))
137#define PTRUNRELOC(x) ((typeof(x))sub_reloc_offset((unsigned long)(x))) 30#define PTRUNRELOC(x) ((typeof(x))sub_reloc_offset((unsigned long)(x)))
138 31
139
140/*
141 * OF address retreival & translation
142 */
143
144
145/* Translate an OF address block into a CPU physical address
146 */
147#define OF_BAD_ADDR ((u64)-1)
148extern u64 of_translate_address(struct device_node *np, u32 *addr);
149
150/* Extract an address from a device, returns the region size and
151 * the address space flags too. The PCI version uses a BAR number
152 * instead of an absolute index
153 */
154extern u32 *of_get_address(struct device_node *dev, int index,
155 u64 *size, unsigned int *flags);
156extern u32 *of_get_pci_address(struct device_node *dev, int bar_no,
157 u64 *size, unsigned int *flags);
158
159/* Get an address as a resource. Note that if your address is
160 * a PIO address, the conversion will fail if the physical address
161 * can't be internally converted to an IO token with
162 * pci_address_to_pio(), that is because it's either called to early
163 * or it can't be matched to any host bridge IO space
164 */
165extern int of_address_to_resource(struct device_node *dev, int index,
166 struct resource *r);
167extern int of_pci_address_to_resource(struct device_node *dev, int bar,
168 struct resource *r);
169
170#ifndef CONFIG_PPC_OF
171/* 32/*
172 * Fallback definitions for builds where we don't have prom.c included. 33 * Fallback definitions since we don't support OF in arch/ppc any more.
173 */ 34 */
174#define machine_is_compatible(x) 0 35#define machine_is_compatible(x) 0
175#define of_find_compatible_node(f, t, c) NULL 36#define of_find_compatible_node(f, t, c) NULL
176#define get_property(p, n, l) NULL 37#define get_property(p, n, l) NULL
177#endif
178 38
179#endif /* _PPC_PROM_H */ 39#endif /* _PPC_PROM_H */
180#endif /* __KERNEL__ */ 40#endif /* __KERNEL__ */
diff --git a/include/asm-ppc/serial.h b/include/asm-ppc/serial.h
index 485a924e4d06..b74af5461564 100644
--- a/include/asm-ppc/serial.h
+++ b/include/asm-ppc/serial.h
@@ -41,15 +41,10 @@
41#else 41#else
42 42
43/* 43/*
44 * XXX Assume for now it has PC-style ISA serial ports. 44 * XXX Assume it has PC-style ISA serial ports - true for PReP at least.
45 * This is true for PReP and CHRP at least.
46 */ 45 */
47#include <asm/pc_serial.h> 46#include <asm/pc_serial.h>
48 47
49#if defined(CONFIG_MAC_SERIAL)
50#define SERIAL_DEV_OFFSET ((_machine == _MACH_prep || _machine == _MACH_chrp) ? 0 : 2)
51#endif
52
53#endif /* !CONFIG_GEMINI and others */ 48#endif /* !CONFIG_GEMINI and others */
54#endif /* __ASM_SERIAL_H__ */ 49#endif /* __ASM_SERIAL_H__ */
55#endif /* __KERNEL__ */ 50#endif /* __KERNEL__ */
diff --git a/include/asm-s390/percpu.h b/include/asm-s390/percpu.h
index e10ed87094f0..436d216601e5 100644
--- a/include/asm-s390/percpu.h
+++ b/include/asm-s390/percpu.h
@@ -46,7 +46,7 @@ extern unsigned long __per_cpu_offset[NR_CPUS];
46#define percpu_modcopy(pcpudst, src, size) \ 46#define percpu_modcopy(pcpudst, src, size) \
47do { \ 47do { \
48 unsigned int __i; \ 48 unsigned int __i; \
49 for_each_cpu(__i) \ 49 for_each_possible_cpu(__i) \
50 memcpy((pcpudst)+__per_cpu_offset[__i], \ 50 memcpy((pcpudst)+__per_cpu_offset[__i], \
51 (src), (size)); \ 51 (src), (size)); \
52} while (0) 52} while (0)
diff --git a/include/asm-um/desc.h b/include/asm-um/desc.h
index ac1d2a20d178..4ec34a51b62c 100644
--- a/include/asm-um/desc.h
+++ b/include/asm-um/desc.h
@@ -1,6 +1,16 @@
1#ifndef __UM_DESC_H 1#ifndef __UM_DESC_H
2#define __UM_DESC_H 2#define __UM_DESC_H
3 3
4#include "asm/arch/desc.h" 4/* Taken from asm-i386/desc.h, it's the only thing we need. The rest wouldn't
5 * compile, and has never been used. */
6#define LDT_empty(info) (\
7 (info)->base_addr == 0 && \
8 (info)->limit == 0 && \
9 (info)->contents == 0 && \
10 (info)->read_exec_only == 1 && \
11 (info)->seg_32bit == 0 && \
12 (info)->limit_in_pages == 0 && \
13 (info)->seg_not_present == 1 && \
14 (info)->useable == 0 )
5 15
6#endif 16#endif
diff --git a/include/asm-um/host_ldt-i386.h b/include/asm-um/host_ldt-i386.h
new file mode 100644
index 000000000000..b27cb0a9dd30
--- /dev/null
+++ b/include/asm-um/host_ldt-i386.h
@@ -0,0 +1,34 @@
1#ifndef __ASM_HOST_LDT_I386_H
2#define __ASM_HOST_LDT_I386_H
3
4#include "asm/arch/ldt.h"
5
6/*
7 * macros stolen from include/asm-i386/desc.h
8 */
9#define LDT_entry_a(info) \
10 ((((info)->base_addr & 0x0000ffff) << 16) | ((info)->limit & 0x0ffff))
11
12#define LDT_entry_b(info) \
13 (((info)->base_addr & 0xff000000) | \
14 (((info)->base_addr & 0x00ff0000) >> 16) | \
15 ((info)->limit & 0xf0000) | \
16 (((info)->read_exec_only ^ 1) << 9) | \
17 ((info)->contents << 10) | \
18 (((info)->seg_not_present ^ 1) << 15) | \
19 ((info)->seg_32bit << 22) | \
20 ((info)->limit_in_pages << 23) | \
21 ((info)->useable << 20) | \
22 0x7000)
23
24#define LDT_empty(info) (\
25 (info)->base_addr == 0 && \
26 (info)->limit == 0 && \
27 (info)->contents == 0 && \
28 (info)->read_exec_only == 1 && \
29 (info)->seg_32bit == 0 && \
30 (info)->limit_in_pages == 0 && \
31 (info)->seg_not_present == 1 && \
32 (info)->useable == 0 )
33
34#endif
diff --git a/include/asm-um/ldt-x86_64.h b/include/asm-um/host_ldt-x86_64.h
index 96b35aada79a..74a63f7d9a90 100644
--- a/include/asm-um/ldt-x86_64.h
+++ b/include/asm-um/host_ldt-x86_64.h
@@ -1,43 +1,8 @@
1/* 1#ifndef __ASM_HOST_LDT_X86_64_H
2 * Copyright (C) 2004 Fujitsu Siemens Computers GmbH 2#define __ASM_HOST_LDT_X86_64_H
3 * Licensed under the GPL
4 *
5 * Author: Bodo Stroesser <bstroesser@fujitsu-siemens.com>
6 */
7 3
8#ifndef __ASM_LDT_X86_64_H
9#define __ASM_LDT_X86_64_H
10
11#include "asm/semaphore.h"
12#include "asm/arch/ldt.h" 4#include "asm/arch/ldt.h"
13 5
14struct mmu_context_skas;
15extern void ldt_host_info(void);
16extern long init_new_ldt(struct mmu_context_skas * to_mm,
17 struct mmu_context_skas * from_mm);
18extern void free_ldt(struct mmu_context_skas * mm);
19
20#define LDT_PAGES_MAX \
21 ((LDT_ENTRIES * LDT_ENTRY_SIZE)/PAGE_SIZE)
22#define LDT_ENTRIES_PER_PAGE \
23 (PAGE_SIZE/LDT_ENTRY_SIZE)
24#define LDT_DIRECT_ENTRIES \
25 ((LDT_PAGES_MAX*sizeof(void *))/LDT_ENTRY_SIZE)
26
27struct ldt_entry {
28 __u32 a;
29 __u32 b;
30};
31
32typedef struct uml_ldt {
33 int entry_count;
34 struct semaphore semaphore;
35 union {
36 struct ldt_entry * pages[LDT_PAGES_MAX];
37 struct ldt_entry entries[LDT_DIRECT_ENTRIES];
38 } u;
39} uml_ldt_t;
40
41/* 6/*
42 * macros stolen from include/asm-x86_64/desc.h 7 * macros stolen from include/asm-x86_64/desc.h
43 */ 8 */
diff --git a/include/asm-um/ldt-i386.h b/include/asm-um/ldt-i386.h
deleted file mode 100644
index 175722a91164..000000000000
--- a/include/asm-um/ldt-i386.h
+++ /dev/null
@@ -1,69 +0,0 @@
1/*
2 * Copyright (C) 2004 Fujitsu Siemens Computers GmbH
3 * Licensed under the GPL
4 *
5 * Author: Bodo Stroesser <bstroesser@fujitsu-siemens.com>
6 */
7
8#ifndef __ASM_LDT_I386_H
9#define __ASM_LDT_I386_H
10
11#include "asm/semaphore.h"
12#include "asm/arch/ldt.h"
13
14struct mmu_context_skas;
15extern void ldt_host_info(void);
16extern long init_new_ldt(struct mmu_context_skas * to_mm,
17 struct mmu_context_skas * from_mm);
18extern void free_ldt(struct mmu_context_skas * mm);
19
20#define LDT_PAGES_MAX \
21 ((LDT_ENTRIES * LDT_ENTRY_SIZE)/PAGE_SIZE)
22#define LDT_ENTRIES_PER_PAGE \
23 (PAGE_SIZE/LDT_ENTRY_SIZE)
24#define LDT_DIRECT_ENTRIES \
25 ((LDT_PAGES_MAX*sizeof(void *))/LDT_ENTRY_SIZE)
26
27struct ldt_entry {
28 __u32 a;
29 __u32 b;
30};
31
32typedef struct uml_ldt {
33 int entry_count;
34 struct semaphore semaphore;
35 union {
36 struct ldt_entry * pages[LDT_PAGES_MAX];
37 struct ldt_entry entries[LDT_DIRECT_ENTRIES];
38 } u;
39} uml_ldt_t;
40
41/*
42 * macros stolen from include/asm-i386/desc.h
43 */
44#define LDT_entry_a(info) \
45 ((((info)->base_addr & 0x0000ffff) << 16) | ((info)->limit & 0x0ffff))
46
47#define LDT_entry_b(info) \
48 (((info)->base_addr & 0xff000000) | \
49 (((info)->base_addr & 0x00ff0000) >> 16) | \
50 ((info)->limit & 0xf0000) | \
51 (((info)->read_exec_only ^ 1) << 9) | \
52 ((info)->contents << 10) | \
53 (((info)->seg_not_present ^ 1) << 15) | \
54 ((info)->seg_32bit << 22) | \
55 ((info)->limit_in_pages << 23) | \
56 ((info)->useable << 20) | \
57 0x7000)
58
59#define LDT_empty(info) (\
60 (info)->base_addr == 0 && \
61 (info)->limit == 0 && \
62 (info)->contents == 0 && \
63 (info)->read_exec_only == 1 && \
64 (info)->seg_32bit == 0 && \
65 (info)->limit_in_pages == 0 && \
66 (info)->seg_not_present == 1 && \
67 (info)->useable == 0 )
68
69#endif
diff --git a/include/asm-um/ldt.h b/include/asm-um/ldt.h
new file mode 100644
index 000000000000..96f82a456ce6
--- /dev/null
+++ b/include/asm-um/ldt.h
@@ -0,0 +1,41 @@
1/*
2 * Copyright (C) 2004 Fujitsu Siemens Computers GmbH
3 * Licensed under the GPL
4 *
5 * Author: Bodo Stroesser <bstroesser@fujitsu-siemens.com>
6 */
7
8#ifndef __ASM_LDT_H
9#define __ASM_LDT_H
10
11#include "asm/semaphore.h"
12#include "asm/host_ldt.h"
13
14struct mmu_context_skas;
15extern void ldt_host_info(void);
16extern long init_new_ldt(struct mmu_context_skas * to_mm,
17 struct mmu_context_skas * from_mm);
18extern void free_ldt(struct mmu_context_skas * mm);
19
20#define LDT_PAGES_MAX \
21 ((LDT_ENTRIES * LDT_ENTRY_SIZE)/PAGE_SIZE)
22#define LDT_ENTRIES_PER_PAGE \
23 (PAGE_SIZE/LDT_ENTRY_SIZE)
24#define LDT_DIRECT_ENTRIES \
25 ((LDT_PAGES_MAX*sizeof(void *))/LDT_ENTRY_SIZE)
26
27struct ldt_entry {
28 __u32 a;
29 __u32 b;
30};
31
32typedef struct uml_ldt {
33 int entry_count;
34 struct semaphore semaphore;
35 union {
36 struct ldt_entry * pages[LDT_PAGES_MAX];
37 struct ldt_entry entries[LDT_DIRECT_ENTRIES];
38 } u;
39} uml_ldt_t;
40
41#endif
diff --git a/include/asm-um/processor-i386.h b/include/asm-um/processor-i386.h
index 4108a579eb92..595f1c3e1e40 100644
--- a/include/asm-um/processor-i386.h
+++ b/include/asm-um/processor-i386.h
@@ -1,4 +1,4 @@
1/* 1/*
2 * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) 2 * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
@@ -6,21 +6,48 @@
6#ifndef __UM_PROCESSOR_I386_H 6#ifndef __UM_PROCESSOR_I386_H
7#define __UM_PROCESSOR_I386_H 7#define __UM_PROCESSOR_I386_H
8 8
9#include "linux/string.h"
10#include "asm/host_ldt.h"
11#include "asm/segment.h"
12
9extern int host_has_xmm; 13extern int host_has_xmm;
10extern int host_has_cmov; 14extern int host_has_cmov;
11 15
12/* include faultinfo structure */ 16/* include faultinfo structure */
13#include "sysdep/faultinfo.h" 17#include "sysdep/faultinfo.h"
14 18
19struct uml_tls_struct {
20 struct user_desc tls;
21 unsigned flushed:1;
22 unsigned present:1;
23};
24
15struct arch_thread { 25struct arch_thread {
26 struct uml_tls_struct tls_array[GDT_ENTRY_TLS_ENTRIES];
16 unsigned long debugregs[8]; 27 unsigned long debugregs[8];
17 int debugregs_seq; 28 int debugregs_seq;
18 struct faultinfo faultinfo; 29 struct faultinfo faultinfo;
19}; 30};
20 31
21#define INIT_ARCH_THREAD { .debugregs = { [ 0 ... 7 ] = 0 }, \ 32#define INIT_ARCH_THREAD { \
22 .debugregs_seq = 0, \ 33 .tls_array = { [ 0 ... GDT_ENTRY_TLS_ENTRIES - 1 ] = \
23 .faultinfo = { 0, 0, 0 } } 34 { .present = 0, .flushed = 0 } }, \
35 .debugregs = { [ 0 ... 7 ] = 0 }, \
36 .debugregs_seq = 0, \
37 .faultinfo = { 0, 0, 0 } \
38}
39
40static inline void arch_flush_thread(struct arch_thread *thread)
41{
42 /* Clear any TLS still hanging */
43 memset(&thread->tls_array, 0, sizeof(thread->tls_array));
44}
45
46static inline void arch_copy_thread(struct arch_thread *from,
47 struct arch_thread *to)
48{
49 memcpy(&to->tls_array, &from->tls_array, sizeof(from->tls_array));
50}
24 51
25#include "asm/arch/user.h" 52#include "asm/arch/user.h"
26 53
diff --git a/include/asm-um/processor-x86_64.h b/include/asm-um/processor-x86_64.h
index e1e1255a1d36..10609af376c0 100644
--- a/include/asm-um/processor-x86_64.h
+++ b/include/asm-um/processor-x86_64.h
@@ -28,6 +28,15 @@ extern inline void rep_nop(void)
28 .debugregs_seq = 0, \ 28 .debugregs_seq = 0, \
29 .faultinfo = { 0, 0, 0 } } 29 .faultinfo = { 0, 0, 0 } }
30 30
31static inline void arch_flush_thread(struct arch_thread *thread)
32{
33}
34
35static inline void arch_copy_thread(struct arch_thread *from,
36 struct arch_thread *to)
37{
38}
39
31#include "asm/arch/user.h" 40#include "asm/arch/user.h"
32 41
33#define current_text_addr() \ 42#define current_text_addr() \
diff --git a/include/asm-um/ptrace-generic.h b/include/asm-um/ptrace-generic.h
index 46599ac44037..503484305e67 100644
--- a/include/asm-um/ptrace-generic.h
+++ b/include/asm-um/ptrace-generic.h
@@ -28,7 +28,7 @@ struct pt_regs {
28 union uml_pt_regs regs; 28 union uml_pt_regs regs;
29}; 29};
30 30
31#define EMPTY_REGS { regs : EMPTY_UML_PT_REGS } 31#define EMPTY_REGS { .regs = EMPTY_UML_PT_REGS }
32 32
33#define PT_REGS_IP(r) UPT_IP(&(r)->regs) 33#define PT_REGS_IP(r) UPT_IP(&(r)->regs)
34#define PT_REGS_SP(r) UPT_SP(&(r)->regs) 34#define PT_REGS_SP(r) UPT_SP(&(r)->regs)
@@ -60,17 +60,9 @@ extern void show_regs(struct pt_regs *regs);
60extern void send_sigtrap(struct task_struct *tsk, union uml_pt_regs *regs, 60extern void send_sigtrap(struct task_struct *tsk, union uml_pt_regs *regs,
61 int error_code); 61 int error_code);
62 62
63#endif 63extern int arch_copy_tls(struct task_struct *new);
64extern void clear_flushed_tls(struct task_struct *task);
64 65
65#endif 66#endif
66 67
67/* 68#endif
68 * Overrides for Emacs so that we follow Linus's tabbing style.
69 * Emacs will notice this stuff at the end of the file and automatically
70 * adjust the settings for this buffer only. This must remain at the end
71 * of the file.
72 * ---------------------------------------------------------------------------
73 * Local variables:
74 * c-file-style: "linux"
75 * End:
76 */
diff --git a/include/asm-um/ptrace-i386.h b/include/asm-um/ptrace-i386.h
index fe882b9d917e..30656c962d74 100644
--- a/include/asm-um/ptrace-i386.h
+++ b/include/asm-um/ptrace-i386.h
@@ -8,8 +8,11 @@
8 8
9#define HOST_AUDIT_ARCH AUDIT_ARCH_I386 9#define HOST_AUDIT_ARCH AUDIT_ARCH_I386
10 10
11#include "linux/compiler.h"
11#include "sysdep/ptrace.h" 12#include "sysdep/ptrace.h"
12#include "asm/ptrace-generic.h" 13#include "asm/ptrace-generic.h"
14#include "asm/host_ldt.h"
15#include "choose-mode.h"
13 16
14#define PT_REGS_EAX(r) UPT_EAX(&(r)->regs) 17#define PT_REGS_EAX(r) UPT_EAX(&(r)->regs)
15#define PT_REGS_EBX(r) UPT_EBX(&(r)->regs) 18#define PT_REGS_EBX(r) UPT_EBX(&(r)->regs)
@@ -38,15 +41,31 @@
38 41
39#define user_mode(r) UPT_IS_USER(&(r)->regs) 42#define user_mode(r) UPT_IS_USER(&(r)->regs)
40 43
41#endif 44extern int ptrace_get_thread_area(struct task_struct *child, int idx,
45 struct user_desc __user *user_desc);
42 46
43/* 47extern int ptrace_set_thread_area(struct task_struct *child, int idx,
44 * Overrides for Emacs so that we follow Linus's tabbing style. 48 struct user_desc __user *user_desc);
45 * Emacs will notice this stuff at the end of the file and automatically 49
46 * adjust the settings for this buffer only. This must remain at the end 50extern int do_set_thread_area_skas(struct user_desc *info);
47 * of the file. 51extern int do_get_thread_area_skas(struct user_desc *info);
48 * --------------------------------------------------------------------------- 52
49 * Local variables: 53extern int do_set_thread_area_tt(struct user_desc *info);
50 * c-file-style: "linux" 54extern int do_get_thread_area_tt(struct user_desc *info);
51 * End: 55
52 */ 56extern int arch_switch_tls_skas(struct task_struct *from, struct task_struct *to);
57extern int arch_switch_tls_tt(struct task_struct *from, struct task_struct *to);
58
59static inline int do_get_thread_area(struct user_desc *info)
60{
61 return CHOOSE_MODE_PROC(do_get_thread_area_tt, do_get_thread_area_skas, info);
62}
63
64static inline int do_set_thread_area(struct user_desc *info)
65{
66 return CHOOSE_MODE_PROC(do_set_thread_area_tt, do_set_thread_area_skas, info);
67}
68
69struct task_struct;
70
71#endif
diff --git a/include/asm-um/ptrace-x86_64.h b/include/asm-um/ptrace-x86_64.h
index be51219a8ffe..c894e68b1f96 100644
--- a/include/asm-um/ptrace-x86_64.h
+++ b/include/asm-um/ptrace-x86_64.h
@@ -8,6 +8,8 @@
8#define __UM_PTRACE_X86_64_H 8#define __UM_PTRACE_X86_64_H
9 9
10#include "linux/compiler.h" 10#include "linux/compiler.h"
11#include "asm/errno.h"
12#include "asm/host_ldt.h"
11 13
12#define signal_fault signal_fault_x86_64 14#define signal_fault signal_fault_x86_64
13#define __FRAME_OFFSETS /* Needed to get the R* macros */ 15#define __FRAME_OFFSETS /* Needed to get the R* macros */
@@ -63,15 +65,26 @@ void signal_fault(struct pt_regs_subarch *regs, void *frame, char *where);
63 65
64#define profile_pc(regs) PT_REGS_IP(regs) 66#define profile_pc(regs) PT_REGS_IP(regs)
65 67
66#endif 68static inline int ptrace_get_thread_area(struct task_struct *child, int idx,
69 struct user_desc __user *user_desc)
70{
71 return -ENOSYS;
72}
67 73
68/* 74static inline int ptrace_set_thread_area(struct task_struct *child, int idx,
69 * Overrides for Emacs so that we follow Linus's tabbing style. 75 struct user_desc __user *user_desc)
70 * Emacs will notice this stuff at the end of the file and automatically 76{
71 * adjust the settings for this buffer only. This must remain at the end 77 return -ENOSYS;
72 * of the file. 78}
73 * --------------------------------------------------------------------------- 79
74 * Local variables: 80static inline void arch_switch_to_tt(struct task_struct *from,
75 * c-file-style: "linux" 81 struct task_struct *to)
76 * End: 82{
77 */ 83}
84
85static inline void arch_switch_to_skas(struct task_struct *from,
86 struct task_struct *to)
87{
88}
89
90#endif
diff --git a/include/asm-um/segment.h b/include/asm-um/segment.h
index 55e40301f625..45183fcd10b6 100644
--- a/include/asm-um/segment.h
+++ b/include/asm-um/segment.h
@@ -1,4 +1,10 @@
1#ifndef __UM_SEGMENT_H 1#ifndef __UM_SEGMENT_H
2#define __UM_SEGMENT_H 2#define __UM_SEGMENT_H
3 3
4extern int host_gdt_entry_tls_min;
5
6#define GDT_ENTRY_TLS_ENTRIES 3
7#define GDT_ENTRY_TLS_MIN host_gdt_entry_tls_min
8#define GDT_ENTRY_TLS_MAX (GDT_ENTRY_TLS_MIN + GDT_ENTRY_TLS_ENTRIES - 1)
9
4#endif 10#endif
diff --git a/include/asm-um/thread_info.h b/include/asm-um/thread_info.h
index 17b6b07c4332..f166b9837c6a 100644
--- a/include/asm-um/thread_info.h
+++ b/include/asm-um/thread_info.h
@@ -27,14 +27,14 @@ struct thread_info {
27 27
28#define INIT_THREAD_INFO(tsk) \ 28#define INIT_THREAD_INFO(tsk) \
29{ \ 29{ \
30 task: &tsk, \ 30 .task = &tsk, \
31 exec_domain: &default_exec_domain, \ 31 .exec_domain = &default_exec_domain, \
32 flags: 0, \ 32 .flags = 0, \
33 cpu: 0, \ 33 .cpu = 0, \
34 preempt_count: 1, \ 34 .preempt_count = 1, \
35 addr_limit: KERNEL_DS, \ 35 .addr_limit = KERNEL_DS, \
36 restart_block: { \ 36 .restart_block = { \
37 fn: do_no_restart_syscall, \ 37 .fn = do_no_restart_syscall, \
38 }, \ 38 }, \
39} 39}
40 40
diff --git a/include/asm-um/uaccess.h b/include/asm-um/uaccess.h
index 4e460d6f5ac8..bea5a015f667 100644
--- a/include/asm-um/uaccess.h
+++ b/include/asm-um/uaccess.h
@@ -57,7 +57,7 @@
57({ \ 57({ \
58 const __typeof__((*(ptr))) __user *private_ptr = (ptr); \ 58 const __typeof__((*(ptr))) __user *private_ptr = (ptr); \
59 (access_ok(VERIFY_READ, private_ptr, sizeof(*private_ptr)) ? \ 59 (access_ok(VERIFY_READ, private_ptr, sizeof(*private_ptr)) ? \
60 __get_user(x, private_ptr) : ((x) = 0, -EFAULT)); \ 60 __get_user(x, private_ptr) : ((x) = (__typeof__(*ptr))0, -EFAULT)); \
61}) 61})
62 62
63#define __put_user(x, ptr) \ 63#define __put_user(x, ptr) \
diff --git a/include/asm-x86_64/local.h b/include/asm-x86_64/local.h
index bf148037d4e5..cd17945bf218 100644
--- a/include/asm-x86_64/local.h
+++ b/include/asm-x86_64/local.h
@@ -5,7 +5,7 @@
5 5
6typedef struct 6typedef struct
7{ 7{
8 volatile unsigned long counter; 8 volatile long counter;
9} local_t; 9} local_t;
10 10
11#define LOCAL_INIT(i) { (i) } 11#define LOCAL_INIT(i) { (i) }
@@ -13,7 +13,7 @@ typedef struct
13#define local_read(v) ((v)->counter) 13#define local_read(v) ((v)->counter)
14#define local_set(v,i) (((v)->counter) = (i)) 14#define local_set(v,i) (((v)->counter) = (i))
15 15
16static __inline__ void local_inc(local_t *v) 16static inline void local_inc(local_t *v)
17{ 17{
18 __asm__ __volatile__( 18 __asm__ __volatile__(
19 "incq %0" 19 "incq %0"
@@ -21,7 +21,7 @@ static __inline__ void local_inc(local_t *v)
21 :"m" (v->counter)); 21 :"m" (v->counter));
22} 22}
23 23
24static __inline__ void local_dec(local_t *v) 24static inline void local_dec(local_t *v)
25{ 25{
26 __asm__ __volatile__( 26 __asm__ __volatile__(
27 "decq %0" 27 "decq %0"
@@ -29,7 +29,7 @@ static __inline__ void local_dec(local_t *v)
29 :"m" (v->counter)); 29 :"m" (v->counter));
30} 30}
31 31
32static __inline__ void local_add(unsigned int i, local_t *v) 32static inline void local_add(long i, local_t *v)
33{ 33{
34 __asm__ __volatile__( 34 __asm__ __volatile__(
35 "addq %1,%0" 35 "addq %1,%0"
@@ -37,7 +37,7 @@ static __inline__ void local_add(unsigned int i, local_t *v)
37 :"ir" (i), "m" (v->counter)); 37 :"ir" (i), "m" (v->counter));
38} 38}
39 39
40static __inline__ void local_sub(unsigned int i, local_t *v) 40static inline void local_sub(long i, local_t *v)
41{ 41{
42 __asm__ __volatile__( 42 __asm__ __volatile__(
43 "subq %1,%0" 43 "subq %1,%0"
diff --git a/include/asm-x86_64/unistd.h b/include/asm-x86_64/unistd.h
index fcc516353087..f21ff2c1e960 100644
--- a/include/asm-x86_64/unistd.h
+++ b/include/asm-x86_64/unistd.h
@@ -609,8 +609,10 @@ __SYSCALL(__NR_unshare, sys_unshare)
609__SYSCALL(__NR_set_robust_list, sys_set_robust_list) 609__SYSCALL(__NR_set_robust_list, sys_set_robust_list)
610#define __NR_get_robust_list 274 610#define __NR_get_robust_list 274
611__SYSCALL(__NR_get_robust_list, sys_get_robust_list) 611__SYSCALL(__NR_get_robust_list, sys_get_robust_list)
612#define __NR_splice 275
613__SYSCALL(__NR_splice, sys_splice)
612 614
613#define __NR_syscall_max __NR_get_robust_list 615#define __NR_syscall_max __NR_splice
614 616
615#ifndef __NO_STUBS 617#ifndef __NO_STUBS
616 618
diff --git a/include/linux/backlight.h b/include/linux/backlight.h
index bb9e54322322..75e91f5b6a04 100644
--- a/include/linux/backlight.h
+++ b/include/linux/backlight.h
@@ -19,20 +19,25 @@ struct fb_info;
19struct backlight_properties { 19struct backlight_properties {
20 /* Owner module */ 20 /* Owner module */
21 struct module *owner; 21 struct module *owner;
22 /* Get the backlight power status (0: full on, 1..3: power saving 22
23 modes; 4: full off), see FB_BLANK_XXX */ 23 /* Notify the backlight driver some property has changed */
24 int (*get_power)(struct backlight_device *); 24 int (*update_status)(struct backlight_device *);
25 /* Enable or disable power to the LCD (0: on; 4: off, see FB_BLANK_XXX) */ 25 /* Return the current backlight brightness (accounting for power,
26 int (*set_power)(struct backlight_device *, int power); 26 fb_blank etc.) */
27 /* Maximal value for brightness (read-only) */
28 int max_brightness;
29 /* Get current backlight brightness */
30 int (*get_brightness)(struct backlight_device *); 27 int (*get_brightness)(struct backlight_device *);
31 /* Set backlight brightness (0..max_brightness) */
32 int (*set_brightness)(struct backlight_device *, int brightness);
33 /* Check if given framebuffer device is the one bound to this backlight; 28 /* Check if given framebuffer device is the one bound to this backlight;
34 return 0 if not, !=0 if it is. If NULL, backlight always matches the fb. */ 29 return 0 if not, !=0 if it is. If NULL, backlight always matches the fb. */
35 int (*check_fb)(struct fb_info *); 30 int (*check_fb)(struct fb_info *);
31
32 /* Current User requested brightness (0 - max_brightness) */
33 int brightness;
34 /* Maximal value for brightness (read-only) */
35 int max_brightness;
36 /* Current FB Power mode (0: full on, 1..3: power saving
37 modes; 4: full off), see FB_BLANK_XXX */
38 int power;
39 /* FB Blanking active? (values as for power) */
40 int fb_blank;
36}; 41};
37 42
38struct backlight_device { 43struct backlight_device {
diff --git a/include/linux/dcache.h b/include/linux/dcache.h
index d10bd30c337e..836325ee0931 100644
--- a/include/linux/dcache.h
+++ b/include/linux/dcache.h
@@ -275,6 +275,7 @@ extern void d_move(struct dentry *, struct dentry *);
275/* appendix may either be NULL or be used for transname suffixes */ 275/* appendix may either be NULL or be used for transname suffixes */
276extern struct dentry * d_lookup(struct dentry *, struct qstr *); 276extern struct dentry * d_lookup(struct dentry *, struct qstr *);
277extern struct dentry * __d_lookup(struct dentry *, struct qstr *); 277extern struct dentry * __d_lookup(struct dentry *, struct qstr *);
278extern struct dentry * d_hash_and_lookup(struct dentry *, struct qstr *);
278 279
279/* validate "insecure" dentry pointer */ 280/* validate "insecure" dentry pointer */
280extern int d_validate(struct dentry *, struct dentry *); 281extern int d_validate(struct dentry *, struct dentry *);
diff --git a/include/linux/fadvise.h b/include/linux/fadvise.h
index b2913bba35d8..e8e747139b9a 100644
--- a/include/linux/fadvise.h
+++ b/include/linux/fadvise.h
@@ -18,10 +18,4 @@
18#define POSIX_FADV_NOREUSE 5 /* Data will be accessed once. */ 18#define POSIX_FADV_NOREUSE 5 /* Data will be accessed once. */
19#endif 19#endif
20 20
21/*
22 * Linux-specific fadvise() extensions:
23 */
24#define LINUX_FADV_ASYNC_WRITE 32 /* Start writeout on range */
25#define LINUX_FADV_WRITE_WAIT 33 /* Wait upon writeout to range */
26
27#endif /* FADVISE_H_INCLUDED */ 21#endif /* FADVISE_H_INCLUDED */
diff --git a/include/linux/fb.h b/include/linux/fb.h
index d03fadfcafe3..315d89740ddf 100644
--- a/include/linux/fb.h
+++ b/include/linux/fb.h
@@ -839,12 +839,10 @@ struct fb_info {
839#define FB_LEFT_POS(bpp) (32 - bpp) 839#define FB_LEFT_POS(bpp) (32 - bpp)
840#define FB_SHIFT_HIGH(val, bits) ((val) >> (bits)) 840#define FB_SHIFT_HIGH(val, bits) ((val) >> (bits))
841#define FB_SHIFT_LOW(val, bits) ((val) << (bits)) 841#define FB_SHIFT_LOW(val, bits) ((val) << (bits))
842#define FB_BIT_NR(b) (7 - (b))
843#else 842#else
844#define FB_LEFT_POS(bpp) (0) 843#define FB_LEFT_POS(bpp) (0)
845#define FB_SHIFT_HIGH(val, bits) ((val) << (bits)) 844#define FB_SHIFT_HIGH(val, bits) ((val) << (bits))
846#define FB_SHIFT_LOW(val, bits) ((val) >> (bits)) 845#define FB_SHIFT_LOW(val, bits) ((val) >> (bits))
847#define FB_BIT_NR(b) (b)
848#endif 846#endif
849 847
850 /* 848 /*
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 408fe89498f4..4ed7e602d703 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -757,6 +757,13 @@ extern void send_sigio(struct fown_struct *fown, int fd, int band);
757extern int fcntl_setlease(unsigned int fd, struct file *filp, long arg); 757extern int fcntl_setlease(unsigned int fd, struct file *filp, long arg);
758extern int fcntl_getlease(struct file *filp); 758extern int fcntl_getlease(struct file *filp);
759 759
760/* fs/sync.c */
761#define SYNC_FILE_RANGE_WAIT_BEFORE 1
762#define SYNC_FILE_RANGE_WRITE 2
763#define SYNC_FILE_RANGE_WAIT_AFTER 4
764extern int do_sync_file_range(struct file *file, loff_t offset, loff_t endbyte,
765 int flags);
766
760/* fs/locks.c */ 767/* fs/locks.c */
761extern void locks_init_lock(struct file_lock *); 768extern void locks_init_lock(struct file_lock *);
762extern void locks_copy_lock(struct file_lock *, struct file_lock *); 769extern void locks_copy_lock(struct file_lock *, struct file_lock *);
@@ -1032,6 +1039,8 @@ struct file_operations {
1032 int (*check_flags)(int); 1039 int (*check_flags)(int);
1033 int (*dir_notify)(struct file *filp, unsigned long arg); 1040 int (*dir_notify)(struct file *filp, unsigned long arg);
1034 int (*flock) (struct file *, int, struct file_lock *); 1041 int (*flock) (struct file *, int, struct file_lock *);
1042 ssize_t (*splice_write)(struct inode *, struct file *, size_t, unsigned int);
1043 ssize_t (*splice_read)(struct file *, struct inode *, size_t, unsigned int);
1035}; 1044};
1036 1045
1037struct inode_operations { 1046struct inode_operations {
@@ -1411,6 +1420,7 @@ extern void bd_release_from_disk(struct block_device *, struct gendisk *);
1411#endif 1420#endif
1412 1421
1413/* fs/char_dev.c */ 1422/* fs/char_dev.c */
1423#define CHRDEV_MAJOR_HASH_SIZE 255
1414extern int alloc_chrdev_region(dev_t *, unsigned, unsigned, const char *); 1424extern int alloc_chrdev_region(dev_t *, unsigned, unsigned, const char *);
1415extern int register_chrdev_region(dev_t, unsigned, const char *); 1425extern int register_chrdev_region(dev_t, unsigned, const char *);
1416extern int register_chrdev(unsigned int, const char *, 1426extern int register_chrdev(unsigned int, const char *,
@@ -1418,25 +1428,17 @@ extern int register_chrdev(unsigned int, const char *,
1418extern int unregister_chrdev(unsigned int, const char *); 1428extern int unregister_chrdev(unsigned int, const char *);
1419extern void unregister_chrdev_region(dev_t, unsigned); 1429extern void unregister_chrdev_region(dev_t, unsigned);
1420extern int chrdev_open(struct inode *, struct file *); 1430extern int chrdev_open(struct inode *, struct file *);
1421extern int get_chrdev_list(char *); 1431extern void chrdev_show(struct seq_file *,off_t);
1422extern void *acquire_chrdev_list(void);
1423extern int count_chrdev_list(void);
1424extern void *get_next_chrdev(void *);
1425extern int get_chrdev_info(void *, int *, char **);
1426extern void release_chrdev_list(void *);
1427 1432
1428/* fs/block_dev.c */ 1433/* fs/block_dev.c */
1434#define BLKDEV_MAJOR_HASH_SIZE 255
1429#define BDEVNAME_SIZE 32 /* Largest string for a blockdev identifier */ 1435#define BDEVNAME_SIZE 32 /* Largest string for a blockdev identifier */
1430extern const char *__bdevname(dev_t, char *buffer); 1436extern const char *__bdevname(dev_t, char *buffer);
1431extern const char *bdevname(struct block_device *bdev, char *buffer); 1437extern const char *bdevname(struct block_device *bdev, char *buffer);
1432extern struct block_device *lookup_bdev(const char *); 1438extern struct block_device *lookup_bdev(const char *);
1433extern struct block_device *open_bdev_excl(const char *, int, void *); 1439extern struct block_device *open_bdev_excl(const char *, int, void *);
1434extern void close_bdev_excl(struct block_device *); 1440extern void close_bdev_excl(struct block_device *);
1435extern void *acquire_blkdev_list(void); 1441extern void blkdev_show(struct seq_file *,off_t);
1436extern int count_blkdev_list(void);
1437extern void *get_next_blkdev(void *);
1438extern int get_blkdev_info(void *, int *, char **);
1439extern void release_blkdev_list(void *);
1440 1442
1441extern void init_special_inode(struct inode *, umode_t, dev_t); 1443extern void init_special_inode(struct inode *, umode_t, dev_t);
1442 1444
@@ -1609,6 +1611,8 @@ extern ssize_t generic_file_sendfile(struct file *, loff_t *, size_t, read_actor
1609extern void do_generic_mapping_read(struct address_space *mapping, 1611extern void do_generic_mapping_read(struct address_space *mapping,
1610 struct file_ra_state *, struct file *, 1612 struct file_ra_state *, struct file *,
1611 loff_t *, read_descriptor_t *, read_actor_t); 1613 loff_t *, read_descriptor_t *, read_actor_t);
1614extern ssize_t generic_file_splice_read(struct file *, struct inode *, size_t, unsigned int);
1615extern ssize_t generic_file_splice_write(struct inode *, struct file *, size_t, unsigned int);
1612extern void 1616extern void
1613file_ra_state_init(struct file_ra_state *ra, struct address_space *mapping); 1617file_ra_state_init(struct file_ra_state *ra, struct address_space *mapping);
1614extern ssize_t generic_file_readv(struct file *filp, const struct iovec *iov, 1618extern ssize_t generic_file_readv(struct file *filp, const struct iovec *iov,
diff --git a/include/linux/hrtimer.h b/include/linux/hrtimer.h
index 93830158348e..b20939287613 100644
--- a/include/linux/hrtimer.h
+++ b/include/linux/hrtimer.h
@@ -58,6 +58,19 @@ struct hrtimer {
58}; 58};
59 59
60/** 60/**
61 * struct hrtimer_sleeper - simple sleeper structure
62 *
63 * @timer: embedded timer structure
64 * @task: task to wake up
65 *
66 * task is set to NULL, when the timer expires.
67 */
68struct hrtimer_sleeper {
69 struct hrtimer timer;
70 struct task_struct *task;
71};
72
73/**
61 * struct hrtimer_base - the timer base for a specific clock 74 * struct hrtimer_base - the timer base for a specific clock
62 * 75 *
63 * @index: clock type index for per_cpu support when moving a timer 76 * @index: clock type index for per_cpu support when moving a timer
@@ -127,6 +140,9 @@ extern long hrtimer_nanosleep(struct timespec *rqtp,
127 const enum hrtimer_mode mode, 140 const enum hrtimer_mode mode,
128 const clockid_t clockid); 141 const clockid_t clockid);
129 142
143extern void hrtimer_init_sleeper(struct hrtimer_sleeper *sl,
144 struct task_struct *tsk);
145
130/* Soft interrupt function to run the hrtimer queues: */ 146/* Soft interrupt function to run the hrtimer queues: */
131extern void hrtimer_run_queues(void); 147extern void hrtimer_run_queues(void);
132 148
diff --git a/include/linux/ipmi_smi.h b/include/linux/ipmi_smi.h
index 53571288a9fc..6d9c7e4da472 100644
--- a/include/linux/ipmi_smi.h
+++ b/include/linux/ipmi_smi.h
@@ -82,6 +82,13 @@ struct ipmi_smi_handlers
82{ 82{
83 struct module *owner; 83 struct module *owner;
84 84
85 /* The low-level interface cannot start sending messages to
86 the upper layer until this function is called. This may
87 not be NULL, the lower layer must take the interface from
88 this call. */
89 int (*start_processing)(void *send_info,
90 ipmi_smi_t new_intf);
91
85 /* Called to enqueue an SMI message to be sent. This 92 /* Called to enqueue an SMI message to be sent. This
86 operation is not allowed to fail. If an error occurs, it 93 operation is not allowed to fail. If an error occurs, it
87 should report back the error in a received message. It may 94 should report back the error in a received message. It may
@@ -157,13 +164,16 @@ static inline void ipmi_demangle_device_id(unsigned char *data,
157} 164}
158 165
159/* Add a low-level interface to the IPMI driver. Note that if the 166/* Add a low-level interface to the IPMI driver. Note that if the
160 interface doesn't know its slave address, it should pass in zero. */ 167 interface doesn't know its slave address, it should pass in zero.
168 The low-level interface should not deliver any messages to the
169 upper layer until the start_processing() function in the handlers
170 is called, and the lower layer must get the interface from that
171 call. */
161int ipmi_register_smi(struct ipmi_smi_handlers *handlers, 172int ipmi_register_smi(struct ipmi_smi_handlers *handlers,
162 void *send_info, 173 void *send_info,
163 struct ipmi_device_id *device_id, 174 struct ipmi_device_id *device_id,
164 struct device *dev, 175 struct device *dev,
165 unsigned char slave_addr, 176 unsigned char slave_addr);
166 ipmi_smi_t *intf);
167 177
168/* 178/*
169 * Remove a low-level interface from the IPMI driver. This will 179 * Remove a low-level interface from the IPMI driver. This will
diff --git a/include/linux/leds.h b/include/linux/leds.h
new file mode 100644
index 000000000000..4617e75903b0
--- /dev/null
+++ b/include/linux/leds.h
@@ -0,0 +1,111 @@
1/*
2 * Driver model for leds and led triggers
3 *
4 * Copyright (C) 2005 John Lenz <lenz@cs.wisc.edu>
5 * Copyright (C) 2005 Richard Purdie <rpurdie@openedhand.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 */
12#ifndef __LINUX_LEDS_H_INCLUDED
13#define __LINUX_LEDS_H_INCLUDED
14
15struct device;
16struct class_device;
17/*
18 * LED Core
19 */
20
21enum led_brightness {
22 LED_OFF = 0,
23 LED_HALF = 127,
24 LED_FULL = 255,
25};
26
27struct led_classdev {
28 const char *name;
29 int brightness;
30 int flags;
31#define LED_SUSPENDED (1 << 0)
32
33 /* A function to set the brightness of the led */
34 void (*brightness_set)(struct led_classdev *led_cdev,
35 enum led_brightness brightness);
36
37 struct class_device *class_dev;
38 /* LED Device linked list */
39 struct list_head node;
40
41 /* Trigger data */
42 char *default_trigger;
43#ifdef CONFIG_LEDS_TRIGGERS
44 rwlock_t trigger_lock;
45 /* Protects the trigger data below */
46
47 struct led_trigger *trigger;
48 struct list_head trig_list;
49 void *trigger_data;
50#endif
51};
52
53extern int led_classdev_register(struct device *parent,
54 struct led_classdev *led_cdev);
55extern void led_classdev_unregister(struct led_classdev *led_cdev);
56extern void led_classdev_suspend(struct led_classdev *led_cdev);
57extern void led_classdev_resume(struct led_classdev *led_cdev);
58
59/*
60 * LED Triggers
61 */
62#ifdef CONFIG_LEDS_TRIGGERS
63
64#define TRIG_NAME_MAX 50
65
66struct led_trigger {
67 /* Trigger Properties */
68 const char *name;
69 void (*activate)(struct led_classdev *led_cdev);
70 void (*deactivate)(struct led_classdev *led_cdev);
71
72 /* LEDs under control by this trigger (for simple triggers) */
73 rwlock_t leddev_list_lock;
74 struct list_head led_cdevs;
75
76 /* Link to next registered trigger */
77 struct list_head next_trig;
78};
79
80/* Registration functions for complex triggers */
81extern int led_trigger_register(struct led_trigger *trigger);
82extern void led_trigger_unregister(struct led_trigger *trigger);
83
84/* Registration functions for simple triggers */
85#define DEFINE_LED_TRIGGER(x) static struct led_trigger *x;
86#define DEFINE_LED_TRIGGER_GLOBAL(x) struct led_trigger *x;
87extern void led_trigger_register_simple(const char *name,
88 struct led_trigger **trigger);
89extern void led_trigger_unregister_simple(struct led_trigger *trigger);
90extern void led_trigger_event(struct led_trigger *trigger,
91 enum led_brightness event);
92
93#else
94
95/* Triggers aren't active - null macros */
96#define DEFINE_LED_TRIGGER(x)
97#define DEFINE_LED_TRIGGER_GLOBAL(x)
98#define led_trigger_register_simple(x, y) do {} while(0)
99#define led_trigger_unregister_simple(x) do {} while(0)
100#define led_trigger_event(x, y) do {} while(0)
101
102#endif
103
104/* Trigger specific functions */
105#ifdef CONFIG_LEDS_TRIGGER_IDE_DISK
106extern void ledtrig_ide_activity(void);
107#else
108#define ledtrig_ide_activity() do {} while(0)
109#endif
110
111#endif /* __LINUX_LEDS_H_INCLUDED */
diff --git a/include/linux/libata.h b/include/linux/libata.h
index 047192253c3a..0d61357604d5 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -160,8 +160,10 @@ enum {
160 ATA_QCFLAG_DMAMAP = ATA_QCFLAG_SG | ATA_QCFLAG_SINGLE, 160 ATA_QCFLAG_DMAMAP = ATA_QCFLAG_SG | ATA_QCFLAG_SINGLE,
161 ATA_QCFLAG_EH_SCHEDULED = (1 << 5), /* EH scheduled */ 161 ATA_QCFLAG_EH_SCHEDULED = (1 << 5), /* EH scheduled */
162 162
163 /* host set flags */
164 ATA_HOST_SIMPLEX = (1 << 0), /* Host is simplex, one DMA channel per host_set only */
165
163 /* various lengths of time */ 166 /* various lengths of time */
164 ATA_TMOUT_EDD = 5 * HZ, /* heuristic */
165 ATA_TMOUT_PIO = 30 * HZ, 167 ATA_TMOUT_PIO = 30 * HZ,
166 ATA_TMOUT_BOOT = 30 * HZ, /* heuristic */ 168 ATA_TMOUT_BOOT = 30 * HZ, /* heuristic */
167 ATA_TMOUT_BOOT_QUICK = 7 * HZ, /* heuristic */ 169 ATA_TMOUT_BOOT_QUICK = 7 * HZ, /* heuristic */
@@ -279,6 +281,7 @@ struct ata_probe_ent {
279 unsigned long irq; 281 unsigned long irq;
280 unsigned int irq_flags; 282 unsigned int irq_flags;
281 unsigned long host_flags; 283 unsigned long host_flags;
284 unsigned long host_set_flags;
282 void __iomem *mmio_base; 285 void __iomem *mmio_base;
283 void *private_data; 286 void *private_data;
284}; 287};
@@ -291,6 +294,9 @@ struct ata_host_set {
291 unsigned int n_ports; 294 unsigned int n_ports;
292 void *private_data; 295 void *private_data;
293 const struct ata_port_operations *ops; 296 const struct ata_port_operations *ops;
297 unsigned long flags;
298 int simplex_claimed; /* Keep seperate in case we
299 ever need to do this locked */
294 struct ata_port * ports[0]; 300 struct ata_port * ports[0];
295}; 301};
296 302
@@ -420,6 +426,7 @@ struct ata_port_operations {
420 426
421 void (*set_piomode) (struct ata_port *, struct ata_device *); 427 void (*set_piomode) (struct ata_port *, struct ata_device *);
422 void (*set_dmamode) (struct ata_port *, struct ata_device *); 428 void (*set_dmamode) (struct ata_port *, struct ata_device *);
429 unsigned long (*mode_filter) (const struct ata_port *, struct ata_device *, unsigned long);
423 430
424 void (*tf_load) (struct ata_port *ap, const struct ata_taskfile *tf); 431 void (*tf_load) (struct ata_port *ap, const struct ata_taskfile *tf);
425 void (*tf_read) (struct ata_port *ap, struct ata_taskfile *tf); 432 void (*tf_read) (struct ata_port *ap, struct ata_taskfile *tf);
@@ -430,6 +437,7 @@ struct ata_port_operations {
430 void (*dev_select)(struct ata_port *ap, unsigned int device); 437 void (*dev_select)(struct ata_port *ap, unsigned int device);
431 438
432 void (*phy_reset) (struct ata_port *ap); /* obsolete */ 439 void (*phy_reset) (struct ata_port *ap); /* obsolete */
440 void (*set_mode) (struct ata_port *ap);
433 int (*probe_reset) (struct ata_port *ap, unsigned int *classes); 441 int (*probe_reset) (struct ata_port *ap, unsigned int *classes);
434 442
435 void (*post_set_mode) (struct ata_port *ap); 443 void (*post_set_mode) (struct ata_port *ap);
diff --git a/include/linux/migrate.h b/include/linux/migrate.h
index 7d09962c3c0b..ff0a64073ebc 100644
--- a/include/linux/migrate.h
+++ b/include/linux/migrate.h
@@ -12,7 +12,7 @@ extern void migrate_page_copy(struct page *, struct page *);
12extern int migrate_page_remove_references(struct page *, struct page *, int); 12extern int migrate_page_remove_references(struct page *, struct page *, int);
13extern int migrate_pages(struct list_head *l, struct list_head *t, 13extern int migrate_pages(struct list_head *l, struct list_head *t,
14 struct list_head *moved, struct list_head *failed); 14 struct list_head *moved, struct list_head *failed);
15int migrate_pages_to(struct list_head *pagelist, 15extern int migrate_pages_to(struct list_head *pagelist,
16 struct vm_area_struct *vma, int dest); 16 struct vm_area_struct *vma, int dest);
17extern int fail_migrate_page(struct page *, struct page *); 17extern int fail_migrate_page(struct page *, struct page *);
18 18
@@ -26,6 +26,9 @@ static inline int putback_lru_pages(struct list_head *l) { return 0; }
26static inline int migrate_pages(struct list_head *l, struct list_head *t, 26static inline int migrate_pages(struct list_head *l, struct list_head *t,
27 struct list_head *moved, struct list_head *failed) { return -ENOSYS; } 27 struct list_head *moved, struct list_head *failed) { return -ENOSYS; }
28 28
29static inline int migrate_pages_to(struct list_head *pagelist,
30 struct vm_area_struct *vma, int dest) { return 0; }
31
29static inline int migrate_prep(void) { return -ENOSYS; } 32static inline int migrate_prep(void) { return -ENOSYS; }
30 33
31/* Possible settings for the migrate_page() method in address_operations */ 34/* Possible settings for the migrate_page() method in address_operations */
diff --git a/include/linux/mtd/blktrans.h b/include/linux/mtd/blktrans.h
index f46afec6fbf8..72fc68c5ee96 100644
--- a/include/linux/mtd/blktrans.h
+++ b/include/linux/mtd/blktrans.h
@@ -10,7 +10,7 @@
10#ifndef __MTD_TRANS_H__ 10#ifndef __MTD_TRANS_H__
11#define __MTD_TRANS_H__ 11#define __MTD_TRANS_H__
12 12
13#include <asm/semaphore.h> 13#include <linux/mutex.h>
14 14
15struct hd_geometry; 15struct hd_geometry;
16struct mtd_info; 16struct mtd_info;
@@ -22,7 +22,7 @@ struct mtd_blktrans_dev {
22 struct mtd_blktrans_ops *tr; 22 struct mtd_blktrans_ops *tr;
23 struct list_head list; 23 struct list_head list;
24 struct mtd_info *mtd; 24 struct mtd_info *mtd;
25 struct semaphore sem; 25 struct mutex lock;
26 int devnum; 26 int devnum;
27 int blksize; 27 int blksize;
28 unsigned long size; 28 unsigned long size;
diff --git a/include/linux/mtd/doc2000.h b/include/linux/mtd/doc2000.h
index 386a52cf8b1b..9addd073bf15 100644
--- a/include/linux/mtd/doc2000.h
+++ b/include/linux/mtd/doc2000.h
@@ -15,7 +15,7 @@
15#define __MTD_DOC2000_H__ 15#define __MTD_DOC2000_H__
16 16
17#include <linux/mtd/mtd.h> 17#include <linux/mtd/mtd.h>
18#include <asm/semaphore.h> 18#include <linux/mutex.h>
19 19
20#define DoC_Sig1 0 20#define DoC_Sig1 0
21#define DoC_Sig2 1 21#define DoC_Sig2 1
@@ -187,7 +187,7 @@ struct DiskOnChip {
187 int numchips; 187 int numchips;
188 struct Nand *chips; 188 struct Nand *chips;
189 struct mtd_info *nextdoc; 189 struct mtd_info *nextdoc;
190 struct semaphore lock; 190 struct mutex lock;
191}; 191};
192 192
193int doc_decode_ecc(unsigned char sector[512], unsigned char ecc1[6]); 193int doc_decode_ecc(unsigned char sector[512], unsigned char ecc1[6]);
diff --git a/include/linux/mtd/inftl.h b/include/linux/mtd/inftl.h
index 0268125a6271..d7eaa40e5ab0 100644
--- a/include/linux/mtd/inftl.h
+++ b/include/linux/mtd/inftl.h
@@ -52,6 +52,11 @@ struct INFTLrecord {
52int INFTL_mount(struct INFTLrecord *s); 52int INFTL_mount(struct INFTLrecord *s);
53int INFTL_formatblock(struct INFTLrecord *s, int block); 53int INFTL_formatblock(struct INFTLrecord *s, int block);
54 54
55extern char inftlmountrev[];
56
57void INFTL_dumptables(struct INFTLrecord *s);
58void INFTL_dumpVUchains(struct INFTLrecord *s);
59
55#endif /* __KERNEL__ */ 60#endif /* __KERNEL__ */
56 61
57#endif /* __MTD_INFTL_H__ */ 62#endif /* __MTD_INFTL_H__ */
diff --git a/include/linux/namei.h b/include/linux/namei.h
index e6698013e4d0..58cb3d3d44b4 100644
--- a/include/linux/namei.h
+++ b/include/linux/namei.h
@@ -75,7 +75,6 @@ extern struct file *nameidata_to_filp(struct nameidata *nd, int flags);
75extern void release_open_intent(struct nameidata *); 75extern void release_open_intent(struct nameidata *);
76 76
77extern struct dentry * lookup_one_len(const char *, struct dentry *, int); 77extern struct dentry * lookup_one_len(const char *, struct dentry *, int);
78extern __deprecated_for_modules struct dentry * lookup_hash(struct nameidata *);
79 78
80extern int follow_down(struct vfsmount **, struct dentry **); 79extern int follow_down(struct vfsmount **, struct dentry **);
81extern int follow_up(struct vfsmount **, struct dentry **); 80extern int follow_up(struct vfsmount **, struct dentry **);
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 950dc55e5192..40ccf8cc4239 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -598,20 +598,7 @@ DECLARE_PER_CPU(struct softnet_data,softnet_data);
598 598
599#define HAVE_NETIF_QUEUE 599#define HAVE_NETIF_QUEUE
600 600
601static inline void __netif_schedule(struct net_device *dev) 601extern void __netif_schedule(struct net_device *dev);
602{
603 if (!test_and_set_bit(__LINK_STATE_SCHED, &dev->state)) {
604 unsigned long flags;
605 struct softnet_data *sd;
606
607 local_irq_save(flags);
608 sd = &__get_cpu_var(softnet_data);
609 dev->next_sched = sd->output_queue;
610 sd->output_queue = dev;
611 raise_softirq_irqoff(NET_TX_SOFTIRQ);
612 local_irq_restore(flags);
613 }
614}
615 602
616static inline void netif_schedule(struct net_device *dev) 603static inline void netif_schedule(struct net_device *dev)
617{ 604{
@@ -675,13 +662,7 @@ static inline void dev_kfree_skb_irq(struct sk_buff *skb)
675/* Use this variant in places where it could be invoked 662/* Use this variant in places where it could be invoked
676 * either from interrupt or non-interrupt context. 663 * either from interrupt or non-interrupt context.
677 */ 664 */
678static inline void dev_kfree_skb_any(struct sk_buff *skb) 665extern void dev_kfree_skb_any(struct sk_buff *skb);
679{
680 if (in_irq() || irqs_disabled())
681 dev_kfree_skb_irq(skb);
682 else
683 dev_kfree_skb(skb);
684}
685 666
686#define HAVE_NETIF_RX 1 667#define HAVE_NETIF_RX 1
687extern int netif_rx(struct sk_buff *skb); 668extern int netif_rx(struct sk_buff *skb);
@@ -768,22 +749,9 @@ static inline int netif_device_present(struct net_device *dev)
768 return test_bit(__LINK_STATE_PRESENT, &dev->state); 749 return test_bit(__LINK_STATE_PRESENT, &dev->state);
769} 750}
770 751
771static inline void netif_device_detach(struct net_device *dev) 752extern void netif_device_detach(struct net_device *dev);
772{
773 if (test_and_clear_bit(__LINK_STATE_PRESENT, &dev->state) &&
774 netif_running(dev)) {
775 netif_stop_queue(dev);
776 }
777}
778 753
779static inline void netif_device_attach(struct net_device *dev) 754extern void netif_device_attach(struct net_device *dev);
780{
781 if (!test_and_set_bit(__LINK_STATE_PRESENT, &dev->state) &&
782 netif_running(dev)) {
783 netif_wake_queue(dev);
784 __netdev_watchdog_up(dev);
785 }
786}
787 755
788/* 756/*
789 * Network interface message level settings 757 * Network interface message level settings
@@ -851,20 +819,7 @@ static inline int netif_rx_schedule_prep(struct net_device *dev)
851 * already been called and returned 1. 819 * already been called and returned 1.
852 */ 820 */
853 821
854static inline void __netif_rx_schedule(struct net_device *dev) 822extern void __netif_rx_schedule(struct net_device *dev);
855{
856 unsigned long flags;
857
858 local_irq_save(flags);
859 dev_hold(dev);
860 list_add_tail(&dev->poll_list, &__get_cpu_var(softnet_data).poll_list);
861 if (dev->quota < 0)
862 dev->quota += dev->weight;
863 else
864 dev->quota = dev->weight;
865 __raise_softirq_irqoff(NET_RX_SOFTIRQ);
866 local_irq_restore(flags);
867}
868 823
869/* Try to reschedule poll. Called by irq handler. */ 824/* Try to reschedule poll. Called by irq handler. */
870 825
diff --git a/include/linux/pagemap.h b/include/linux/pagemap.h
index 839f0b3c23aa..9539efd4f7e6 100644
--- a/include/linux/pagemap.h
+++ b/include/linux/pagemap.h
@@ -72,8 +72,8 @@ extern struct page * find_get_page(struct address_space *mapping,
72 unsigned long index); 72 unsigned long index);
73extern struct page * find_lock_page(struct address_space *mapping, 73extern struct page * find_lock_page(struct address_space *mapping,
74 unsigned long index); 74 unsigned long index);
75extern struct page * find_trylock_page(struct address_space *mapping, 75extern __deprecated_for_modules struct page * find_trylock_page(
76 unsigned long index); 76 struct address_space *mapping, unsigned long index);
77extern struct page * find_or_create_page(struct address_space *mapping, 77extern struct page * find_or_create_page(struct address_space *mapping,
78 unsigned long index, gfp_t gfp_mask); 78 unsigned long index, gfp_t gfp_mask);
79unsigned find_get_pages(struct address_space *mapping, pgoff_t start, 79unsigned find_get_pages(struct address_space *mapping, pgoff_t start,
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
index e2ab2ac18d6b..870fe38378b1 100644
--- a/include/linux/pci_ids.h
+++ b/include/linux/pci_ids.h
@@ -773,6 +773,7 @@
773#define PCI_DEVICE_ID_MOTOROLA_HAWK 0x4803 773#define PCI_DEVICE_ID_MOTOROLA_HAWK 0x4803
774#define PCI_DEVICE_ID_MOTOROLA_HARRIER 0x480b 774#define PCI_DEVICE_ID_MOTOROLA_HARRIER 0x480b
775#define PCI_DEVICE_ID_MOTOROLA_MPC5200 0x5803 775#define PCI_DEVICE_ID_MOTOROLA_MPC5200 0x5803
776#define PCI_DEVICE_ID_MOTOROLA_MPC5200B 0x5809
776 777
777#define PCI_VENDOR_ID_PROMISE 0x105a 778#define PCI_VENDOR_ID_PROMISE 0x105a
778#define PCI_DEVICE_ID_PROMISE_20265 0x0d30 779#define PCI_DEVICE_ID_PROMISE_20265 0x0d30
diff --git a/include/linux/pid.h b/include/linux/pid.h
index 5b9082cc600f..29960b03bef7 100644
--- a/include/linux/pid.h
+++ b/include/linux/pid.h
@@ -1,6 +1,8 @@
1#ifndef _LINUX_PID_H 1#ifndef _LINUX_PID_H
2#define _LINUX_PID_H 2#define _LINUX_PID_H
3 3
4#include <linux/rcupdate.h>
5
4enum pid_type 6enum pid_type
5{ 7{
6 PIDTYPE_PID, 8 PIDTYPE_PID,
@@ -9,45 +11,109 @@ enum pid_type
9 PIDTYPE_MAX 11 PIDTYPE_MAX
10}; 12};
11 13
14/*
15 * What is struct pid?
16 *
17 * A struct pid is the kernel's internal notion of a process identifier.
18 * It refers to individual tasks, process groups, and sessions. While
19 * there are processes attached to it the struct pid lives in a hash
20 * table, so it and then the processes that it refers to can be found
21 * quickly from the numeric pid value. The attached processes may be
22 * quickly accessed by following pointers from struct pid.
23 *
24 * Storing pid_t values in the kernel and refering to them later has a
25 * problem. The process originally with that pid may have exited and the
26 * pid allocator wrapped, and another process could have come along
27 * and been assigned that pid.
28 *
29 * Referring to user space processes by holding a reference to struct
30 * task_struct has a problem. When the user space process exits
31 * the now useless task_struct is still kept. A task_struct plus a
32 * stack consumes around 10K of low kernel memory. More precisely
33 * this is THREAD_SIZE + sizeof(struct task_struct). By comparison
34 * a struct pid is about 64 bytes.
35 *
36 * Holding a reference to struct pid solves both of these problems.
37 * It is small so holding a reference does not consume a lot of
38 * resources, and since a new struct pid is allocated when the numeric
39 * pid value is reused we don't mistakenly refer to new processes.
40 */
41
12struct pid 42struct pid
13{ 43{
44 atomic_t count;
14 /* Try to keep pid_chain in the same cacheline as nr for find_pid */ 45 /* Try to keep pid_chain in the same cacheline as nr for find_pid */
15 int nr; 46 int nr;
16 struct hlist_node pid_chain; 47 struct hlist_node pid_chain;
17 /* list of pids with the same nr, only one of them is in the hash */ 48 /* lists of tasks that use this pid */
18 struct list_head pid_list; 49 struct hlist_head tasks[PIDTYPE_MAX];
50 struct rcu_head rcu;
19}; 51};
20 52
21#define pid_task(elem, type) \ 53struct pid_link
22 list_entry(elem, struct task_struct, pids[type].pid_list) 54{
55 struct hlist_node node;
56 struct pid *pid;
57};
58
59static inline struct pid *get_pid(struct pid *pid)
60{
61 if (pid)
62 atomic_inc(&pid->count);
63 return pid;
64}
65
66extern void FASTCALL(put_pid(struct pid *pid));
67extern struct task_struct *FASTCALL(pid_task(struct pid *pid, enum pid_type));
68extern struct task_struct *FASTCALL(get_pid_task(struct pid *pid,
69 enum pid_type));
23 70
24/* 71/*
25 * attach_pid() and detach_pid() must be called with the tasklist_lock 72 * attach_pid() and detach_pid() must be called with the tasklist_lock
26 * write-held. 73 * write-held.
27 */ 74 */
28extern int FASTCALL(attach_pid(struct task_struct *task, enum pid_type type, int nr)); 75extern int FASTCALL(attach_pid(struct task_struct *task,
76 enum pid_type type, int nr));
29 77
30extern void FASTCALL(detach_pid(struct task_struct *task, enum pid_type)); 78extern void FASTCALL(detach_pid(struct task_struct *task, enum pid_type));
31 79
32/* 80/*
33 * look up a PID in the hash table. Must be called with the tasklist_lock 81 * look up a PID in the hash table. Must be called with the tasklist_lock
34 * held. 82 * or rcu_read_lock() held.
83 */
84extern struct pid *FASTCALL(find_pid(int nr));
85
86/*
87 * Lookup a PID in the hash table, and return with it's count elevated.
35 */ 88 */
36extern struct pid *FASTCALL(find_pid(enum pid_type, int)); 89extern struct pid *find_get_pid(int nr);
37 90
38extern int alloc_pidmap(void); 91extern struct pid *alloc_pid(void);
39extern void FASTCALL(free_pidmap(int)); 92extern void FASTCALL(free_pid(struct pid *pid));
40 93
94#define pid_next(task, type) \
95 ((task)->pids[(type)].node.next)
96
97#define pid_next_task(task, type) \
98 hlist_entry(pid_next(task, type), struct task_struct, \
99 pids[(type)].node)
100
101
102/* We could use hlist_for_each_entry_rcu here but it takes more arguments
103 * than the do_each_task_pid/while_each_task_pid. So we roll our own
104 * to preserve the existing interface.
105 */
41#define do_each_task_pid(who, type, task) \ 106#define do_each_task_pid(who, type, task) \
42 if ((task = find_task_by_pid_type(type, who))) { \ 107 if ((task = find_task_by_pid_type(type, who))) { \
43 prefetch((task)->pids[type].pid_list.next); \ 108 prefetch(pid_next(task, type)); \
44 do { 109 do {
45 110
46#define while_each_task_pid(who, type, task) \ 111#define while_each_task_pid(who, type, task) \
47 } while (task = pid_task((task)->pids[type].pid_list.next,\ 112 } while (pid_next(task, type) && ({ \
48 type), \ 113 task = pid_next_task(task, type); \
49 prefetch((task)->pids[type].pid_list.next), \ 114 rcu_dereference(task); \
50 hlist_unhashed(&(task)->pids[type].pid_chain)); \ 115 prefetch(pid_next(task, type)); \
51 } \ 116 1; }) ); \
117 }
52 118
53#endif /* _LINUX_PID_H */ 119#endif /* _LINUX_PID_H */
diff --git a/include/linux/pipe_fs_i.h b/include/linux/pipe_fs_i.h
index b12e59c75752..75c7f55023ab 100644
--- a/include/linux/pipe_fs_i.h
+++ b/include/linux/pipe_fs_i.h
@@ -9,6 +9,7 @@ struct pipe_buffer {
9 struct page *page; 9 struct page *page;
10 unsigned int offset, len; 10 unsigned int offset, len;
11 struct pipe_buf_operations *ops; 11 struct pipe_buf_operations *ops;
12 unsigned int stolen;
12}; 13};
13 14
14struct pipe_buf_operations { 15struct pipe_buf_operations {
@@ -16,6 +17,7 @@ struct pipe_buf_operations {
16 void * (*map)(struct file *, struct pipe_inode_info *, struct pipe_buffer *); 17 void * (*map)(struct file *, struct pipe_inode_info *, struct pipe_buffer *);
17 void (*unmap)(struct pipe_inode_info *, struct pipe_buffer *); 18 void (*unmap)(struct pipe_inode_info *, struct pipe_buffer *);
18 void (*release)(struct pipe_inode_info *, struct pipe_buffer *); 19 void (*release)(struct pipe_inode_info *, struct pipe_buffer *);
20 int (*steal)(struct pipe_inode_info *, struct pipe_buffer *);
19}; 21};
20 22
21struct pipe_inode_info { 23struct pipe_inode_info {
@@ -53,4 +55,10 @@ void pipe_wait(struct inode * inode);
53struct inode* pipe_new(struct inode* inode); 55struct inode* pipe_new(struct inode* inode);
54void free_pipe_info(struct inode* inode); 56void free_pipe_info(struct inode* inode);
55 57
58/*
59 * splice is tied to pipes as a transport (at least for now), so we'll just
60 * add the splice flags here.
61 */
62#define SPLICE_F_MOVE (0x01) /* move pages instead of copying */
63
56#endif 64#endif
diff --git a/include/linux/sched.h b/include/linux/sched.h
index d04186d8cc68..541f4828f5e7 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -100,6 +100,7 @@ DECLARE_PER_CPU(unsigned long, process_counts);
100extern int nr_processes(void); 100extern int nr_processes(void);
101extern unsigned long nr_running(void); 101extern unsigned long nr_running(void);
102extern unsigned long nr_uninterruptible(void); 102extern unsigned long nr_uninterruptible(void);
103extern unsigned long nr_active(void);
103extern unsigned long nr_iowait(void); 104extern unsigned long nr_iowait(void);
104 105
105#include <linux/time.h> 106#include <linux/time.h>
@@ -483,6 +484,7 @@ struct signal_struct {
483#define MAX_PRIO (MAX_RT_PRIO + 40) 484#define MAX_PRIO (MAX_RT_PRIO + 40)
484 485
485#define rt_task(p) (unlikely((p)->prio < MAX_RT_PRIO)) 486#define rt_task(p) (unlikely((p)->prio < MAX_RT_PRIO))
487#define batch_task(p) (unlikely((p)->policy == SCHED_BATCH))
486 488
487/* 489/*
488 * Some day this will be a full-fledged user tracking system.. 490 * Some day this will be a full-fledged user tracking system..
@@ -683,6 +685,13 @@ static inline void prefetch_stack(struct task_struct *t) { }
683struct audit_context; /* See audit.c */ 685struct audit_context; /* See audit.c */
684struct mempolicy; 686struct mempolicy;
685 687
688enum sleep_type {
689 SLEEP_NORMAL,
690 SLEEP_NONINTERACTIVE,
691 SLEEP_INTERACTIVE,
692 SLEEP_INTERRUPTED,
693};
694
686struct task_struct { 695struct task_struct {
687 volatile long state; /* -1 unrunnable, 0 runnable, >0 stopped */ 696 volatile long state; /* -1 unrunnable, 0 runnable, >0 stopped */
688 struct thread_info *thread_info; 697 struct thread_info *thread_info;
@@ -705,7 +714,7 @@ struct task_struct {
705 unsigned long sleep_avg; 714 unsigned long sleep_avg;
706 unsigned long long timestamp, last_ran; 715 unsigned long long timestamp, last_ran;
707 unsigned long long sched_time; /* sched_clock time spent running */ 716 unsigned long long sched_time; /* sched_clock time spent running */
708 int activated; 717 enum sleep_type sleep_type;
709 718
710 unsigned long policy; 719 unsigned long policy;
711 cpumask_t cpus_allowed; 720 cpumask_t cpus_allowed;
@@ -751,7 +760,7 @@ struct task_struct {
751 struct task_struct *group_leader; /* threadgroup leader */ 760 struct task_struct *group_leader; /* threadgroup leader */
752 761
753 /* PID/PID hash table linkage. */ 762 /* PID/PID hash table linkage. */
754 struct pid pids[PIDTYPE_MAX]; 763 struct pid_link pids[PIDTYPE_MAX];
755 struct list_head thread_group; 764 struct list_head thread_group;
756 765
757 struct completion *vfork_done; /* for vfork() */ 766 struct completion *vfork_done; /* for vfork() */
@@ -890,18 +899,19 @@ static inline pid_t process_group(struct task_struct *tsk)
890 */ 899 */
891static inline int pid_alive(struct task_struct *p) 900static inline int pid_alive(struct task_struct *p)
892{ 901{
893 return p->pids[PIDTYPE_PID].nr != 0; 902 return p->pids[PIDTYPE_PID].pid != NULL;
894} 903}
895 904
896extern void free_task(struct task_struct *tsk); 905extern void free_task(struct task_struct *tsk);
897#define get_task_struct(tsk) do { atomic_inc(&(tsk)->usage); } while(0) 906#define get_task_struct(tsk) do { atomic_inc(&(tsk)->usage); } while(0)
898 907
899extern void __put_task_struct_cb(struct rcu_head *rhp); 908extern void __put_task_struct_cb(struct rcu_head *rhp);
909extern void __put_task_struct(struct task_struct *t);
900 910
901static inline void put_task_struct(struct task_struct *t) 911static inline void put_task_struct(struct task_struct *t)
902{ 912{
903 if (atomic_dec_and_test(&t->usage)) 913 if (atomic_dec_and_test(&t->usage))
904 call_rcu(&t->rcu, __put_task_struct_cb); 914 __put_task_struct(t);
905} 915}
906 916
907/* 917/*
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index 613b9513f8b9..c4619a428d9b 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -941,6 +941,25 @@ static inline void skb_reserve(struct sk_buff *skb, int len)
941#define NET_IP_ALIGN 2 941#define NET_IP_ALIGN 2
942#endif 942#endif
943 943
944/*
945 * The networking layer reserves some headroom in skb data (via
946 * dev_alloc_skb). This is used to avoid having to reallocate skb data when
947 * the header has to grow. In the default case, if the header has to grow
948 * 16 bytes or less we avoid the reallocation.
949 *
950 * Unfortunately this headroom changes the DMA alignment of the resulting
951 * network packet. As for NET_IP_ALIGN, this unaligned DMA is expensive
952 * on some architectures. An architecture can override this value,
953 * perhaps setting it to a cacheline in size (since that will maintain
954 * cacheline alignment of the DMA). It must be a power of 2.
955 *
956 * Various parts of the networking layer expect at least 16 bytes of
957 * headroom, you should not reduce this.
958 */
959#ifndef NET_SKB_PAD
960#define NET_SKB_PAD 16
961#endif
962
944extern int ___pskb_trim(struct sk_buff *skb, unsigned int len, int realloc); 963extern int ___pskb_trim(struct sk_buff *skb, unsigned int len, int realloc);
945 964
946static inline void __skb_trim(struct sk_buff *skb, unsigned int len) 965static inline void __skb_trim(struct sk_buff *skb, unsigned int len)
@@ -1030,9 +1049,9 @@ static inline void __skb_queue_purge(struct sk_buff_head *list)
1030static inline struct sk_buff *__dev_alloc_skb(unsigned int length, 1049static inline struct sk_buff *__dev_alloc_skb(unsigned int length,
1031 gfp_t gfp_mask) 1050 gfp_t gfp_mask)
1032{ 1051{
1033 struct sk_buff *skb = alloc_skb(length + 16, gfp_mask); 1052 struct sk_buff *skb = alloc_skb(length + NET_SKB_PAD, gfp_mask);
1034 if (likely(skb)) 1053 if (likely(skb))
1035 skb_reserve(skb, 16); 1054 skb_reserve(skb, NET_SKB_PAD);
1036 return skb; 1055 return skb;
1037} 1056}
1038#else 1057#else
@@ -1070,13 +1089,15 @@ static inline struct sk_buff *dev_alloc_skb(unsigned int length)
1070 */ 1089 */
1071static inline int skb_cow(struct sk_buff *skb, unsigned int headroom) 1090static inline int skb_cow(struct sk_buff *skb, unsigned int headroom)
1072{ 1091{
1073 int delta = (headroom > 16 ? headroom : 16) - skb_headroom(skb); 1092 int delta = (headroom > NET_SKB_PAD ? headroom : NET_SKB_PAD) -
1093 skb_headroom(skb);
1074 1094
1075 if (delta < 0) 1095 if (delta < 0)
1076 delta = 0; 1096 delta = 0;
1077 1097
1078 if (delta || skb_cloned(skb)) 1098 if (delta || skb_cloned(skb))
1079 return pskb_expand_head(skb, (delta + 15) & ~15, 0, GFP_ATOMIC); 1099 return pskb_expand_head(skb, (delta + (NET_SKB_PAD-1)) &
1100 ~(NET_SKB_PAD-1), 0, GFP_ATOMIC);
1080 return 0; 1101 return 0;
1081} 1102}
1082 1103
diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h
index e487e3b60f60..5717147596b6 100644
--- a/include/linux/syscalls.h
+++ b/include/linux/syscalls.h
@@ -569,5 +569,9 @@ asmlinkage long compat_sys_newfstatat(unsigned int dfd, char __user * filename,
569asmlinkage long compat_sys_openat(unsigned int dfd, const char __user *filename, 569asmlinkage long compat_sys_openat(unsigned int dfd, const char __user *filename,
570 int flags, int mode); 570 int flags, int mode);
571asmlinkage long sys_unshare(unsigned long unshare_flags); 571asmlinkage long sys_unshare(unsigned long unshare_flags);
572asmlinkage long sys_splice(int fdin, int fdout, size_t len,
573 unsigned int flags);
574asmlinkage long sys_sync_file_range(int fd, loff_t offset, loff_t nbytes,
575 int flags);
572 576
573#endif 577#endif
diff --git a/include/linux/timer.h b/include/linux/timer.h
index b5caabca553c..0a485beba9f5 100644
--- a/include/linux/timer.h
+++ b/include/linux/timer.h
@@ -6,7 +6,7 @@
6#include <linux/spinlock.h> 6#include <linux/spinlock.h>
7#include <linux/stddef.h> 7#include <linux/stddef.h>
8 8
9struct timer_base_s; 9struct tvec_t_base_s;
10 10
11struct timer_list { 11struct timer_list {
12 struct list_head entry; 12 struct list_head entry;
@@ -15,16 +15,16 @@ struct timer_list {
15 void (*function)(unsigned long); 15 void (*function)(unsigned long);
16 unsigned long data; 16 unsigned long data;
17 17
18 struct timer_base_s *base; 18 struct tvec_t_base_s *base;
19}; 19};
20 20
21extern struct timer_base_s __init_timer_base; 21extern struct tvec_t_base_s boot_tvec_bases;
22 22
23#define TIMER_INITIALIZER(_function, _expires, _data) { \ 23#define TIMER_INITIALIZER(_function, _expires, _data) { \
24 .function = (_function), \ 24 .function = (_function), \
25 .expires = (_expires), \ 25 .expires = (_expires), \
26 .data = (_data), \ 26 .data = (_data), \
27 .base = &__init_timer_base, \ 27 .base = &boot_tvec_bases, \
28 } 28 }
29 29
30#define DEFINE_TIMER(_name, _function, _expires, _data) \ 30#define DEFINE_TIMER(_name, _function, _expires, _data) \
diff --git a/include/linux/tiocl.h b/include/linux/tiocl.h
index 2c9e847f6ed1..4756862c4ed4 100644
--- a/include/linux/tiocl.h
+++ b/include/linux/tiocl.h
@@ -34,5 +34,6 @@ struct tiocl_selection {
34#define TIOCL_SCROLLCONSOLE 13 /* scroll console */ 34#define TIOCL_SCROLLCONSOLE 13 /* scroll console */
35#define TIOCL_BLANKSCREEN 14 /* keep screen blank even if a key is pressed */ 35#define TIOCL_BLANKSCREEN 14 /* keep screen blank even if a key is pressed */
36#define TIOCL_BLANKEDSCREEN 15 /* return which vt was blanked */ 36#define TIOCL_BLANKEDSCREEN 15 /* return which vt was blanked */
37#define TIOCL_GETKMSGREDIRECT 17 /* get the vt the kernel messages are restricted to */
37 38
38#endif /* _LINUX_TIOCL_H */ 39#endif /* _LINUX_TIOCL_H */
diff --git a/include/net/sock.h b/include/net/sock.h
index 2aa73c0ec6c2..af2b0544586e 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -938,28 +938,7 @@ static inline void sock_put(struct sock *sk)
938 sk_free(sk); 938 sk_free(sk);
939} 939}
940 940
941static inline int sk_receive_skb(struct sock *sk, struct sk_buff *skb) 941extern int sk_receive_skb(struct sock *sk, struct sk_buff *skb);
942{
943 int rc = NET_RX_SUCCESS;
944
945 if (sk_filter(sk, skb, 0))
946 goto discard_and_relse;
947
948 skb->dev = NULL;
949
950 bh_lock_sock(sk);
951 if (!sock_owned_by_user(sk))
952 rc = sk->sk_backlog_rcv(sk, skb);
953 else
954 sk_add_backlog(sk, skb);
955 bh_unlock_sock(sk);
956out:
957 sock_put(sk);
958 return rc;
959discard_and_relse:
960 kfree_skb(skb);
961 goto out;
962}
963 942
964/* Detach socket from process context. 943/* Detach socket from process context.
965 * Announce socket dead, detach it from wait queue and inode. 944 * Announce socket dead, detach it from wait queue and inode.
@@ -1044,33 +1023,9 @@ sk_dst_reset(struct sock *sk)
1044 write_unlock(&sk->sk_dst_lock); 1023 write_unlock(&sk->sk_dst_lock);
1045} 1024}
1046 1025
1047static inline struct dst_entry * 1026extern struct dst_entry *__sk_dst_check(struct sock *sk, u32 cookie);
1048__sk_dst_check(struct sock *sk, u32 cookie)
1049{
1050 struct dst_entry *dst = sk->sk_dst_cache;
1051
1052 if (dst && dst->obsolete && dst->ops->check(dst, cookie) == NULL) {
1053 sk->sk_dst_cache = NULL;
1054 dst_release(dst);
1055 return NULL;
1056 }
1057
1058 return dst;
1059}
1060
1061static inline struct dst_entry *
1062sk_dst_check(struct sock *sk, u32 cookie)
1063{
1064 struct dst_entry *dst = sk_dst_get(sk);
1065 1027
1066 if (dst && dst->obsolete && dst->ops->check(dst, cookie) == NULL) { 1028extern struct dst_entry *sk_dst_check(struct sock *sk, u32 cookie);
1067 sk_dst_reset(sk);
1068 dst_release(dst);
1069 return NULL;
1070 }
1071
1072 return dst;
1073}
1074 1029
1075static inline void sk_setup_caps(struct sock *sk, struct dst_entry *dst) 1030static inline void sk_setup_caps(struct sock *sk, struct dst_entry *dst)
1076{ 1031{
@@ -1140,45 +1095,7 @@ extern void sk_reset_timer(struct sock *sk, struct timer_list* timer,
1140 1095
1141extern void sk_stop_timer(struct sock *sk, struct timer_list* timer); 1096extern void sk_stop_timer(struct sock *sk, struct timer_list* timer);
1142 1097
1143static inline int sock_queue_rcv_skb(struct sock *sk, struct sk_buff *skb) 1098extern int sock_queue_rcv_skb(struct sock *sk, struct sk_buff *skb);
1144{
1145 int err = 0;
1146 int skb_len;
1147
1148 /* Cast skb->rcvbuf to unsigned... It's pointless, but reduces
1149 number of warnings when compiling with -W --ANK
1150 */
1151 if (atomic_read(&sk->sk_rmem_alloc) + skb->truesize >=
1152 (unsigned)sk->sk_rcvbuf) {
1153 err = -ENOMEM;
1154 goto out;
1155 }
1156
1157 /* It would be deadlock, if sock_queue_rcv_skb is used
1158 with socket lock! We assume that users of this
1159 function are lock free.
1160 */
1161 err = sk_filter(sk, skb, 1);
1162 if (err)
1163 goto out;
1164
1165 skb->dev = NULL;
1166 skb_set_owner_r(skb, sk);
1167
1168 /* Cache the SKB length before we tack it onto the receive
1169 * queue. Once it is added it no longer belongs to us and
1170 * may be freed by other threads of control pulling packets
1171 * from the queue.
1172 */
1173 skb_len = skb->len;
1174
1175 skb_queue_tail(&sk->sk_receive_queue, skb);
1176
1177 if (!sock_flag(sk, SOCK_DEAD))
1178 sk->sk_data_ready(sk, skb_len);
1179out:
1180 return err;
1181}
1182 1099
1183static inline int sock_queue_err_skb(struct sock *sk, struct sk_buff *skb) 1100static inline int sock_queue_err_skb(struct sock *sk, struct sk_buff *skb)
1184{ 1101{
diff --git a/include/net/tcp.h b/include/net/tcp.h
index 9418f4d1afbb..3c989db8a7aa 100644
--- a/include/net/tcp.h
+++ b/include/net/tcp.h
@@ -405,9 +405,6 @@ extern int tcp_disconnect(struct sock *sk, int flags);
405 405
406extern void tcp_unhash(struct sock *sk); 406extern void tcp_unhash(struct sock *sk);
407 407
408extern int tcp_v4_hash_connecting(struct sock *sk);
409
410
411/* From syncookies.c */ 408/* From syncookies.c */
412extern struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb, 409extern struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb,
413 struct ip_options *opt); 410 struct ip_options *opt);
diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index 61b7504fc2ba..e100291e43f4 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -864,13 +864,19 @@ struct xfrm_algo_desc {
864/* XFRM tunnel handlers. */ 864/* XFRM tunnel handlers. */
865struct xfrm_tunnel { 865struct xfrm_tunnel {
866 int (*handler)(struct sk_buff *skb); 866 int (*handler)(struct sk_buff *skb);
867 void (*err_handler)(struct sk_buff *skb, __u32 info); 867 int (*err_handler)(struct sk_buff *skb, __u32 info);
868
869 struct xfrm_tunnel *next;
870 int priority;
868}; 871};
869 872
870struct xfrm6_tunnel { 873struct xfrm6_tunnel {
871 int (*handler)(struct sk_buff **pskb); 874 int (*handler)(struct sk_buff *skb);
872 void (*err_handler)(struct sk_buff *skb, struct inet6_skb_parm *opt, 875 int (*err_handler)(struct sk_buff *skb, struct inet6_skb_parm *opt,
873 int type, int code, int offset, __u32 info); 876 int type, int code, int offset, __u32 info);
877
878 struct xfrm6_tunnel *next;
879 int priority;
874}; 880};
875 881
876extern void xfrm_init(void); 882extern void xfrm_init(void);
@@ -906,7 +912,7 @@ extern int xfrm4_rcv(struct sk_buff *skb);
906extern int xfrm4_output(struct sk_buff *skb); 912extern int xfrm4_output(struct sk_buff *skb);
907extern int xfrm4_tunnel_register(struct xfrm_tunnel *handler); 913extern int xfrm4_tunnel_register(struct xfrm_tunnel *handler);
908extern int xfrm4_tunnel_deregister(struct xfrm_tunnel *handler); 914extern int xfrm4_tunnel_deregister(struct xfrm_tunnel *handler);
909extern int xfrm6_rcv_spi(struct sk_buff **pskb, u32 spi); 915extern int xfrm6_rcv_spi(struct sk_buff *skb, u32 spi);
910extern int xfrm6_rcv(struct sk_buff **pskb); 916extern int xfrm6_rcv(struct sk_buff **pskb);
911extern int xfrm6_tunnel_register(struct xfrm6_tunnel *handler); 917extern int xfrm6_tunnel_register(struct xfrm6_tunnel *handler);
912extern int xfrm6_tunnel_deregister(struct xfrm6_tunnel *handler); 918extern int xfrm6_tunnel_deregister(struct xfrm6_tunnel *handler);
diff --git a/include/rdma/ib_mad.h b/include/rdma/ib_mad.h
index 51ab8eddb295..5ff77558013b 100644
--- a/include/rdma/ib_mad.h
+++ b/include/rdma/ib_mad.h
@@ -3,7 +3,7 @@
3 * Copyright (c) 2004 Infinicon Corporation. All rights reserved. 3 * Copyright (c) 2004 Infinicon Corporation. All rights reserved.
4 * Copyright (c) 2004 Intel Corporation. All rights reserved. 4 * Copyright (c) 2004 Intel Corporation. All rights reserved.
5 * Copyright (c) 2004 Topspin Corporation. All rights reserved. 5 * Copyright (c) 2004 Topspin Corporation. All rights reserved.
6 * Copyright (c) 2004 Voltaire Corporation. All rights reserved. 6 * Copyright (c) 2004-2006 Voltaire Corporation. All rights reserved.
7 * 7 *
8 * This software is available to you under a choice of one of two 8 * This software is available to you under a choice of one of two
9 * licenses. You may choose to be licensed under the terms of the GNU 9 * licenses. You may choose to be licensed under the terms of the GNU
@@ -55,6 +55,10 @@
55#define IB_MGMT_CLASS_DEVICE_MGMT 0x06 55#define IB_MGMT_CLASS_DEVICE_MGMT 0x06
56#define IB_MGMT_CLASS_CM 0x07 56#define IB_MGMT_CLASS_CM 0x07
57#define IB_MGMT_CLASS_SNMP 0x08 57#define IB_MGMT_CLASS_SNMP 0x08
58#define IB_MGMT_CLASS_DEVICE_ADM 0x10
59#define IB_MGMT_CLASS_BOOT_MGMT 0x11
60#define IB_MGMT_CLASS_BIS 0x12
61#define IB_MGMT_CLASS_CONG_MGMT 0x21
58#define IB_MGMT_CLASS_VENDOR_RANGE2_START 0x30 62#define IB_MGMT_CLASS_VENDOR_RANGE2_START 0x30
59#define IB_MGMT_CLASS_VENDOR_RANGE2_END 0x4F 63#define IB_MGMT_CLASS_VENDOR_RANGE2_END 0x4F
60 64
@@ -117,6 +121,8 @@ enum {
117 IB_MGMT_VENDOR_DATA = 216, 121 IB_MGMT_VENDOR_DATA = 216,
118 IB_MGMT_SA_HDR = 56, 122 IB_MGMT_SA_HDR = 56,
119 IB_MGMT_SA_DATA = 200, 123 IB_MGMT_SA_DATA = 200,
124 IB_MGMT_DEVICE_HDR = 64,
125 IB_MGMT_DEVICE_DATA = 192,
120}; 126};
121 127
122struct ib_mad_hdr { 128struct ib_mad_hdr {
@@ -603,6 +609,25 @@ struct ib_mad_send_buf * ib_create_send_mad(struct ib_mad_agent *mad_agent,
603 gfp_t gfp_mask); 609 gfp_t gfp_mask);
604 610
605/** 611/**
612 * ib_is_mad_class_rmpp - returns whether given management class
613 * supports RMPP.
614 * @mgmt_class: management class
615 *
616 * This routine returns whether the management class supports RMPP.
617 */
618int ib_is_mad_class_rmpp(u8 mgmt_class);
619
620/**
621 * ib_get_mad_data_offset - returns the data offset for a given
622 * management class.
623 * @mgmt_class: management class
624 *
625 * This routine returns the data offset in the MAD for the management
626 * class requested.
627 */
628int ib_get_mad_data_offset(u8 mgmt_class);
629
630/**
606 * ib_get_rmpp_segment - returns the data buffer for a given RMPP segment. 631 * ib_get_rmpp_segment - returns the data buffer for a given RMPP segment.
607 * @send_buf: Previously allocated send data buffer. 632 * @send_buf: Previously allocated send data buffer.
608 * @seg_num: number of segment to return 633 * @seg_num: number of segment to return
diff --git a/kernel/acct.c b/kernel/acct.c
index 065d8b4e51ef..b327f4d20104 100644
--- a/kernel/acct.c
+++ b/kernel/acct.c
@@ -449,8 +449,8 @@ static void do_acct_process(long exitcode, struct file *file)
449 /* calculate run_time in nsec*/ 449 /* calculate run_time in nsec*/
450 do_posix_clock_monotonic_gettime(&uptime); 450 do_posix_clock_monotonic_gettime(&uptime);
451 run_time = (u64)uptime.tv_sec*NSEC_PER_SEC + uptime.tv_nsec; 451 run_time = (u64)uptime.tv_sec*NSEC_PER_SEC + uptime.tv_nsec;
452 run_time -= (u64)current->start_time.tv_sec*NSEC_PER_SEC 452 run_time -= (u64)current->group_leader->start_time.tv_sec * NSEC_PER_SEC
453 + current->start_time.tv_nsec; 453 + current->group_leader->start_time.tv_nsec;
454 /* convert nsec -> AHZ */ 454 /* convert nsec -> AHZ */
455 elapsed = nsec_to_AHZ(run_time); 455 elapsed = nsec_to_AHZ(run_time);
456#if ACCT_VERSION==3 456#if ACCT_VERSION==3
@@ -469,10 +469,10 @@ static void do_acct_process(long exitcode, struct file *file)
469#endif 469#endif
470 do_div(elapsed, AHZ); 470 do_div(elapsed, AHZ);
471 ac.ac_btime = xtime.tv_sec - elapsed; 471 ac.ac_btime = xtime.tv_sec - elapsed;
472 jiffies = cputime_to_jiffies(cputime_add(current->group_leader->utime, 472 jiffies = cputime_to_jiffies(cputime_add(current->utime,
473 current->signal->utime)); 473 current->signal->utime));
474 ac.ac_utime = encode_comp_t(jiffies_to_AHZ(jiffies)); 474 ac.ac_utime = encode_comp_t(jiffies_to_AHZ(jiffies));
475 jiffies = cputime_to_jiffies(cputime_add(current->group_leader->stime, 475 jiffies = cputime_to_jiffies(cputime_add(current->stime,
476 current->signal->stime)); 476 current->signal->stime));
477 ac.ac_stime = encode_comp_t(jiffies_to_AHZ(jiffies)); 477 ac.ac_stime = encode_comp_t(jiffies_to_AHZ(jiffies));
478 /* we really need to bite the bullet and change layout */ 478 /* we really need to bite the bullet and change layout */
@@ -522,9 +522,9 @@ static void do_acct_process(long exitcode, struct file *file)
522 ac.ac_io = encode_comp_t(0 /* current->io_usage */); /* %% */ 522 ac.ac_io = encode_comp_t(0 /* current->io_usage */); /* %% */
523 ac.ac_rw = encode_comp_t(ac.ac_io / 1024); 523 ac.ac_rw = encode_comp_t(ac.ac_io / 1024);
524 ac.ac_minflt = encode_comp_t(current->signal->min_flt + 524 ac.ac_minflt = encode_comp_t(current->signal->min_flt +
525 current->group_leader->min_flt); 525 current->min_flt);
526 ac.ac_majflt = encode_comp_t(current->signal->maj_flt + 526 ac.ac_majflt = encode_comp_t(current->signal->maj_flt +
527 current->group_leader->maj_flt); 527 current->maj_flt);
528 ac.ac_swaps = encode_comp_t(0); 528 ac.ac_swaps = encode_comp_t(0);
529 ac.ac_exitcode = exitcode; 529 ac.ac_exitcode = exitcode;
530 530
diff --git a/kernel/audit.c b/kernel/audit.c
index 04fe2e301b61..c8ccbd09048f 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -578,7 +578,7 @@ static int __init audit_enable(char *str)
578 audit_initialized ? "" : " (after initialization)"); 578 audit_initialized ? "" : " (after initialization)");
579 if (audit_initialized) 579 if (audit_initialized)
580 audit_enabled = audit_default; 580 audit_enabled = audit_default;
581 return 0; 581 return 1;
582} 582}
583 583
584__setup("audit=", audit_enable); 584__setup("audit=", audit_enable);
diff --git a/kernel/cpuset.c b/kernel/cpuset.c
index 18aea1bd1284..72248d1b9e3f 100644
--- a/kernel/cpuset.c
+++ b/kernel/cpuset.c
@@ -616,12 +616,10 @@ static void guarantee_online_mems(const struct cpuset *cs, nodemask_t *pmask)
616 * current->cpuset if a task has its memory placement changed. 616 * current->cpuset if a task has its memory placement changed.
617 * Do not call this routine if in_interrupt(). 617 * Do not call this routine if in_interrupt().
618 * 618 *
619 * Call without callback_mutex or task_lock() held. May be called 619 * Call without callback_mutex or task_lock() held. May be
620 * with or without manage_mutex held. Doesn't need task_lock to guard 620 * called with or without manage_mutex held. Thanks in part to
621 * against another task changing a non-NULL cpuset pointer to NULL, 621 * 'the_top_cpuset_hack', the tasks cpuset pointer will never
622 * as that is only done by a task on itself, and if the current task 622 * be NULL. This routine also might acquire callback_mutex and
623 * is here, it is not simultaneously in the exit code NULL'ing its
624 * cpuset pointer. This routine also might acquire callback_mutex and
625 * current->mm->mmap_sem during call. 623 * current->mm->mmap_sem during call.
626 * 624 *
627 * Reading current->cpuset->mems_generation doesn't need task_lock 625 * Reading current->cpuset->mems_generation doesn't need task_lock
@@ -836,6 +834,55 @@ static int update_cpumask(struct cpuset *cs, char *buf)
836} 834}
837 835
838/* 836/*
837 * cpuset_migrate_mm
838 *
839 * Migrate memory region from one set of nodes to another.
840 *
841 * Temporarilly set tasks mems_allowed to target nodes of migration,
842 * so that the migration code can allocate pages on these nodes.
843 *
844 * Call holding manage_mutex, so our current->cpuset won't change
845 * during this call, as manage_mutex holds off any attach_task()
846 * calls. Therefore we don't need to take task_lock around the
847 * call to guarantee_online_mems(), as we know no one is changing
848 * our tasks cpuset.
849 *
850 * Hold callback_mutex around the two modifications of our tasks
851 * mems_allowed to synchronize with cpuset_mems_allowed().
852 *
853 * While the mm_struct we are migrating is typically from some
854 * other task, the task_struct mems_allowed that we are hacking
855 * is for our current task, which must allocate new pages for that
856 * migrating memory region.
857 *
858 * We call cpuset_update_task_memory_state() before hacking
859 * our tasks mems_allowed, so that we are assured of being in
860 * sync with our tasks cpuset, and in particular, callbacks to
861 * cpuset_update_task_memory_state() from nested page allocations
862 * won't see any mismatch of our cpuset and task mems_generation
863 * values, so won't overwrite our hacked tasks mems_allowed
864 * nodemask.
865 */
866
867static void cpuset_migrate_mm(struct mm_struct *mm, const nodemask_t *from,
868 const nodemask_t *to)
869{
870 struct task_struct *tsk = current;
871
872 cpuset_update_task_memory_state();
873
874 mutex_lock(&callback_mutex);
875 tsk->mems_allowed = *to;
876 mutex_unlock(&callback_mutex);
877
878 do_migrate_pages(mm, from, to, MPOL_MF_MOVE_ALL);
879
880 mutex_lock(&callback_mutex);
881 guarantee_online_mems(tsk->cpuset, &tsk->mems_allowed);
882 mutex_unlock(&callback_mutex);
883}
884
885/*
839 * Handle user request to change the 'mems' memory placement 886 * Handle user request to change the 'mems' memory placement
840 * of a cpuset. Needs to validate the request, update the 887 * of a cpuset. Needs to validate the request, update the
841 * cpusets mems_allowed and mems_generation, and for each 888 * cpusets mems_allowed and mems_generation, and for each
@@ -947,10 +994,8 @@ static int update_nodemask(struct cpuset *cs, char *buf)
947 struct mm_struct *mm = mmarray[i]; 994 struct mm_struct *mm = mmarray[i];
948 995
949 mpol_rebind_mm(mm, &cs->mems_allowed); 996 mpol_rebind_mm(mm, &cs->mems_allowed);
950 if (migrate) { 997 if (migrate)
951 do_migrate_pages(mm, &oldmem, &cs->mems_allowed, 998 cpuset_migrate_mm(mm, &oldmem, &cs->mems_allowed);
952 MPOL_MF_MOVE_ALL);
953 }
954 mmput(mm); 999 mmput(mm);
955 } 1000 }
956 1001
@@ -1185,11 +1230,11 @@ static int attach_task(struct cpuset *cs, char *pidbuf, char **ppathbuf)
1185 mm = get_task_mm(tsk); 1230 mm = get_task_mm(tsk);
1186 if (mm) { 1231 if (mm) {
1187 mpol_rebind_mm(mm, &to); 1232 mpol_rebind_mm(mm, &to);
1233 if (is_memory_migrate(cs))
1234 cpuset_migrate_mm(mm, &from, &to);
1188 mmput(mm); 1235 mmput(mm);
1189 } 1236 }
1190 1237
1191 if (is_memory_migrate(cs))
1192 do_migrate_pages(tsk->mm, &from, &to, MPOL_MF_MOVE_ALL);
1193 put_task_struct(tsk); 1238 put_task_struct(tsk);
1194 synchronize_rcu(); 1239 synchronize_rcu();
1195 if (atomic_dec_and_test(&oldcs->count)) 1240 if (atomic_dec_and_test(&oldcs->count))
diff --git a/kernel/exit.c b/kernel/exit.c
index bc0ec674d3f4..6c2eeb8f6390 100644
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -127,6 +127,11 @@ static void __exit_signal(struct task_struct *tsk)
127 } 127 }
128} 128}
129 129
130static void delayed_put_task_struct(struct rcu_head *rhp)
131{
132 put_task_struct(container_of(rhp, struct task_struct, rcu));
133}
134
130void release_task(struct task_struct * p) 135void release_task(struct task_struct * p)
131{ 136{
132 int zap_leader; 137 int zap_leader;
@@ -168,7 +173,7 @@ repeat:
168 spin_unlock(&p->proc_lock); 173 spin_unlock(&p->proc_lock);
169 proc_pid_flush(proc_dentry); 174 proc_pid_flush(proc_dentry);
170 release_thread(p); 175 release_thread(p);
171 put_task_struct(p); 176 call_rcu(&p->rcu, delayed_put_task_struct);
172 177
173 p = leader; 178 p = leader;
174 if (unlikely(zap_leader)) 179 if (unlikely(zap_leader))
diff --git a/kernel/fork.c b/kernel/fork.c
index b3f7a1bb5e55..3384eb89cb1c 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -108,10 +108,8 @@ void free_task(struct task_struct *tsk)
108} 108}
109EXPORT_SYMBOL(free_task); 109EXPORT_SYMBOL(free_task);
110 110
111void __put_task_struct_cb(struct rcu_head *rhp) 111void __put_task_struct(struct task_struct *tsk)
112{ 112{
113 struct task_struct *tsk = container_of(rhp, struct task_struct, rcu);
114
115 WARN_ON(!(tsk->exit_state & (EXIT_DEAD | EXIT_ZOMBIE))); 113 WARN_ON(!(tsk->exit_state & (EXIT_DEAD | EXIT_ZOMBIE)));
116 WARN_ON(atomic_read(&tsk->usage)); 114 WARN_ON(atomic_read(&tsk->usage));
117 WARN_ON(tsk == current); 115 WARN_ON(tsk == current);
@@ -126,6 +124,12 @@ void __put_task_struct_cb(struct rcu_head *rhp)
126 free_task(tsk); 124 free_task(tsk);
127} 125}
128 126
127void __put_task_struct_cb(struct rcu_head *rhp)
128{
129 struct task_struct *tsk = container_of(rhp, struct task_struct, rcu);
130 __put_task_struct(tsk);
131}
132
129void __init fork_init(unsigned long mempages) 133void __init fork_init(unsigned long mempages)
130{ 134{
131#ifndef __HAVE_ARCH_TASK_STRUCT_ALLOCATOR 135#ifndef __HAVE_ARCH_TASK_STRUCT_ALLOCATOR
@@ -721,7 +725,7 @@ out_release:
721 free_fdset (new_fdt->open_fds, new_fdt->max_fdset); 725 free_fdset (new_fdt->open_fds, new_fdt->max_fdset);
722 free_fd_array(new_fdt->fd, new_fdt->max_fds); 726 free_fd_array(new_fdt->fd, new_fdt->max_fds);
723 kmem_cache_free(files_cachep, newf); 727 kmem_cache_free(files_cachep, newf);
724 goto out; 728 return NULL;
725} 729}
726 730
727static int copy_files(unsigned long clone_flags, struct task_struct * tsk) 731static int copy_files(unsigned long clone_flags, struct task_struct * tsk)
@@ -1311,17 +1315,19 @@ long do_fork(unsigned long clone_flags,
1311{ 1315{
1312 struct task_struct *p; 1316 struct task_struct *p;
1313 int trace = 0; 1317 int trace = 0;
1314 long pid = alloc_pidmap(); 1318 struct pid *pid = alloc_pid();
1319 long nr;
1315 1320
1316 if (pid < 0) 1321 if (!pid)
1317 return -EAGAIN; 1322 return -EAGAIN;
1323 nr = pid->nr;
1318 if (unlikely(current->ptrace)) { 1324 if (unlikely(current->ptrace)) {
1319 trace = fork_traceflag (clone_flags); 1325 trace = fork_traceflag (clone_flags);
1320 if (trace) 1326 if (trace)
1321 clone_flags |= CLONE_PTRACE; 1327 clone_flags |= CLONE_PTRACE;
1322 } 1328 }
1323 1329
1324 p = copy_process(clone_flags, stack_start, regs, stack_size, parent_tidptr, child_tidptr, pid); 1330 p = copy_process(clone_flags, stack_start, regs, stack_size, parent_tidptr, child_tidptr, nr);
1325 /* 1331 /*
1326 * Do this prior waking up the new thread - the thread pointer 1332 * Do this prior waking up the new thread - the thread pointer
1327 * might get invalid after that point, if the thread exits quickly. 1333 * might get invalid after that point, if the thread exits quickly.
@@ -1348,7 +1354,7 @@ long do_fork(unsigned long clone_flags,
1348 p->state = TASK_STOPPED; 1354 p->state = TASK_STOPPED;
1349 1355
1350 if (unlikely (trace)) { 1356 if (unlikely (trace)) {
1351 current->ptrace_message = pid; 1357 current->ptrace_message = nr;
1352 ptrace_notify ((trace << 8) | SIGTRAP); 1358 ptrace_notify ((trace << 8) | SIGTRAP);
1353 } 1359 }
1354 1360
@@ -1358,10 +1364,10 @@ long do_fork(unsigned long clone_flags,
1358 ptrace_notify ((PTRACE_EVENT_VFORK_DONE << 8) | SIGTRAP); 1364 ptrace_notify ((PTRACE_EVENT_VFORK_DONE << 8) | SIGTRAP);
1359 } 1365 }
1360 } else { 1366 } else {
1361 free_pidmap(pid); 1367 free_pid(pid);
1362 pid = PTR_ERR(p); 1368 nr = PTR_ERR(p);
1363 } 1369 }
1364 return pid; 1370 return nr;
1365} 1371}
1366 1372
1367#ifndef ARCH_MIN_MMSTRUCT_ALIGN 1373#ifndef ARCH_MIN_MMSTRUCT_ALIGN
diff --git a/kernel/futex.c b/kernel/futex.c
index 9c9b2b6b22dd..5699c512057b 100644
--- a/kernel/futex.c
+++ b/kernel/futex.c
@@ -1039,9 +1039,11 @@ asmlinkage long sys_futex(u32 __user *uaddr, int op, int val,
1039 unsigned long timeout = MAX_SCHEDULE_TIMEOUT; 1039 unsigned long timeout = MAX_SCHEDULE_TIMEOUT;
1040 int val2 = 0; 1040 int val2 = 0;
1041 1041
1042 if ((op == FUTEX_WAIT) && utime) { 1042 if (utime && (op == FUTEX_WAIT)) {
1043 if (copy_from_user(&t, utime, sizeof(t)) != 0) 1043 if (copy_from_user(&t, utime, sizeof(t)) != 0)
1044 return -EFAULT; 1044 return -EFAULT;
1045 if (!timespec_valid(&t))
1046 return -EINVAL;
1045 timeout = timespec_to_jiffies(&t) + 1; 1047 timeout = timespec_to_jiffies(&t) + 1;
1046 } 1048 }
1047 /* 1049 /*
diff --git a/kernel/futex_compat.c b/kernel/futex_compat.c
index 54274fc85321..1ab6a0ea3d14 100644
--- a/kernel/futex_compat.c
+++ b/kernel/futex_compat.c
@@ -129,9 +129,11 @@ asmlinkage long compat_sys_futex(u32 __user *uaddr, int op, u32 val,
129 unsigned long timeout = MAX_SCHEDULE_TIMEOUT; 129 unsigned long timeout = MAX_SCHEDULE_TIMEOUT;
130 int val2 = 0; 130 int val2 = 0;
131 131
132 if ((op == FUTEX_WAIT) && utime) { 132 if (utime && (op == FUTEX_WAIT)) {
133 if (get_compat_timespec(&t, utime)) 133 if (get_compat_timespec(&t, utime))
134 return -EFAULT; 134 return -EFAULT;
135 if (!timespec_valid(&t))
136 return -EINVAL;
135 timeout = timespec_to_jiffies(&t) + 1; 137 timeout = timespec_to_jiffies(&t) + 1;
136 } 138 }
137 if (op >= FUTEX_REQUEUE) 139 if (op >= FUTEX_REQUEUE)
diff --git a/kernel/hrtimer.c b/kernel/hrtimer.c
index 0237a556eb1f..f181ff4dd32e 100644
--- a/kernel/hrtimer.c
+++ b/kernel/hrtimer.c
@@ -606,6 +606,9 @@ static inline void run_hrtimer_queue(struct hrtimer_base *base)
606{ 606{
607 struct rb_node *node; 607 struct rb_node *node;
608 608
609 if (!base->first)
610 return;
611
609 if (base->get_softirq_time) 612 if (base->get_softirq_time)
610 base->softirq_time = base->get_softirq_time(); 613 base->softirq_time = base->get_softirq_time();
611 614
@@ -655,29 +658,28 @@ void hrtimer_run_queues(void)
655/* 658/*
656 * Sleep related functions: 659 * Sleep related functions:
657 */ 660 */
658 661static int hrtimer_wakeup(struct hrtimer *timer)
659struct sleep_hrtimer {
660 struct hrtimer timer;
661 struct task_struct *task;
662 int expired;
663};
664
665static int nanosleep_wakeup(struct hrtimer *timer)
666{ 662{
667 struct sleep_hrtimer *t = 663 struct hrtimer_sleeper *t =
668 container_of(timer, struct sleep_hrtimer, timer); 664 container_of(timer, struct hrtimer_sleeper, timer);
665 struct task_struct *task = t->task;
669 666
670 t->expired = 1; 667 t->task = NULL;
671 wake_up_process(t->task); 668 if (task)
669 wake_up_process(task);
672 670
673 return HRTIMER_NORESTART; 671 return HRTIMER_NORESTART;
674} 672}
675 673
676static int __sched do_nanosleep(struct sleep_hrtimer *t, enum hrtimer_mode mode) 674void hrtimer_init_sleeper(struct hrtimer_sleeper *sl, task_t *task)
677{ 675{
678 t->timer.function = nanosleep_wakeup; 676 sl->timer.function = hrtimer_wakeup;
679 t->task = current; 677 sl->task = task;
680 t->expired = 0; 678}
679
680static int __sched do_nanosleep(struct hrtimer_sleeper *t, enum hrtimer_mode mode)
681{
682 hrtimer_init_sleeper(t, current);
681 683
682 do { 684 do {
683 set_current_state(TASK_INTERRUPTIBLE); 685 set_current_state(TASK_INTERRUPTIBLE);
@@ -685,18 +687,17 @@ static int __sched do_nanosleep(struct sleep_hrtimer *t, enum hrtimer_mode mode)
685 687
686 schedule(); 688 schedule();
687 689
688 if (unlikely(!t->expired)) { 690 hrtimer_cancel(&t->timer);
689 hrtimer_cancel(&t->timer); 691 mode = HRTIMER_ABS;
690 mode = HRTIMER_ABS; 692
691 } 693 } while (t->task && !signal_pending(current));
692 } while (!t->expired && !signal_pending(current));
693 694
694 return t->expired; 695 return t->task == NULL;
695} 696}
696 697
697static long __sched nanosleep_restart(struct restart_block *restart) 698static long __sched nanosleep_restart(struct restart_block *restart)
698{ 699{
699 struct sleep_hrtimer t; 700 struct hrtimer_sleeper t;
700 struct timespec __user *rmtp; 701 struct timespec __user *rmtp;
701 struct timespec tu; 702 struct timespec tu;
702 ktime_t time; 703 ktime_t time;
@@ -729,7 +730,7 @@ long hrtimer_nanosleep(struct timespec *rqtp, struct timespec __user *rmtp,
729 const enum hrtimer_mode mode, const clockid_t clockid) 730 const enum hrtimer_mode mode, const clockid_t clockid)
730{ 731{
731 struct restart_block *restart; 732 struct restart_block *restart;
732 struct sleep_hrtimer t; 733 struct hrtimer_sleeper t;
733 struct timespec tu; 734 struct timespec tu;
734 ktime_t rem; 735 ktime_t rem;
735 736
diff --git a/kernel/module.c b/kernel/module.c
index bd088a7c1499..d24deb0dbbc9 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -1254,6 +1254,7 @@ static inline int license_is_gpl_compatible(const char *license)
1254 || strcmp(license, "GPL v2") == 0 1254 || strcmp(license, "GPL v2") == 0
1255 || strcmp(license, "GPL and additional rights") == 0 1255 || strcmp(license, "GPL and additional rights") == 0
1256 || strcmp(license, "Dual BSD/GPL") == 0 1256 || strcmp(license, "Dual BSD/GPL") == 0
1257 || strcmp(license, "Dual MIT/GPL") == 0
1257 || strcmp(license, "Dual MPL/GPL") == 0); 1258 || strcmp(license, "Dual MPL/GPL") == 0);
1258} 1259}
1259 1260
diff --git a/kernel/pid.c b/kernel/pid.c
index a9f2dfd006d2..eeb836b65ca4 100644
--- a/kernel/pid.c
+++ b/kernel/pid.c
@@ -28,8 +28,9 @@
28#include <linux/hash.h> 28#include <linux/hash.h>
29 29
30#define pid_hashfn(nr) hash_long((unsigned long)nr, pidhash_shift) 30#define pid_hashfn(nr) hash_long((unsigned long)nr, pidhash_shift)
31static struct hlist_head *pid_hash[PIDTYPE_MAX]; 31static struct hlist_head *pid_hash;
32static int pidhash_shift; 32static int pidhash_shift;
33static kmem_cache_t *pid_cachep;
33 34
34int pid_max = PID_MAX_DEFAULT; 35int pid_max = PID_MAX_DEFAULT;
35int last_pid; 36int last_pid;
@@ -60,9 +61,22 @@ typedef struct pidmap {
60static pidmap_t pidmap_array[PIDMAP_ENTRIES] = 61static pidmap_t pidmap_array[PIDMAP_ENTRIES] =
61 { [ 0 ... PIDMAP_ENTRIES-1 ] = { ATOMIC_INIT(BITS_PER_PAGE), NULL } }; 62 { [ 0 ... PIDMAP_ENTRIES-1 ] = { ATOMIC_INIT(BITS_PER_PAGE), NULL } };
62 63
64/*
65 * Note: disable interrupts while the pidmap_lock is held as an
66 * interrupt might come in and do read_lock(&tasklist_lock).
67 *
68 * If we don't disable interrupts there is a nasty deadlock between
69 * detach_pid()->free_pid() and another cpu that does
70 * spin_lock(&pidmap_lock) followed by an interrupt routine that does
71 * read_lock(&tasklist_lock);
72 *
73 * After we clean up the tasklist_lock and know there are no
74 * irq handlers that take it we can leave the interrupts enabled.
75 * For now it is easier to be safe than to prove it can't happen.
76 */
63static __cacheline_aligned_in_smp DEFINE_SPINLOCK(pidmap_lock); 77static __cacheline_aligned_in_smp DEFINE_SPINLOCK(pidmap_lock);
64 78
65fastcall void free_pidmap(int pid) 79static fastcall void free_pidmap(int pid)
66{ 80{
67 pidmap_t *map = pidmap_array + pid / BITS_PER_PAGE; 81 pidmap_t *map = pidmap_array + pid / BITS_PER_PAGE;
68 int offset = pid & BITS_PER_PAGE_MASK; 82 int offset = pid & BITS_PER_PAGE_MASK;
@@ -71,7 +85,7 @@ fastcall void free_pidmap(int pid)
71 atomic_inc(&map->nr_free); 85 atomic_inc(&map->nr_free);
72} 86}
73 87
74int alloc_pidmap(void) 88static int alloc_pidmap(void)
75{ 89{
76 int i, offset, max_scan, pid, last = last_pid; 90 int i, offset, max_scan, pid, last = last_pid;
77 pidmap_t *map; 91 pidmap_t *map;
@@ -89,12 +103,12 @@ int alloc_pidmap(void)
89 * Free the page if someone raced with us 103 * Free the page if someone raced with us
90 * installing it: 104 * installing it:
91 */ 105 */
92 spin_lock(&pidmap_lock); 106 spin_lock_irq(&pidmap_lock);
93 if (map->page) 107 if (map->page)
94 free_page(page); 108 free_page(page);
95 else 109 else
96 map->page = (void *)page; 110 map->page = (void *)page;
97 spin_unlock(&pidmap_lock); 111 spin_unlock_irq(&pidmap_lock);
98 if (unlikely(!map->page)) 112 if (unlikely(!map->page))
99 break; 113 break;
100 } 114 }
@@ -131,13 +145,73 @@ int alloc_pidmap(void)
131 return -1; 145 return -1;
132} 146}
133 147
134struct pid * fastcall find_pid(enum pid_type type, int nr) 148fastcall void put_pid(struct pid *pid)
149{
150 if (!pid)
151 return;
152 if ((atomic_read(&pid->count) == 1) ||
153 atomic_dec_and_test(&pid->count))
154 kmem_cache_free(pid_cachep, pid);
155}
156
157static void delayed_put_pid(struct rcu_head *rhp)
158{
159 struct pid *pid = container_of(rhp, struct pid, rcu);
160 put_pid(pid);
161}
162
163fastcall void free_pid(struct pid *pid)
164{
165 /* We can be called with write_lock_irq(&tasklist_lock) held */
166 unsigned long flags;
167
168 spin_lock_irqsave(&pidmap_lock, flags);
169 hlist_del_rcu(&pid->pid_chain);
170 spin_unlock_irqrestore(&pidmap_lock, flags);
171
172 free_pidmap(pid->nr);
173 call_rcu(&pid->rcu, delayed_put_pid);
174}
175
176struct pid *alloc_pid(void)
177{
178 struct pid *pid;
179 enum pid_type type;
180 int nr = -1;
181
182 pid = kmem_cache_alloc(pid_cachep, GFP_KERNEL);
183 if (!pid)
184 goto out;
185
186 nr = alloc_pidmap();
187 if (nr < 0)
188 goto out_free;
189
190 atomic_set(&pid->count, 1);
191 pid->nr = nr;
192 for (type = 0; type < PIDTYPE_MAX; ++type)
193 INIT_HLIST_HEAD(&pid->tasks[type]);
194
195 spin_lock_irq(&pidmap_lock);
196 hlist_add_head_rcu(&pid->pid_chain, &pid_hash[pid_hashfn(pid->nr)]);
197 spin_unlock_irq(&pidmap_lock);
198
199out:
200 return pid;
201
202out_free:
203 kmem_cache_free(pid_cachep, pid);
204 pid = NULL;
205 goto out;
206}
207
208struct pid * fastcall find_pid(int nr)
135{ 209{
136 struct hlist_node *elem; 210 struct hlist_node *elem;
137 struct pid *pid; 211 struct pid *pid;
138 212
139 hlist_for_each_entry_rcu(pid, elem, 213 hlist_for_each_entry_rcu(pid, elem,
140 &pid_hash[type][pid_hashfn(nr)], pid_chain) { 214 &pid_hash[pid_hashfn(nr)], pid_chain) {
141 if (pid->nr == nr) 215 if (pid->nr == nr)
142 return pid; 216 return pid;
143 } 217 }
@@ -146,77 +220,82 @@ struct pid * fastcall find_pid(enum pid_type type, int nr)
146 220
147int fastcall attach_pid(task_t *task, enum pid_type type, int nr) 221int fastcall attach_pid(task_t *task, enum pid_type type, int nr)
148{ 222{
149 struct pid *pid, *task_pid; 223 struct pid_link *link;
150 224 struct pid *pid;
151 task_pid = &task->pids[type]; 225
152 pid = find_pid(type, nr); 226 WARN_ON(!task->pid); /* to be removed soon */
153 task_pid->nr = nr; 227 WARN_ON(!nr); /* to be removed soon */
154 if (pid == NULL) { 228
155 INIT_LIST_HEAD(&task_pid->pid_list); 229 link = &task->pids[type];
156 hlist_add_head_rcu(&task_pid->pid_chain, 230 link->pid = pid = find_pid(nr);
157 &pid_hash[type][pid_hashfn(nr)]); 231 hlist_add_head_rcu(&link->node, &pid->tasks[type]);
158 } else {
159 INIT_HLIST_NODE(&task_pid->pid_chain);
160 list_add_tail_rcu(&task_pid->pid_list, &pid->pid_list);
161 }
162 232
163 return 0; 233 return 0;
164} 234}
165 235
166static fastcall int __detach_pid(task_t *task, enum pid_type type) 236void fastcall detach_pid(task_t *task, enum pid_type type)
167{ 237{
168 struct pid *pid, *pid_next; 238 struct pid_link *link;
169 int nr = 0; 239 struct pid *pid;
240 int tmp;
170 241
171 pid = &task->pids[type]; 242 link = &task->pids[type];
172 if (!hlist_unhashed(&pid->pid_chain)) { 243 pid = link->pid;
173 244
174 if (list_empty(&pid->pid_list)) { 245 hlist_del_rcu(&link->node);
175 nr = pid->nr; 246 link->pid = NULL;
176 hlist_del_rcu(&pid->pid_chain);
177 } else {
178 pid_next = list_entry(pid->pid_list.next,
179 struct pid, pid_list);
180 /* insert next pid from pid_list to hash */
181 hlist_replace_rcu(&pid->pid_chain,
182 &pid_next->pid_chain);
183 }
184 }
185 247
186 list_del_rcu(&pid->pid_list); 248 for (tmp = PIDTYPE_MAX; --tmp >= 0; )
187 pid->nr = 0; 249 if (!hlist_empty(&pid->tasks[tmp]))
250 return;
188 251
189 return nr; 252 free_pid(pid);
190} 253}
191 254
192void fastcall detach_pid(task_t *task, enum pid_type type) 255struct task_struct * fastcall pid_task(struct pid *pid, enum pid_type type)
193{ 256{
194 int tmp, nr; 257 struct task_struct *result = NULL;
258 if (pid) {
259 struct hlist_node *first;
260 first = rcu_dereference(pid->tasks[type].first);
261 if (first)
262 result = hlist_entry(first, struct task_struct, pids[(type)].node);
263 }
264 return result;
265}
195 266
196 nr = __detach_pid(task, type); 267/*
197 if (!nr) 268 * Must be called under rcu_read_lock() or with tasklist_lock read-held.
198 return; 269 */
270task_t *find_task_by_pid_type(int type, int nr)
271{
272 return pid_task(find_pid(nr), type);
273}
199 274
200 for (tmp = PIDTYPE_MAX; --tmp >= 0; ) 275EXPORT_SYMBOL(find_task_by_pid_type);
201 if (tmp != type && find_pid(tmp, nr))
202 return;
203 276
204 free_pidmap(nr); 277struct task_struct *fastcall get_pid_task(struct pid *pid, enum pid_type type)
278{
279 struct task_struct *result;
280 rcu_read_lock();
281 result = pid_task(pid, type);
282 if (result)
283 get_task_struct(result);
284 rcu_read_unlock();
285 return result;
205} 286}
206 287
207task_t *find_task_by_pid_type(int type, int nr) 288struct pid *find_get_pid(pid_t nr)
208{ 289{
209 struct pid *pid; 290 struct pid *pid;
210 291
211 pid = find_pid(type, nr); 292 rcu_read_lock();
212 if (!pid) 293 pid = get_pid(find_pid(nr));
213 return NULL; 294 rcu_read_unlock();
214 295
215 return pid_task(&pid->pid_list, type); 296 return pid;
216} 297}
217 298
218EXPORT_SYMBOL(find_task_by_pid_type);
219
220/* 299/*
221 * The pid hash table is scaled according to the amount of memory in the 300 * The pid hash table is scaled according to the amount of memory in the
222 * machine. From a minimum of 16 slots up to 4096 slots at one gigabyte or 301 * machine. From a minimum of 16 slots up to 4096 slots at one gigabyte or
@@ -224,7 +303,7 @@ EXPORT_SYMBOL(find_task_by_pid_type);
224 */ 303 */
225void __init pidhash_init(void) 304void __init pidhash_init(void)
226{ 305{
227 int i, j, pidhash_size; 306 int i, pidhash_size;
228 unsigned long megabytes = nr_kernel_pages >> (20 - PAGE_SHIFT); 307 unsigned long megabytes = nr_kernel_pages >> (20 - PAGE_SHIFT);
229 308
230 pidhash_shift = max(4, fls(megabytes * 4)); 309 pidhash_shift = max(4, fls(megabytes * 4));
@@ -233,16 +312,13 @@ void __init pidhash_init(void)
233 312
234 printk("PID hash table entries: %d (order: %d, %Zd bytes)\n", 313 printk("PID hash table entries: %d (order: %d, %Zd bytes)\n",
235 pidhash_size, pidhash_shift, 314 pidhash_size, pidhash_shift,
236 PIDTYPE_MAX * pidhash_size * sizeof(struct hlist_head)); 315 pidhash_size * sizeof(struct hlist_head));
237 316
238 for (i = 0; i < PIDTYPE_MAX; i++) { 317 pid_hash = alloc_bootmem(pidhash_size * sizeof(*(pid_hash)));
239 pid_hash[i] = alloc_bootmem(pidhash_size * 318 if (!pid_hash)
240 sizeof(*(pid_hash[i]))); 319 panic("Could not alloc pidhash!\n");
241 if (!pid_hash[i]) 320 for (i = 0; i < pidhash_size; i++)
242 panic("Could not alloc pidhash!\n"); 321 INIT_HLIST_HEAD(&pid_hash[i]);
243 for (j = 0; j < pidhash_size; j++)
244 INIT_HLIST_HEAD(&pid_hash[i][j]);
245 }
246} 322}
247 323
248void __init pidmap_init(void) 324void __init pidmap_init(void)
@@ -251,4 +327,8 @@ void __init pidmap_init(void)
251 /* Reserve PID 0. We never call free_pidmap(0) */ 327 /* Reserve PID 0. We never call free_pidmap(0) */
252 set_bit(0, pidmap_array->page); 328 set_bit(0, pidmap_array->page);
253 atomic_dec(&pidmap_array->nr_free); 329 atomic_dec(&pidmap_array->nr_free);
330
331 pid_cachep = kmem_cache_create("pid", sizeof(struct pid),
332 __alignof__(struct pid),
333 SLAB_PANIC, NULL, NULL);
254} 334}
diff --git a/kernel/power/process.c b/kernel/power/process.c
index 8ac7c35fad77..b2a5f671d6cd 100644
--- a/kernel/power/process.c
+++ b/kernel/power/process.c
@@ -26,8 +26,7 @@ static inline int freezeable(struct task_struct * p)
26 (p->flags & PF_NOFREEZE) || 26 (p->flags & PF_NOFREEZE) ||
27 (p->exit_state == EXIT_ZOMBIE) || 27 (p->exit_state == EXIT_ZOMBIE) ||
28 (p->exit_state == EXIT_DEAD) || 28 (p->exit_state == EXIT_DEAD) ||
29 (p->state == TASK_STOPPED) || 29 (p->state == TASK_STOPPED))
30 (p->state == TASK_TRACED))
31 return 0; 30 return 0;
32 return 1; 31 return 1;
33} 32}
diff --git a/kernel/sched.c b/kernel/sched.c
index a9ecac398bb9..dd153d6f8a04 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -667,9 +667,13 @@ static int effective_prio(task_t *p)
667/* 667/*
668 * __activate_task - move a task to the runqueue. 668 * __activate_task - move a task to the runqueue.
669 */ 669 */
670static inline void __activate_task(task_t *p, runqueue_t *rq) 670static void __activate_task(task_t *p, runqueue_t *rq)
671{ 671{
672 enqueue_task(p, rq->active); 672 prio_array_t *target = rq->active;
673
674 if (batch_task(p))
675 target = rq->expired;
676 enqueue_task(p, target);
673 rq->nr_running++; 677 rq->nr_running++;
674} 678}
675 679
@@ -688,7 +692,7 @@ static int recalc_task_prio(task_t *p, unsigned long long now)
688 unsigned long long __sleep_time = now - p->timestamp; 692 unsigned long long __sleep_time = now - p->timestamp;
689 unsigned long sleep_time; 693 unsigned long sleep_time;
690 694
691 if (unlikely(p->policy == SCHED_BATCH)) 695 if (batch_task(p))
692 sleep_time = 0; 696 sleep_time = 0;
693 else { 697 else {
694 if (__sleep_time > NS_MAX_SLEEP_AVG) 698 if (__sleep_time > NS_MAX_SLEEP_AVG)
@@ -700,21 +704,25 @@ static int recalc_task_prio(task_t *p, unsigned long long now)
700 if (likely(sleep_time > 0)) { 704 if (likely(sleep_time > 0)) {
701 /* 705 /*
702 * User tasks that sleep a long time are categorised as 706 * User tasks that sleep a long time are categorised as
703 * idle and will get just interactive status to stay active & 707 * idle. They will only have their sleep_avg increased to a
704 * prevent them suddenly becoming cpu hogs and starving 708 * level that makes them just interactive priority to stay
705 * other processes. 709 * active yet prevent them suddenly becoming cpu hogs and
710 * starving other processes.
706 */ 711 */
707 if (p->mm && p->activated != -1 && 712 if (p->mm && sleep_time > INTERACTIVE_SLEEP(p)) {
708 sleep_time > INTERACTIVE_SLEEP(p)) { 713 unsigned long ceiling;
709 p->sleep_avg = JIFFIES_TO_NS(MAX_SLEEP_AVG - 714
710 DEF_TIMESLICE); 715 ceiling = JIFFIES_TO_NS(MAX_SLEEP_AVG -
716 DEF_TIMESLICE);
717 if (p->sleep_avg < ceiling)
718 p->sleep_avg = ceiling;
711 } else { 719 } else {
712 /* 720 /*
713 * Tasks waking from uninterruptible sleep are 721 * Tasks waking from uninterruptible sleep are
714 * limited in their sleep_avg rise as they 722 * limited in their sleep_avg rise as they
715 * are likely to be waiting on I/O 723 * are likely to be waiting on I/O
716 */ 724 */
717 if (p->activated == -1 && p->mm) { 725 if (p->sleep_type == SLEEP_NONINTERACTIVE && p->mm) {
718 if (p->sleep_avg >= INTERACTIVE_SLEEP(p)) 726 if (p->sleep_avg >= INTERACTIVE_SLEEP(p))
719 sleep_time = 0; 727 sleep_time = 0;
720 else if (p->sleep_avg + sleep_time >= 728 else if (p->sleep_avg + sleep_time >=
@@ -769,7 +777,7 @@ static void activate_task(task_t *p, runqueue_t *rq, int local)
769 * This checks to make sure it's not an uninterruptible task 777 * This checks to make sure it's not an uninterruptible task
770 * that is now waking up. 778 * that is now waking up.
771 */ 779 */
772 if (!p->activated) { 780 if (p->sleep_type == SLEEP_NORMAL) {
773 /* 781 /*
774 * Tasks which were woken up by interrupts (ie. hw events) 782 * Tasks which were woken up by interrupts (ie. hw events)
775 * are most likely of interactive nature. So we give them 783 * are most likely of interactive nature. So we give them
@@ -778,13 +786,13 @@ static void activate_task(task_t *p, runqueue_t *rq, int local)
778 * on a CPU, first time around: 786 * on a CPU, first time around:
779 */ 787 */
780 if (in_interrupt()) 788 if (in_interrupt())
781 p->activated = 2; 789 p->sleep_type = SLEEP_INTERRUPTED;
782 else { 790 else {
783 /* 791 /*
784 * Normal first-time wakeups get a credit too for 792 * Normal first-time wakeups get a credit too for
785 * on-runqueue time, but it will be weighted down: 793 * on-runqueue time, but it will be weighted down:
786 */ 794 */
787 p->activated = 1; 795 p->sleep_type = SLEEP_INTERACTIVE;
788 } 796 }
789 } 797 }
790 p->timestamp = now; 798 p->timestamp = now;
@@ -1272,19 +1280,19 @@ out_activate:
1272 * Tasks on involuntary sleep don't earn 1280 * Tasks on involuntary sleep don't earn
1273 * sleep_avg beyond just interactive state. 1281 * sleep_avg beyond just interactive state.
1274 */ 1282 */
1275 p->activated = -1; 1283 p->sleep_type = SLEEP_NONINTERACTIVE;
1276 } 1284 } else
1277 1285
1278 /* 1286 /*
1279 * Tasks that have marked their sleep as noninteractive get 1287 * Tasks that have marked their sleep as noninteractive get
1280 * woken up without updating their sleep average. (i.e. their 1288 * woken up with their sleep average not weighted in an
1281 * sleep is handled in a priority-neutral manner, no priority 1289 * interactive way.
1282 * boost and no penalty.)
1283 */ 1290 */
1284 if (old_state & TASK_NONINTERACTIVE) 1291 if (old_state & TASK_NONINTERACTIVE)
1285 __activate_task(p, rq); 1292 p->sleep_type = SLEEP_NONINTERACTIVE;
1286 else 1293
1287 activate_task(p, rq, cpu == this_cpu); 1294
1295 activate_task(p, rq, cpu == this_cpu);
1288 /* 1296 /*
1289 * Sync wakeups (i.e. those types of wakeups where the waker 1297 * Sync wakeups (i.e. those types of wakeups where the waker
1290 * has indicated that it will leave the CPU in short order) 1298 * has indicated that it will leave the CPU in short order)
@@ -1658,6 +1666,21 @@ unsigned long nr_iowait(void)
1658 return sum; 1666 return sum;
1659} 1667}
1660 1668
1669unsigned long nr_active(void)
1670{
1671 unsigned long i, running = 0, uninterruptible = 0;
1672
1673 for_each_online_cpu(i) {
1674 running += cpu_rq(i)->nr_running;
1675 uninterruptible += cpu_rq(i)->nr_uninterruptible;
1676 }
1677
1678 if (unlikely((long)uninterruptible < 0))
1679 uninterruptible = 0;
1680
1681 return running + uninterruptible;
1682}
1683
1661#ifdef CONFIG_SMP 1684#ifdef CONFIG_SMP
1662 1685
1663/* 1686/*
@@ -2860,6 +2883,12 @@ EXPORT_SYMBOL(sub_preempt_count);
2860 2883
2861#endif 2884#endif
2862 2885
2886static inline int interactive_sleep(enum sleep_type sleep_type)
2887{
2888 return (sleep_type == SLEEP_INTERACTIVE ||
2889 sleep_type == SLEEP_INTERRUPTED);
2890}
2891
2863/* 2892/*
2864 * schedule() is the main scheduler function. 2893 * schedule() is the main scheduler function.
2865 */ 2894 */
@@ -2983,12 +3012,12 @@ go_idle:
2983 queue = array->queue + idx; 3012 queue = array->queue + idx;
2984 next = list_entry(queue->next, task_t, run_list); 3013 next = list_entry(queue->next, task_t, run_list);
2985 3014
2986 if (!rt_task(next) && next->activated > 0) { 3015 if (!rt_task(next) && interactive_sleep(next->sleep_type)) {
2987 unsigned long long delta = now - next->timestamp; 3016 unsigned long long delta = now - next->timestamp;
2988 if (unlikely((long long)(now - next->timestamp) < 0)) 3017 if (unlikely((long long)(now - next->timestamp) < 0))
2989 delta = 0; 3018 delta = 0;
2990 3019
2991 if (next->activated == 1) 3020 if (next->sleep_type == SLEEP_INTERACTIVE)
2992 delta = delta * (ON_RUNQUEUE_WEIGHT * 128 / 100) / 128; 3021 delta = delta * (ON_RUNQUEUE_WEIGHT * 128 / 100) / 128;
2993 3022
2994 array = next->array; 3023 array = next->array;
@@ -2998,10 +3027,9 @@ go_idle:
2998 dequeue_task(next, array); 3027 dequeue_task(next, array);
2999 next->prio = new_prio; 3028 next->prio = new_prio;
3000 enqueue_task(next, array); 3029 enqueue_task(next, array);
3001 } else 3030 }
3002 requeue_task(next, array);
3003 } 3031 }
3004 next->activated = 0; 3032 next->sleep_type = SLEEP_NORMAL;
3005switch_tasks: 3033switch_tasks:
3006 if (next == rq->idle) 3034 if (next == rq->idle)
3007 schedstat_inc(rq, sched_goidle); 3035 schedstat_inc(rq, sched_goidle);
diff --git a/kernel/signal.c b/kernel/signal.c
index 4922928d91f6..92025b108791 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -1560,6 +1560,7 @@ static void ptrace_stop(int exit_code, int nostop_code, siginfo_t *info)
1560 /* Let the debugger run. */ 1560 /* Let the debugger run. */
1561 set_current_state(TASK_TRACED); 1561 set_current_state(TASK_TRACED);
1562 spin_unlock_irq(&current->sighand->siglock); 1562 spin_unlock_irq(&current->sighand->siglock);
1563 try_to_freeze();
1563 read_lock(&tasklist_lock); 1564 read_lock(&tasklist_lock);
1564 if (likely(current->ptrace & PT_PTRACED) && 1565 if (likely(current->ptrace & PT_PTRACED) &&
1565 likely(current->parent != current->real_parent || 1566 likely(current->parent != current->real_parent ||
diff --git a/kernel/sys.c b/kernel/sys.c
index 7ef7f6054c28..0b6ec0e7936f 100644
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -1372,18 +1372,29 @@ asmlinkage long sys_getsid(pid_t pid)
1372asmlinkage long sys_setsid(void) 1372asmlinkage long sys_setsid(void)
1373{ 1373{
1374 struct task_struct *group_leader = current->group_leader; 1374 struct task_struct *group_leader = current->group_leader;
1375 struct pid *pid; 1375 pid_t session;
1376 int err = -EPERM; 1376 int err = -EPERM;
1377 1377
1378 mutex_lock(&tty_mutex); 1378 mutex_lock(&tty_mutex);
1379 write_lock_irq(&tasklist_lock); 1379 write_lock_irq(&tasklist_lock);
1380 1380
1381 pid = find_pid(PIDTYPE_PGID, group_leader->pid); 1381 /* Fail if I am already a session leader */
1382 if (pid) 1382 if (group_leader->signal->leader)
1383 goto out;
1384
1385 session = group_leader->pid;
1386 /* Fail if a process group id already exists that equals the
1387 * proposed session id.
1388 *
1389 * Don't check if session id == 1 because kernel threads use this
1390 * session id and so the check will always fail and make it so
1391 * init cannot successfully call setsid.
1392 */
1393 if (session > 1 && find_task_by_pid_type(PIDTYPE_PGID, session))
1383 goto out; 1394 goto out;
1384 1395
1385 group_leader->signal->leader = 1; 1396 group_leader->signal->leader = 1;
1386 __set_special_pids(group_leader->pid, group_leader->pid); 1397 __set_special_pids(session, session);
1387 group_leader->signal->tty = NULL; 1398 group_leader->signal->tty = NULL;
1388 group_leader->signal->tty_old_pgrp = 0; 1399 group_leader->signal->tty_old_pgrp = 0;
1389 err = process_group(group_leader); 1400 err = process_group(group_leader);
diff --git a/kernel/timer.c b/kernel/timer.c
index ab189dd187cb..6b812c04737b 100644
--- a/kernel/timer.c
+++ b/kernel/timer.c
@@ -54,7 +54,6 @@ EXPORT_SYMBOL(jiffies_64);
54/* 54/*
55 * per-CPU timer vector definitions: 55 * per-CPU timer vector definitions:
56 */ 56 */
57
58#define TVN_BITS (CONFIG_BASE_SMALL ? 4 : 6) 57#define TVN_BITS (CONFIG_BASE_SMALL ? 4 : 6)
59#define TVR_BITS (CONFIG_BASE_SMALL ? 6 : 8) 58#define TVR_BITS (CONFIG_BASE_SMALL ? 6 : 8)
60#define TVN_SIZE (1 << TVN_BITS) 59#define TVN_SIZE (1 << TVN_BITS)
@@ -62,11 +61,6 @@ EXPORT_SYMBOL(jiffies_64);
62#define TVN_MASK (TVN_SIZE - 1) 61#define TVN_MASK (TVN_SIZE - 1)
63#define TVR_MASK (TVR_SIZE - 1) 62#define TVR_MASK (TVR_SIZE - 1)
64 63
65struct timer_base_s {
66 spinlock_t lock;
67 struct timer_list *running_timer;
68};
69
70typedef struct tvec_s { 64typedef struct tvec_s {
71 struct list_head vec[TVN_SIZE]; 65 struct list_head vec[TVN_SIZE];
72} tvec_t; 66} tvec_t;
@@ -76,7 +70,8 @@ typedef struct tvec_root_s {
76} tvec_root_t; 70} tvec_root_t;
77 71
78struct tvec_t_base_s { 72struct tvec_t_base_s {
79 struct timer_base_s t_base; 73 spinlock_t lock;
74 struct timer_list *running_timer;
80 unsigned long timer_jiffies; 75 unsigned long timer_jiffies;
81 tvec_root_t tv1; 76 tvec_root_t tv1;
82 tvec_t tv2; 77 tvec_t tv2;
@@ -87,13 +82,14 @@ struct tvec_t_base_s {
87 82
88typedef struct tvec_t_base_s tvec_base_t; 83typedef struct tvec_t_base_s tvec_base_t;
89static DEFINE_PER_CPU(tvec_base_t *, tvec_bases); 84static DEFINE_PER_CPU(tvec_base_t *, tvec_bases);
90static tvec_base_t boot_tvec_bases; 85tvec_base_t boot_tvec_bases;
86EXPORT_SYMBOL(boot_tvec_bases);
91 87
92static inline void set_running_timer(tvec_base_t *base, 88static inline void set_running_timer(tvec_base_t *base,
93 struct timer_list *timer) 89 struct timer_list *timer)
94{ 90{
95#ifdef CONFIG_SMP 91#ifdef CONFIG_SMP
96 base->t_base.running_timer = timer; 92 base->running_timer = timer;
97#endif 93#endif
98} 94}
99 95
@@ -139,15 +135,6 @@ static void internal_add_timer(tvec_base_t *base, struct timer_list *timer)
139 list_add_tail(&timer->entry, vec); 135 list_add_tail(&timer->entry, vec);
140} 136}
141 137
142typedef struct timer_base_s timer_base_t;
143/*
144 * Used by TIMER_INITIALIZER, we can't use per_cpu(tvec_bases)
145 * at compile time, and we need timer->base to lock the timer.
146 */
147timer_base_t __init_timer_base
148 ____cacheline_aligned_in_smp = { .lock = SPIN_LOCK_UNLOCKED };
149EXPORT_SYMBOL(__init_timer_base);
150
151/*** 138/***
152 * init_timer - initialize a timer. 139 * init_timer - initialize a timer.
153 * @timer: the timer to be initialized 140 * @timer: the timer to be initialized
@@ -158,7 +145,7 @@ EXPORT_SYMBOL(__init_timer_base);
158void fastcall init_timer(struct timer_list *timer) 145void fastcall init_timer(struct timer_list *timer)
159{ 146{
160 timer->entry.next = NULL; 147 timer->entry.next = NULL;
161 timer->base = &per_cpu(tvec_bases, raw_smp_processor_id())->t_base; 148 timer->base = per_cpu(tvec_bases, raw_smp_processor_id());
162} 149}
163EXPORT_SYMBOL(init_timer); 150EXPORT_SYMBOL(init_timer);
164 151
@@ -174,7 +161,7 @@ static inline void detach_timer(struct timer_list *timer,
174} 161}
175 162
176/* 163/*
177 * We are using hashed locking: holding per_cpu(tvec_bases).t_base.lock 164 * We are using hashed locking: holding per_cpu(tvec_bases).lock
178 * means that all timers which are tied to this base via timer->base are 165 * means that all timers which are tied to this base via timer->base are
179 * locked, and the base itself is locked too. 166 * locked, and the base itself is locked too.
180 * 167 *
@@ -185,10 +172,10 @@ static inline void detach_timer(struct timer_list *timer,
185 * possible to set timer->base = NULL and drop the lock: the timer remains 172 * possible to set timer->base = NULL and drop the lock: the timer remains
186 * locked. 173 * locked.
187 */ 174 */
188static timer_base_t *lock_timer_base(struct timer_list *timer, 175static tvec_base_t *lock_timer_base(struct timer_list *timer,
189 unsigned long *flags) 176 unsigned long *flags)
190{ 177{
191 timer_base_t *base; 178 tvec_base_t *base;
192 179
193 for (;;) { 180 for (;;) {
194 base = timer->base; 181 base = timer->base;
@@ -205,8 +192,7 @@ static timer_base_t *lock_timer_base(struct timer_list *timer,
205 192
206int __mod_timer(struct timer_list *timer, unsigned long expires) 193int __mod_timer(struct timer_list *timer, unsigned long expires)
207{ 194{
208 timer_base_t *base; 195 tvec_base_t *base, *new_base;
209 tvec_base_t *new_base;
210 unsigned long flags; 196 unsigned long flags;
211 int ret = 0; 197 int ret = 0;
212 198
@@ -221,7 +207,7 @@ int __mod_timer(struct timer_list *timer, unsigned long expires)
221 207
222 new_base = __get_cpu_var(tvec_bases); 208 new_base = __get_cpu_var(tvec_bases);
223 209
224 if (base != &new_base->t_base) { 210 if (base != new_base) {
225 /* 211 /*
226 * We are trying to schedule the timer on the local CPU. 212 * We are trying to schedule the timer on the local CPU.
227 * However we can't change timer's base while it is running, 213 * However we can't change timer's base while it is running,
@@ -229,21 +215,19 @@ int __mod_timer(struct timer_list *timer, unsigned long expires)
229 * handler yet has not finished. This also guarantees that 215 * handler yet has not finished. This also guarantees that
230 * the timer is serialized wrt itself. 216 * the timer is serialized wrt itself.
231 */ 217 */
232 if (unlikely(base->running_timer == timer)) { 218 if (likely(base->running_timer != timer)) {
233 /* The timer remains on a former base */
234 new_base = container_of(base, tvec_base_t, t_base);
235 } else {
236 /* See the comment in lock_timer_base() */ 219 /* See the comment in lock_timer_base() */
237 timer->base = NULL; 220 timer->base = NULL;
238 spin_unlock(&base->lock); 221 spin_unlock(&base->lock);
239 spin_lock(&new_base->t_base.lock); 222 base = new_base;
240 timer->base = &new_base->t_base; 223 spin_lock(&base->lock);
224 timer->base = base;
241 } 225 }
242 } 226 }
243 227
244 timer->expires = expires; 228 timer->expires = expires;
245 internal_add_timer(new_base, timer); 229 internal_add_timer(base, timer);
246 spin_unlock_irqrestore(&new_base->t_base.lock, flags); 230 spin_unlock_irqrestore(&base->lock, flags);
247 231
248 return ret; 232 return ret;
249} 233}
@@ -263,10 +247,10 @@ void add_timer_on(struct timer_list *timer, int cpu)
263 unsigned long flags; 247 unsigned long flags;
264 248
265 BUG_ON(timer_pending(timer) || !timer->function); 249 BUG_ON(timer_pending(timer) || !timer->function);
266 spin_lock_irqsave(&base->t_base.lock, flags); 250 spin_lock_irqsave(&base->lock, flags);
267 timer->base = &base->t_base; 251 timer->base = base;
268 internal_add_timer(base, timer); 252 internal_add_timer(base, timer);
269 spin_unlock_irqrestore(&base->t_base.lock, flags); 253 spin_unlock_irqrestore(&base->lock, flags);
270} 254}
271 255
272 256
@@ -319,7 +303,7 @@ EXPORT_SYMBOL(mod_timer);
319 */ 303 */
320int del_timer(struct timer_list *timer) 304int del_timer(struct timer_list *timer)
321{ 305{
322 timer_base_t *base; 306 tvec_base_t *base;
323 unsigned long flags; 307 unsigned long flags;
324 int ret = 0; 308 int ret = 0;
325 309
@@ -346,7 +330,7 @@ EXPORT_SYMBOL(del_timer);
346 */ 330 */
347int try_to_del_timer_sync(struct timer_list *timer) 331int try_to_del_timer_sync(struct timer_list *timer)
348{ 332{
349 timer_base_t *base; 333 tvec_base_t *base;
350 unsigned long flags; 334 unsigned long flags;
351 int ret = -1; 335 int ret = -1;
352 336
@@ -410,7 +394,7 @@ static int cascade(tvec_base_t *base, tvec_t *tv, int index)
410 struct timer_list *tmp; 394 struct timer_list *tmp;
411 395
412 tmp = list_entry(curr, struct timer_list, entry); 396 tmp = list_entry(curr, struct timer_list, entry);
413 BUG_ON(tmp->base != &base->t_base); 397 BUG_ON(tmp->base != base);
414 curr = curr->next; 398 curr = curr->next;
415 internal_add_timer(base, tmp); 399 internal_add_timer(base, tmp);
416 } 400 }
@@ -432,7 +416,7 @@ static inline void __run_timers(tvec_base_t *base)
432{ 416{
433 struct timer_list *timer; 417 struct timer_list *timer;
434 418
435 spin_lock_irq(&base->t_base.lock); 419 spin_lock_irq(&base->lock);
436 while (time_after_eq(jiffies, base->timer_jiffies)) { 420 while (time_after_eq(jiffies, base->timer_jiffies)) {
437 struct list_head work_list = LIST_HEAD_INIT(work_list); 421 struct list_head work_list = LIST_HEAD_INIT(work_list);
438 struct list_head *head = &work_list; 422 struct list_head *head = &work_list;
@@ -458,7 +442,7 @@ static inline void __run_timers(tvec_base_t *base)
458 442
459 set_running_timer(base, timer); 443 set_running_timer(base, timer);
460 detach_timer(timer, 1); 444 detach_timer(timer, 1);
461 spin_unlock_irq(&base->t_base.lock); 445 spin_unlock_irq(&base->lock);
462 { 446 {
463 int preempt_count = preempt_count(); 447 int preempt_count = preempt_count();
464 fn(data); 448 fn(data);
@@ -471,11 +455,11 @@ static inline void __run_timers(tvec_base_t *base)
471 BUG(); 455 BUG();
472 } 456 }
473 } 457 }
474 spin_lock_irq(&base->t_base.lock); 458 spin_lock_irq(&base->lock);
475 } 459 }
476 } 460 }
477 set_running_timer(base, NULL); 461 set_running_timer(base, NULL);
478 spin_unlock_irq(&base->t_base.lock); 462 spin_unlock_irq(&base->lock);
479} 463}
480 464
481#ifdef CONFIG_NO_IDLE_HZ 465#ifdef CONFIG_NO_IDLE_HZ
@@ -506,7 +490,7 @@ unsigned long next_timer_interrupt(void)
506 hr_expires += jiffies; 490 hr_expires += jiffies;
507 491
508 base = __get_cpu_var(tvec_bases); 492 base = __get_cpu_var(tvec_bases);
509 spin_lock(&base->t_base.lock); 493 spin_lock(&base->lock);
510 expires = base->timer_jiffies + (LONG_MAX >> 1); 494 expires = base->timer_jiffies + (LONG_MAX >> 1);
511 list = NULL; 495 list = NULL;
512 496
@@ -554,7 +538,7 @@ found:
554 expires = nte->expires; 538 expires = nte->expires;
555 } 539 }
556 } 540 }
557 spin_unlock(&base->t_base.lock); 541 spin_unlock(&base->lock);
558 542
559 if (time_before(hr_expires, expires)) 543 if (time_before(hr_expires, expires))
560 return hr_expires; 544 return hr_expires;
@@ -841,7 +825,7 @@ void update_process_times(int user_tick)
841 */ 825 */
842static unsigned long count_active_tasks(void) 826static unsigned long count_active_tasks(void)
843{ 827{
844 return (nr_running() + nr_uninterruptible()) * FIXED_1; 828 return nr_active() * FIXED_1;
845} 829}
846 830
847/* 831/*
@@ -1262,7 +1246,7 @@ static int __devinit init_timers_cpu(int cpu)
1262 } 1246 }
1263 per_cpu(tvec_bases, cpu) = base; 1247 per_cpu(tvec_bases, cpu) = base;
1264 } 1248 }
1265 spin_lock_init(&base->t_base.lock); 1249 spin_lock_init(&base->lock);
1266 for (j = 0; j < TVN_SIZE; j++) { 1250 for (j = 0; j < TVN_SIZE; j++) {
1267 INIT_LIST_HEAD(base->tv5.vec + j); 1251 INIT_LIST_HEAD(base->tv5.vec + j);
1268 INIT_LIST_HEAD(base->tv4.vec + j); 1252 INIT_LIST_HEAD(base->tv4.vec + j);
@@ -1284,7 +1268,7 @@ static void migrate_timer_list(tvec_base_t *new_base, struct list_head *head)
1284 while (!list_empty(head)) { 1268 while (!list_empty(head)) {
1285 timer = list_entry(head->next, struct timer_list, entry); 1269 timer = list_entry(head->next, struct timer_list, entry);
1286 detach_timer(timer, 0); 1270 detach_timer(timer, 0);
1287 timer->base = &new_base->t_base; 1271 timer->base = new_base;
1288 internal_add_timer(new_base, timer); 1272 internal_add_timer(new_base, timer);
1289 } 1273 }
1290} 1274}
@@ -1300,11 +1284,11 @@ static void __devinit migrate_timers(int cpu)
1300 new_base = get_cpu_var(tvec_bases); 1284 new_base = get_cpu_var(tvec_bases);
1301 1285
1302 local_irq_disable(); 1286 local_irq_disable();
1303 spin_lock(&new_base->t_base.lock); 1287 spin_lock(&new_base->lock);
1304 spin_lock(&old_base->t_base.lock); 1288 spin_lock(&old_base->lock);
1289
1290 BUG_ON(old_base->running_timer);
1305 1291
1306 if (old_base->t_base.running_timer)
1307 BUG();
1308 for (i = 0; i < TVR_SIZE; i++) 1292 for (i = 0; i < TVR_SIZE; i++)
1309 migrate_timer_list(new_base, old_base->tv1.vec + i); 1293 migrate_timer_list(new_base, old_base->tv1.vec + i);
1310 for (i = 0; i < TVN_SIZE; i++) { 1294 for (i = 0; i < TVN_SIZE; i++) {
@@ -1314,8 +1298,8 @@ static void __devinit migrate_timers(int cpu)
1314 migrate_timer_list(new_base, old_base->tv5.vec + i); 1298 migrate_timer_list(new_base, old_base->tv5.vec + i);
1315 } 1299 }
1316 1300
1317 spin_unlock(&old_base->t_base.lock); 1301 spin_unlock(&old_base->lock);
1318 spin_unlock(&new_base->t_base.lock); 1302 spin_unlock(&new_base->lock);
1319 local_irq_enable(); 1303 local_irq_enable();
1320 put_cpu_var(tvec_bases); 1304 put_cpu_var(tvec_bases);
1321} 1305}
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index 6e8a60f67c7a..d57fd9181b18 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -157,19 +157,6 @@ config DEBUG_INFO
157 157
158 If unsure, say N. 158 If unsure, say N.
159 159
160config DEBUG_IOREMAP
161 bool "Enable ioremap() debugging"
162 depends on DEBUG_KERNEL && PARISC
163 help
164 Enabling this option will cause the kernel to distinguish between
165 ioremapped and physical addresses. It will print a backtrace (at
166 most one every 10 seconds), hopefully allowing you to see which
167 drivers need work. Fixing all these problems is a prerequisite
168 for turning on USE_HPPA_IOREMAP. The warnings are harmless;
169 the kernel has enough information to fix the broken drivers
170 automatically, but we'd like to make it more efficient by not
171 having to do that.
172
173config DEBUG_FS 160config DEBUG_FS
174 bool "Debug Filesystem" 161 bool "Debug Filesystem"
175 depends on SYSFS 162 depends on SYSFS
diff --git a/mm/fadvise.c b/mm/fadvise.c
index 907c39257ca0..0a03357a1f8e 100644
--- a/mm/fadvise.c
+++ b/mm/fadvise.c
@@ -35,17 +35,6 @@
35 * 35 *
36 * LINUX_FADV_ASYNC_WRITE: push some or all of the dirty pages at the disk. 36 * LINUX_FADV_ASYNC_WRITE: push some or all of the dirty pages at the disk.
37 * 37 *
38 * LINUX_FADV_WRITE_WAIT, LINUX_FADV_ASYNC_WRITE: push all of the currently
39 * dirty pages at the disk.
40 *
41 * LINUX_FADV_WRITE_WAIT, LINUX_FADV_ASYNC_WRITE, LINUX_FADV_WRITE_WAIT: push
42 * all of the currently dirty pages at the disk, wait until they have been
43 * written.
44 *
45 * It should be noted that none of these operations write out the file's
46 * metadata. So unless the application is strictly performing overwrites of
47 * already-instantiated disk blocks, there are no guarantees here that the data
48 * will be available after a crash.
49 */ 38 */
50asmlinkage long sys_fadvise64_64(int fd, loff_t offset, loff_t len, int advice) 39asmlinkage long sys_fadvise64_64(int fd, loff_t offset, loff_t len, int advice)
51{ 40{
@@ -129,15 +118,6 @@ asmlinkage long sys_fadvise64_64(int fd, loff_t offset, loff_t len, int advice)
129 invalidate_mapping_pages(mapping, start_index, 118 invalidate_mapping_pages(mapping, start_index,
130 end_index); 119 end_index);
131 break; 120 break;
132 case LINUX_FADV_ASYNC_WRITE:
133 ret = __filemap_fdatawrite_range(mapping, offset, endbyte,
134 WB_SYNC_NONE);
135 break;
136 case LINUX_FADV_WRITE_WAIT:
137 ret = wait_on_page_writeback_range(mapping,
138 offset >> PAGE_CACHE_SHIFT,
139 endbyte >> PAGE_CACHE_SHIFT);
140 break;
141 default: 121 default:
142 ret = -EINVAL; 122 ret = -EINVAL;
143 } 123 }
diff --git a/mm/hugetlb.c b/mm/hugetlb.c
index ebad6bbb3501..832f676ca038 100644
--- a/mm/hugetlb.c
+++ b/mm/hugetlb.c
@@ -334,6 +334,7 @@ static unsigned long set_max_huge_pages(unsigned long count)
334 return nr_huge_pages; 334 return nr_huge_pages;
335 335
336 spin_lock(&hugetlb_lock); 336 spin_lock(&hugetlb_lock);
337 count = max(count, reserved_huge_pages);
337 try_to_free_low(count); 338 try_to_free_low(count);
338 while (count < nr_huge_pages) { 339 while (count < nr_huge_pages) {
339 struct page *page = dequeue_huge_page(NULL, 0); 340 struct page *page = dequeue_huge_page(NULL, 0);
@@ -697,9 +698,10 @@ int follow_hugetlb_page(struct mm_struct *mm, struct vm_area_struct *vma,
697 pfn_offset = (vaddr & ~HPAGE_MASK) >> PAGE_SHIFT; 698 pfn_offset = (vaddr & ~HPAGE_MASK) >> PAGE_SHIFT;
698 page = pte_page(*pte); 699 page = pte_page(*pte);
699same_page: 700same_page:
700 get_page(page); 701 if (pages) {
701 if (pages) 702 get_page(page);
702 pages[i] = page + pfn_offset; 703 pages[i] = page + pfn_offset;
704 }
703 705
704 if (vmas) 706 if (vmas)
705 vmas[i] = vma; 707 vmas[i] = vma;
diff --git a/mm/memory.c b/mm/memory.c
index 8d8f52569f32..0ec7bc644271 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -87,7 +87,7 @@ int randomize_va_space __read_mostly = 1;
87static int __init disable_randmaps(char *s) 87static int __init disable_randmaps(char *s)
88{ 88{
89 randomize_va_space = 0; 89 randomize_va_space = 0;
90 return 0; 90 return 1;
91} 91}
92__setup("norandmaps", disable_randmaps); 92__setup("norandmaps", disable_randmaps);
93 93
diff --git a/mm/swapfile.c b/mm/swapfile.c
index 39aa9d129612..e5fd5385f0cc 100644
--- a/mm/swapfile.c
+++ b/mm/swapfile.c
@@ -397,18 +397,24 @@ void free_swap_and_cache(swp_entry_t entry)
397 397
398 p = swap_info_get(entry); 398 p = swap_info_get(entry);
399 if (p) { 399 if (p) {
400 if (swap_entry_free(p, swp_offset(entry)) == 1) 400 if (swap_entry_free(p, swp_offset(entry)) == 1) {
401 page = find_trylock_page(&swapper_space, entry.val); 401 page = find_get_page(&swapper_space, entry.val);
402 if (page && unlikely(TestSetPageLocked(page))) {
403 page_cache_release(page);
404 page = NULL;
405 }
406 }
402 spin_unlock(&swap_lock); 407 spin_unlock(&swap_lock);
403 } 408 }
404 if (page) { 409 if (page) {
405 int one_user; 410 int one_user;
406 411
407 BUG_ON(PagePrivate(page)); 412 BUG_ON(PagePrivate(page));
408 page_cache_get(page);
409 one_user = (page_count(page) == 2); 413 one_user = (page_count(page) == 2);
410 /* Only cache user (+us), or swap space full? Free it! */ 414 /* Only cache user (+us), or swap space full? Free it! */
411 if (!PageWriteback(page) && (one_user || vm_swap_full())) { 415 /* Also recheck PageSwapCache after page is locked (above) */
416 if (PageSwapCache(page) && !PageWriteback(page) &&
417 (one_user || vm_swap_full())) {
412 delete_from_swap_cache(page); 418 delete_from_swap_cache(page);
413 SetPageDirty(page); 419 SetPageDirty(page);
414 } 420 }
diff --git a/net/appletalk/ddp.c b/net/appletalk/ddp.c
index 697ac55e29dc..7b1eb9a4fc96 100644
--- a/net/appletalk/ddp.c
+++ b/net/appletalk/ddp.c
@@ -1819,6 +1819,22 @@ static int atalk_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
1819 return rc; 1819 return rc;
1820} 1820}
1821 1821
1822
1823#ifdef CONFIG_COMPAT
1824static int atalk_compat_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
1825{
1826 /*
1827 * All Appletalk ioctls except SIOCATALKDIFADDR are standard. And
1828 * SIOCATALKDIFADDR is handled by upper layer as well, so there is
1829 * nothing to do. Eventually SIOCATALKDIFADDR should be moved
1830 * here so there is no generic SIOCPROTOPRIVATE translation in the
1831 * system.
1832 */
1833 return -ENOIOCTLCMD;
1834}
1835#endif
1836
1837
1822static struct net_proto_family atalk_family_ops = { 1838static struct net_proto_family atalk_family_ops = {
1823 .family = PF_APPLETALK, 1839 .family = PF_APPLETALK,
1824 .create = atalk_create, 1840 .create = atalk_create,
@@ -1836,6 +1852,9 @@ static const struct proto_ops SOCKOPS_WRAPPED(atalk_dgram_ops) = {
1836 .getname = atalk_getname, 1852 .getname = atalk_getname,
1837 .poll = datagram_poll, 1853 .poll = datagram_poll,
1838 .ioctl = atalk_ioctl, 1854 .ioctl = atalk_ioctl,
1855#ifdef CONFIG_COMPAT
1856 .compat_ioctl = atalk_compat_ioctl,
1857#endif
1839 .listen = sock_no_listen, 1858 .listen = sock_no_listen,
1840 .shutdown = sock_no_shutdown, 1859 .shutdown = sock_no_shutdown,
1841 .setsockopt = sock_no_setsockopt, 1860 .setsockopt = sock_no_setsockopt,
diff --git a/net/bridge/netfilter/ebt_802_3.c b/net/bridge/netfilter/ebt_802_3.c
index 468ebdf4bc1c..d42f63f5e9f8 100644
--- a/net/bridge/netfilter/ebt_802_3.c
+++ b/net/bridge/netfilter/ebt_802_3.c
@@ -58,16 +58,16 @@ static struct ebt_match filter_802_3 =
58 .me = THIS_MODULE, 58 .me = THIS_MODULE,
59}; 59};
60 60
61static int __init init(void) 61static int __init ebt_802_3_init(void)
62{ 62{
63 return ebt_register_match(&filter_802_3); 63 return ebt_register_match(&filter_802_3);
64} 64}
65 65
66static void __exit fini(void) 66static void __exit ebt_802_3_fini(void)
67{ 67{
68 ebt_unregister_match(&filter_802_3); 68 ebt_unregister_match(&filter_802_3);
69} 69}
70 70
71module_init(init); 71module_init(ebt_802_3_init);
72module_exit(fini); 72module_exit(ebt_802_3_fini);
73MODULE_LICENSE("GPL"); 73MODULE_LICENSE("GPL");
diff --git a/net/bridge/netfilter/ebt_among.c b/net/bridge/netfilter/ebt_among.c
index 5a1f5e3bff15..a614485828af 100644
--- a/net/bridge/netfilter/ebt_among.c
+++ b/net/bridge/netfilter/ebt_among.c
@@ -213,16 +213,16 @@ static struct ebt_match filter_among = {
213 .me = THIS_MODULE, 213 .me = THIS_MODULE,
214}; 214};
215 215
216static int __init init(void) 216static int __init ebt_among_init(void)
217{ 217{
218 return ebt_register_match(&filter_among); 218 return ebt_register_match(&filter_among);
219} 219}
220 220
221static void __exit fini(void) 221static void __exit ebt_among_fini(void)
222{ 222{
223 ebt_unregister_match(&filter_among); 223 ebt_unregister_match(&filter_among);
224} 224}
225 225
226module_init(init); 226module_init(ebt_among_init);
227module_exit(fini); 227module_exit(ebt_among_fini);
228MODULE_LICENSE("GPL"); 228MODULE_LICENSE("GPL");
diff --git a/net/bridge/netfilter/ebt_arp.c b/net/bridge/netfilter/ebt_arp.c
index b94c48cb6e4b..a6c81d9f73b8 100644
--- a/net/bridge/netfilter/ebt_arp.c
+++ b/net/bridge/netfilter/ebt_arp.c
@@ -125,16 +125,16 @@ static struct ebt_match filter_arp =
125 .me = THIS_MODULE, 125 .me = THIS_MODULE,
126}; 126};
127 127
128static int __init init(void) 128static int __init ebt_arp_init(void)
129{ 129{
130 return ebt_register_match(&filter_arp); 130 return ebt_register_match(&filter_arp);
131} 131}
132 132
133static void __exit fini(void) 133static void __exit ebt_arp_fini(void)
134{ 134{
135 ebt_unregister_match(&filter_arp); 135 ebt_unregister_match(&filter_arp);
136} 136}
137 137
138module_init(init); 138module_init(ebt_arp_init);
139module_exit(fini); 139module_exit(ebt_arp_fini);
140MODULE_LICENSE("GPL"); 140MODULE_LICENSE("GPL");
diff --git a/net/bridge/netfilter/ebt_arpreply.c b/net/bridge/netfilter/ebt_arpreply.c
index b934de90f7c5..d19fc4b328dc 100644
--- a/net/bridge/netfilter/ebt_arpreply.c
+++ b/net/bridge/netfilter/ebt_arpreply.c
@@ -82,16 +82,16 @@ static struct ebt_target reply_target =
82 .me = THIS_MODULE, 82 .me = THIS_MODULE,
83}; 83};
84 84
85static int __init init(void) 85static int __init ebt_arpreply_init(void)
86{ 86{
87 return ebt_register_target(&reply_target); 87 return ebt_register_target(&reply_target);
88} 88}
89 89
90static void __exit fini(void) 90static void __exit ebt_arpreply_fini(void)
91{ 91{
92 ebt_unregister_target(&reply_target); 92 ebt_unregister_target(&reply_target);
93} 93}
94 94
95module_init(init); 95module_init(ebt_arpreply_init);
96module_exit(fini); 96module_exit(ebt_arpreply_fini);
97MODULE_LICENSE("GPL"); 97MODULE_LICENSE("GPL");
diff --git a/net/bridge/netfilter/ebt_dnat.c b/net/bridge/netfilter/ebt_dnat.c
index f5463086c7bd..4582659dff0e 100644
--- a/net/bridge/netfilter/ebt_dnat.c
+++ b/net/bridge/netfilter/ebt_dnat.c
@@ -61,16 +61,16 @@ static struct ebt_target dnat =
61 .me = THIS_MODULE, 61 .me = THIS_MODULE,
62}; 62};
63 63
64static int __init init(void) 64static int __init ebt_dnat_init(void)
65{ 65{
66 return ebt_register_target(&dnat); 66 return ebt_register_target(&dnat);
67} 67}
68 68
69static void __exit fini(void) 69static void __exit ebt_dnat_fini(void)
70{ 70{
71 ebt_unregister_target(&dnat); 71 ebt_unregister_target(&dnat);
72} 72}
73 73
74module_init(init); 74module_init(ebt_dnat_init);
75module_exit(fini); 75module_exit(ebt_dnat_fini);
76MODULE_LICENSE("GPL"); 76MODULE_LICENSE("GPL");
diff --git a/net/bridge/netfilter/ebt_ip.c b/net/bridge/netfilter/ebt_ip.c
index dc5d0b2427cf..65b665ce57b5 100644
--- a/net/bridge/netfilter/ebt_ip.c
+++ b/net/bridge/netfilter/ebt_ip.c
@@ -112,16 +112,16 @@ static struct ebt_match filter_ip =
112 .me = THIS_MODULE, 112 .me = THIS_MODULE,
113}; 113};
114 114
115static int __init init(void) 115static int __init ebt_ip_init(void)
116{ 116{
117 return ebt_register_match(&filter_ip); 117 return ebt_register_match(&filter_ip);
118} 118}
119 119
120static void __exit fini(void) 120static void __exit ebt_ip_fini(void)
121{ 121{
122 ebt_unregister_match(&filter_ip); 122 ebt_unregister_match(&filter_ip);
123} 123}
124 124
125module_init(init); 125module_init(ebt_ip_init);
126module_exit(fini); 126module_exit(ebt_ip_fini);
127MODULE_LICENSE("GPL"); 127MODULE_LICENSE("GPL");
diff --git a/net/bridge/netfilter/ebt_limit.c b/net/bridge/netfilter/ebt_limit.c
index 637c8844cd5f..d48fa5cb26cf 100644
--- a/net/bridge/netfilter/ebt_limit.c
+++ b/net/bridge/netfilter/ebt_limit.c
@@ -98,16 +98,16 @@ static struct ebt_match ebt_limit_reg =
98 .me = THIS_MODULE, 98 .me = THIS_MODULE,
99}; 99};
100 100
101static int __init init(void) 101static int __init ebt_limit_init(void)
102{ 102{
103 return ebt_register_match(&ebt_limit_reg); 103 return ebt_register_match(&ebt_limit_reg);
104} 104}
105 105
106static void __exit fini(void) 106static void __exit ebt_limit_fini(void)
107{ 107{
108 ebt_unregister_match(&ebt_limit_reg); 108 ebt_unregister_match(&ebt_limit_reg);
109} 109}
110 110
111module_init(init); 111module_init(ebt_limit_init);
112module_exit(fini); 112module_exit(ebt_limit_fini);
113MODULE_LICENSE("GPL"); 113MODULE_LICENSE("GPL");
diff --git a/net/bridge/netfilter/ebt_log.c b/net/bridge/netfilter/ebt_log.c
index 288ff1d4ccc4..d159c92cca84 100644
--- a/net/bridge/netfilter/ebt_log.c
+++ b/net/bridge/netfilter/ebt_log.c
@@ -188,7 +188,7 @@ static struct nf_logger ebt_log_logger = {
188 .me = THIS_MODULE, 188 .me = THIS_MODULE,
189}; 189};
190 190
191static int __init init(void) 191static int __init ebt_log_init(void)
192{ 192{
193 int ret; 193 int ret;
194 194
@@ -205,12 +205,12 @@ static int __init init(void)
205 return 0; 205 return 0;
206} 206}
207 207
208static void __exit fini(void) 208static void __exit ebt_log_fini(void)
209{ 209{
210 nf_log_unregister_logger(&ebt_log_logger); 210 nf_log_unregister_logger(&ebt_log_logger);
211 ebt_unregister_watcher(&log); 211 ebt_unregister_watcher(&log);
212} 212}
213 213
214module_init(init); 214module_init(ebt_log_init);
215module_exit(fini); 215module_exit(ebt_log_fini);
216MODULE_LICENSE("GPL"); 216MODULE_LICENSE("GPL");
diff --git a/net/bridge/netfilter/ebt_mark.c b/net/bridge/netfilter/ebt_mark.c
index c93d35ab95c0..770c0df972a3 100644
--- a/net/bridge/netfilter/ebt_mark.c
+++ b/net/bridge/netfilter/ebt_mark.c
@@ -52,16 +52,16 @@ static struct ebt_target mark_target =
52 .me = THIS_MODULE, 52 .me = THIS_MODULE,
53}; 53};
54 54
55static int __init init(void) 55static int __init ebt_mark_init(void)
56{ 56{
57 return ebt_register_target(&mark_target); 57 return ebt_register_target(&mark_target);
58} 58}
59 59
60static void __exit fini(void) 60static void __exit ebt_mark_fini(void)
61{ 61{
62 ebt_unregister_target(&mark_target); 62 ebt_unregister_target(&mark_target);
63} 63}
64 64
65module_init(init); 65module_init(ebt_mark_init);
66module_exit(fini); 66module_exit(ebt_mark_fini);
67MODULE_LICENSE("GPL"); 67MODULE_LICENSE("GPL");
diff --git a/net/bridge/netfilter/ebt_mark_m.c b/net/bridge/netfilter/ebt_mark_m.c
index 625102de1495..a6413e4b4982 100644
--- a/net/bridge/netfilter/ebt_mark_m.c
+++ b/net/bridge/netfilter/ebt_mark_m.c
@@ -47,16 +47,16 @@ static struct ebt_match filter_mark =
47 .me = THIS_MODULE, 47 .me = THIS_MODULE,
48}; 48};
49 49
50static int __init init(void) 50static int __init ebt_mark_m_init(void)
51{ 51{
52 return ebt_register_match(&filter_mark); 52 return ebt_register_match(&filter_mark);
53} 53}
54 54
55static void __exit fini(void) 55static void __exit ebt_mark_m_fini(void)
56{ 56{
57 ebt_unregister_match(&filter_mark); 57 ebt_unregister_match(&filter_mark);
58} 58}
59 59
60module_init(init); 60module_init(ebt_mark_m_init);
61module_exit(fini); 61module_exit(ebt_mark_m_fini);
62MODULE_LICENSE("GPL"); 62MODULE_LICENSE("GPL");
diff --git a/net/bridge/netfilter/ebt_pkttype.c b/net/bridge/netfilter/ebt_pkttype.c
index ecd3b42b19b0..4fffd70e4da7 100644
--- a/net/bridge/netfilter/ebt_pkttype.c
+++ b/net/bridge/netfilter/ebt_pkttype.c
@@ -44,16 +44,16 @@ static struct ebt_match filter_pkttype =
44 .me = THIS_MODULE, 44 .me = THIS_MODULE,
45}; 45};
46 46
47static int __init init(void) 47static int __init ebt_pkttype_init(void)
48{ 48{
49 return ebt_register_match(&filter_pkttype); 49 return ebt_register_match(&filter_pkttype);
50} 50}
51 51
52static void __exit fini(void) 52static void __exit ebt_pkttype_fini(void)
53{ 53{
54 ebt_unregister_match(&filter_pkttype); 54 ebt_unregister_match(&filter_pkttype);
55} 55}
56 56
57module_init(init); 57module_init(ebt_pkttype_init);
58module_exit(fini); 58module_exit(ebt_pkttype_fini);
59MODULE_LICENSE("GPL"); 59MODULE_LICENSE("GPL");
diff --git a/net/bridge/netfilter/ebt_redirect.c b/net/bridge/netfilter/ebt_redirect.c
index 1538b4386662..9f378eab72d0 100644
--- a/net/bridge/netfilter/ebt_redirect.c
+++ b/net/bridge/netfilter/ebt_redirect.c
@@ -66,16 +66,16 @@ static struct ebt_target redirect_target =
66 .me = THIS_MODULE, 66 .me = THIS_MODULE,
67}; 67};
68 68
69static int __init init(void) 69static int __init ebt_redirect_init(void)
70{ 70{
71 return ebt_register_target(&redirect_target); 71 return ebt_register_target(&redirect_target);
72} 72}
73 73
74static void __exit fini(void) 74static void __exit ebt_redirect_fini(void)
75{ 75{
76 ebt_unregister_target(&redirect_target); 76 ebt_unregister_target(&redirect_target);
77} 77}
78 78
79module_init(init); 79module_init(ebt_redirect_init);
80module_exit(fini); 80module_exit(ebt_redirect_fini);
81MODULE_LICENSE("GPL"); 81MODULE_LICENSE("GPL");
diff --git a/net/bridge/netfilter/ebt_snat.c b/net/bridge/netfilter/ebt_snat.c
index 1529bdcb9a48..cbb33e24ca8a 100644
--- a/net/bridge/netfilter/ebt_snat.c
+++ b/net/bridge/netfilter/ebt_snat.c
@@ -61,16 +61,16 @@ static struct ebt_target snat =
61 .me = THIS_MODULE, 61 .me = THIS_MODULE,
62}; 62};
63 63
64static int __init init(void) 64static int __init ebt_snat_init(void)
65{ 65{
66 return ebt_register_target(&snat); 66 return ebt_register_target(&snat);
67} 67}
68 68
69static void __exit fini(void) 69static void __exit ebt_snat_fini(void)
70{ 70{
71 ebt_unregister_target(&snat); 71 ebt_unregister_target(&snat);
72} 72}
73 73
74module_init(init); 74module_init(ebt_snat_init);
75module_exit(fini); 75module_exit(ebt_snat_fini);
76MODULE_LICENSE("GPL"); 76MODULE_LICENSE("GPL");
diff --git a/net/bridge/netfilter/ebt_stp.c b/net/bridge/netfilter/ebt_stp.c
index 0248c67277ee..a0bed82145ed 100644
--- a/net/bridge/netfilter/ebt_stp.c
+++ b/net/bridge/netfilter/ebt_stp.c
@@ -180,16 +180,16 @@ static struct ebt_match filter_stp =
180 .me = THIS_MODULE, 180 .me = THIS_MODULE,
181}; 181};
182 182
183static int __init init(void) 183static int __init ebt_stp_init(void)
184{ 184{
185 return ebt_register_match(&filter_stp); 185 return ebt_register_match(&filter_stp);
186} 186}
187 187
188static void __exit fini(void) 188static void __exit ebt_stp_fini(void)
189{ 189{
190 ebt_unregister_match(&filter_stp); 190 ebt_unregister_match(&filter_stp);
191} 191}
192 192
193module_init(init); 193module_init(ebt_stp_init);
194module_exit(fini); 194module_exit(ebt_stp_fini);
195MODULE_LICENSE("GPL"); 195MODULE_LICENSE("GPL");
diff --git a/net/bridge/netfilter/ebt_ulog.c b/net/bridge/netfilter/ebt_ulog.c
index 802baf755ef4..ee5a51761260 100644
--- a/net/bridge/netfilter/ebt_ulog.c
+++ b/net/bridge/netfilter/ebt_ulog.c
@@ -281,7 +281,7 @@ static struct nf_logger ebt_ulog_logger = {
281 .me = THIS_MODULE, 281 .me = THIS_MODULE,
282}; 282};
283 283
284static int __init init(void) 284static int __init ebt_ulog_init(void)
285{ 285{
286 int i, ret = 0; 286 int i, ret = 0;
287 287
@@ -316,7 +316,7 @@ static int __init init(void)
316 return ret; 316 return ret;
317} 317}
318 318
319static void __exit fini(void) 319static void __exit ebt_ulog_fini(void)
320{ 320{
321 ebt_ulog_buff_t *ub; 321 ebt_ulog_buff_t *ub;
322 int i; 322 int i;
@@ -337,8 +337,8 @@ static void __exit fini(void)
337 sock_release(ebtulognl->sk_socket); 337 sock_release(ebtulognl->sk_socket);
338} 338}
339 339
340module_init(init); 340module_init(ebt_ulog_init);
341module_exit(fini); 341module_exit(ebt_ulog_fini);
342MODULE_LICENSE("GPL"); 342MODULE_LICENSE("GPL");
343MODULE_AUTHOR("Bart De Schuymer <bdschuym@pandora.be>"); 343MODULE_AUTHOR("Bart De Schuymer <bdschuym@pandora.be>");
344MODULE_DESCRIPTION("ebtables userspace logging module for bridged Ethernet" 344MODULE_DESCRIPTION("ebtables userspace logging module for bridged Ethernet"
diff --git a/net/bridge/netfilter/ebt_vlan.c b/net/bridge/netfilter/ebt_vlan.c
index db60d734908b..a2b452862b73 100644
--- a/net/bridge/netfilter/ebt_vlan.c
+++ b/net/bridge/netfilter/ebt_vlan.c
@@ -178,7 +178,7 @@ static struct ebt_match filter_vlan = {
178 .me = THIS_MODULE, 178 .me = THIS_MODULE,
179}; 179};
180 180
181static int __init init(void) 181static int __init ebt_vlan_init(void)
182{ 182{
183 DEBUG_MSG("ebtables 802.1Q extension module v" 183 DEBUG_MSG("ebtables 802.1Q extension module v"
184 MODULE_VERS "\n"); 184 MODULE_VERS "\n");
@@ -186,10 +186,10 @@ static int __init init(void)
186 return ebt_register_match(&filter_vlan); 186 return ebt_register_match(&filter_vlan);
187} 187}
188 188
189static void __exit fini(void) 189static void __exit ebt_vlan_fini(void)
190{ 190{
191 ebt_unregister_match(&filter_vlan); 191 ebt_unregister_match(&filter_vlan);
192} 192}
193 193
194module_init(init); 194module_init(ebt_vlan_init);
195module_exit(fini); 195module_exit(ebt_vlan_fini);
diff --git a/net/bridge/netfilter/ebtable_broute.c b/net/bridge/netfilter/ebtable_broute.c
index 1767c94cd3de..9a6e548e148b 100644
--- a/net/bridge/netfilter/ebtable_broute.c
+++ b/net/bridge/netfilter/ebtable_broute.c
@@ -62,7 +62,7 @@ static int ebt_broute(struct sk_buff **pskb)
62 return 0; /* bridge it */ 62 return 0; /* bridge it */
63} 63}
64 64
65static int __init init(void) 65static int __init ebtable_broute_init(void)
66{ 66{
67 int ret; 67 int ret;
68 68
@@ -74,13 +74,13 @@ static int __init init(void)
74 return ret; 74 return ret;
75} 75}
76 76
77static void __exit fini(void) 77static void __exit ebtable_broute_fini(void)
78{ 78{
79 br_should_route_hook = NULL; 79 br_should_route_hook = NULL;
80 synchronize_net(); 80 synchronize_net();
81 ebt_unregister_table(&broute_table); 81 ebt_unregister_table(&broute_table);
82} 82}
83 83
84module_init(init); 84module_init(ebtable_broute_init);
85module_exit(fini); 85module_exit(ebtable_broute_fini);
86MODULE_LICENSE("GPL"); 86MODULE_LICENSE("GPL");
diff --git a/net/bridge/netfilter/ebtable_filter.c b/net/bridge/netfilter/ebtable_filter.c
index c18666e0392b..3d5bd44f2395 100644
--- a/net/bridge/netfilter/ebtable_filter.c
+++ b/net/bridge/netfilter/ebtable_filter.c
@@ -91,7 +91,7 @@ static struct nf_hook_ops ebt_ops_filter[] = {
91 }, 91 },
92}; 92};
93 93
94static int __init init(void) 94static int __init ebtable_filter_init(void)
95{ 95{
96 int i, j, ret; 96 int i, j, ret;
97 97
@@ -109,7 +109,7 @@ cleanup:
109 return ret; 109 return ret;
110} 110}
111 111
112static void __exit fini(void) 112static void __exit ebtable_filter_fini(void)
113{ 113{
114 int i; 114 int i;
115 115
@@ -118,6 +118,6 @@ static void __exit fini(void)
118 ebt_unregister_table(&frame_filter); 118 ebt_unregister_table(&frame_filter);
119} 119}
120 120
121module_init(init); 121module_init(ebtable_filter_init);
122module_exit(fini); 122module_exit(ebtable_filter_fini);
123MODULE_LICENSE("GPL"); 123MODULE_LICENSE("GPL");
diff --git a/net/bridge/netfilter/ebtable_nat.c b/net/bridge/netfilter/ebtable_nat.c
index 828cac2cc4a3..04dd42efda1d 100644
--- a/net/bridge/netfilter/ebtable_nat.c
+++ b/net/bridge/netfilter/ebtable_nat.c
@@ -98,7 +98,7 @@ static struct nf_hook_ops ebt_ops_nat[] = {
98 }, 98 },
99}; 99};
100 100
101static int __init init(void) 101static int __init ebtable_nat_init(void)
102{ 102{
103 int i, ret, j; 103 int i, ret, j;
104 104
@@ -116,7 +116,7 @@ cleanup:
116 return ret; 116 return ret;
117} 117}
118 118
119static void __exit fini(void) 119static void __exit ebtable_nat_fini(void)
120{ 120{
121 int i; 121 int i;
122 122
@@ -125,6 +125,6 @@ static void __exit fini(void)
125 ebt_unregister_table(&frame_nat); 125 ebt_unregister_table(&frame_nat);
126} 126}
127 127
128module_init(init); 128module_init(ebtable_nat_init);
129module_exit(fini); 129module_exit(ebtable_nat_fini);
130MODULE_LICENSE("GPL"); 130MODULE_LICENSE("GPL");
diff --git a/net/bridge/netfilter/ebtables.c b/net/bridge/netfilter/ebtables.c
index 997953367204..01eae97c53d9 100644
--- a/net/bridge/netfilter/ebtables.c
+++ b/net/bridge/netfilter/ebtables.c
@@ -1487,7 +1487,7 @@ static struct nf_sockopt_ops ebt_sockopts =
1487 .get = do_ebt_get_ctl, 1487 .get = do_ebt_get_ctl,
1488}; 1488};
1489 1489
1490static int __init init(void) 1490static int __init ebtables_init(void)
1491{ 1491{
1492 int ret; 1492 int ret;
1493 1493
@@ -1501,7 +1501,7 @@ static int __init init(void)
1501 return 0; 1501 return 0;
1502} 1502}
1503 1503
1504static void __exit fini(void) 1504static void __exit ebtables_fini(void)
1505{ 1505{
1506 nf_unregister_sockopt(&ebt_sockopts); 1506 nf_unregister_sockopt(&ebt_sockopts);
1507 printk(KERN_NOTICE "Ebtables v2.0 unregistered\n"); 1507 printk(KERN_NOTICE "Ebtables v2.0 unregistered\n");
@@ -1516,6 +1516,6 @@ EXPORT_SYMBOL(ebt_unregister_watcher);
1516EXPORT_SYMBOL(ebt_register_target); 1516EXPORT_SYMBOL(ebt_register_target);
1517EXPORT_SYMBOL(ebt_unregister_target); 1517EXPORT_SYMBOL(ebt_unregister_target);
1518EXPORT_SYMBOL(ebt_do_table); 1518EXPORT_SYMBOL(ebt_do_table);
1519module_init(init); 1519module_init(ebtables_init);
1520module_exit(fini); 1520module_exit(ebtables_fini);
1521MODULE_LICENSE("GPL"); 1521MODULE_LICENSE("GPL");
diff --git a/net/core/dev.c b/net/core/dev.c
index a3ab11f34153..434220d093aa 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -1080,6 +1080,70 @@ void dev_queue_xmit_nit(struct sk_buff *skb, struct net_device *dev)
1080 rcu_read_unlock(); 1080 rcu_read_unlock();
1081} 1081}
1082 1082
1083
1084void __netif_schedule(struct net_device *dev)
1085{
1086 if (!test_and_set_bit(__LINK_STATE_SCHED, &dev->state)) {
1087 unsigned long flags;
1088 struct softnet_data *sd;
1089
1090 local_irq_save(flags);
1091 sd = &__get_cpu_var(softnet_data);
1092 dev->next_sched = sd->output_queue;
1093 sd->output_queue = dev;
1094 raise_softirq_irqoff(NET_TX_SOFTIRQ);
1095 local_irq_restore(flags);
1096 }
1097}
1098EXPORT_SYMBOL(__netif_schedule);
1099
1100void __netif_rx_schedule(struct net_device *dev)
1101{
1102 unsigned long flags;
1103
1104 local_irq_save(flags);
1105 dev_hold(dev);
1106 list_add_tail(&dev->poll_list, &__get_cpu_var(softnet_data).poll_list);
1107 if (dev->quota < 0)
1108 dev->quota += dev->weight;
1109 else
1110 dev->quota = dev->weight;
1111 __raise_softirq_irqoff(NET_RX_SOFTIRQ);
1112 local_irq_restore(flags);
1113}
1114EXPORT_SYMBOL(__netif_rx_schedule);
1115
1116void dev_kfree_skb_any(struct sk_buff *skb)
1117{
1118 if (in_irq() || irqs_disabled())
1119 dev_kfree_skb_irq(skb);
1120 else
1121 dev_kfree_skb(skb);
1122}
1123EXPORT_SYMBOL(dev_kfree_skb_any);
1124
1125
1126/* Hot-plugging. */
1127void netif_device_detach(struct net_device *dev)
1128{
1129 if (test_and_clear_bit(__LINK_STATE_PRESENT, &dev->state) &&
1130 netif_running(dev)) {
1131 netif_stop_queue(dev);
1132 }
1133}
1134EXPORT_SYMBOL(netif_device_detach);
1135
1136void netif_device_attach(struct net_device *dev)
1137{
1138 if (!test_and_set_bit(__LINK_STATE_PRESENT, &dev->state) &&
1139 netif_running(dev)) {
1140 netif_wake_queue(dev);
1141 __netdev_watchdog_up(dev);
1142 }
1143}
1144EXPORT_SYMBOL(netif_device_attach);
1145
1146
1083/* 1147/*
1084 * Invalidate hardware checksum when packet is to be mangled, and 1148 * Invalidate hardware checksum when packet is to be mangled, and
1085 * complete checksum manually on outgoing path. 1149 * complete checksum manually on outgoing path.
diff --git a/net/core/sock.c b/net/core/sock.c
index e110b9004147..ed2afdb9ea2d 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -187,6 +187,99 @@ static void sock_disable_timestamp(struct sock *sk)
187} 187}
188 188
189 189
190int sock_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
191{
192 int err = 0;
193 int skb_len;
194
195 /* Cast skb->rcvbuf to unsigned... It's pointless, but reduces
196 number of warnings when compiling with -W --ANK
197 */
198 if (atomic_read(&sk->sk_rmem_alloc) + skb->truesize >=
199 (unsigned)sk->sk_rcvbuf) {
200 err = -ENOMEM;
201 goto out;
202 }
203
204 /* It would be deadlock, if sock_queue_rcv_skb is used
205 with socket lock! We assume that users of this
206 function are lock free.
207 */
208 err = sk_filter(sk, skb, 1);
209 if (err)
210 goto out;
211
212 skb->dev = NULL;
213 skb_set_owner_r(skb, sk);
214
215 /* Cache the SKB length before we tack it onto the receive
216 * queue. Once it is added it no longer belongs to us and
217 * may be freed by other threads of control pulling packets
218 * from the queue.
219 */
220 skb_len = skb->len;
221
222 skb_queue_tail(&sk->sk_receive_queue, skb);
223
224 if (!sock_flag(sk, SOCK_DEAD))
225 sk->sk_data_ready(sk, skb_len);
226out:
227 return err;
228}
229EXPORT_SYMBOL(sock_queue_rcv_skb);
230
231int sk_receive_skb(struct sock *sk, struct sk_buff *skb)
232{
233 int rc = NET_RX_SUCCESS;
234
235 if (sk_filter(sk, skb, 0))
236 goto discard_and_relse;
237
238 skb->dev = NULL;
239
240 bh_lock_sock(sk);
241 if (!sock_owned_by_user(sk))
242 rc = sk->sk_backlog_rcv(sk, skb);
243 else
244 sk_add_backlog(sk, skb);
245 bh_unlock_sock(sk);
246out:
247 sock_put(sk);
248 return rc;
249discard_and_relse:
250 kfree_skb(skb);
251 goto out;
252}
253EXPORT_SYMBOL(sk_receive_skb);
254
255struct dst_entry *__sk_dst_check(struct sock *sk, u32 cookie)
256{
257 struct dst_entry *dst = sk->sk_dst_cache;
258
259 if (dst && dst->obsolete && dst->ops->check(dst, cookie) == NULL) {
260 sk->sk_dst_cache = NULL;
261 dst_release(dst);
262 return NULL;
263 }
264
265 return dst;
266}
267EXPORT_SYMBOL(__sk_dst_check);
268
269struct dst_entry *sk_dst_check(struct sock *sk, u32 cookie)
270{
271 struct dst_entry *dst = sk_dst_get(sk);
272
273 if (dst && dst->obsolete && dst->ops->check(dst, cookie) == NULL) {
274 sk_dst_reset(sk);
275 dst_release(dst);
276 return NULL;
277 }
278
279 return dst;
280}
281EXPORT_SYMBOL(sk_dst_check);
282
190/* 283/*
191 * This is meant for all protocols to use and covers goings on 284 * This is meant for all protocols to use and covers goings on
192 * at the socket level. Everything here is generic. 285 * at the socket level. Everything here is generic.
@@ -292,7 +385,21 @@ set_sndbuf:
292 val = sysctl_rmem_max; 385 val = sysctl_rmem_max;
293set_rcvbuf: 386set_rcvbuf:
294 sk->sk_userlocks |= SOCK_RCVBUF_LOCK; 387 sk->sk_userlocks |= SOCK_RCVBUF_LOCK;
295 /* FIXME: is this lower bound the right one? */ 388 /*
389 * We double it on the way in to account for
390 * "struct sk_buff" etc. overhead. Applications
391 * assume that the SO_RCVBUF setting they make will
392 * allow that much actual data to be received on that
393 * socket.
394 *
395 * Applications are unaware that "struct sk_buff" and
396 * other overheads allocate from the receive buffer
397 * during socket buffer allocation.
398 *
399 * And after considering the possible alternatives,
400 * returning the value we actually used in getsockopt
401 * is the most desirable behavior.
402 */
296 if ((val * 2) < SOCK_MIN_RCVBUF) 403 if ((val * 2) < SOCK_MIN_RCVBUF)
297 sk->sk_rcvbuf = SOCK_MIN_RCVBUF; 404 sk->sk_rcvbuf = SOCK_MIN_RCVBUF;
298 else 405 else
diff --git a/net/dccp/feat.c b/net/dccp/feat.c
index e3dd30d36c8a..b39e2a597889 100644
--- a/net/dccp/feat.c
+++ b/net/dccp/feat.c
@@ -204,7 +204,7 @@ static int dccp_feat_reconcile(struct sock *sk, struct dccp_opt_pend *opt,
204 if (rc) { 204 if (rc) {
205 kfree(opt->dccpop_sc->dccpoc_val); 205 kfree(opt->dccpop_sc->dccpoc_val);
206 kfree(opt->dccpop_sc); 206 kfree(opt->dccpop_sc);
207 opt->dccpop_sc = 0; 207 opt->dccpop_sc = NULL;
208 return rc; 208 return rc;
209 } 209 }
210 210
@@ -322,7 +322,7 @@ static void dccp_feat_empty_confirm(struct dccp_minisock *dmsk,
322 opt->dccpop_type = type == DCCPO_CHANGE_L ? DCCPO_CONFIRM_R : 322 opt->dccpop_type = type == DCCPO_CHANGE_L ? DCCPO_CONFIRM_R :
323 DCCPO_CONFIRM_L; 323 DCCPO_CONFIRM_L;
324 opt->dccpop_feat = feature; 324 opt->dccpop_feat = feature;
325 opt->dccpop_val = 0; 325 opt->dccpop_val = NULL;
326 opt->dccpop_len = 0; 326 opt->dccpop_len = 0;
327 327
328 /* change feature */ 328 /* change feature */
@@ -523,7 +523,7 @@ int dccp_feat_clone(struct sock *oldsk, struct sock *newsk)
523 * once... 523 * once...
524 */ 524 */
525 /* the master socket no longer needs to worry about confirms */ 525 /* the master socket no longer needs to worry about confirms */
526 opt->dccpop_sc = 0; /* it's not a memleak---new socket has it */ 526 opt->dccpop_sc = NULL; /* it's not a memleak---new socket has it */
527 527
528 /* reset state for a new socket */ 528 /* reset state for a new socket */
529 opt->dccpop_conf = 0; 529 opt->dccpop_conf = 0;
diff --git a/net/decnet/dn_dev.c b/net/decnet/dn_dev.c
index d2ae9893ca17..a26ff9f44576 100644
--- a/net/decnet/dn_dev.c
+++ b/net/decnet/dn_dev.c
@@ -620,7 +620,7 @@ int dn_dev_set_default(struct net_device *dev, int force)
620 } 620 }
621 write_unlock(&dndev_lock); 621 write_unlock(&dndev_lock);
622 if (old) 622 if (old)
623 dev_put(dev); 623 dev_put(old);
624 return rv; 624 return rv;
625} 625}
626 626
diff --git a/net/decnet/netfilter/dn_rtmsg.c b/net/decnet/netfilter/dn_rtmsg.c
index 16a5a31e2126..74133ecd7700 100644
--- a/net/decnet/netfilter/dn_rtmsg.c
+++ b/net/decnet/netfilter/dn_rtmsg.c
@@ -133,7 +133,7 @@ static struct nf_hook_ops dnrmg_ops = {
133 .priority = NF_DN_PRI_DNRTMSG, 133 .priority = NF_DN_PRI_DNRTMSG,
134}; 134};
135 135
136static int __init init(void) 136static int __init dn_rtmsg_init(void)
137{ 137{
138 int rv = 0; 138 int rv = 0;
139 139
@@ -152,7 +152,7 @@ static int __init init(void)
152 return rv; 152 return rv;
153} 153}
154 154
155static void __exit fini(void) 155static void __exit dn_rtmsg_fini(void)
156{ 156{
157 nf_unregister_hook(&dnrmg_ops); 157 nf_unregister_hook(&dnrmg_ops);
158 sock_release(dnrmg->sk_socket); 158 sock_release(dnrmg->sk_socket);
@@ -164,6 +164,6 @@ MODULE_AUTHOR("Steven Whitehouse <steve@chygwyn.com>");
164MODULE_LICENSE("GPL"); 164MODULE_LICENSE("GPL");
165MODULE_ALIAS_NET_PF_PROTO(PF_NETLINK, NETLINK_DNRTMSG); 165MODULE_ALIAS_NET_PF_PROTO(PF_NETLINK, NETLINK_DNRTMSG);
166 166
167module_init(init); 167module_init(dn_rtmsg_init);
168module_exit(fini); 168module_exit(dn_rtmsg_fini);
169 169
diff --git a/net/econet/af_econet.c b/net/econet/af_econet.c
index c792994d7952..868265619dbb 100644
--- a/net/econet/af_econet.c
+++ b/net/econet/af_econet.c
@@ -42,6 +42,7 @@
42#include <linux/spinlock.h> 42#include <linux/spinlock.h>
43#include <linux/rcupdate.h> 43#include <linux/rcupdate.h>
44#include <linux/bitops.h> 44#include <linux/bitops.h>
45#include <linux/mutex.h>
45 46
46#include <asm/uaccess.h> 47#include <asm/uaccess.h>
47#include <asm/system.h> 48#include <asm/system.h>
@@ -49,6 +50,7 @@
49static const struct proto_ops econet_ops; 50static const struct proto_ops econet_ops;
50static struct hlist_head econet_sklist; 51static struct hlist_head econet_sklist;
51static DEFINE_RWLOCK(econet_lock); 52static DEFINE_RWLOCK(econet_lock);
53static DEFINE_MUTEX(econet_mutex);
52 54
53/* Since there are only 256 possible network numbers (or fewer, depends 55/* Since there are only 256 possible network numbers (or fewer, depends
54 how you count) it makes sense to use a simple lookup table. */ 56 how you count) it makes sense to use a simple lookup table. */
@@ -124,6 +126,8 @@ static int econet_recvmsg(struct kiocb *iocb, struct socket *sock,
124 126
125 msg->msg_namelen = sizeof(struct sockaddr_ec); 127 msg->msg_namelen = sizeof(struct sockaddr_ec);
126 128
129 mutex_lock(&econet_mutex);
130
127 /* 131 /*
128 * Call the generic datagram receiver. This handles all sorts 132 * Call the generic datagram receiver. This handles all sorts
129 * of horrible races and re-entrancy so we can forget about it 133 * of horrible races and re-entrancy so we can forget about it
@@ -174,6 +178,7 @@ static int econet_recvmsg(struct kiocb *iocb, struct socket *sock,
174out_free: 178out_free:
175 skb_free_datagram(sk, skb); 179 skb_free_datagram(sk, skb);
176out: 180out:
181 mutex_unlock(&econet_mutex);
177 return err; 182 return err;
178} 183}
179 184
@@ -184,8 +189,8 @@ out:
184static int econet_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) 189static int econet_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
185{ 190{
186 struct sockaddr_ec *sec = (struct sockaddr_ec *)uaddr; 191 struct sockaddr_ec *sec = (struct sockaddr_ec *)uaddr;
187 struct sock *sk=sock->sk; 192 struct sock *sk;
188 struct econet_sock *eo = ec_sk(sk); 193 struct econet_sock *eo;
189 194
190 /* 195 /*
191 * Check legality 196 * Check legality
@@ -195,11 +200,18 @@ static int econet_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len
195 sec->sec_family != AF_ECONET) 200 sec->sec_family != AF_ECONET)
196 return -EINVAL; 201 return -EINVAL;
197 202
203 mutex_lock(&econet_mutex);
204
205 sk = sock->sk;
206 eo = ec_sk(sk);
207
198 eo->cb = sec->cb; 208 eo->cb = sec->cb;
199 eo->port = sec->port; 209 eo->port = sec->port;
200 eo->station = sec->addr.station; 210 eo->station = sec->addr.station;
201 eo->net = sec->addr.net; 211 eo->net = sec->addr.net;
202 212
213 mutex_unlock(&econet_mutex);
214
203 return 0; 215 return 0;
204} 216}
205 217
@@ -284,6 +296,8 @@ static int econet_sendmsg(struct kiocb *iocb, struct socket *sock,
284 * Get and verify the address. 296 * Get and verify the address.
285 */ 297 */
286 298
299 mutex_lock(&econet_mutex);
300
287 if (saddr == NULL) { 301 if (saddr == NULL) {
288 struct econet_sock *eo = ec_sk(sk); 302 struct econet_sock *eo = ec_sk(sk);
289 303
@@ -292,8 +306,10 @@ static int econet_sendmsg(struct kiocb *iocb, struct socket *sock,
292 port = eo->port; 306 port = eo->port;
293 cb = eo->cb; 307 cb = eo->cb;
294 } else { 308 } else {
295 if (msg->msg_namelen < sizeof(struct sockaddr_ec)) 309 if (msg->msg_namelen < sizeof(struct sockaddr_ec)) {
310 mutex_unlock(&econet_mutex);
296 return -EINVAL; 311 return -EINVAL;
312 }
297 addr.station = saddr->addr.station; 313 addr.station = saddr->addr.station;
298 addr.net = saddr->addr.net; 314 addr.net = saddr->addr.net;
299 port = saddr->port; 315 port = saddr->port;
@@ -304,19 +320,21 @@ static int econet_sendmsg(struct kiocb *iocb, struct socket *sock,
304 dev = net2dev_map[addr.net]; 320 dev = net2dev_map[addr.net];
305 321
306 /* If not directly reachable, use some default */ 322 /* If not directly reachable, use some default */
307 if (dev == NULL) 323 if (dev == NULL) {
308 {
309 dev = net2dev_map[0]; 324 dev = net2dev_map[0];
310 /* No interfaces at all? */ 325 /* No interfaces at all? */
311 if (dev == NULL) 326 if (dev == NULL) {
327 mutex_unlock(&econet_mutex);
312 return -ENETDOWN; 328 return -ENETDOWN;
329 }
313 } 330 }
314 331
315 if (len + 15 > dev->mtu) 332 if (len + 15 > dev->mtu) {
333 mutex_unlock(&econet_mutex);
316 return -EMSGSIZE; 334 return -EMSGSIZE;
335 }
317 336
318 if (dev->type == ARPHRD_ECONET) 337 if (dev->type == ARPHRD_ECONET) {
319 {
320 /* Real hardware Econet. We're not worthy etc. */ 338 /* Real hardware Econet. We're not worthy etc. */
321#ifdef CONFIG_ECONET_NATIVE 339#ifdef CONFIG_ECONET_NATIVE
322 unsigned short proto = 0; 340 unsigned short proto = 0;
@@ -374,6 +392,7 @@ static int econet_sendmsg(struct kiocb *iocb, struct socket *sock,
374 392
375 dev_queue_xmit(skb); 393 dev_queue_xmit(skb);
376 dev_put(dev); 394 dev_put(dev);
395 mutex_unlock(&econet_mutex);
377 return(len); 396 return(len);
378 397
379 out_free: 398 out_free:
@@ -384,14 +403,18 @@ static int econet_sendmsg(struct kiocb *iocb, struct socket *sock,
384#else 403#else
385 err = -EPROTOTYPE; 404 err = -EPROTOTYPE;
386#endif 405#endif
406 mutex_unlock(&econet_mutex);
407
387 return err; 408 return err;
388 } 409 }
389 410
390#ifdef CONFIG_ECONET_AUNUDP 411#ifdef CONFIG_ECONET_AUNUDP
391 /* AUN virtual Econet. */ 412 /* AUN virtual Econet. */
392 413
393 if (udpsock == NULL) 414 if (udpsock == NULL) {
415 mutex_unlock(&econet_mutex);
394 return -ENETDOWN; /* No socket - can't send */ 416 return -ENETDOWN; /* No socket - can't send */
417 }
395 418
396 /* Make up a UDP datagram and hand it off to some higher intellect. */ 419 /* Make up a UDP datagram and hand it off to some higher intellect. */
397 420
@@ -438,8 +461,10 @@ static int econet_sendmsg(struct kiocb *iocb, struct socket *sock,
438 void __user *base = msg->msg_iov[i].iov_base; 461 void __user *base = msg->msg_iov[i].iov_base;
439 size_t len = msg->msg_iov[i].iov_len; 462 size_t len = msg->msg_iov[i].iov_len;
440 /* Check it now since we switch to KERNEL_DS later. */ 463 /* Check it now since we switch to KERNEL_DS later. */
441 if (!access_ok(VERIFY_READ, base, len)) 464 if (!access_ok(VERIFY_READ, base, len)) {
465 mutex_unlock(&econet_mutex);
442 return -EFAULT; 466 return -EFAULT;
467 }
443 iov[i+1].iov_base = base; 468 iov[i+1].iov_base = base;
444 iov[i+1].iov_len = len; 469 iov[i+1].iov_len = len;
445 size += len; 470 size += len;
@@ -447,8 +472,11 @@ static int econet_sendmsg(struct kiocb *iocb, struct socket *sock,
447 472
448 /* Get a skbuff (no data, just holds our cb information) */ 473 /* Get a skbuff (no data, just holds our cb information) */
449 if ((skb = sock_alloc_send_skb(sk, 0, 474 if ((skb = sock_alloc_send_skb(sk, 0,
450 msg->msg_flags & MSG_DONTWAIT, &err)) == NULL) 475 msg->msg_flags & MSG_DONTWAIT,
476 &err)) == NULL) {
477 mutex_unlock(&econet_mutex);
451 return err; 478 return err;
479 }
452 480
453 eb = (struct ec_cb *)&skb->cb; 481 eb = (struct ec_cb *)&skb->cb;
454 482
@@ -475,6 +503,8 @@ static int econet_sendmsg(struct kiocb *iocb, struct socket *sock,
475#else 503#else
476 err = -EPROTOTYPE; 504 err = -EPROTOTYPE;
477#endif 505#endif
506 mutex_unlock(&econet_mutex);
507
478 return err; 508 return err;
479} 509}
480 510
@@ -485,18 +515,25 @@ static int econet_sendmsg(struct kiocb *iocb, struct socket *sock,
485static int econet_getname(struct socket *sock, struct sockaddr *uaddr, 515static int econet_getname(struct socket *sock, struct sockaddr *uaddr,
486 int *uaddr_len, int peer) 516 int *uaddr_len, int peer)
487{ 517{
488 struct sock *sk = sock->sk; 518 struct sock *sk;
489 struct econet_sock *eo = ec_sk(sk); 519 struct econet_sock *eo;
490 struct sockaddr_ec *sec = (struct sockaddr_ec *)uaddr; 520 struct sockaddr_ec *sec = (struct sockaddr_ec *)uaddr;
491 521
492 if (peer) 522 if (peer)
493 return -EOPNOTSUPP; 523 return -EOPNOTSUPP;
494 524
525 mutex_lock(&econet_mutex);
526
527 sk = sock->sk;
528 eo = ec_sk(sk);
529
495 sec->sec_family = AF_ECONET; 530 sec->sec_family = AF_ECONET;
496 sec->port = eo->port; 531 sec->port = eo->port;
497 sec->addr.station = eo->station; 532 sec->addr.station = eo->station;
498 sec->addr.net = eo->net; 533 sec->addr.net = eo->net;
499 534
535 mutex_unlock(&econet_mutex);
536
500 *uaddr_len = sizeof(*sec); 537 *uaddr_len = sizeof(*sec);
501 return 0; 538 return 0;
502} 539}
@@ -522,10 +559,13 @@ static void econet_destroy_timer(unsigned long data)
522 559
523static int econet_release(struct socket *sock) 560static int econet_release(struct socket *sock)
524{ 561{
525 struct sock *sk = sock->sk; 562 struct sock *sk;
526 563
564 mutex_lock(&econet_mutex);
565
566 sk = sock->sk;
527 if (!sk) 567 if (!sk)
528 return 0; 568 goto out_unlock;
529 569
530 econet_remove_socket(&econet_sklist, sk); 570 econet_remove_socket(&econet_sklist, sk);
531 571
@@ -549,10 +589,14 @@ static int econet_release(struct socket *sock)
549 sk->sk_timer.expires = jiffies + HZ; 589 sk->sk_timer.expires = jiffies + HZ;
550 sk->sk_timer.function = econet_destroy_timer; 590 sk->sk_timer.function = econet_destroy_timer;
551 add_timer(&sk->sk_timer); 591 add_timer(&sk->sk_timer);
552 return 0; 592
593 goto out_unlock;
553 } 594 }
554 595
555 sk_free(sk); 596 sk_free(sk);
597
598out_unlock:
599 mutex_unlock(&econet_mutex);
556 return 0; 600 return 0;
557} 601}
558 602
@@ -608,6 +652,7 @@ static int ec_dev_ioctl(struct socket *sock, unsigned int cmd, void __user *arg)
608 struct ec_device *edev; 652 struct ec_device *edev;
609 struct net_device *dev; 653 struct net_device *dev;
610 struct sockaddr_ec *sec; 654 struct sockaddr_ec *sec;
655 int err;
611 656
612 /* 657 /*
613 * Fetch the caller's info block into kernel space 658 * Fetch the caller's info block into kernel space
@@ -621,38 +666,35 @@ static int ec_dev_ioctl(struct socket *sock, unsigned int cmd, void __user *arg)
621 666
622 sec = (struct sockaddr_ec *)&ifr.ifr_addr; 667 sec = (struct sockaddr_ec *)&ifr.ifr_addr;
623 668
624 switch (cmd) 669 mutex_lock(&econet_mutex);
625 { 670
671 err = 0;
672 switch (cmd) {
626 case SIOCSIFADDR: 673 case SIOCSIFADDR:
627 edev = dev->ec_ptr; 674 edev = dev->ec_ptr;
628 if (edev == NULL) 675 if (edev == NULL) {
629 {
630 /* Magic up a new one. */ 676 /* Magic up a new one. */
631 edev = kmalloc(sizeof(struct ec_device), GFP_KERNEL); 677 edev = kmalloc(sizeof(struct ec_device), GFP_KERNEL);
632 if (edev == NULL) { 678 if (edev == NULL) {
633 printk("af_ec: memory squeeze.\n"); 679 err = -ENOMEM;
634 dev_put(dev); 680 break;
635 return -ENOMEM;
636 } 681 }
637 memset(edev, 0, sizeof(struct ec_device)); 682 memset(edev, 0, sizeof(struct ec_device));
638 dev->ec_ptr = edev; 683 dev->ec_ptr = edev;
639 } 684 } else
640 else
641 net2dev_map[edev->net] = NULL; 685 net2dev_map[edev->net] = NULL;
642 edev->station = sec->addr.station; 686 edev->station = sec->addr.station;
643 edev->net = sec->addr.net; 687 edev->net = sec->addr.net;
644 net2dev_map[sec->addr.net] = dev; 688 net2dev_map[sec->addr.net] = dev;
645 if (!net2dev_map[0]) 689 if (!net2dev_map[0])
646 net2dev_map[0] = dev; 690 net2dev_map[0] = dev;
647 dev_put(dev); 691 break;
648 return 0;
649 692
650 case SIOCGIFADDR: 693 case SIOCGIFADDR:
651 edev = dev->ec_ptr; 694 edev = dev->ec_ptr;
652 if (edev == NULL) 695 if (edev == NULL) {
653 { 696 err = -ENODEV;
654 dev_put(dev); 697 break;
655 return -ENODEV;
656 } 698 }
657 memset(sec, 0, sizeof(struct sockaddr_ec)); 699 memset(sec, 0, sizeof(struct sockaddr_ec));
658 sec->addr.station = edev->station; 700 sec->addr.station = edev->station;
@@ -660,12 +702,19 @@ static int ec_dev_ioctl(struct socket *sock, unsigned int cmd, void __user *arg)
660 sec->sec_family = AF_ECONET; 702 sec->sec_family = AF_ECONET;
661 dev_put(dev); 703 dev_put(dev);
662 if (copy_to_user(arg, &ifr, sizeof(struct ifreq))) 704 if (copy_to_user(arg, &ifr, sizeof(struct ifreq)))
663 return -EFAULT; 705 err = -EFAULT;
664 return 0; 706 break;
707
708 default:
709 err = -EINVAL;
710 break;
665 } 711 }
666 712
713 mutex_unlock(&econet_mutex);
714
667 dev_put(dev); 715 dev_put(dev);
668 return -EINVAL; 716
717 return err;
669} 718}
670 719
671/* 720/*
@@ -699,7 +748,7 @@ static struct net_proto_family econet_family_ops = {
699 .owner = THIS_MODULE, 748 .owner = THIS_MODULE,
700}; 749};
701 750
702static const struct proto_ops SOCKOPS_WRAPPED(econet_ops) = { 751static const struct proto_ops econet_ops = {
703 .family = PF_ECONET, 752 .family = PF_ECONET,
704 .owner = THIS_MODULE, 753 .owner = THIS_MODULE,
705 .release = econet_release, 754 .release = econet_release,
@@ -720,9 +769,6 @@ static const struct proto_ops SOCKOPS_WRAPPED(econet_ops) = {
720 .sendpage = sock_no_sendpage, 769 .sendpage = sock_no_sendpage,
721}; 770};
722 771
723#include <linux/smp_lock.h>
724SOCKOPS_WRAP(econet, PF_ECONET);
725
726#if defined(CONFIG_ECONET_AUNUDP) || defined(CONFIG_ECONET_NATIVE) 772#if defined(CONFIG_ECONET_AUNUDP) || defined(CONFIG_ECONET_NATIVE)
727/* 773/*
728 * Find the listening socket, if any, for the given data. 774 * Find the listening socket, if any, for the given data.
diff --git a/net/ieee80211/ieee80211_wx.c b/net/ieee80211/ieee80211_wx.c
index af7f9bbfd18a..b885fd189403 100644
--- a/net/ieee80211/ieee80211_wx.c
+++ b/net/ieee80211/ieee80211_wx.c
@@ -42,7 +42,7 @@ static const char *ieee80211_modes[] = {
42}; 42};
43 43
44#define MAX_CUSTOM_LEN 64 44#define MAX_CUSTOM_LEN 64
45static char *ipw2100_translate_scan(struct ieee80211_device *ieee, 45static char *ieee80211_translate_scan(struct ieee80211_device *ieee,
46 char *start, char *stop, 46 char *start, char *stop,
47 struct ieee80211_network *network) 47 struct ieee80211_network *network)
48{ 48{
@@ -274,7 +274,7 @@ int ieee80211_wx_get_scan(struct ieee80211_device *ieee,
274 274
275 if (ieee->scan_age == 0 || 275 if (ieee->scan_age == 0 ||
276 time_after(network->last_scanned + ieee->scan_age, jiffies)) 276 time_after(network->last_scanned + ieee->scan_age, jiffies))
277 ev = ipw2100_translate_scan(ieee, ev, stop, network); 277 ev = ieee80211_translate_scan(ieee, ev, stop, network);
278 else 278 else
279 IEEE80211_DEBUG_SCAN("Not showing network '%s (" 279 IEEE80211_DEBUG_SCAN("Not showing network '%s ("
280 MAC_FMT ")' due to age (%dms).\n", 280 MAC_FMT ")' due to age (%dms).\n",
diff --git a/net/ieee80211/softmac/ieee80211softmac_module.c b/net/ieee80211/softmac/ieee80211softmac_module.c
index 6f99f781bff8..60f06a31f0d1 100644
--- a/net/ieee80211/softmac/ieee80211softmac_module.c
+++ b/net/ieee80211/softmac/ieee80211softmac_module.c
@@ -183,16 +183,21 @@ void ieee80211softmac_start(struct net_device *dev)
183 */ 183 */
184 if (mac->txrates_change) 184 if (mac->txrates_change)
185 oldrates = mac->txrates; 185 oldrates = mac->txrates;
186 if (ieee->modulation & IEEE80211_OFDM_MODULATION) { 186 /* FIXME: We don't correctly handle backing down to lower
187 mac->txrates.default_rate = IEEE80211_OFDM_RATE_54MB; 187 rates, so 801.11g devices start off at 11M for now. People
188 change |= IEEE80211SOFTMAC_TXRATECHG_DEFAULT; 188 can manually change it if they really need to, but 11M is
189 mac->txrates.default_fallback = IEEE80211_OFDM_RATE_24MB; 189 more reliable. Note similar logic in
190 change |= IEEE80211SOFTMAC_TXRATECHG_DEFAULT_FBACK; 190 ieee80211softmac_wx_set_rate() */
191 } else if (ieee->modulation & IEEE80211_CCK_MODULATION) { 191 if (ieee->modulation & IEEE80211_CCK_MODULATION) {
192 mac->txrates.default_rate = IEEE80211_CCK_RATE_11MB; 192 mac->txrates.default_rate = IEEE80211_CCK_RATE_11MB;
193 change |= IEEE80211SOFTMAC_TXRATECHG_DEFAULT; 193 change |= IEEE80211SOFTMAC_TXRATECHG_DEFAULT;
194 mac->txrates.default_fallback = IEEE80211_CCK_RATE_5MB; 194 mac->txrates.default_fallback = IEEE80211_CCK_RATE_5MB;
195 change |= IEEE80211SOFTMAC_TXRATECHG_DEFAULT_FBACK; 195 change |= IEEE80211SOFTMAC_TXRATECHG_DEFAULT_FBACK;
196 } else if (ieee->modulation & IEEE80211_OFDM_MODULATION) {
197 mac->txrates.default_rate = IEEE80211_OFDM_RATE_54MB;
198 change |= IEEE80211SOFTMAC_TXRATECHG_DEFAULT;
199 mac->txrates.default_fallback = IEEE80211_OFDM_RATE_24MB;
200 change |= IEEE80211SOFTMAC_TXRATECHG_DEFAULT_FBACK;
196 } else 201 } else
197 assert(0); 202 assert(0);
198 if (mac->txrates_change) 203 if (mac->txrates_change)
diff --git a/net/ieee80211/softmac/ieee80211softmac_priv.h b/net/ieee80211/softmac/ieee80211softmac_priv.h
index 9ba7dbd161eb..65d9816c8ecc 100644
--- a/net/ieee80211/softmac/ieee80211softmac_priv.h
+++ b/net/ieee80211/softmac/ieee80211softmac_priv.h
@@ -167,7 +167,7 @@ static inline int ieee80211softmac_scan_sanity_check(struct ieee80211softmac_dev
167 ) || ieee80211softmac_scan_handlers_check_self(sm); 167 ) || ieee80211softmac_scan_handlers_check_self(sm);
168} 168}
169 169
170#define IEEE80211SOFTMAC_PROBE_DELAY HZ/2 170#define IEEE80211SOFTMAC_PROBE_DELAY HZ/50
171#define IEEE80211SOFTMAC_WORKQUEUE_NAME_LEN (17 + IFNAMSIZ) 171#define IEEE80211SOFTMAC_WORKQUEUE_NAME_LEN (17 + IFNAMSIZ)
172 172
173struct ieee80211softmac_network { 173struct ieee80211softmac_network {
diff --git a/net/ieee80211/softmac/ieee80211softmac_wx.c b/net/ieee80211/softmac/ieee80211softmac_wx.c
index e1a9bc6d36ff..b559aa9b5507 100644
--- a/net/ieee80211/softmac/ieee80211softmac_wx.c
+++ b/net/ieee80211/softmac/ieee80211softmac_wx.c
@@ -135,11 +135,15 @@ ieee80211softmac_wx_set_rate(struct net_device *net_dev,
135 int err = -EINVAL; 135 int err = -EINVAL;
136 136
137 if (in_rate == -1) { 137 if (in_rate == -1) {
138 /* automatic detect */ 138 /* FIXME: We don't correctly handle backing down to lower
139 if (ieee->modulation & IEEE80211_OFDM_MODULATION) 139 rates, so 801.11g devices start off at 11M for now. People
140 in_rate = 54000000; 140 can manually change it if they really need to, but 11M is
141 else 141 more reliable. Note similar logic in
142 ieee80211softmac_wx_set_rate() */
143 if (ieee->modulation & IEEE80211_CCK_MODULATION)
142 in_rate = 11000000; 144 in_rate = 11000000;
145 else
146 in_rate = 54000000;
143 } 147 }
144 148
145 switch (in_rate) { 149 switch (in_rate) {
diff --git a/net/ipv4/Kconfig b/net/ipv4/Kconfig
index 011cca7ae02b..e40f75322377 100644
--- a/net/ipv4/Kconfig
+++ b/net/ipv4/Kconfig
@@ -235,6 +235,7 @@ config IP_PNP_RARP
235# bool ' IP: ARP support' CONFIG_IP_PNP_ARP 235# bool ' IP: ARP support' CONFIG_IP_PNP_ARP
236config NET_IPIP 236config NET_IPIP
237 tristate "IP: tunneling" 237 tristate "IP: tunneling"
238 select INET_TUNNEL
238 ---help--- 239 ---help---
239 Tunneling means encapsulating data of one protocol type within 240 Tunneling means encapsulating data of one protocol type within
240 another protocol and sending it over a channel that understands the 241 another protocol and sending it over a channel that understands the
@@ -395,7 +396,7 @@ config INET_ESP
395config INET_IPCOMP 396config INET_IPCOMP
396 tristate "IP: IPComp transformation" 397 tristate "IP: IPComp transformation"
397 select XFRM 398 select XFRM
398 select INET_TUNNEL 399 select INET_XFRM_TUNNEL
399 select CRYPTO 400 select CRYPTO
400 select CRYPTO_DEFLATE 401 select CRYPTO_DEFLATE
401 ---help--- 402 ---help---
@@ -404,14 +405,14 @@ config INET_IPCOMP
404 405
405 If unsure, say Y. 406 If unsure, say Y.
406 407
408config INET_XFRM_TUNNEL
409 tristate
410 select INET_TUNNEL
411 default n
412
407config INET_TUNNEL 413config INET_TUNNEL
408 tristate "IP: tunnel transformation" 414 tristate
409 select XFRM 415 default n
410 ---help---
411 Support for generic IP tunnel transformation, which is required by
412 the IP tunneling module as well as tunnel mode IPComp.
413
414 If unsure, say Y.
415 416
416config INET_DIAG 417config INET_DIAG
417 tristate "INET: socket monitoring interface" 418 tristate "INET: socket monitoring interface"
diff --git a/net/ipv4/Makefile b/net/ipv4/Makefile
index 35e5f5999092..9ef50a0b9d2c 100644
--- a/net/ipv4/Makefile
+++ b/net/ipv4/Makefile
@@ -22,7 +22,8 @@ obj-$(CONFIG_SYN_COOKIES) += syncookies.o
22obj-$(CONFIG_INET_AH) += ah4.o 22obj-$(CONFIG_INET_AH) += ah4.o
23obj-$(CONFIG_INET_ESP) += esp4.o 23obj-$(CONFIG_INET_ESP) += esp4.o
24obj-$(CONFIG_INET_IPCOMP) += ipcomp.o 24obj-$(CONFIG_INET_IPCOMP) += ipcomp.o
25obj-$(CONFIG_INET_TUNNEL) += xfrm4_tunnel.o 25obj-$(CONFIG_INET_XFRM_TUNNEL) += xfrm4_tunnel.o
26obj-$(CONFIG_INET_TUNNEL) += tunnel4.o
26obj-$(CONFIG_IP_PNP) += ipconfig.o 27obj-$(CONFIG_IP_PNP) += ipconfig.o
27obj-$(CONFIG_IP_ROUTE_MULTIPATH_RR) += multipath_rr.o 28obj-$(CONFIG_IP_ROUTE_MULTIPATH_RR) += multipath_rr.o
28obj-$(CONFIG_IP_ROUTE_MULTIPATH_RANDOM) += multipath_random.o 29obj-$(CONFIG_IP_ROUTE_MULTIPATH_RANDOM) += multipath_random.o
diff --git a/net/ipv4/ipip.c b/net/ipv4/ipip.c
index 03d13742a4b8..eef07b0916a3 100644
--- a/net/ipv4/ipip.c
+++ b/net/ipv4/ipip.c
@@ -114,7 +114,6 @@
114#include <net/sock.h> 114#include <net/sock.h>
115#include <net/ip.h> 115#include <net/ip.h>
116#include <net/icmp.h> 116#include <net/icmp.h>
117#include <net/protocol.h>
118#include <net/ipip.h> 117#include <net/ipip.h>
119#include <net/inet_ecn.h> 118#include <net/inet_ecn.h>
120#include <net/xfrm.h> 119#include <net/xfrm.h>
@@ -274,7 +273,7 @@ static void ipip_tunnel_uninit(struct net_device *dev)
274 dev_put(dev); 273 dev_put(dev);
275} 274}
276 275
277static void ipip_err(struct sk_buff *skb, u32 info) 276static int ipip_err(struct sk_buff *skb, u32 info)
278{ 277{
279#ifndef I_WISH_WORLD_WERE_PERFECT 278#ifndef I_WISH_WORLD_WERE_PERFECT
280 279
@@ -286,21 +285,22 @@ static void ipip_err(struct sk_buff *skb, u32 info)
286 int type = skb->h.icmph->type; 285 int type = skb->h.icmph->type;
287 int code = skb->h.icmph->code; 286 int code = skb->h.icmph->code;
288 struct ip_tunnel *t; 287 struct ip_tunnel *t;
288 int err;
289 289
290 switch (type) { 290 switch (type) {
291 default: 291 default:
292 case ICMP_PARAMETERPROB: 292 case ICMP_PARAMETERPROB:
293 return; 293 return 0;
294 294
295 case ICMP_DEST_UNREACH: 295 case ICMP_DEST_UNREACH:
296 switch (code) { 296 switch (code) {
297 case ICMP_SR_FAILED: 297 case ICMP_SR_FAILED:
298 case ICMP_PORT_UNREACH: 298 case ICMP_PORT_UNREACH:
299 /* Impossible event. */ 299 /* Impossible event. */
300 return; 300 return 0;
301 case ICMP_FRAG_NEEDED: 301 case ICMP_FRAG_NEEDED:
302 /* Soft state for pmtu is maintained by IP core. */ 302 /* Soft state for pmtu is maintained by IP core. */
303 return; 303 return 0;
304 default: 304 default:
305 /* All others are translated to HOST_UNREACH. 305 /* All others are translated to HOST_UNREACH.
306 rfc2003 contains "deep thoughts" about NET_UNREACH, 306 rfc2003 contains "deep thoughts" about NET_UNREACH,
@@ -311,14 +311,18 @@ static void ipip_err(struct sk_buff *skb, u32 info)
311 break; 311 break;
312 case ICMP_TIME_EXCEEDED: 312 case ICMP_TIME_EXCEEDED:
313 if (code != ICMP_EXC_TTL) 313 if (code != ICMP_EXC_TTL)
314 return; 314 return 0;
315 break; 315 break;
316 } 316 }
317 317
318 err = -ENOENT;
319
318 read_lock(&ipip_lock); 320 read_lock(&ipip_lock);
319 t = ipip_tunnel_lookup(iph->daddr, iph->saddr); 321 t = ipip_tunnel_lookup(iph->daddr, iph->saddr);
320 if (t == NULL || t->parms.iph.daddr == 0) 322 if (t == NULL || t->parms.iph.daddr == 0)
321 goto out; 323 goto out;
324
325 err = 0;
322 if (t->parms.iph.ttl == 0 && type == ICMP_TIME_EXCEEDED) 326 if (t->parms.iph.ttl == 0 && type == ICMP_TIME_EXCEEDED)
323 goto out; 327 goto out;
324 328
@@ -329,7 +333,7 @@ static void ipip_err(struct sk_buff *skb, u32 info)
329 t->err_time = jiffies; 333 t->err_time = jiffies;
330out: 334out:
331 read_unlock(&ipip_lock); 335 read_unlock(&ipip_lock);
332 return; 336 return err;
333#else 337#else
334 struct iphdr *iph = (struct iphdr*)dp; 338 struct iphdr *iph = (struct iphdr*)dp;
335 int hlen = iph->ihl<<2; 339 int hlen = iph->ihl<<2;
@@ -344,15 +348,15 @@ out:
344 struct rtable *rt; 348 struct rtable *rt;
345 349
346 if (len < hlen + sizeof(struct iphdr)) 350 if (len < hlen + sizeof(struct iphdr))
347 return; 351 return 0;
348 eiph = (struct iphdr*)(dp + hlen); 352 eiph = (struct iphdr*)(dp + hlen);
349 353
350 switch (type) { 354 switch (type) {
351 default: 355 default:
352 return; 356 return 0;
353 case ICMP_PARAMETERPROB: 357 case ICMP_PARAMETERPROB:
354 if (skb->h.icmph->un.gateway < hlen) 358 if (skb->h.icmph->un.gateway < hlen)
355 return; 359 return 0;
356 360
357 /* So... This guy found something strange INSIDE encapsulated 361 /* So... This guy found something strange INSIDE encapsulated
358 packet. Well, he is fool, but what can we do ? 362 packet. Well, he is fool, but what can we do ?
@@ -366,16 +370,16 @@ out:
366 case ICMP_SR_FAILED: 370 case ICMP_SR_FAILED:
367 case ICMP_PORT_UNREACH: 371 case ICMP_PORT_UNREACH:
368 /* Impossible event. */ 372 /* Impossible event. */
369 return; 373 return 0;
370 case ICMP_FRAG_NEEDED: 374 case ICMP_FRAG_NEEDED:
371 /* And it is the only really necessary thing :-) */ 375 /* And it is the only really necessary thing :-) */
372 rel_info = ntohs(skb->h.icmph->un.frag.mtu); 376 rel_info = ntohs(skb->h.icmph->un.frag.mtu);
373 if (rel_info < hlen+68) 377 if (rel_info < hlen+68)
374 return; 378 return 0;
375 rel_info -= hlen; 379 rel_info -= hlen;
376 /* BSD 4.2 MORE DOES NOT EXIST IN NATURE. */ 380 /* BSD 4.2 MORE DOES NOT EXIST IN NATURE. */
377 if (rel_info > ntohs(eiph->tot_len)) 381 if (rel_info > ntohs(eiph->tot_len))
378 return; 382 return 0;
379 break; 383 break;
380 default: 384 default:
381 /* All others are translated to HOST_UNREACH. 385 /* All others are translated to HOST_UNREACH.
@@ -389,14 +393,14 @@ out:
389 break; 393 break;
390 case ICMP_TIME_EXCEEDED: 394 case ICMP_TIME_EXCEEDED:
391 if (code != ICMP_EXC_TTL) 395 if (code != ICMP_EXC_TTL)
392 return; 396 return 0;
393 break; 397 break;
394 } 398 }
395 399
396 /* Prepare fake skb to feed it to icmp_send */ 400 /* Prepare fake skb to feed it to icmp_send */
397 skb2 = skb_clone(skb, GFP_ATOMIC); 401 skb2 = skb_clone(skb, GFP_ATOMIC);
398 if (skb2 == NULL) 402 if (skb2 == NULL)
399 return; 403 return 0;
400 dst_release(skb2->dst); 404 dst_release(skb2->dst);
401 skb2->dst = NULL; 405 skb2->dst = NULL;
402 skb_pull(skb2, skb->data - (u8*)eiph); 406 skb_pull(skb2, skb->data - (u8*)eiph);
@@ -409,7 +413,7 @@ out:
409 fl.proto = IPPROTO_IPIP; 413 fl.proto = IPPROTO_IPIP;
410 if (ip_route_output_key(&rt, &key)) { 414 if (ip_route_output_key(&rt, &key)) {
411 kfree_skb(skb2); 415 kfree_skb(skb2);
412 return; 416 return 0;
413 } 417 }
414 skb2->dev = rt->u.dst.dev; 418 skb2->dev = rt->u.dst.dev;
415 419
@@ -424,14 +428,14 @@ out:
424 rt->u.dst.dev->type != ARPHRD_TUNNEL) { 428 rt->u.dst.dev->type != ARPHRD_TUNNEL) {
425 ip_rt_put(rt); 429 ip_rt_put(rt);
426 kfree_skb(skb2); 430 kfree_skb(skb2);
427 return; 431 return 0;
428 } 432 }
429 } else { 433 } else {
430 ip_rt_put(rt); 434 ip_rt_put(rt);
431 if (ip_route_input(skb2, eiph->daddr, eiph->saddr, eiph->tos, skb2->dev) || 435 if (ip_route_input(skb2, eiph->daddr, eiph->saddr, eiph->tos, skb2->dev) ||
432 skb2->dst->dev->type != ARPHRD_TUNNEL) { 436 skb2->dst->dev->type != ARPHRD_TUNNEL) {
433 kfree_skb(skb2); 437 kfree_skb(skb2);
434 return; 438 return 0;
435 } 439 }
436 } 440 }
437 441
@@ -439,7 +443,7 @@ out:
439 if (type == ICMP_DEST_UNREACH && code == ICMP_FRAG_NEEDED) { 443 if (type == ICMP_DEST_UNREACH && code == ICMP_FRAG_NEEDED) {
440 if (rel_info > dst_mtu(skb2->dst)) { 444 if (rel_info > dst_mtu(skb2->dst)) {
441 kfree_skb(skb2); 445 kfree_skb(skb2);
442 return; 446 return 0;
443 } 447 }
444 skb2->dst->ops->update_pmtu(skb2->dst, rel_info); 448 skb2->dst->ops->update_pmtu(skb2->dst, rel_info);
445 rel_info = htonl(rel_info); 449 rel_info = htonl(rel_info);
@@ -453,7 +457,7 @@ out:
453 457
454 icmp_send(skb2, rel_type, rel_code, rel_info); 458 icmp_send(skb2, rel_type, rel_code, rel_info);
455 kfree_skb(skb2); 459 kfree_skb(skb2);
456 return; 460 return 0;
457#endif 461#endif
458} 462}
459 463
@@ -855,39 +859,12 @@ static int __init ipip_fb_tunnel_init(struct net_device *dev)
855 return 0; 859 return 0;
856} 860}
857 861
858#ifdef CONFIG_INET_TUNNEL
859static struct xfrm_tunnel ipip_handler = { 862static struct xfrm_tunnel ipip_handler = {
860 .handler = ipip_rcv, 863 .handler = ipip_rcv,
861 .err_handler = ipip_err, 864 .err_handler = ipip_err,
865 .priority = 1,
862}; 866};
863 867
864static inline int ipip_register(void)
865{
866 return xfrm4_tunnel_register(&ipip_handler);
867}
868
869static inline int ipip_unregister(void)
870{
871 return xfrm4_tunnel_deregister(&ipip_handler);
872}
873#else
874static struct net_protocol ipip_protocol = {
875 .handler = ipip_rcv,
876 .err_handler = ipip_err,
877 .no_policy = 1,
878};
879
880static inline int ipip_register(void)
881{
882 return inet_add_protocol(&ipip_protocol, IPPROTO_IPIP);
883}
884
885static inline int ipip_unregister(void)
886{
887 return inet_del_protocol(&ipip_protocol, IPPROTO_IPIP);
888}
889#endif
890
891static char banner[] __initdata = 868static char banner[] __initdata =
892 KERN_INFO "IPv4 over IPv4 tunneling driver\n"; 869 KERN_INFO "IPv4 over IPv4 tunneling driver\n";
893 870
@@ -897,7 +874,7 @@ static int __init ipip_init(void)
897 874
898 printk(banner); 875 printk(banner);
899 876
900 if (ipip_register() < 0) { 877 if (xfrm4_tunnel_register(&ipip_handler)) {
901 printk(KERN_INFO "ipip init: can't register tunnel\n"); 878 printk(KERN_INFO "ipip init: can't register tunnel\n");
902 return -EAGAIN; 879 return -EAGAIN;
903 } 880 }
@@ -919,7 +896,7 @@ static int __init ipip_init(void)
919 err2: 896 err2:
920 free_netdev(ipip_fb_tunnel_dev); 897 free_netdev(ipip_fb_tunnel_dev);
921 err1: 898 err1:
922 ipip_unregister(); 899 xfrm4_tunnel_deregister(&ipip_handler);
923 goto out; 900 goto out;
924} 901}
925 902
@@ -939,7 +916,7 @@ static void __exit ipip_destroy_tunnels(void)
939 916
940static void __exit ipip_fini(void) 917static void __exit ipip_fini(void)
941{ 918{
942 if (ipip_unregister() < 0) 919 if (xfrm4_tunnel_deregister(&ipip_handler))
943 printk(KERN_INFO "ipip close: can't deregister tunnel\n"); 920 printk(KERN_INFO "ipip close: can't deregister tunnel\n");
944 921
945 rtnl_lock(); 922 rtnl_lock();
diff --git a/net/ipv4/netfilter.c b/net/ipv4/netfilter.c
index ed42cdc57cd9..b5ad9ac2fbcc 100644
--- a/net/ipv4/netfilter.c
+++ b/net/ipv4/netfilter.c
@@ -167,15 +167,15 @@ static struct nf_queue_rerouter ip_reroute = {
167 .reroute = queue_reroute, 167 .reroute = queue_reroute,
168}; 168};
169 169
170static int init(void) 170static int ipv4_netfilter_init(void)
171{ 171{
172 return nf_register_queue_rerouter(PF_INET, &ip_reroute); 172 return nf_register_queue_rerouter(PF_INET, &ip_reroute);
173} 173}
174 174
175static void fini(void) 175static void ipv4_netfilter_fini(void)
176{ 176{
177 nf_unregister_queue_rerouter(PF_INET); 177 nf_unregister_queue_rerouter(PF_INET);
178} 178}
179 179
180module_init(init); 180module_init(ipv4_netfilter_init);
181module_exit(fini); 181module_exit(ipv4_netfilter_fini);
diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c
index ff0c594a4198..a44a5d73457d 100644
--- a/net/ipv4/netfilter/arp_tables.c
+++ b/net/ipv4/netfilter/arp_tables.c
@@ -1166,7 +1166,7 @@ static struct nf_sockopt_ops arpt_sockopts = {
1166 .get = do_arpt_get_ctl, 1166 .get = do_arpt_get_ctl,
1167}; 1167};
1168 1168
1169static int __init init(void) 1169static int __init arp_tables_init(void)
1170{ 1170{
1171 int ret; 1171 int ret;
1172 1172
@@ -1187,7 +1187,7 @@ static int __init init(void)
1187 return 0; 1187 return 0;
1188} 1188}
1189 1189
1190static void __exit fini(void) 1190static void __exit arp_tables_fini(void)
1191{ 1191{
1192 nf_unregister_sockopt(&arpt_sockopts); 1192 nf_unregister_sockopt(&arpt_sockopts);
1193 xt_proto_fini(NF_ARP); 1193 xt_proto_fini(NF_ARP);
@@ -1197,5 +1197,5 @@ EXPORT_SYMBOL(arpt_register_table);
1197EXPORT_SYMBOL(arpt_unregister_table); 1197EXPORT_SYMBOL(arpt_unregister_table);
1198EXPORT_SYMBOL(arpt_do_table); 1198EXPORT_SYMBOL(arpt_do_table);
1199 1199
1200module_init(init); 1200module_init(arp_tables_init);
1201module_exit(fini); 1201module_exit(arp_tables_fini);
diff --git a/net/ipv4/netfilter/arpt_mangle.c b/net/ipv4/netfilter/arpt_mangle.c
index 0f2a95350e26..a58325c1ceb9 100644
--- a/net/ipv4/netfilter/arpt_mangle.c
+++ b/net/ipv4/netfilter/arpt_mangle.c
@@ -89,7 +89,7 @@ static struct arpt_target arpt_mangle_reg = {
89 .me = THIS_MODULE, 89 .me = THIS_MODULE,
90}; 90};
91 91
92static int __init init(void) 92static int __init arpt_mangle_init(void)
93{ 93{
94 if (arpt_register_target(&arpt_mangle_reg)) 94 if (arpt_register_target(&arpt_mangle_reg))
95 return -EINVAL; 95 return -EINVAL;
@@ -97,10 +97,10 @@ static int __init init(void)
97 return 0; 97 return 0;
98} 98}
99 99
100static void __exit fini(void) 100static void __exit arpt_mangle_fini(void)
101{ 101{
102 arpt_unregister_target(&arpt_mangle_reg); 102 arpt_unregister_target(&arpt_mangle_reg);
103} 103}
104 104
105module_init(init); 105module_init(arpt_mangle_init);
106module_exit(fini); 106module_exit(arpt_mangle_fini);
diff --git a/net/ipv4/netfilter/arptable_filter.c b/net/ipv4/netfilter/arptable_filter.c
index f6ab45f48681..d0d379c7df9a 100644
--- a/net/ipv4/netfilter/arptable_filter.c
+++ b/net/ipv4/netfilter/arptable_filter.c
@@ -179,7 +179,7 @@ static struct nf_hook_ops arpt_ops[] = {
179 }, 179 },
180}; 180};
181 181
182static int __init init(void) 182static int __init arptable_filter_init(void)
183{ 183{
184 int ret, i; 184 int ret, i;
185 185
@@ -201,7 +201,7 @@ cleanup_hooks:
201 return ret; 201 return ret;
202} 202}
203 203
204static void __exit fini(void) 204static void __exit arptable_filter_fini(void)
205{ 205{
206 unsigned int i; 206 unsigned int i;
207 207
@@ -211,5 +211,5 @@ static void __exit fini(void)
211 arpt_unregister_table(&packet_filter); 211 arpt_unregister_table(&packet_filter);
212} 212}
213 213
214module_init(init); 214module_init(arptable_filter_init);
215module_exit(fini); 215module_exit(arptable_filter_fini);
diff --git a/net/ipv4/netfilter/ip_conntrack_amanda.c b/net/ipv4/netfilter/ip_conntrack_amanda.c
index 84e4f79b7ffa..a604b1ccfdaa 100644
--- a/net/ipv4/netfilter/ip_conntrack_amanda.c
+++ b/net/ipv4/netfilter/ip_conntrack_amanda.c
@@ -153,13 +153,13 @@ static struct ip_conntrack_helper amanda_helper = {
153 }, 153 },
154}; 154};
155 155
156static void __exit fini(void) 156static void __exit ip_conntrack_amanda_fini(void)
157{ 157{
158 ip_conntrack_helper_unregister(&amanda_helper); 158 ip_conntrack_helper_unregister(&amanda_helper);
159 kfree(amanda_buffer); 159 kfree(amanda_buffer);
160} 160}
161 161
162static int __init init(void) 162static int __init ip_conntrack_amanda_init(void)
163{ 163{
164 int ret; 164 int ret;
165 165
@@ -177,5 +177,5 @@ static int __init init(void)
177 177
178} 178}
179 179
180module_init(init); 180module_init(ip_conntrack_amanda_init);
181module_exit(fini); 181module_exit(ip_conntrack_amanda_fini);
diff --git a/net/ipv4/netfilter/ip_conntrack_ftp.c b/net/ipv4/netfilter/ip_conntrack_ftp.c
index e627e5856172..3e542bf28a9d 100644
--- a/net/ipv4/netfilter/ip_conntrack_ftp.c
+++ b/net/ipv4/netfilter/ip_conntrack_ftp.c
@@ -453,7 +453,7 @@ static struct ip_conntrack_helper ftp[MAX_PORTS];
453static char ftp_names[MAX_PORTS][sizeof("ftp-65535")]; 453static char ftp_names[MAX_PORTS][sizeof("ftp-65535")];
454 454
455/* Not __exit: called from init() */ 455/* Not __exit: called from init() */
456static void fini(void) 456static void ip_conntrack_ftp_fini(void)
457{ 457{
458 int i; 458 int i;
459 for (i = 0; i < ports_c; i++) { 459 for (i = 0; i < ports_c; i++) {
@@ -465,7 +465,7 @@ static void fini(void)
465 kfree(ftp_buffer); 465 kfree(ftp_buffer);
466} 466}
467 467
468static int __init init(void) 468static int __init ip_conntrack_ftp_init(void)
469{ 469{
470 int i, ret; 470 int i, ret;
471 char *tmpname; 471 char *tmpname;
@@ -499,12 +499,12 @@ static int __init init(void)
499 ret = ip_conntrack_helper_register(&ftp[i]); 499 ret = ip_conntrack_helper_register(&ftp[i]);
500 500
501 if (ret) { 501 if (ret) {
502 fini(); 502 ip_conntrack_ftp_fini();
503 return ret; 503 return ret;
504 } 504 }
505 } 505 }
506 return 0; 506 return 0;
507} 507}
508 508
509module_init(init); 509module_init(ip_conntrack_ftp_init);
510module_exit(fini); 510module_exit(ip_conntrack_ftp_fini);
diff --git a/net/ipv4/netfilter/ip_conntrack_helper_pptp.c b/net/ipv4/netfilter/ip_conntrack_helper_pptp.c
index d716bba798f2..7d3ba4302e9e 100644
--- a/net/ipv4/netfilter/ip_conntrack_helper_pptp.c
+++ b/net/ipv4/netfilter/ip_conntrack_helper_pptp.c
@@ -766,7 +766,7 @@ extern void ip_ct_proto_gre_fini(void);
766extern int __init ip_ct_proto_gre_init(void); 766extern int __init ip_ct_proto_gre_init(void);
767 767
768/* ip_conntrack_pptp initialization */ 768/* ip_conntrack_pptp initialization */
769static int __init init(void) 769static int __init ip_conntrack_helper_pptp_init(void)
770{ 770{
771 int retcode; 771 int retcode;
772 772
@@ -786,15 +786,15 @@ static int __init init(void)
786 return 0; 786 return 0;
787} 787}
788 788
789static void __exit fini(void) 789static void __exit ip_conntrack_helper_pptp_fini(void)
790{ 790{
791 ip_conntrack_helper_unregister(&pptp); 791 ip_conntrack_helper_unregister(&pptp);
792 ip_ct_proto_gre_fini(); 792 ip_ct_proto_gre_fini();
793 printk("ip_conntrack_pptp version %s unloaded\n", IP_CT_PPTP_VERSION); 793 printk("ip_conntrack_pptp version %s unloaded\n", IP_CT_PPTP_VERSION);
794} 794}
795 795
796module_init(init); 796module_init(ip_conntrack_helper_pptp_init);
797module_exit(fini); 797module_exit(ip_conntrack_helper_pptp_fini);
798 798
799EXPORT_SYMBOL(ip_nat_pptp_hook_outbound); 799EXPORT_SYMBOL(ip_nat_pptp_hook_outbound);
800EXPORT_SYMBOL(ip_nat_pptp_hook_inbound); 800EXPORT_SYMBOL(ip_nat_pptp_hook_inbound);
diff --git a/net/ipv4/netfilter/ip_conntrack_irc.c b/net/ipv4/netfilter/ip_conntrack_irc.c
index c51a2cf71b4b..a2ac5ce544b2 100644
--- a/net/ipv4/netfilter/ip_conntrack_irc.c
+++ b/net/ipv4/netfilter/ip_conntrack_irc.c
@@ -242,9 +242,9 @@ static int help(struct sk_buff **pskb,
242static struct ip_conntrack_helper irc_helpers[MAX_PORTS]; 242static struct ip_conntrack_helper irc_helpers[MAX_PORTS];
243static char irc_names[MAX_PORTS][sizeof("irc-65535")]; 243static char irc_names[MAX_PORTS][sizeof("irc-65535")];
244 244
245static void fini(void); 245static void ip_conntrack_irc_fini(void);
246 246
247static int __init init(void) 247static int __init ip_conntrack_irc_init(void)
248{ 248{
249 int i, ret; 249 int i, ret;
250 struct ip_conntrack_helper *hlpr; 250 struct ip_conntrack_helper *hlpr;
@@ -288,7 +288,7 @@ static int __init init(void)
288 if (ret) { 288 if (ret) {
289 printk("ip_conntrack_irc: ERROR registering port %d\n", 289 printk("ip_conntrack_irc: ERROR registering port %d\n",
290 ports[i]); 290 ports[i]);
291 fini(); 291 ip_conntrack_irc_fini();
292 return -EBUSY; 292 return -EBUSY;
293 } 293 }
294 } 294 }
@@ -297,7 +297,7 @@ static int __init init(void)
297 297
298/* This function is intentionally _NOT_ defined as __exit, because 298/* This function is intentionally _NOT_ defined as __exit, because
299 * it is needed by the init function */ 299 * it is needed by the init function */
300static void fini(void) 300static void ip_conntrack_irc_fini(void)
301{ 301{
302 int i; 302 int i;
303 for (i = 0; i < ports_c; i++) { 303 for (i = 0; i < ports_c; i++) {
@@ -308,5 +308,5 @@ static void fini(void)
308 kfree(irc_buffer); 308 kfree(irc_buffer);
309} 309}
310 310
311module_init(init); 311module_init(ip_conntrack_irc_init);
312module_exit(fini); 312module_exit(ip_conntrack_irc_fini);
diff --git a/net/ipv4/netfilter/ip_conntrack_netbios_ns.c b/net/ipv4/netfilter/ip_conntrack_netbios_ns.c
index 4e68e16a2612..a566a81325b2 100644
--- a/net/ipv4/netfilter/ip_conntrack_netbios_ns.c
+++ b/net/ipv4/netfilter/ip_conntrack_netbios_ns.c
@@ -127,16 +127,16 @@ static struct ip_conntrack_helper helper = {
127 .help = help, 127 .help = help,
128}; 128};
129 129
130static int __init init(void) 130static int __init ip_conntrack_netbios_ns_init(void)
131{ 131{
132 helper.timeout = timeout; 132 helper.timeout = timeout;
133 return ip_conntrack_helper_register(&helper); 133 return ip_conntrack_helper_register(&helper);
134} 134}
135 135
136static void __exit fini(void) 136static void __exit ip_conntrack_netbios_ns_fini(void)
137{ 137{
138 ip_conntrack_helper_unregister(&helper); 138 ip_conntrack_helper_unregister(&helper);
139} 139}
140 140
141module_init(init); 141module_init(ip_conntrack_netbios_ns_init);
142module_exit(fini); 142module_exit(ip_conntrack_netbios_ns_fini);
diff --git a/net/ipv4/netfilter/ip_conntrack_proto_sctp.c b/net/ipv4/netfilter/ip_conntrack_proto_sctp.c
index be602e8aeab0..5259abd0fb42 100644
--- a/net/ipv4/netfilter/ip_conntrack_proto_sctp.c
+++ b/net/ipv4/netfilter/ip_conntrack_proto_sctp.c
@@ -609,7 +609,7 @@ static ctl_table ip_ct_net_table[] = {
609static struct ctl_table_header *ip_ct_sysctl_header; 609static struct ctl_table_header *ip_ct_sysctl_header;
610#endif 610#endif
611 611
612static int __init init(void) 612static int __init ip_conntrack_proto_sctp_init(void)
613{ 613{
614 int ret; 614 int ret;
615 615
@@ -640,7 +640,7 @@ static int __init init(void)
640 return ret; 640 return ret;
641} 641}
642 642
643static void __exit fini(void) 643static void __exit ip_conntrack_proto_sctp_fini(void)
644{ 644{
645 ip_conntrack_protocol_unregister(&ip_conntrack_protocol_sctp); 645 ip_conntrack_protocol_unregister(&ip_conntrack_protocol_sctp);
646#ifdef CONFIG_SYSCTL 646#ifdef CONFIG_SYSCTL
@@ -649,8 +649,8 @@ static void __exit fini(void)
649 DEBUGP("SCTP conntrack module unloaded\n"); 649 DEBUGP("SCTP conntrack module unloaded\n");
650} 650}
651 651
652module_init(init); 652module_init(ip_conntrack_proto_sctp_init);
653module_exit(fini); 653module_exit(ip_conntrack_proto_sctp_fini);
654 654
655MODULE_LICENSE("GPL"); 655MODULE_LICENSE("GPL");
656MODULE_AUTHOR("Kiran Kumar Immidi"); 656MODULE_AUTHOR("Kiran Kumar Immidi");
diff --git a/net/ipv4/netfilter/ip_conntrack_standalone.c b/net/ipv4/netfilter/ip_conntrack_standalone.c
index 833fcb4be5e7..52076026db36 100644
--- a/net/ipv4/netfilter/ip_conntrack_standalone.c
+++ b/net/ipv4/netfilter/ip_conntrack_standalone.c
@@ -929,18 +929,18 @@ void ip_conntrack_protocol_unregister(struct ip_conntrack_protocol *proto)
929 ip_ct_iterate_cleanup(kill_proto, &proto->proto); 929 ip_ct_iterate_cleanup(kill_proto, &proto->proto);
930} 930}
931 931
932static int __init init(void) 932static int __init ip_conntrack_standalone_init(void)
933{ 933{
934 return init_or_cleanup(1); 934 return init_or_cleanup(1);
935} 935}
936 936
937static void __exit fini(void) 937static void __exit ip_conntrack_standalone_fini(void)
938{ 938{
939 init_or_cleanup(0); 939 init_or_cleanup(0);
940} 940}
941 941
942module_init(init); 942module_init(ip_conntrack_standalone_init);
943module_exit(fini); 943module_exit(ip_conntrack_standalone_fini);
944 944
945/* Some modules need us, but don't depend directly on any symbol. 945/* Some modules need us, but don't depend directly on any symbol.
946 They should call this. */ 946 They should call this. */
diff --git a/net/ipv4/netfilter/ip_conntrack_tftp.c b/net/ipv4/netfilter/ip_conntrack_tftp.c
index 4ba4463cec28..7e33d3bed5e3 100644
--- a/net/ipv4/netfilter/ip_conntrack_tftp.c
+++ b/net/ipv4/netfilter/ip_conntrack_tftp.c
@@ -103,7 +103,7 @@ static int tftp_help(struct sk_buff **pskb,
103static struct ip_conntrack_helper tftp[MAX_PORTS]; 103static struct ip_conntrack_helper tftp[MAX_PORTS];
104static char tftp_names[MAX_PORTS][sizeof("tftp-65535")]; 104static char tftp_names[MAX_PORTS][sizeof("tftp-65535")];
105 105
106static void fini(void) 106static void ip_conntrack_tftp_fini(void)
107{ 107{
108 int i; 108 int i;
109 109
@@ -114,7 +114,7 @@ static void fini(void)
114 } 114 }
115} 115}
116 116
117static int __init init(void) 117static int __init ip_conntrack_tftp_init(void)
118{ 118{
119 int i, ret; 119 int i, ret;
120 char *tmpname; 120 char *tmpname;
@@ -148,12 +148,12 @@ static int __init init(void)
148 if (ret) { 148 if (ret) {
149 printk("ERROR registering helper for port %d\n", 149 printk("ERROR registering helper for port %d\n",
150 ports[i]); 150 ports[i]);
151 fini(); 151 ip_conntrack_tftp_fini();
152 return(ret); 152 return(ret);
153 } 153 }
154 } 154 }
155 return(0); 155 return(0);
156} 156}
157 157
158module_init(init); 158module_init(ip_conntrack_tftp_init);
159module_exit(fini); 159module_exit(ip_conntrack_tftp_fini);
diff --git a/net/ipv4/netfilter/ip_nat_amanda.c b/net/ipv4/netfilter/ip_nat_amanda.c
index 706c8074f422..3a888715bbf3 100644
--- a/net/ipv4/netfilter/ip_nat_amanda.c
+++ b/net/ipv4/netfilter/ip_nat_amanda.c
@@ -68,19 +68,19 @@ static unsigned int help(struct sk_buff **pskb,
68 return ret; 68 return ret;
69} 69}
70 70
71static void __exit fini(void) 71static void __exit ip_nat_amanda_fini(void)
72{ 72{
73 ip_nat_amanda_hook = NULL; 73 ip_nat_amanda_hook = NULL;
74 /* Make sure noone calls it, meanwhile. */ 74 /* Make sure noone calls it, meanwhile. */
75 synchronize_net(); 75 synchronize_net();
76} 76}
77 77
78static int __init init(void) 78static int __init ip_nat_amanda_init(void)
79{ 79{
80 BUG_ON(ip_nat_amanda_hook); 80 BUG_ON(ip_nat_amanda_hook);
81 ip_nat_amanda_hook = help; 81 ip_nat_amanda_hook = help;
82 return 0; 82 return 0;
83} 83}
84 84
85module_init(init); 85module_init(ip_nat_amanda_init);
86module_exit(fini); 86module_exit(ip_nat_amanda_fini);
diff --git a/net/ipv4/netfilter/ip_nat_ftp.c b/net/ipv4/netfilter/ip_nat_ftp.c
index b8daab3c64af..3328fc5c5f50 100644
--- a/net/ipv4/netfilter/ip_nat_ftp.c
+++ b/net/ipv4/netfilter/ip_nat_ftp.c
@@ -154,14 +154,14 @@ static unsigned int ip_nat_ftp(struct sk_buff **pskb,
154 return NF_ACCEPT; 154 return NF_ACCEPT;
155} 155}
156 156
157static void __exit fini(void) 157static void __exit ip_nat_ftp_fini(void)
158{ 158{
159 ip_nat_ftp_hook = NULL; 159 ip_nat_ftp_hook = NULL;
160 /* Make sure noone calls it, meanwhile. */ 160 /* Make sure noone calls it, meanwhile. */
161 synchronize_net(); 161 synchronize_net();
162} 162}
163 163
164static int __init init(void) 164static int __init ip_nat_ftp_init(void)
165{ 165{
166 BUG_ON(ip_nat_ftp_hook); 166 BUG_ON(ip_nat_ftp_hook);
167 ip_nat_ftp_hook = ip_nat_ftp; 167 ip_nat_ftp_hook = ip_nat_ftp;
@@ -177,5 +177,5 @@ static int warn_set(const char *val, struct kernel_param *kp)
177} 177}
178module_param_call(ports, warn_set, NULL, NULL, 0); 178module_param_call(ports, warn_set, NULL, NULL, 0);
179 179
180module_init(init); 180module_init(ip_nat_ftp_init);
181module_exit(fini); 181module_exit(ip_nat_ftp_fini);
diff --git a/net/ipv4/netfilter/ip_nat_helper_pptp.c b/net/ipv4/netfilter/ip_nat_helper_pptp.c
index b9c016c063b8..f3977726ff09 100644
--- a/net/ipv4/netfilter/ip_nat_helper_pptp.c
+++ b/net/ipv4/netfilter/ip_nat_helper_pptp.c
@@ -370,7 +370,7 @@ pptp_inbound_pkt(struct sk_buff **pskb,
370extern int __init ip_nat_proto_gre_init(void); 370extern int __init ip_nat_proto_gre_init(void);
371extern void __exit ip_nat_proto_gre_fini(void); 371extern void __exit ip_nat_proto_gre_fini(void);
372 372
373static int __init init(void) 373static int __init ip_nat_helper_pptp_init(void)
374{ 374{
375 int ret; 375 int ret;
376 376
@@ -396,7 +396,7 @@ static int __init init(void)
396 return 0; 396 return 0;
397} 397}
398 398
399static void __exit fini(void) 399static void __exit ip_nat_helper_pptp_fini(void)
400{ 400{
401 DEBUGP("cleanup_module\n" ); 401 DEBUGP("cleanup_module\n" );
402 402
@@ -412,5 +412,5 @@ static void __exit fini(void)
412 printk("ip_nat_pptp version %s unloaded\n", IP_NAT_PPTP_VERSION); 412 printk("ip_nat_pptp version %s unloaded\n", IP_NAT_PPTP_VERSION);
413} 413}
414 414
415module_init(init); 415module_init(ip_nat_helper_pptp_init);
416module_exit(fini); 416module_exit(ip_nat_helper_pptp_fini);
diff --git a/net/ipv4/netfilter/ip_nat_irc.c b/net/ipv4/netfilter/ip_nat_irc.c
index 461c833eaca1..a767123e082c 100644
--- a/net/ipv4/netfilter/ip_nat_irc.c
+++ b/net/ipv4/netfilter/ip_nat_irc.c
@@ -96,14 +96,14 @@ static unsigned int help(struct sk_buff **pskb,
96 return ret; 96 return ret;
97} 97}
98 98
99static void __exit fini(void) 99static void __exit ip_nat_irc_fini(void)
100{ 100{
101 ip_nat_irc_hook = NULL; 101 ip_nat_irc_hook = NULL;
102 /* Make sure noone calls it, meanwhile. */ 102 /* Make sure noone calls it, meanwhile. */
103 synchronize_net(); 103 synchronize_net();
104} 104}
105 105
106static int __init init(void) 106static int __init ip_nat_irc_init(void)
107{ 107{
108 BUG_ON(ip_nat_irc_hook); 108 BUG_ON(ip_nat_irc_hook);
109 ip_nat_irc_hook = help; 109 ip_nat_irc_hook = help;
@@ -119,5 +119,5 @@ static int warn_set(const char *val, struct kernel_param *kp)
119} 119}
120module_param_call(ports, warn_set, NULL, NULL, 0); 120module_param_call(ports, warn_set, NULL, NULL, 0);
121 121
122module_init(init); 122module_init(ip_nat_irc_init);
123module_exit(fini); 123module_exit(ip_nat_irc_fini);
diff --git a/net/ipv4/netfilter/ip_nat_snmp_basic.c b/net/ipv4/netfilter/ip_nat_snmp_basic.c
index f029da2a60ee..c62253845538 100644
--- a/net/ipv4/netfilter/ip_nat_snmp_basic.c
+++ b/net/ipv4/netfilter/ip_nat_snmp_basic.c
@@ -1324,7 +1324,7 @@ static struct ip_conntrack_helper snmp_trap_helper = {
1324 * 1324 *
1325 *****************************************************************************/ 1325 *****************************************************************************/
1326 1326
1327static int __init init(void) 1327static int __init ip_nat_snmp_basic_init(void)
1328{ 1328{
1329 int ret = 0; 1329 int ret = 0;
1330 1330
@@ -1339,13 +1339,13 @@ static int __init init(void)
1339 return ret; 1339 return ret;
1340} 1340}
1341 1341
1342static void __exit fini(void) 1342static void __exit ip_nat_snmp_basic_fini(void)
1343{ 1343{
1344 ip_conntrack_helper_unregister(&snmp_helper); 1344 ip_conntrack_helper_unregister(&snmp_helper);
1345 ip_conntrack_helper_unregister(&snmp_trap_helper); 1345 ip_conntrack_helper_unregister(&snmp_trap_helper);
1346} 1346}
1347 1347
1348module_init(init); 1348module_init(ip_nat_snmp_basic_init);
1349module_exit(fini); 1349module_exit(ip_nat_snmp_basic_fini);
1350 1350
1351module_param(debug, bool, 0600); 1351module_param(debug, bool, 0600);
diff --git a/net/ipv4/netfilter/ip_nat_standalone.c b/net/ipv4/netfilter/ip_nat_standalone.c
index 380aef3d7865..3505b0de2e04 100644
--- a/net/ipv4/netfilter/ip_nat_standalone.c
+++ b/net/ipv4/netfilter/ip_nat_standalone.c
@@ -425,17 +425,17 @@ static int init_or_cleanup(int init)
425 return ret; 425 return ret;
426} 426}
427 427
428static int __init init(void) 428static int __init ip_nat_standalone_init(void)
429{ 429{
430 return init_or_cleanup(1); 430 return init_or_cleanup(1);
431} 431}
432 432
433static void __exit fini(void) 433static void __exit ip_nat_standalone_fini(void)
434{ 434{
435 init_or_cleanup(0); 435 init_or_cleanup(0);
436} 436}
437 437
438module_init(init); 438module_init(ip_nat_standalone_init);
439module_exit(fini); 439module_exit(ip_nat_standalone_fini);
440 440
441MODULE_LICENSE("GPL"); 441MODULE_LICENSE("GPL");
diff --git a/net/ipv4/netfilter/ip_nat_tftp.c b/net/ipv4/netfilter/ip_nat_tftp.c
index 43c3bd7c118e..94a78015451c 100644
--- a/net/ipv4/netfilter/ip_nat_tftp.c
+++ b/net/ipv4/netfilter/ip_nat_tftp.c
@@ -53,19 +53,19 @@ static unsigned int help(struct sk_buff **pskb,
53 return NF_ACCEPT; 53 return NF_ACCEPT;
54} 54}
55 55
56static void __exit fini(void) 56static void __exit ip_nat_tftp_fini(void)
57{ 57{
58 ip_nat_tftp_hook = NULL; 58 ip_nat_tftp_hook = NULL;
59 /* Make sure noone calls it, meanwhile. */ 59 /* Make sure noone calls it, meanwhile. */
60 synchronize_net(); 60 synchronize_net();
61} 61}
62 62
63static int __init init(void) 63static int __init ip_nat_tftp_init(void)
64{ 64{
65 BUG_ON(ip_nat_tftp_hook); 65 BUG_ON(ip_nat_tftp_hook);
66 ip_nat_tftp_hook = help; 66 ip_nat_tftp_hook = help;
67 return 0; 67 return 0;
68} 68}
69 69
70module_init(init); 70module_init(ip_nat_tftp_init);
71module_exit(fini); 71module_exit(ip_nat_tftp_fini);
diff --git a/net/ipv4/netfilter/ip_queue.c b/net/ipv4/netfilter/ip_queue.c
index 1655866c55b9..896a244f8f91 100644
--- a/net/ipv4/netfilter/ip_queue.c
+++ b/net/ipv4/netfilter/ip_queue.c
@@ -717,13 +717,13 @@ cleanup_netlink_notifier:
717 return status; 717 return status;
718} 718}
719 719
720static int __init init(void) 720static int __init ip_queue_init(void)
721{ 721{
722 722
723 return init_or_cleanup(1); 723 return init_or_cleanup(1);
724} 724}
725 725
726static void __exit fini(void) 726static void __exit ip_queue_fini(void)
727{ 727{
728 init_or_cleanup(0); 728 init_or_cleanup(0);
729} 729}
@@ -732,5 +732,5 @@ MODULE_DESCRIPTION("IPv4 packet queue handler");
732MODULE_AUTHOR("James Morris <jmorris@intercode.com.au>"); 732MODULE_AUTHOR("James Morris <jmorris@intercode.com.au>");
733MODULE_LICENSE("GPL"); 733MODULE_LICENSE("GPL");
734 734
735module_init(init); 735module_init(ip_queue_init);
736module_exit(fini); 736module_exit(ip_queue_fini);
diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c
index a7b194c4d79d..460fd905fad0 100644
--- a/net/ipv4/netfilter/ip_tables.c
+++ b/net/ipv4/netfilter/ip_tables.c
@@ -1364,7 +1364,7 @@ static struct ipt_match icmp_matchstruct = {
1364 .checkentry = icmp_checkentry, 1364 .checkentry = icmp_checkentry,
1365}; 1365};
1366 1366
1367static int __init init(void) 1367static int __init ip_tables_init(void)
1368{ 1368{
1369 int ret; 1369 int ret;
1370 1370
@@ -1386,7 +1386,7 @@ static int __init init(void)
1386 return 0; 1386 return 0;
1387} 1387}
1388 1388
1389static void __exit fini(void) 1389static void __exit ip_tables_fini(void)
1390{ 1390{
1391 nf_unregister_sockopt(&ipt_sockopts); 1391 nf_unregister_sockopt(&ipt_sockopts);
1392 1392
@@ -1400,5 +1400,5 @@ static void __exit fini(void)
1400EXPORT_SYMBOL(ipt_register_table); 1400EXPORT_SYMBOL(ipt_register_table);
1401EXPORT_SYMBOL(ipt_unregister_table); 1401EXPORT_SYMBOL(ipt_unregister_table);
1402EXPORT_SYMBOL(ipt_do_table); 1402EXPORT_SYMBOL(ipt_do_table);
1403module_init(init); 1403module_init(ip_tables_init);
1404module_exit(fini); 1404module_exit(ip_tables_fini);
diff --git a/net/ipv4/netfilter/ipt_CLUSTERIP.c b/net/ipv4/netfilter/ipt_CLUSTERIP.c
index 61e11edcd6af..e4768a31718b 100644
--- a/net/ipv4/netfilter/ipt_CLUSTERIP.c
+++ b/net/ipv4/netfilter/ipt_CLUSTERIP.c
@@ -770,15 +770,15 @@ cleanup_none:
770 return -EINVAL; 770 return -EINVAL;
771} 771}
772 772
773static int __init init(void) 773static int __init ipt_clusterip_init(void)
774{ 774{
775 return init_or_cleanup(0); 775 return init_or_cleanup(0);
776} 776}
777 777
778static void __exit fini(void) 778static void __exit ipt_clusterip_fini(void)
779{ 779{
780 init_or_cleanup(1); 780 init_or_cleanup(1);
781} 781}
782 782
783module_init(init); 783module_init(ipt_clusterip_init);
784module_exit(fini); 784module_exit(ipt_clusterip_fini);
diff --git a/net/ipv4/netfilter/ipt_DSCP.c b/net/ipv4/netfilter/ipt_DSCP.c
index cfb0b90e598a..c8e971288dfe 100644
--- a/net/ipv4/netfilter/ipt_DSCP.c
+++ b/net/ipv4/netfilter/ipt_DSCP.c
@@ -82,15 +82,15 @@ static struct ipt_target ipt_dscp_reg = {
82 .me = THIS_MODULE, 82 .me = THIS_MODULE,
83}; 83};
84 84
85static int __init init(void) 85static int __init ipt_dscp_init(void)
86{ 86{
87 return ipt_register_target(&ipt_dscp_reg); 87 return ipt_register_target(&ipt_dscp_reg);
88} 88}
89 89
90static void __exit fini(void) 90static void __exit ipt_dscp_fini(void)
91{ 91{
92 ipt_unregister_target(&ipt_dscp_reg); 92 ipt_unregister_target(&ipt_dscp_reg);
93} 93}
94 94
95module_init(init); 95module_init(ipt_dscp_init);
96module_exit(fini); 96module_exit(ipt_dscp_fini);
diff --git a/net/ipv4/netfilter/ipt_ECN.c b/net/ipv4/netfilter/ipt_ECN.c
index b9b80f90c84e..4adf5c9d34f5 100644
--- a/net/ipv4/netfilter/ipt_ECN.c
+++ b/net/ipv4/netfilter/ipt_ECN.c
@@ -151,15 +151,15 @@ static struct ipt_target ipt_ecn_reg = {
151 .me = THIS_MODULE, 151 .me = THIS_MODULE,
152}; 152};
153 153
154static int __init init(void) 154static int __init ipt_ecn_init(void)
155{ 155{
156 return ipt_register_target(&ipt_ecn_reg); 156 return ipt_register_target(&ipt_ecn_reg);
157} 157}
158 158
159static void __exit fini(void) 159static void __exit ipt_ecn_fini(void)
160{ 160{
161 ipt_unregister_target(&ipt_ecn_reg); 161 ipt_unregister_target(&ipt_ecn_reg);
162} 162}
163 163
164module_init(init); 164module_init(ipt_ecn_init);
165module_exit(fini); 165module_exit(ipt_ecn_fini);
diff --git a/net/ipv4/netfilter/ipt_LOG.c b/net/ipv4/netfilter/ipt_LOG.c
index 750d3221b280..39fd4c2a2386 100644
--- a/net/ipv4/netfilter/ipt_LOG.c
+++ b/net/ipv4/netfilter/ipt_LOG.c
@@ -471,7 +471,7 @@ static struct nf_logger ipt_log_logger ={
471 .me = THIS_MODULE, 471 .me = THIS_MODULE,
472}; 472};
473 473
474static int __init init(void) 474static int __init ipt_log_init(void)
475{ 475{
476 if (ipt_register_target(&ipt_log_reg)) 476 if (ipt_register_target(&ipt_log_reg))
477 return -EINVAL; 477 return -EINVAL;
@@ -485,11 +485,11 @@ static int __init init(void)
485 return 0; 485 return 0;
486} 486}
487 487
488static void __exit fini(void) 488static void __exit ipt_log_fini(void)
489{ 489{
490 nf_log_unregister_logger(&ipt_log_logger); 490 nf_log_unregister_logger(&ipt_log_logger);
491 ipt_unregister_target(&ipt_log_reg); 491 ipt_unregister_target(&ipt_log_reg);
492} 492}
493 493
494module_init(init); 494module_init(ipt_log_init);
495module_exit(fini); 495module_exit(ipt_log_fini);
diff --git a/net/ipv4/netfilter/ipt_MASQUERADE.c b/net/ipv4/netfilter/ipt_MASQUERADE.c
index e0c321c3bae5..8b3e7f99b861 100644
--- a/net/ipv4/netfilter/ipt_MASQUERADE.c
+++ b/net/ipv4/netfilter/ipt_MASQUERADE.c
@@ -175,7 +175,7 @@ static struct ipt_target masquerade = {
175 .me = THIS_MODULE, 175 .me = THIS_MODULE,
176}; 176};
177 177
178static int __init init(void) 178static int __init ipt_masquerade_init(void)
179{ 179{
180 int ret; 180 int ret;
181 181
@@ -191,12 +191,12 @@ static int __init init(void)
191 return ret; 191 return ret;
192} 192}
193 193
194static void __exit fini(void) 194static void __exit ipt_masquerade_fini(void)
195{ 195{
196 ipt_unregister_target(&masquerade); 196 ipt_unregister_target(&masquerade);
197 unregister_netdevice_notifier(&masq_dev_notifier); 197 unregister_netdevice_notifier(&masq_dev_notifier);
198 unregister_inetaddr_notifier(&masq_inet_notifier); 198 unregister_inetaddr_notifier(&masq_inet_notifier);
199} 199}
200 200
201module_init(init); 201module_init(ipt_masquerade_init);
202module_exit(fini); 202module_exit(ipt_masquerade_fini);
diff --git a/net/ipv4/netfilter/ipt_NETMAP.c b/net/ipv4/netfilter/ipt_NETMAP.c
index fba181c2a426..2fcf1075b027 100644
--- a/net/ipv4/netfilter/ipt_NETMAP.c
+++ b/net/ipv4/netfilter/ipt_NETMAP.c
@@ -98,15 +98,15 @@ static struct ipt_target target_module = {
98 .me = THIS_MODULE 98 .me = THIS_MODULE
99}; 99};
100 100
101static int __init init(void) 101static int __init ipt_netmap_init(void)
102{ 102{
103 return ipt_register_target(&target_module); 103 return ipt_register_target(&target_module);
104} 104}
105 105
106static void __exit fini(void) 106static void __exit ipt_netmap_fini(void)
107{ 107{
108 ipt_unregister_target(&target_module); 108 ipt_unregister_target(&target_module);
109} 109}
110 110
111module_init(init); 111module_init(ipt_netmap_init);
112module_exit(fini); 112module_exit(ipt_netmap_fini);
diff --git a/net/ipv4/netfilter/ipt_REDIRECT.c b/net/ipv4/netfilter/ipt_REDIRECT.c
index be3da7c4b871..f290463232de 100644
--- a/net/ipv4/netfilter/ipt_REDIRECT.c
+++ b/net/ipv4/netfilter/ipt_REDIRECT.c
@@ -112,15 +112,15 @@ static struct ipt_target redirect_reg = {
112 .me = THIS_MODULE, 112 .me = THIS_MODULE,
113}; 113};
114 114
115static int __init init(void) 115static int __init ipt_redirect_init(void)
116{ 116{
117 return ipt_register_target(&redirect_reg); 117 return ipt_register_target(&redirect_reg);
118} 118}
119 119
120static void __exit fini(void) 120static void __exit ipt_redirect_fini(void)
121{ 121{
122 ipt_unregister_target(&redirect_reg); 122 ipt_unregister_target(&redirect_reg);
123} 123}
124 124
125module_init(init); 125module_init(ipt_redirect_init);
126module_exit(fini); 126module_exit(ipt_redirect_fini);
diff --git a/net/ipv4/netfilter/ipt_REJECT.c b/net/ipv4/netfilter/ipt_REJECT.c
index 9d3b3579f27c..4269a5440d43 100644
--- a/net/ipv4/netfilter/ipt_REJECT.c
+++ b/net/ipv4/netfilter/ipt_REJECT.c
@@ -313,15 +313,15 @@ static struct ipt_target ipt_reject_reg = {
313 .me = THIS_MODULE, 313 .me = THIS_MODULE,
314}; 314};
315 315
316static int __init init(void) 316static int __init ipt_reject_init(void)
317{ 317{
318 return ipt_register_target(&ipt_reject_reg); 318 return ipt_register_target(&ipt_reject_reg);
319} 319}
320 320
321static void __exit fini(void) 321static void __exit ipt_reject_fini(void)
322{ 322{
323 ipt_unregister_target(&ipt_reject_reg); 323 ipt_unregister_target(&ipt_reject_reg);
324} 324}
325 325
326module_init(init); 326module_init(ipt_reject_init);
327module_exit(fini); 327module_exit(ipt_reject_fini);
diff --git a/net/ipv4/netfilter/ipt_SAME.c b/net/ipv4/netfilter/ipt_SAME.c
index 7e2ebc9d945e..7169b09b5a67 100644
--- a/net/ipv4/netfilter/ipt_SAME.c
+++ b/net/ipv4/netfilter/ipt_SAME.c
@@ -189,16 +189,16 @@ static struct ipt_target same_reg = {
189 .me = THIS_MODULE, 189 .me = THIS_MODULE,
190}; 190};
191 191
192static int __init init(void) 192static int __init ipt_same_init(void)
193{ 193{
194 return ipt_register_target(&same_reg); 194 return ipt_register_target(&same_reg);
195} 195}
196 196
197static void __exit fini(void) 197static void __exit ipt_same_fini(void)
198{ 198{
199 ipt_unregister_target(&same_reg); 199 ipt_unregister_target(&same_reg);
200} 200}
201 201
202module_init(init); 202module_init(ipt_same_init);
203module_exit(fini); 203module_exit(ipt_same_fini);
204 204
diff --git a/net/ipv4/netfilter/ipt_TCPMSS.c b/net/ipv4/netfilter/ipt_TCPMSS.c
index c4fc50ec2ddb..ef2fe5b3f0d8 100644
--- a/net/ipv4/netfilter/ipt_TCPMSS.c
+++ b/net/ipv4/netfilter/ipt_TCPMSS.c
@@ -243,15 +243,15 @@ static struct ipt_target ipt_tcpmss_reg = {
243 .me = THIS_MODULE, 243 .me = THIS_MODULE,
244}; 244};
245 245
246static int __init init(void) 246static int __init ipt_tcpmss_init(void)
247{ 247{
248 return ipt_register_target(&ipt_tcpmss_reg); 248 return ipt_register_target(&ipt_tcpmss_reg);
249} 249}
250 250
251static void __exit fini(void) 251static void __exit ipt_tcpmss_fini(void)
252{ 252{
253 ipt_unregister_target(&ipt_tcpmss_reg); 253 ipt_unregister_target(&ipt_tcpmss_reg);
254} 254}
255 255
256module_init(init); 256module_init(ipt_tcpmss_init);
257module_exit(fini); 257module_exit(ipt_tcpmss_fini);
diff --git a/net/ipv4/netfilter/ipt_TOS.c b/net/ipv4/netfilter/ipt_TOS.c
index 9aa7817657f0..1c7a5ca399b3 100644
--- a/net/ipv4/netfilter/ipt_TOS.c
+++ b/net/ipv4/netfilter/ipt_TOS.c
@@ -81,15 +81,15 @@ static struct ipt_target ipt_tos_reg = {
81 .me = THIS_MODULE, 81 .me = THIS_MODULE,
82}; 82};
83 83
84static int __init init(void) 84static int __init ipt_tos_init(void)
85{ 85{
86 return ipt_register_target(&ipt_tos_reg); 86 return ipt_register_target(&ipt_tos_reg);
87} 87}
88 88
89static void __exit fini(void) 89static void __exit ipt_tos_fini(void)
90{ 90{
91 ipt_unregister_target(&ipt_tos_reg); 91 ipt_unregister_target(&ipt_tos_reg);
92} 92}
93 93
94module_init(init); 94module_init(ipt_tos_init);
95module_exit(fini); 95module_exit(ipt_tos_fini);
diff --git a/net/ipv4/netfilter/ipt_TTL.c b/net/ipv4/netfilter/ipt_TTL.c
index 5009a003d578..f48892ae0be5 100644
--- a/net/ipv4/netfilter/ipt_TTL.c
+++ b/net/ipv4/netfilter/ipt_TTL.c
@@ -94,15 +94,15 @@ static struct ipt_target ipt_TTL = {
94 .me = THIS_MODULE, 94 .me = THIS_MODULE,
95}; 95};
96 96
97static int __init init(void) 97static int __init ipt_ttl_init(void)
98{ 98{
99 return ipt_register_target(&ipt_TTL); 99 return ipt_register_target(&ipt_TTL);
100} 100}
101 101
102static void __exit fini(void) 102static void __exit ipt_ttl_fini(void)
103{ 103{
104 ipt_unregister_target(&ipt_TTL); 104 ipt_unregister_target(&ipt_TTL);
105} 105}
106 106
107module_init(init); 107module_init(ipt_ttl_init);
108module_exit(fini); 108module_exit(ipt_ttl_fini);
diff --git a/net/ipv4/netfilter/ipt_ULOG.c b/net/ipv4/netfilter/ipt_ULOG.c
index a82a32ed0e2f..c84cc03389d8 100644
--- a/net/ipv4/netfilter/ipt_ULOG.c
+++ b/net/ipv4/netfilter/ipt_ULOG.c
@@ -374,7 +374,7 @@ static struct nf_logger ipt_ulog_logger = {
374 .me = THIS_MODULE, 374 .me = THIS_MODULE,
375}; 375};
376 376
377static int __init init(void) 377static int __init ipt_ulog_init(void)
378{ 378{
379 int i; 379 int i;
380 380
@@ -407,7 +407,7 @@ static int __init init(void)
407 return 0; 407 return 0;
408} 408}
409 409
410static void __exit fini(void) 410static void __exit ipt_ulog_fini(void)
411{ 411{
412 ulog_buff_t *ub; 412 ulog_buff_t *ub;
413 int i; 413 int i;
@@ -435,5 +435,5 @@ static void __exit fini(void)
435 435
436} 436}
437 437
438module_init(init); 438module_init(ipt_ulog_init);
439module_exit(fini); 439module_exit(ipt_ulog_fini);
diff --git a/net/ipv4/netfilter/ipt_addrtype.c b/net/ipv4/netfilter/ipt_addrtype.c
index 5fdf85d0efcf..893dae210b04 100644
--- a/net/ipv4/netfilter/ipt_addrtype.c
+++ b/net/ipv4/netfilter/ipt_addrtype.c
@@ -51,15 +51,15 @@ static struct ipt_match addrtype_match = {
51 .me = THIS_MODULE 51 .me = THIS_MODULE
52}; 52};
53 53
54static int __init init(void) 54static int __init ipt_addrtype_init(void)
55{ 55{
56 return ipt_register_match(&addrtype_match); 56 return ipt_register_match(&addrtype_match);
57} 57}
58 58
59static void __exit fini(void) 59static void __exit ipt_addrtype_fini(void)
60{ 60{
61 ipt_unregister_match(&addrtype_match); 61 ipt_unregister_match(&addrtype_match);
62} 62}
63 63
64module_init(init); 64module_init(ipt_addrtype_init);
65module_exit(fini); 65module_exit(ipt_addrtype_fini);
diff --git a/net/ipv4/netfilter/ipt_ah.c b/net/ipv4/netfilter/ipt_ah.c
index 35a21fb1f8e0..2927135873d7 100644
--- a/net/ipv4/netfilter/ipt_ah.c
+++ b/net/ipv4/netfilter/ipt_ah.c
@@ -96,15 +96,15 @@ static struct ipt_match ah_match = {
96 .me = THIS_MODULE, 96 .me = THIS_MODULE,
97}; 97};
98 98
99static int __init init(void) 99static int __init ipt_ah_init(void)
100{ 100{
101 return ipt_register_match(&ah_match); 101 return ipt_register_match(&ah_match);
102} 102}
103 103
104static void __exit cleanup(void) 104static void __exit ipt_ah_fini(void)
105{ 105{
106 ipt_unregister_match(&ah_match); 106 ipt_unregister_match(&ah_match);
107} 107}
108 108
109module_init(init); 109module_init(ipt_ah_init);
110module_exit(cleanup); 110module_exit(ipt_ah_fini);
diff --git a/net/ipv4/netfilter/ipt_dscp.c b/net/ipv4/netfilter/ipt_dscp.c
index 11963c385dea..47177591aeb6 100644
--- a/net/ipv4/netfilter/ipt_dscp.c
+++ b/net/ipv4/netfilter/ipt_dscp.c
@@ -39,16 +39,16 @@ static struct ipt_match dscp_match = {
39 .me = THIS_MODULE, 39 .me = THIS_MODULE,
40}; 40};
41 41
42static int __init init(void) 42static int __init ipt_dscp_init(void)
43{ 43{
44 return ipt_register_match(&dscp_match); 44 return ipt_register_match(&dscp_match);
45} 45}
46 46
47static void __exit fini(void) 47static void __exit ipt_dscp_fini(void)
48{ 48{
49 ipt_unregister_match(&dscp_match); 49 ipt_unregister_match(&dscp_match);
50 50
51} 51}
52 52
53module_init(init); 53module_init(ipt_dscp_init);
54module_exit(fini); 54module_exit(ipt_dscp_fini);
diff --git a/net/ipv4/netfilter/ipt_ecn.c b/net/ipv4/netfilter/ipt_ecn.c
index d7e29f6a38d8..b28250414933 100644
--- a/net/ipv4/netfilter/ipt_ecn.c
+++ b/net/ipv4/netfilter/ipt_ecn.c
@@ -118,15 +118,15 @@ static struct ipt_match ecn_match = {
118 .me = THIS_MODULE, 118 .me = THIS_MODULE,
119}; 119};
120 120
121static int __init init(void) 121static int __init ipt_ecn_init(void)
122{ 122{
123 return ipt_register_match(&ecn_match); 123 return ipt_register_match(&ecn_match);
124} 124}
125 125
126static void __exit fini(void) 126static void __exit ipt_ecn_fini(void)
127{ 127{
128 ipt_unregister_match(&ecn_match); 128 ipt_unregister_match(&ecn_match);
129} 129}
130 130
131module_init(init); 131module_init(ipt_ecn_init);
132module_exit(fini); 132module_exit(ipt_ecn_fini);
diff --git a/net/ipv4/netfilter/ipt_esp.c b/net/ipv4/netfilter/ipt_esp.c
index af0d5ec79cb5..3840b417a3c5 100644
--- a/net/ipv4/netfilter/ipt_esp.c
+++ b/net/ipv4/netfilter/ipt_esp.c
@@ -97,15 +97,15 @@ static struct ipt_match esp_match = {
97 .me = THIS_MODULE, 97 .me = THIS_MODULE,
98}; 98};
99 99
100static int __init init(void) 100static int __init ipt_esp_init(void)
101{ 101{
102 return ipt_register_match(&esp_match); 102 return ipt_register_match(&esp_match);
103} 103}
104 104
105static void __exit cleanup(void) 105static void __exit ipt_esp_fini(void)
106{ 106{
107 ipt_unregister_match(&esp_match); 107 ipt_unregister_match(&esp_match);
108} 108}
109 109
110module_init(init); 110module_init(ipt_esp_init);
111module_exit(cleanup); 111module_exit(ipt_esp_fini);
diff --git a/net/ipv4/netfilter/ipt_hashlimit.c b/net/ipv4/netfilter/ipt_hashlimit.c
index ba5e23505e88..7c6836c4646e 100644
--- a/net/ipv4/netfilter/ipt_hashlimit.c
+++ b/net/ipv4/netfilter/ipt_hashlimit.c
@@ -719,15 +719,15 @@ cleanup_nothing:
719 719
720} 720}
721 721
722static int __init init(void) 722static int __init ipt_hashlimit_init(void)
723{ 723{
724 return init_or_fini(0); 724 return init_or_fini(0);
725} 725}
726 726
727static void __exit fini(void) 727static void __exit ipt_hashlimit_fini(void)
728{ 728{
729 init_or_fini(1); 729 init_or_fini(1);
730} 730}
731 731
732module_init(init); 732module_init(ipt_hashlimit_init);
733module_exit(fini); 733module_exit(ipt_hashlimit_fini);
diff --git a/net/ipv4/netfilter/ipt_iprange.c b/net/ipv4/netfilter/ipt_iprange.c
index ae70112f5e06..5202edd8d333 100644
--- a/net/ipv4/netfilter/ipt_iprange.c
+++ b/net/ipv4/netfilter/ipt_iprange.c
@@ -71,15 +71,15 @@ static struct ipt_match iprange_match = {
71 .me = THIS_MODULE 71 .me = THIS_MODULE
72}; 72};
73 73
74static int __init init(void) 74static int __init ipt_iprange_init(void)
75{ 75{
76 return ipt_register_match(&iprange_match); 76 return ipt_register_match(&iprange_match);
77} 77}
78 78
79static void __exit fini(void) 79static void __exit ipt_iprange_fini(void)
80{ 80{
81 ipt_unregister_match(&iprange_match); 81 ipt_unregister_match(&iprange_match);
82} 82}
83 83
84module_init(init); 84module_init(ipt_iprange_init);
85module_exit(fini); 85module_exit(ipt_iprange_fini);
diff --git a/net/ipv4/netfilter/ipt_multiport.c b/net/ipv4/netfilter/ipt_multiport.c
index bd07f7c53872..ac95d8390bcc 100644
--- a/net/ipv4/netfilter/ipt_multiport.c
+++ b/net/ipv4/netfilter/ipt_multiport.c
@@ -171,7 +171,7 @@ static struct ipt_match multiport_match_v1 = {
171 .me = THIS_MODULE, 171 .me = THIS_MODULE,
172}; 172};
173 173
174static int __init init(void) 174static int __init ipt_multiport_init(void)
175{ 175{
176 int err; 176 int err;
177 177
@@ -185,11 +185,11 @@ static int __init init(void)
185 return err; 185 return err;
186} 186}
187 187
188static void __exit fini(void) 188static void __exit ipt_multiport_fini(void)
189{ 189{
190 ipt_unregister_match(&multiport_match); 190 ipt_unregister_match(&multiport_match);
191 ipt_unregister_match(&multiport_match_v1); 191 ipt_unregister_match(&multiport_match_v1);
192} 192}
193 193
194module_init(init); 194module_init(ipt_multiport_init);
195module_exit(fini); 195module_exit(ipt_multiport_fini);
diff --git a/net/ipv4/netfilter/ipt_owner.c b/net/ipv4/netfilter/ipt_owner.c
index 3900428771f3..5ac6ac023b5e 100644
--- a/net/ipv4/netfilter/ipt_owner.c
+++ b/net/ipv4/netfilter/ipt_owner.c
@@ -78,15 +78,15 @@ static struct ipt_match owner_match = {
78 .me = THIS_MODULE, 78 .me = THIS_MODULE,
79}; 79};
80 80
81static int __init init(void) 81static int __init ipt_owner_init(void)
82{ 82{
83 return ipt_register_match(&owner_match); 83 return ipt_register_match(&owner_match);
84} 84}
85 85
86static void __exit fini(void) 86static void __exit ipt_owner_fini(void)
87{ 87{
88 ipt_unregister_match(&owner_match); 88 ipt_unregister_match(&owner_match);
89} 89}
90 90
91module_init(init); 91module_init(ipt_owner_init);
92module_exit(fini); 92module_exit(ipt_owner_fini);
diff --git a/net/ipv4/netfilter/ipt_recent.c b/net/ipv4/netfilter/ipt_recent.c
index 06792ead1da4..143843285702 100644
--- a/net/ipv4/netfilter/ipt_recent.c
+++ b/net/ipv4/netfilter/ipt_recent.c
@@ -962,7 +962,7 @@ static struct ipt_match recent_match = {
962}; 962};
963 963
964/* Kernel module initialization. */ 964/* Kernel module initialization. */
965static int __init init(void) 965static int __init ipt_recent_init(void)
966{ 966{
967 int err, count; 967 int err, count;
968 968
@@ -995,7 +995,7 @@ static int __init init(void)
995} 995}
996 996
997/* Kernel module destruction. */ 997/* Kernel module destruction. */
998static void __exit fini(void) 998static void __exit ipt_recent_fini(void)
999{ 999{
1000 ipt_unregister_match(&recent_match); 1000 ipt_unregister_match(&recent_match);
1001 1001
@@ -1003,5 +1003,5 @@ static void __exit fini(void)
1003} 1003}
1004 1004
1005/* Register our module with the kernel. */ 1005/* Register our module with the kernel. */
1006module_init(init); 1006module_init(ipt_recent_init);
1007module_exit(fini); 1007module_exit(ipt_recent_fini);
diff --git a/net/ipv4/netfilter/ipt_tos.c b/net/ipv4/netfilter/ipt_tos.c
index e404e92ddd01..5549c39c7851 100644
--- a/net/ipv4/netfilter/ipt_tos.c
+++ b/net/ipv4/netfilter/ipt_tos.c
@@ -39,15 +39,15 @@ static struct ipt_match tos_match = {
39 .me = THIS_MODULE, 39 .me = THIS_MODULE,
40}; 40};
41 41
42static int __init init(void) 42static int __init ipt_multiport_init(void)
43{ 43{
44 return ipt_register_match(&tos_match); 44 return ipt_register_match(&tos_match);
45} 45}
46 46
47static void __exit fini(void) 47static void __exit ipt_multiport_fini(void)
48{ 48{
49 ipt_unregister_match(&tos_match); 49 ipt_unregister_match(&tos_match);
50} 50}
51 51
52module_init(init); 52module_init(ipt_multiport_init);
53module_exit(fini); 53module_exit(ipt_multiport_fini);
diff --git a/net/ipv4/netfilter/ipt_ttl.c b/net/ipv4/netfilter/ipt_ttl.c
index ae7ce4d8d90e..a5243bdb87d7 100644
--- a/net/ipv4/netfilter/ipt_ttl.c
+++ b/net/ipv4/netfilter/ipt_ttl.c
@@ -55,16 +55,16 @@ static struct ipt_match ttl_match = {
55 .me = THIS_MODULE, 55 .me = THIS_MODULE,
56}; 56};
57 57
58static int __init init(void) 58static int __init ipt_ttl_init(void)
59{ 59{
60 return ipt_register_match(&ttl_match); 60 return ipt_register_match(&ttl_match);
61} 61}
62 62
63static void __exit fini(void) 63static void __exit ipt_ttl_fini(void)
64{ 64{
65 ipt_unregister_match(&ttl_match); 65 ipt_unregister_match(&ttl_match);
66 66
67} 67}
68 68
69module_init(init); 69module_init(ipt_ttl_init);
70module_exit(fini); 70module_exit(ipt_ttl_fini);
diff --git a/net/ipv4/netfilter/iptable_filter.c b/net/ipv4/netfilter/iptable_filter.c
index 212a3079085b..3d80aefe9cfa 100644
--- a/net/ipv4/netfilter/iptable_filter.c
+++ b/net/ipv4/netfilter/iptable_filter.c
@@ -139,7 +139,7 @@ static struct nf_hook_ops ipt_ops[] = {
139static int forward = NF_ACCEPT; 139static int forward = NF_ACCEPT;
140module_param(forward, bool, 0000); 140module_param(forward, bool, 0000);
141 141
142static int __init init(void) 142static int __init iptable_filter_init(void)
143{ 143{
144 int ret; 144 int ret;
145 145
@@ -181,7 +181,7 @@ static int __init init(void)
181 return ret; 181 return ret;
182} 182}
183 183
184static void __exit fini(void) 184static void __exit iptable_filter_fini(void)
185{ 185{
186 unsigned int i; 186 unsigned int i;
187 187
@@ -191,5 +191,5 @@ static void __exit fini(void)
191 ipt_unregister_table(&packet_filter); 191 ipt_unregister_table(&packet_filter);
192} 192}
193 193
194module_init(init); 194module_init(iptable_filter_init);
195module_exit(fini); 195module_exit(iptable_filter_fini);
diff --git a/net/ipv4/netfilter/iptable_mangle.c b/net/ipv4/netfilter/iptable_mangle.c
index 3212a5cc4b6b..412fc96cc896 100644
--- a/net/ipv4/netfilter/iptable_mangle.c
+++ b/net/ipv4/netfilter/iptable_mangle.c
@@ -201,7 +201,7 @@ static struct nf_hook_ops ipt_ops[] = {
201 }, 201 },
202}; 202};
203 203
204static int __init init(void) 204static int __init iptable_mangle_init(void)
205{ 205{
206 int ret; 206 int ret;
207 207
@@ -247,7 +247,7 @@ static int __init init(void)
247 return ret; 247 return ret;
248} 248}
249 249
250static void __exit fini(void) 250static void __exit iptable_mangle_fini(void)
251{ 251{
252 unsigned int i; 252 unsigned int i;
253 253
@@ -257,5 +257,5 @@ static void __exit fini(void)
257 ipt_unregister_table(&packet_mangler); 257 ipt_unregister_table(&packet_mangler);
258} 258}
259 259
260module_init(init); 260module_init(iptable_mangle_init);
261module_exit(fini); 261module_exit(iptable_mangle_fini);
diff --git a/net/ipv4/netfilter/iptable_raw.c b/net/ipv4/netfilter/iptable_raw.c
index fdb9e9c81e81..03cc79a6160a 100644
--- a/net/ipv4/netfilter/iptable_raw.c
+++ b/net/ipv4/netfilter/iptable_raw.c
@@ -116,7 +116,7 @@ static struct nf_hook_ops ipt_ops[] = {
116 }, 116 },
117}; 117};
118 118
119static int __init init(void) 119static int __init iptable_raw_init(void)
120{ 120{
121 int ret; 121 int ret;
122 122
@@ -144,7 +144,7 @@ static int __init init(void)
144 return ret; 144 return ret;
145} 145}
146 146
147static void __exit fini(void) 147static void __exit iptable_raw_fini(void)
148{ 148{
149 unsigned int i; 149 unsigned int i;
150 150
@@ -154,6 +154,6 @@ static void __exit fini(void)
154 ipt_unregister_table(&packet_raw); 154 ipt_unregister_table(&packet_raw);
155} 155}
156 156
157module_init(init); 157module_init(iptable_raw_init);
158module_exit(fini); 158module_exit(iptable_raw_fini);
159MODULE_LICENSE("GPL"); 159MODULE_LICENSE("GPL");
diff --git a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
index c8abc9d859b9..4afbc699d3ba 100644
--- a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
+++ b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
@@ -571,18 +571,18 @@ static int init_or_cleanup(int init)
571MODULE_ALIAS("nf_conntrack-" __stringify(AF_INET)); 571MODULE_ALIAS("nf_conntrack-" __stringify(AF_INET));
572MODULE_LICENSE("GPL"); 572MODULE_LICENSE("GPL");
573 573
574static int __init init(void) 574static int __init nf_conntrack_l3proto_ipv4_init(void)
575{ 575{
576 need_conntrack(); 576 need_conntrack();
577 return init_or_cleanup(1); 577 return init_or_cleanup(1);
578} 578}
579 579
580static void __exit fini(void) 580static void __exit nf_conntrack_l3proto_ipv4_fini(void)
581{ 581{
582 init_or_cleanup(0); 582 init_or_cleanup(0);
583} 583}
584 584
585module_init(init); 585module_init(nf_conntrack_l3proto_ipv4_init);
586module_exit(fini); 586module_exit(nf_conntrack_l3proto_ipv4_fini);
587 587
588EXPORT_SYMBOL(nf_ct_ipv4_gather_frags); 588EXPORT_SYMBOL(nf_ct_ipv4_gather_frags);
diff --git a/net/ipv4/tcp_cong.c b/net/ipv4/tcp_cong.c
index e688c687d62d..91c2f41c7f58 100644
--- a/net/ipv4/tcp_cong.c
+++ b/net/ipv4/tcp_cong.c
@@ -223,7 +223,7 @@ void tcp_reno_cong_avoid(struct sock *sk, u32 ack, u32 rtt, u32 in_flight,
223 223
224 /* In dangerous area, increase slowly. */ 224 /* In dangerous area, increase slowly. */
225 else if (sysctl_tcp_abc) { 225 else if (sysctl_tcp_abc) {
226 /* RFC3465: Apppriate Byte Count 226 /* RFC3465: Appropriate Byte Count
227 * increase once for each full cwnd acked 227 * increase once for each full cwnd acked
228 */ 228 */
229 if (tp->bytes_acked >= tp->snd_cwnd*tp->mss_cache) { 229 if (tp->bytes_acked >= tp->snd_cwnd*tp->mss_cache) {
diff --git a/net/ipv4/tunnel4.c b/net/ipv4/tunnel4.c
new file mode 100644
index 000000000000..0d7d386dac22
--- /dev/null
+++ b/net/ipv4/tunnel4.c
@@ -0,0 +1,113 @@
1/* tunnel4.c: Generic IP tunnel transformer.
2 *
3 * Copyright (C) 2003 David S. Miller (davem@redhat.com)
4 */
5
6#include <linux/init.h>
7#include <linux/module.h>
8#include <linux/mutex.h>
9#include <linux/netdevice.h>
10#include <linux/skbuff.h>
11#include <net/protocol.h>
12#include <net/xfrm.h>
13
14static struct xfrm_tunnel *tunnel4_handlers;
15static DEFINE_MUTEX(tunnel4_mutex);
16
17int xfrm4_tunnel_register(struct xfrm_tunnel *handler)
18{
19 struct xfrm_tunnel **pprev;
20 int ret = -EEXIST;
21 int priority = handler->priority;
22
23 mutex_lock(&tunnel4_mutex);
24
25 for (pprev = &tunnel4_handlers; *pprev; pprev = &(*pprev)->next) {
26 if ((*pprev)->priority > priority)
27 break;
28 if ((*pprev)->priority == priority)
29 goto err;
30 }
31
32 handler->next = *pprev;
33 *pprev = handler;
34
35 ret = 0;
36
37err:
38 mutex_unlock(&tunnel4_mutex);
39
40 return ret;
41}
42
43EXPORT_SYMBOL(xfrm4_tunnel_register);
44
45int xfrm4_tunnel_deregister(struct xfrm_tunnel *handler)
46{
47 struct xfrm_tunnel **pprev;
48 int ret = -ENOENT;
49
50 mutex_lock(&tunnel4_mutex);
51
52 for (pprev = &tunnel4_handlers; *pprev; pprev = &(*pprev)->next) {
53 if (*pprev == handler) {
54 *pprev = handler->next;
55 ret = 0;
56 break;
57 }
58 }
59
60 mutex_unlock(&tunnel4_mutex);
61
62 synchronize_net();
63
64 return ret;
65}
66
67EXPORT_SYMBOL(xfrm4_tunnel_deregister);
68
69static int tunnel4_rcv(struct sk_buff *skb)
70{
71 struct xfrm_tunnel *handler;
72
73 for (handler = tunnel4_handlers; handler; handler = handler->next)
74 if (!handler->handler(skb))
75 return 0;
76
77 kfree_skb(skb);
78 return 0;
79}
80
81static void tunnel4_err(struct sk_buff *skb, u32 info)
82{
83 struct xfrm_tunnel *handler;
84
85 for (handler = tunnel4_handlers; handler; handler = handler->next)
86 if (!handler->err_handler(skb, info))
87 break;
88}
89
90static struct net_protocol tunnel4_protocol = {
91 .handler = tunnel4_rcv,
92 .err_handler = tunnel4_err,
93 .no_policy = 1,
94};
95
96static int __init tunnel4_init(void)
97{
98 if (inet_add_protocol(&tunnel4_protocol, IPPROTO_IPIP)) {
99 printk(KERN_ERR "tunnel4 init: can't add protocol\n");
100 return -EAGAIN;
101 }
102 return 0;
103}
104
105static void __exit tunnel4_fini(void)
106{
107 if (inet_del_protocol(&tunnel4_protocol, IPPROTO_IPIP))
108 printk(KERN_ERR "tunnel4 close: can't remove protocol\n");
109}
110
111module_init(tunnel4_init);
112module_exit(tunnel4_fini);
113MODULE_LICENSE("GPL");
diff --git a/net/ipv4/xfrm4_tunnel.c b/net/ipv4/xfrm4_tunnel.c
index b08d56b117f8..2d670935c2b5 100644
--- a/net/ipv4/xfrm4_tunnel.c
+++ b/net/ipv4/xfrm4_tunnel.c
@@ -26,64 +26,6 @@ static int ipip_xfrm_rcv(struct xfrm_state *x, struct xfrm_decap_state *decap, s
26 return 0; 26 return 0;
27} 27}
28 28
29static struct xfrm_tunnel *ipip_handler;
30static DEFINE_MUTEX(xfrm4_tunnel_mutex);
31
32int xfrm4_tunnel_register(struct xfrm_tunnel *handler)
33{
34 int ret;
35
36 mutex_lock(&xfrm4_tunnel_mutex);
37 ret = 0;
38 if (ipip_handler != NULL)
39 ret = -EINVAL;
40 if (!ret)
41 ipip_handler = handler;
42 mutex_unlock(&xfrm4_tunnel_mutex);
43
44 return ret;
45}
46
47EXPORT_SYMBOL(xfrm4_tunnel_register);
48
49int xfrm4_tunnel_deregister(struct xfrm_tunnel *handler)
50{
51 int ret;
52
53 mutex_lock(&xfrm4_tunnel_mutex);
54 ret = 0;
55 if (ipip_handler != handler)
56 ret = -EINVAL;
57 if (!ret)
58 ipip_handler = NULL;
59 mutex_unlock(&xfrm4_tunnel_mutex);
60
61 synchronize_net();
62
63 return ret;
64}
65
66EXPORT_SYMBOL(xfrm4_tunnel_deregister);
67
68static int ipip_rcv(struct sk_buff *skb)
69{
70 struct xfrm_tunnel *handler = ipip_handler;
71
72 /* Tunnel devices take precedence. */
73 if (handler && handler->handler(skb) == 0)
74 return 0;
75
76 return xfrm4_rcv(skb);
77}
78
79static void ipip_err(struct sk_buff *skb, u32 info)
80{
81 struct xfrm_tunnel *handler = ipip_handler;
82
83 if (handler)
84 handler->err_handler(skb, info);
85}
86
87static int ipip_init_state(struct xfrm_state *x) 29static int ipip_init_state(struct xfrm_state *x)
88{ 30{
89 if (!x->props.mode) 31 if (!x->props.mode)
@@ -111,10 +53,15 @@ static struct xfrm_type ipip_type = {
111 .output = ipip_output 53 .output = ipip_output
112}; 54};
113 55
114static struct net_protocol ipip_protocol = { 56static int xfrm_tunnel_err(struct sk_buff *skb, u32 info)
115 .handler = ipip_rcv, 57{
116 .err_handler = ipip_err, 58 return -ENOENT;
117 .no_policy = 1, 59}
60
61static struct xfrm_tunnel xfrm_tunnel_handler = {
62 .handler = xfrm4_rcv,
63 .err_handler = xfrm_tunnel_err,
64 .priority = 2,
118}; 65};
119 66
120static int __init ipip_init(void) 67static int __init ipip_init(void)
@@ -123,8 +70,8 @@ static int __init ipip_init(void)
123 printk(KERN_INFO "ipip init: can't add xfrm type\n"); 70 printk(KERN_INFO "ipip init: can't add xfrm type\n");
124 return -EAGAIN; 71 return -EAGAIN;
125 } 72 }
126 if (inet_add_protocol(&ipip_protocol, IPPROTO_IPIP) < 0) { 73 if (xfrm4_tunnel_register(&xfrm_tunnel_handler)) {
127 printk(KERN_INFO "ipip init: can't add protocol\n"); 74 printk(KERN_INFO "ipip init: can't add xfrm handler\n");
128 xfrm_unregister_type(&ipip_type, AF_INET); 75 xfrm_unregister_type(&ipip_type, AF_INET);
129 return -EAGAIN; 76 return -EAGAIN;
130 } 77 }
@@ -133,8 +80,8 @@ static int __init ipip_init(void)
133 80
134static void __exit ipip_fini(void) 81static void __exit ipip_fini(void)
135{ 82{
136 if (inet_del_protocol(&ipip_protocol, IPPROTO_IPIP) < 0) 83 if (xfrm4_tunnel_deregister(&xfrm_tunnel_handler))
137 printk(KERN_INFO "ipip close: can't remove protocol\n"); 84 printk(KERN_INFO "ipip close: can't remove xfrm handler\n");
138 if (xfrm_unregister_type(&ipip_type, AF_INET) < 0) 85 if (xfrm_unregister_type(&ipip_type, AF_INET) < 0)
139 printk(KERN_INFO "ipip close: can't remove xfrm type\n"); 86 printk(KERN_INFO "ipip close: can't remove xfrm type\n");
140} 87}
diff --git a/net/ipv6/Kconfig b/net/ipv6/Kconfig
index e6f83b6a2b76..f8a107ab5592 100644
--- a/net/ipv6/Kconfig
+++ b/net/ipv6/Kconfig
@@ -88,7 +88,7 @@ config INET6_IPCOMP
88 tristate "IPv6: IPComp transformation" 88 tristate "IPv6: IPComp transformation"
89 depends on IPV6 89 depends on IPV6
90 select XFRM 90 select XFRM
91 select INET6_TUNNEL 91 select INET6_XFRM_TUNNEL
92 select CRYPTO 92 select CRYPTO
93 select CRYPTO_DEFLATE 93 select CRYPTO_DEFLATE
94 ---help--- 94 ---help---
@@ -97,19 +97,18 @@ config INET6_IPCOMP
97 97
98 If unsure, say Y. 98 If unsure, say Y.
99 99
100config INET6_XFRM_TUNNEL
101 tristate
102 select INET6_TUNNEL
103 default n
104
100config INET6_TUNNEL 105config INET6_TUNNEL
101 tristate "IPv6: tunnel transformation" 106 tristate
102 depends on IPV6 107 default n
103 select XFRM
104 ---help---
105 Support for generic IPv6-in-IPv6 tunnel transformation, which is
106 required by the IPv6-in-IPv6 tunneling module as well as tunnel mode
107 IPComp.
108
109 If unsure, say Y.
110 108
111config IPV6_TUNNEL 109config IPV6_TUNNEL
112 tristate "IPv6: IPv6-in-IPv6 tunnel" 110 tristate "IPv6: IPv6-in-IPv6 tunnel"
111 select INET6_TUNNEL
113 depends on IPV6 112 depends on IPV6
114 ---help--- 113 ---help---
115 Support for IPv6-in-IPv6 tunnels described in RFC 2473. 114 Support for IPv6-in-IPv6 tunnels described in RFC 2473.
diff --git a/net/ipv6/Makefile b/net/ipv6/Makefile
index 41877abd22e6..a760b0988fbb 100644
--- a/net/ipv6/Makefile
+++ b/net/ipv6/Makefile
@@ -18,7 +18,8 @@ ipv6-objs += $(ipv6-y)
18obj-$(CONFIG_INET6_AH) += ah6.o 18obj-$(CONFIG_INET6_AH) += ah6.o
19obj-$(CONFIG_INET6_ESP) += esp6.o 19obj-$(CONFIG_INET6_ESP) += esp6.o
20obj-$(CONFIG_INET6_IPCOMP) += ipcomp6.o 20obj-$(CONFIG_INET6_IPCOMP) += ipcomp6.o
21obj-$(CONFIG_INET6_TUNNEL) += xfrm6_tunnel.o 21obj-$(CONFIG_INET6_XFRM_TUNNEL) += xfrm6_tunnel.o
22obj-$(CONFIG_INET6_TUNNEL) += tunnel6.o
22obj-$(CONFIG_NETFILTER) += netfilter/ 23obj-$(CONFIG_NETFILTER) += netfilter/
23 24
24obj-$(CONFIG_IPV6_TUNNEL) += ip6_tunnel.o 25obj-$(CONFIG_IPV6_TUNNEL) += ip6_tunnel.o
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c
index 48597538db3f..ff9040c92556 100644
--- a/net/ipv6/ip6_tunnel.c
+++ b/net/ipv6/ip6_tunnel.c
@@ -44,7 +44,6 @@
44 44
45#include <net/ip.h> 45#include <net/ip.h>
46#include <net/ipv6.h> 46#include <net/ipv6.h>
47#include <net/protocol.h>
48#include <net/ip6_route.h> 47#include <net/ip6_route.h>
49#include <net/addrconf.h> 48#include <net/addrconf.h>
50#include <net/ip6_tunnel.h> 49#include <net/ip6_tunnel.h>
@@ -391,7 +390,7 @@ parse_tlv_tnl_enc_lim(struct sk_buff *skb, __u8 * raw)
391 * to the specifications in RFC 2473. 390 * to the specifications in RFC 2473.
392 **/ 391 **/
393 392
394static void 393static int
395ip6ip6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, 394ip6ip6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
396 int type, int code, int offset, __u32 info) 395 int type, int code, int offset, __u32 info)
397{ 396{
@@ -402,6 +401,7 @@ ip6ip6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
402 int rel_code = ICMPV6_ADDR_UNREACH; 401 int rel_code = ICMPV6_ADDR_UNREACH;
403 __u32 rel_info = 0; 402 __u32 rel_info = 0;
404 __u16 len; 403 __u16 len;
404 int err = -ENOENT;
405 405
406 /* If the packet doesn't contain the original IPv6 header we are 406 /* If the packet doesn't contain the original IPv6 header we are
407 in trouble since we might need the source address for further 407 in trouble since we might need the source address for further
@@ -411,6 +411,8 @@ ip6ip6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
411 if ((t = ip6ip6_tnl_lookup(&ipv6h->daddr, &ipv6h->saddr)) == NULL) 411 if ((t = ip6ip6_tnl_lookup(&ipv6h->daddr, &ipv6h->saddr)) == NULL)
412 goto out; 412 goto out;
413 413
414 err = 0;
415
414 switch (type) { 416 switch (type) {
415 __u32 teli; 417 __u32 teli;
416 struct ipv6_tlv_tnl_enc_lim *tel; 418 struct ipv6_tlv_tnl_enc_lim *tel;
@@ -492,6 +494,7 @@ ip6ip6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
492 } 494 }
493out: 495out:
494 read_unlock(&ip6ip6_lock); 496 read_unlock(&ip6ip6_lock);
497 return err;
495} 498}
496 499
497static inline void ip6ip6_ecn_decapsulate(struct ipv6hdr *outer_iph, 500static inline void ip6ip6_ecn_decapsulate(struct ipv6hdr *outer_iph,
@@ -511,9 +514,8 @@ static inline void ip6ip6_ecn_decapsulate(struct ipv6hdr *outer_iph,
511 **/ 514 **/
512 515
513static int 516static int
514ip6ip6_rcv(struct sk_buff **pskb) 517ip6ip6_rcv(struct sk_buff *skb)
515{ 518{
516 struct sk_buff *skb = *pskb;
517 struct ipv6hdr *ipv6h; 519 struct ipv6hdr *ipv6h;
518 struct ip6_tnl *t; 520 struct ip6_tnl *t;
519 521
@@ -1112,39 +1114,12 @@ ip6ip6_fb_tnl_dev_init(struct net_device *dev)
1112 return 0; 1114 return 0;
1113} 1115}
1114 1116
1115#ifdef CONFIG_INET6_TUNNEL
1116static struct xfrm6_tunnel ip6ip6_handler = { 1117static struct xfrm6_tunnel ip6ip6_handler = {
1117 .handler = ip6ip6_rcv, 1118 .handler = ip6ip6_rcv,
1118 .err_handler = ip6ip6_err, 1119 .err_handler = ip6ip6_err,
1120 .priority = 1,
1119}; 1121};
1120 1122
1121static inline int ip6ip6_register(void)
1122{
1123 return xfrm6_tunnel_register(&ip6ip6_handler);
1124}
1125
1126static inline int ip6ip6_unregister(void)
1127{
1128 return xfrm6_tunnel_deregister(&ip6ip6_handler);
1129}
1130#else
1131static struct inet6_protocol xfrm6_tunnel_protocol = {
1132 .handler = ip6ip6_rcv,
1133 .err_handler = ip6ip6_err,
1134 .flags = INET6_PROTO_NOPOLICY|INET6_PROTO_FINAL,
1135};
1136
1137static inline int ip6ip6_register(void)
1138{
1139 return inet6_add_protocol(&xfrm6_tunnel_protocol, IPPROTO_IPV6);
1140}
1141
1142static inline int ip6ip6_unregister(void)
1143{
1144 return inet6_del_protocol(&xfrm6_tunnel_protocol, IPPROTO_IPV6);
1145}
1146#endif
1147
1148/** 1123/**
1149 * ip6_tunnel_init - register protocol and reserve needed resources 1124 * ip6_tunnel_init - register protocol and reserve needed resources
1150 * 1125 *
@@ -1155,7 +1130,7 @@ static int __init ip6_tunnel_init(void)
1155{ 1130{
1156 int err; 1131 int err;
1157 1132
1158 if (ip6ip6_register() < 0) { 1133 if (xfrm6_tunnel_register(&ip6ip6_handler)) {
1159 printk(KERN_ERR "ip6ip6 init: can't register tunnel\n"); 1134 printk(KERN_ERR "ip6ip6 init: can't register tunnel\n");
1160 return -EAGAIN; 1135 return -EAGAIN;
1161 } 1136 }
@@ -1174,7 +1149,7 @@ static int __init ip6_tunnel_init(void)
1174 } 1149 }
1175 return 0; 1150 return 0;
1176fail: 1151fail:
1177 ip6ip6_unregister(); 1152 xfrm6_tunnel_deregister(&ip6ip6_handler);
1178 return err; 1153 return err;
1179} 1154}
1180 1155
@@ -1184,7 +1159,7 @@ fail:
1184 1159
1185static void __exit ip6_tunnel_cleanup(void) 1160static void __exit ip6_tunnel_cleanup(void)
1186{ 1161{
1187 if (ip6ip6_unregister() < 0) 1162 if (xfrm6_tunnel_deregister(&ip6ip6_handler))
1188 printk(KERN_INFO "ip6ip6 close: can't deregister tunnel\n"); 1163 printk(KERN_INFO "ip6ip6 close: can't deregister tunnel\n");
1189 1164
1190 unregister_netdev(ip6ip6_fb_tnl_dev); 1165 unregister_netdev(ip6ip6_fb_tnl_dev);
diff --git a/net/ipv6/netfilter/ip6_queue.c b/net/ipv6/netfilter/ip6_queue.c
index 344eab3b5da8..e81c6a9dab81 100644
--- a/net/ipv6/netfilter/ip6_queue.c
+++ b/net/ipv6/netfilter/ip6_queue.c
@@ -713,13 +713,13 @@ cleanup_netlink_notifier:
713 return status; 713 return status;
714} 714}
715 715
716static int __init init(void) 716static int __init ip6_queue_init(void)
717{ 717{
718 718
719 return init_or_cleanup(1); 719 return init_or_cleanup(1);
720} 720}
721 721
722static void __exit fini(void) 722static void __exit ip6_queue_fini(void)
723{ 723{
724 init_or_cleanup(0); 724 init_or_cleanup(0);
725} 725}
@@ -727,5 +727,5 @@ static void __exit fini(void)
727MODULE_DESCRIPTION("IPv6 packet queue handler"); 727MODULE_DESCRIPTION("IPv6 packet queue handler");
728MODULE_LICENSE("GPL"); 728MODULE_LICENSE("GPL");
729 729
730module_init(init); 730module_init(ip6_queue_init);
731module_exit(fini); 731module_exit(ip6_queue_fini);
diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c
index db3c9ae98e95..3ecf2db841f8 100644
--- a/net/ipv6/netfilter/ip6_tables.c
+++ b/net/ipv6/netfilter/ip6_tables.c
@@ -1406,7 +1406,7 @@ static struct ip6t_match icmp6_matchstruct = {
1406 .family = AF_INET6, 1406 .family = AF_INET6,
1407}; 1407};
1408 1408
1409static int __init init(void) 1409static int __init ip6_tables_init(void)
1410{ 1410{
1411 int ret; 1411 int ret;
1412 1412
@@ -1429,7 +1429,7 @@ static int __init init(void)
1429 return 0; 1429 return 0;
1430} 1430}
1431 1431
1432static void __exit fini(void) 1432static void __exit ip6_tables_fini(void)
1433{ 1433{
1434 nf_unregister_sockopt(&ip6t_sockopts); 1434 nf_unregister_sockopt(&ip6t_sockopts);
1435 xt_unregister_match(&icmp6_matchstruct); 1435 xt_unregister_match(&icmp6_matchstruct);
@@ -1517,5 +1517,5 @@ EXPORT_SYMBOL(ip6t_do_table);
1517EXPORT_SYMBOL(ip6t_ext_hdr); 1517EXPORT_SYMBOL(ip6t_ext_hdr);
1518EXPORT_SYMBOL(ipv6_find_hdr); 1518EXPORT_SYMBOL(ipv6_find_hdr);
1519 1519
1520module_init(init); 1520module_init(ip6_tables_init);
1521module_exit(fini); 1521module_exit(ip6_tables_fini);
diff --git a/net/ipv6/netfilter/ip6t_HL.c b/net/ipv6/netfilter/ip6t_HL.c
index da14c6d86bcc..b8eff8ee69b1 100644
--- a/net/ipv6/netfilter/ip6t_HL.c
+++ b/net/ipv6/netfilter/ip6t_HL.c
@@ -93,15 +93,15 @@ static struct ip6t_target ip6t_HL = {
93 .me = THIS_MODULE 93 .me = THIS_MODULE
94}; 94};
95 95
96static int __init init(void) 96static int __init ip6t_hl_init(void)
97{ 97{
98 return ip6t_register_target(&ip6t_HL); 98 return ip6t_register_target(&ip6t_HL);
99} 99}
100 100
101static void __exit fini(void) 101static void __exit ip6t_hl_fini(void)
102{ 102{
103 ip6t_unregister_target(&ip6t_HL); 103 ip6t_unregister_target(&ip6t_HL);
104} 104}
105 105
106module_init(init); 106module_init(ip6t_hl_init);
107module_exit(fini); 107module_exit(ip6t_hl_fini);
diff --git a/net/ipv6/netfilter/ip6t_LOG.c b/net/ipv6/netfilter/ip6t_LOG.c
index 07c6bcbe4c5f..a96c0de14b00 100644
--- a/net/ipv6/netfilter/ip6t_LOG.c
+++ b/net/ipv6/netfilter/ip6t_LOG.c
@@ -483,7 +483,7 @@ static struct nf_logger ip6t_logger = {
483 .me = THIS_MODULE, 483 .me = THIS_MODULE,
484}; 484};
485 485
486static int __init init(void) 486static int __init ip6t_log_init(void)
487{ 487{
488 if (ip6t_register_target(&ip6t_log_reg)) 488 if (ip6t_register_target(&ip6t_log_reg))
489 return -EINVAL; 489 return -EINVAL;
@@ -497,11 +497,11 @@ static int __init init(void)
497 return 0; 497 return 0;
498} 498}
499 499
500static void __exit fini(void) 500static void __exit ip6t_log_fini(void)
501{ 501{
502 nf_log_unregister_logger(&ip6t_logger); 502 nf_log_unregister_logger(&ip6t_logger);
503 ip6t_unregister_target(&ip6t_log_reg); 503 ip6t_unregister_target(&ip6t_log_reg);
504} 504}
505 505
506module_init(init); 506module_init(ip6t_log_init);
507module_exit(fini); 507module_exit(ip6t_log_fini);
diff --git a/net/ipv6/netfilter/ip6t_REJECT.c b/net/ipv6/netfilter/ip6t_REJECT.c
index ddfa38575fe2..de1175c27f6d 100644
--- a/net/ipv6/netfilter/ip6t_REJECT.c
+++ b/net/ipv6/netfilter/ip6t_REJECT.c
@@ -255,17 +255,17 @@ static struct ip6t_target ip6t_reject_reg = {
255 .me = THIS_MODULE 255 .me = THIS_MODULE
256}; 256};
257 257
258static int __init init(void) 258static int __init ip6t_reject_init(void)
259{ 259{
260 if (ip6t_register_target(&ip6t_reject_reg)) 260 if (ip6t_register_target(&ip6t_reject_reg))
261 return -EINVAL; 261 return -EINVAL;
262 return 0; 262 return 0;
263} 263}
264 264
265static void __exit fini(void) 265static void __exit ip6t_reject_fini(void)
266{ 266{
267 ip6t_unregister_target(&ip6t_reject_reg); 267 ip6t_unregister_target(&ip6t_reject_reg);
268} 268}
269 269
270module_init(init); 270module_init(ip6t_reject_init);
271module_exit(fini); 271module_exit(ip6t_reject_fini);
diff --git a/net/ipv6/netfilter/ip6t_ah.c b/net/ipv6/netfilter/ip6t_ah.c
index 178f6fb1e53d..2f7bb20c758b 100644
--- a/net/ipv6/netfilter/ip6t_ah.c
+++ b/net/ipv6/netfilter/ip6t_ah.c
@@ -122,15 +122,15 @@ static struct ip6t_match ah_match = {
122 .me = THIS_MODULE, 122 .me = THIS_MODULE,
123}; 123};
124 124
125static int __init init(void) 125static int __init ip6t_ah_init(void)
126{ 126{
127 return ip6t_register_match(&ah_match); 127 return ip6t_register_match(&ah_match);
128} 128}
129 129
130static void __exit cleanup(void) 130static void __exit ip6t_ah_fini(void)
131{ 131{
132 ip6t_unregister_match(&ah_match); 132 ip6t_unregister_match(&ah_match);
133} 133}
134 134
135module_init(init); 135module_init(ip6t_ah_init);
136module_exit(cleanup); 136module_exit(ip6t_ah_fini);
diff --git a/net/ipv6/netfilter/ip6t_dst.c b/net/ipv6/netfilter/ip6t_dst.c
index e97a70226987..9422413d0571 100644
--- a/net/ipv6/netfilter/ip6t_dst.c
+++ b/net/ipv6/netfilter/ip6t_dst.c
@@ -206,15 +206,15 @@ static struct ip6t_match opts_match = {
206 .me = THIS_MODULE, 206 .me = THIS_MODULE,
207}; 207};
208 208
209static int __init init(void) 209static int __init ip6t_dst_init(void)
210{ 210{
211 return ip6t_register_match(&opts_match); 211 return ip6t_register_match(&opts_match);
212} 212}
213 213
214static void __exit cleanup(void) 214static void __exit ip6t_dst_fini(void)
215{ 215{
216 ip6t_unregister_match(&opts_match); 216 ip6t_unregister_match(&opts_match);
217} 217}
218 218
219module_init(init); 219module_init(ip6t_dst_init);
220module_exit(cleanup); 220module_exit(ip6t_dst_fini);
diff --git a/net/ipv6/netfilter/ip6t_esp.c b/net/ipv6/netfilter/ip6t_esp.c
index 540b8bfd5055..36bedad2c6f7 100644
--- a/net/ipv6/netfilter/ip6t_esp.c
+++ b/net/ipv6/netfilter/ip6t_esp.c
@@ -101,15 +101,15 @@ static struct ip6t_match esp_match = {
101 .me = THIS_MODULE, 101 .me = THIS_MODULE,
102}; 102};
103 103
104static int __init init(void) 104static int __init ip6t_esp_init(void)
105{ 105{
106 return ip6t_register_match(&esp_match); 106 return ip6t_register_match(&esp_match);
107} 107}
108 108
109static void __exit cleanup(void) 109static void __exit ip6t_esp_fini(void)
110{ 110{
111 ip6t_unregister_match(&esp_match); 111 ip6t_unregister_match(&esp_match);
112} 112}
113 113
114module_init(init); 114module_init(ip6t_esp_init);
115module_exit(cleanup); 115module_exit(ip6t_esp_fini);
diff --git a/net/ipv6/netfilter/ip6t_eui64.c b/net/ipv6/netfilter/ip6t_eui64.c
index d4b0bad52830..94dbdb8b458d 100644
--- a/net/ipv6/netfilter/ip6t_eui64.c
+++ b/net/ipv6/netfilter/ip6t_eui64.c
@@ -70,15 +70,15 @@ static struct ip6t_match eui64_match = {
70 .me = THIS_MODULE, 70 .me = THIS_MODULE,
71}; 71};
72 72
73static int __init init(void) 73static int __init ip6t_eui64_init(void)
74{ 74{
75 return ip6t_register_match(&eui64_match); 75 return ip6t_register_match(&eui64_match);
76} 76}
77 77
78static void __exit fini(void) 78static void __exit ip6t_eui64_fini(void)
79{ 79{
80 ip6t_unregister_match(&eui64_match); 80 ip6t_unregister_match(&eui64_match);
81} 81}
82 82
83module_init(init); 83module_init(ip6t_eui64_init);
84module_exit(fini); 84module_exit(ip6t_eui64_fini);
diff --git a/net/ipv6/netfilter/ip6t_frag.c b/net/ipv6/netfilter/ip6t_frag.c
index 4c41e14823d5..06768c84bd31 100644
--- a/net/ipv6/netfilter/ip6t_frag.c
+++ b/net/ipv6/netfilter/ip6t_frag.c
@@ -139,15 +139,15 @@ static struct ip6t_match frag_match = {
139 .me = THIS_MODULE, 139 .me = THIS_MODULE,
140}; 140};
141 141
142static int __init init(void) 142static int __init ip6t_frag_init(void)
143{ 143{
144 return ip6t_register_match(&frag_match); 144 return ip6t_register_match(&frag_match);
145} 145}
146 146
147static void __exit cleanup(void) 147static void __exit ip6t_frag_fini(void)
148{ 148{
149 ip6t_unregister_match(&frag_match); 149 ip6t_unregister_match(&frag_match);
150} 150}
151 151
152module_init(init); 152module_init(ip6t_frag_init);
153module_exit(cleanup); 153module_exit(ip6t_frag_fini);
diff --git a/net/ipv6/netfilter/ip6t_hbh.c b/net/ipv6/netfilter/ip6t_hbh.c
index b4a1fdfe6abc..374f1be85c0d 100644
--- a/net/ipv6/netfilter/ip6t_hbh.c
+++ b/net/ipv6/netfilter/ip6t_hbh.c
@@ -206,15 +206,15 @@ static struct ip6t_match opts_match = {
206 .me = THIS_MODULE, 206 .me = THIS_MODULE,
207}; 207};
208 208
209static int __init init(void) 209static int __init ip6t_hbh_init(void)
210{ 210{
211 return ip6t_register_match(&opts_match); 211 return ip6t_register_match(&opts_match);
212} 212}
213 213
214static void __exit cleanup(void) 214static void __exit ip6t_hbh_fini(void)
215{ 215{
216 ip6t_unregister_match(&opts_match); 216 ip6t_unregister_match(&opts_match);
217} 217}
218 218
219module_init(init); 219module_init(ip6t_hbh_init);
220module_exit(cleanup); 220module_exit(ip6t_hbh_fini);
diff --git a/net/ipv6/netfilter/ip6t_hl.c b/net/ipv6/netfilter/ip6t_hl.c
index 374055733b26..44a729e17c48 100644
--- a/net/ipv6/netfilter/ip6t_hl.c
+++ b/net/ipv6/netfilter/ip6t_hl.c
@@ -55,16 +55,16 @@ static struct ip6t_match hl_match = {
55 .me = THIS_MODULE, 55 .me = THIS_MODULE,
56}; 56};
57 57
58static int __init init(void) 58static int __init ip6t_hl_init(void)
59{ 59{
60 return ip6t_register_match(&hl_match); 60 return ip6t_register_match(&hl_match);
61} 61}
62 62
63static void __exit fini(void) 63static void __exit ip6t_hl_fini(void)
64{ 64{
65 ip6t_unregister_match(&hl_match); 65 ip6t_unregister_match(&hl_match);
66 66
67} 67}
68 68
69module_init(init); 69module_init(ip6t_hl_init);
70module_exit(fini); 70module_exit(ip6t_hl_fini);
diff --git a/net/ipv6/netfilter/ip6t_multiport.c b/net/ipv6/netfilter/ip6t_multiport.c
index 752b65d21c72..10c48ba596d6 100644
--- a/net/ipv6/netfilter/ip6t_multiport.c
+++ b/net/ipv6/netfilter/ip6t_multiport.c
@@ -111,15 +111,15 @@ static struct ip6t_match multiport_match = {
111 .me = THIS_MODULE, 111 .me = THIS_MODULE,
112}; 112};
113 113
114static int __init init(void) 114static int __init ip6t_multiport_init(void)
115{ 115{
116 return ip6t_register_match(&multiport_match); 116 return ip6t_register_match(&multiport_match);
117} 117}
118 118
119static void __exit fini(void) 119static void __exit ip6t_multiport_fini(void)
120{ 120{
121 ip6t_unregister_match(&multiport_match); 121 ip6t_unregister_match(&multiport_match);
122} 122}
123 123
124module_init(init); 124module_init(ip6t_multiport_init);
125module_exit(fini); 125module_exit(ip6t_multiport_fini);
diff --git a/net/ipv6/netfilter/ip6t_owner.c b/net/ipv6/netfilter/ip6t_owner.c
index e2cee3bcdef9..5d047990cd44 100644
--- a/net/ipv6/netfilter/ip6t_owner.c
+++ b/net/ipv6/netfilter/ip6t_owner.c
@@ -79,15 +79,15 @@ static struct ip6t_match owner_match = {
79 .me = THIS_MODULE, 79 .me = THIS_MODULE,
80}; 80};
81 81
82static int __init init(void) 82static int __init ip6t_owner_init(void)
83{ 83{
84 return ip6t_register_match(&owner_match); 84 return ip6t_register_match(&owner_match);
85} 85}
86 86
87static void __exit fini(void) 87static void __exit ip6t_owner_fini(void)
88{ 88{
89 ip6t_unregister_match(&owner_match); 89 ip6t_unregister_match(&owner_match);
90} 90}
91 91
92module_init(init); 92module_init(ip6t_owner_init);
93module_exit(fini); 93module_exit(ip6t_owner_fini);
diff --git a/net/ipv6/netfilter/ip6t_rt.c b/net/ipv6/netfilter/ip6t_rt.c
index 4c6b55bb225b..fbb0184a41d8 100644
--- a/net/ipv6/netfilter/ip6t_rt.c
+++ b/net/ipv6/netfilter/ip6t_rt.c
@@ -225,15 +225,15 @@ static struct ip6t_match rt_match = {
225 .me = THIS_MODULE, 225 .me = THIS_MODULE,
226}; 226};
227 227
228static int __init init(void) 228static int __init ip6t_rt_init(void)
229{ 229{
230 return ip6t_register_match(&rt_match); 230 return ip6t_register_match(&rt_match);
231} 231}
232 232
233static void __exit cleanup(void) 233static void __exit ip6t_rt_fini(void)
234{ 234{
235 ip6t_unregister_match(&rt_match); 235 ip6t_unregister_match(&rt_match);
236} 236}
237 237
238module_init(init); 238module_init(ip6t_rt_init);
239module_exit(cleanup); 239module_exit(ip6t_rt_fini);
diff --git a/net/ipv6/netfilter/ip6table_filter.c b/net/ipv6/netfilter/ip6table_filter.c
index ce4a968e1f70..e5e724d9ee60 100644
--- a/net/ipv6/netfilter/ip6table_filter.c
+++ b/net/ipv6/netfilter/ip6table_filter.c
@@ -159,7 +159,7 @@ static struct nf_hook_ops ip6t_ops[] = {
159static int forward = NF_ACCEPT; 159static int forward = NF_ACCEPT;
160module_param(forward, bool, 0000); 160module_param(forward, bool, 0000);
161 161
162static int __init init(void) 162static int __init ip6table_filter_init(void)
163{ 163{
164 int ret; 164 int ret;
165 165
@@ -201,7 +201,7 @@ static int __init init(void)
201 return ret; 201 return ret;
202} 202}
203 203
204static void __exit fini(void) 204static void __exit ip6table_filter_fini(void)
205{ 205{
206 unsigned int i; 206 unsigned int i;
207 207
@@ -211,5 +211,5 @@ static void __exit fini(void)
211 ip6t_unregister_table(&packet_filter); 211 ip6t_unregister_table(&packet_filter);
212} 212}
213 213
214module_init(init); 214module_init(ip6table_filter_init);
215module_exit(fini); 215module_exit(ip6table_filter_fini);
diff --git a/net/ipv6/netfilter/ip6table_mangle.c b/net/ipv6/netfilter/ip6table_mangle.c
index 30a4627e000d..e1f0f6ae9841 100644
--- a/net/ipv6/netfilter/ip6table_mangle.c
+++ b/net/ipv6/netfilter/ip6table_mangle.c
@@ -228,7 +228,7 @@ static struct nf_hook_ops ip6t_ops[] = {
228 }, 228 },
229}; 229};
230 230
231static int __init init(void) 231static int __init ip6table_mangle_init(void)
232{ 232{
233 int ret; 233 int ret;
234 234
@@ -274,7 +274,7 @@ static int __init init(void)
274 return ret; 274 return ret;
275} 275}
276 276
277static void __exit fini(void) 277static void __exit ip6table_mangle_fini(void)
278{ 278{
279 unsigned int i; 279 unsigned int i;
280 280
@@ -284,5 +284,5 @@ static void __exit fini(void)
284 ip6t_unregister_table(&packet_mangler); 284 ip6t_unregister_table(&packet_mangler);
285} 285}
286 286
287module_init(init); 287module_init(ip6table_mangle_init);
288module_exit(fini); 288module_exit(ip6table_mangle_fini);
diff --git a/net/ipv6/netfilter/ip6table_raw.c b/net/ipv6/netfilter/ip6table_raw.c
index db28ba3855e2..54d1fffd62ba 100644
--- a/net/ipv6/netfilter/ip6table_raw.c
+++ b/net/ipv6/netfilter/ip6table_raw.c
@@ -142,7 +142,7 @@ static struct nf_hook_ops ip6t_ops[] = {
142 }, 142 },
143}; 143};
144 144
145static int __init init(void) 145static int __init ip6table_raw_init(void)
146{ 146{
147 int ret; 147 int ret;
148 148
@@ -170,7 +170,7 @@ static int __init init(void)
170 return ret; 170 return ret;
171} 171}
172 172
173static void __exit fini(void) 173static void __exit ip6table_raw_fini(void)
174{ 174{
175 unsigned int i; 175 unsigned int i;
176 176
@@ -180,6 +180,6 @@ static void __exit fini(void)
180 ip6t_unregister_table(&packet_raw); 180 ip6t_unregister_table(&packet_raw);
181} 181}
182 182
183module_init(init); 183module_init(ip6table_raw_init);
184module_exit(fini); 184module_exit(ip6table_raw_fini);
185MODULE_LICENSE("GPL"); 185MODULE_LICENSE("GPL");
diff --git a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
index c16f62934bd9..c8b5a96cbb0f 100644
--- a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
+++ b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
@@ -588,16 +588,16 @@ MODULE_ALIAS("nf_conntrack-" __stringify(AF_INET6));
588MODULE_LICENSE("GPL"); 588MODULE_LICENSE("GPL");
589MODULE_AUTHOR("Yasuyuki KOZAKAI @USAGI <yasuyuki.kozakai@toshiba.co.jp>"); 589MODULE_AUTHOR("Yasuyuki KOZAKAI @USAGI <yasuyuki.kozakai@toshiba.co.jp>");
590 590
591static int __init init(void) 591static int __init nf_conntrack_l3proto_ipv6_init(void)
592{ 592{
593 need_conntrack(); 593 need_conntrack();
594 return init_or_cleanup(1); 594 return init_or_cleanup(1);
595} 595}
596 596
597static void __exit fini(void) 597static void __exit nf_conntrack_l3proto_ipv6_fini(void)
598{ 598{
599 init_or_cleanup(0); 599 init_or_cleanup(0);
600} 600}
601 601
602module_init(init); 602module_init(nf_conntrack_l3proto_ipv6_init);
603module_exit(fini); 603module_exit(nf_conntrack_l3proto_ipv6_fini);
diff --git a/net/ipv6/tunnel6.c b/net/ipv6/tunnel6.c
new file mode 100644
index 000000000000..5659b52284bd
--- /dev/null
+++ b/net/ipv6/tunnel6.c
@@ -0,0 +1,131 @@
1/*
2 * Copyright (C)2003,2004 USAGI/WIDE Project
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 *
18 * Authors Mitsuru KANDA <mk@linux-ipv6.org>
19 * YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
20 */
21
22#include <linux/init.h>
23#include <linux/module.h>
24#include <linux/mutex.h>
25#include <linux/netdevice.h>
26#include <linux/skbuff.h>
27#include <net/protocol.h>
28#include <net/xfrm.h>
29
30static struct xfrm6_tunnel *tunnel6_handlers;
31static DEFINE_MUTEX(tunnel6_mutex);
32
33int xfrm6_tunnel_register(struct xfrm6_tunnel *handler)
34{
35 struct xfrm6_tunnel **pprev;
36 int ret = -EEXIST;
37 int priority = handler->priority;
38
39 mutex_lock(&tunnel6_mutex);
40
41 for (pprev = &tunnel6_handlers; *pprev; pprev = &(*pprev)->next) {
42 if ((*pprev)->priority > priority)
43 break;
44 if ((*pprev)->priority == priority)
45 goto err;
46 }
47
48 handler->next = *pprev;
49 *pprev = handler;
50
51 ret = 0;
52
53err:
54 mutex_unlock(&tunnel6_mutex);
55
56 return ret;
57}
58
59EXPORT_SYMBOL(xfrm6_tunnel_register);
60
61int xfrm6_tunnel_deregister(struct xfrm6_tunnel *handler)
62{
63 struct xfrm6_tunnel **pprev;
64 int ret = -ENOENT;
65
66 mutex_lock(&tunnel6_mutex);
67
68 for (pprev = &tunnel6_handlers; *pprev; pprev = &(*pprev)->next) {
69 if (*pprev == handler) {
70 *pprev = handler->next;
71 ret = 0;
72 break;
73 }
74 }
75
76 mutex_unlock(&tunnel6_mutex);
77
78 synchronize_net();
79
80 return ret;
81}
82
83EXPORT_SYMBOL(xfrm6_tunnel_deregister);
84
85static int tunnel6_rcv(struct sk_buff **pskb)
86{
87 struct sk_buff *skb = *pskb;
88 struct xfrm6_tunnel *handler;
89
90 for (handler = tunnel6_handlers; handler; handler = handler->next)
91 if (!handler->handler(skb))
92 return 0;
93
94 kfree_skb(skb);
95 return 0;
96}
97
98static void tunnel6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
99 int type, int code, int offset, __u32 info)
100{
101 struct xfrm6_tunnel *handler;
102
103 for (handler = tunnel6_handlers; handler; handler = handler->next)
104 if (!handler->err_handler(skb, opt, type, code, offset, info))
105 break;
106}
107
108static struct inet6_protocol tunnel6_protocol = {
109 .handler = tunnel6_rcv,
110 .err_handler = tunnel6_err,
111 .flags = INET6_PROTO_NOPOLICY|INET6_PROTO_FINAL,
112};
113
114static int __init tunnel6_init(void)
115{
116 if (inet6_add_protocol(&tunnel6_protocol, IPPROTO_IPV6)) {
117 printk(KERN_ERR "tunnel6 init(): can't add protocol\n");
118 return -EAGAIN;
119 }
120 return 0;
121}
122
123static void __exit tunnel6_fini(void)
124{
125 if (inet6_del_protocol(&tunnel6_protocol, IPPROTO_IPV6))
126 printk(KERN_ERR "tunnel6 close: can't remove protocol\n");
127}
128
129module_init(tunnel6_init);
130module_exit(tunnel6_fini);
131MODULE_LICENSE("GPL");
diff --git a/net/ipv6/xfrm6_input.c b/net/ipv6/xfrm6_input.c
index 1ca2da68ef69..cccf8b76f046 100644
--- a/net/ipv6/xfrm6_input.c
+++ b/net/ipv6/xfrm6_input.c
@@ -28,9 +28,8 @@ static inline void ipip6_ecn_decapsulate(struct sk_buff *skb)
28 IP6_ECN_set_ce(inner_iph); 28 IP6_ECN_set_ce(inner_iph);
29} 29}
30 30
31int xfrm6_rcv_spi(struct sk_buff **pskb, u32 spi) 31int xfrm6_rcv_spi(struct sk_buff *skb, u32 spi)
32{ 32{
33 struct sk_buff *skb = *pskb;
34 int err; 33 int err;
35 u32 seq; 34 u32 seq;
36 struct sec_decap_state xfrm_vec[XFRM_MAX_DEPTH]; 35 struct sec_decap_state xfrm_vec[XFRM_MAX_DEPTH];
@@ -159,5 +158,5 @@ EXPORT_SYMBOL(xfrm6_rcv_spi);
159 158
160int xfrm6_rcv(struct sk_buff **pskb) 159int xfrm6_rcv(struct sk_buff **pskb)
161{ 160{
162 return xfrm6_rcv_spi(pskb, 0); 161 return xfrm6_rcv_spi(*pskb, 0);
163} 162}
diff --git a/net/ipv6/xfrm6_tunnel.c b/net/ipv6/xfrm6_tunnel.c
index 08f9abbdf1d7..a8f6776c518d 100644
--- a/net/ipv6/xfrm6_tunnel.c
+++ b/net/ipv6/xfrm6_tunnel.c
@@ -28,7 +28,6 @@
28#include <net/ip.h> 28#include <net/ip.h>
29#include <net/xfrm.h> 29#include <net/xfrm.h>
30#include <net/ipv6.h> 30#include <net/ipv6.h>
31#include <net/protocol.h>
32#include <linux/ipv6.h> 31#include <linux/ipv6.h>
33#include <linux/icmpv6.h> 32#include <linux/icmpv6.h>
34#include <linux/mutex.h> 33#include <linux/mutex.h>
@@ -357,71 +356,18 @@ static int xfrm6_tunnel_input(struct xfrm_state *x, struct xfrm_decap_state *dec
357 return 0; 356 return 0;
358} 357}
359 358
360static struct xfrm6_tunnel *xfrm6_tunnel_handler; 359static int xfrm6_tunnel_rcv(struct sk_buff *skb)
361static DEFINE_MUTEX(xfrm6_tunnel_mutex);
362
363int xfrm6_tunnel_register(struct xfrm6_tunnel *handler)
364{ 360{
365 int ret;
366
367 mutex_lock(&xfrm6_tunnel_mutex);
368 ret = 0;
369 if (xfrm6_tunnel_handler != NULL)
370 ret = -EINVAL;
371 if (!ret)
372 xfrm6_tunnel_handler = handler;
373 mutex_unlock(&xfrm6_tunnel_mutex);
374
375 return ret;
376}
377
378EXPORT_SYMBOL(xfrm6_tunnel_register);
379
380int xfrm6_tunnel_deregister(struct xfrm6_tunnel *handler)
381{
382 int ret;
383
384 mutex_lock(&xfrm6_tunnel_mutex);
385 ret = 0;
386 if (xfrm6_tunnel_handler != handler)
387 ret = -EINVAL;
388 if (!ret)
389 xfrm6_tunnel_handler = NULL;
390 mutex_unlock(&xfrm6_tunnel_mutex);
391
392 synchronize_net();
393
394 return ret;
395}
396
397EXPORT_SYMBOL(xfrm6_tunnel_deregister);
398
399static int xfrm6_tunnel_rcv(struct sk_buff **pskb)
400{
401 struct sk_buff *skb = *pskb;
402 struct xfrm6_tunnel *handler = xfrm6_tunnel_handler;
403 struct ipv6hdr *iph = skb->nh.ipv6h; 361 struct ipv6hdr *iph = skb->nh.ipv6h;
404 u32 spi; 362 u32 spi;
405 363
406 /* device-like_ip6ip6_handler() */
407 if (handler && handler->handler(pskb) == 0)
408 return 0;
409
410 spi = xfrm6_tunnel_spi_lookup((xfrm_address_t *)&iph->saddr); 364 spi = xfrm6_tunnel_spi_lookup((xfrm_address_t *)&iph->saddr);
411 return xfrm6_rcv_spi(pskb, spi); 365 return xfrm6_rcv_spi(skb, spi);
412} 366}
413 367
414static void xfrm6_tunnel_err(struct sk_buff *skb, struct inet6_skb_parm *opt, 368static int xfrm6_tunnel_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
415 int type, int code, int offset, __u32 info) 369 int type, int code, int offset, __u32 info)
416{ 370{
417 struct xfrm6_tunnel *handler = xfrm6_tunnel_handler;
418
419 /* call here first for device-like ip6ip6 err handling */
420 if (handler) {
421 handler->err_handler(skb, opt, type, code, offset, info);
422 return;
423 }
424
425 /* xfrm6_tunnel native err handling */ 371 /* xfrm6_tunnel native err handling */
426 switch (type) { 372 switch (type) {
427 case ICMPV6_DEST_UNREACH: 373 case ICMPV6_DEST_UNREACH:
@@ -462,7 +408,8 @@ static void xfrm6_tunnel_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
462 default: 408 default:
463 break; 409 break;
464 } 410 }
465 return; 411
412 return 0;
466} 413}
467 414
468static int xfrm6_tunnel_init_state(struct xfrm_state *x) 415static int xfrm6_tunnel_init_state(struct xfrm_state *x)
@@ -493,10 +440,10 @@ static struct xfrm_type xfrm6_tunnel_type = {
493 .output = xfrm6_tunnel_output, 440 .output = xfrm6_tunnel_output,
494}; 441};
495 442
496static struct inet6_protocol xfrm6_tunnel_protocol = { 443static struct xfrm6_tunnel xfrm6_tunnel_handler = {
497 .handler = xfrm6_tunnel_rcv, 444 .handler = xfrm6_tunnel_rcv,
498 .err_handler = xfrm6_tunnel_err, 445 .err_handler = xfrm6_tunnel_err,
499 .flags = INET6_PROTO_NOPOLICY|INET6_PROTO_FINAL, 446 .priority = 2,
500}; 447};
501 448
502static int __init xfrm6_tunnel_init(void) 449static int __init xfrm6_tunnel_init(void)
@@ -508,16 +455,16 @@ static int __init xfrm6_tunnel_init(void)
508 "xfrm6_tunnel init: can't add xfrm type\n"); 455 "xfrm6_tunnel init: can't add xfrm type\n");
509 return -EAGAIN; 456 return -EAGAIN;
510 } 457 }
511 if (inet6_add_protocol(&xfrm6_tunnel_protocol, IPPROTO_IPV6) < 0) { 458 if (xfrm6_tunnel_register(&xfrm6_tunnel_handler)) {
512 X6TPRINTK1(KERN_ERR 459 X6TPRINTK1(KERN_ERR
513 "xfrm6_tunnel init(): can't add protocol\n"); 460 "xfrm6_tunnel init(): can't add handler\n");
514 xfrm_unregister_type(&xfrm6_tunnel_type, AF_INET6); 461 xfrm_unregister_type(&xfrm6_tunnel_type, AF_INET6);
515 return -EAGAIN; 462 return -EAGAIN;
516 } 463 }
517 if (xfrm6_tunnel_spi_init() < 0) { 464 if (xfrm6_tunnel_spi_init() < 0) {
518 X6TPRINTK1(KERN_ERR 465 X6TPRINTK1(KERN_ERR
519 "xfrm6_tunnel init: failed to initialize spi\n"); 466 "xfrm6_tunnel init: failed to initialize spi\n");
520 inet6_del_protocol(&xfrm6_tunnel_protocol, IPPROTO_IPV6); 467 xfrm6_tunnel_deregister(&xfrm6_tunnel_handler);
521 xfrm_unregister_type(&xfrm6_tunnel_type, AF_INET6); 468 xfrm_unregister_type(&xfrm6_tunnel_type, AF_INET6);
522 return -EAGAIN; 469 return -EAGAIN;
523 } 470 }
@@ -529,9 +476,9 @@ static void __exit xfrm6_tunnel_fini(void)
529 X6TPRINTK3(KERN_DEBUG "%s()\n", __FUNCTION__); 476 X6TPRINTK3(KERN_DEBUG "%s()\n", __FUNCTION__);
530 477
531 xfrm6_tunnel_spi_fini(); 478 xfrm6_tunnel_spi_fini();
532 if (inet6_del_protocol(&xfrm6_tunnel_protocol, IPPROTO_IPV6) < 0) 479 if (xfrm6_tunnel_deregister(&xfrm6_tunnel_handler))
533 X6TPRINTK1(KERN_ERR 480 X6TPRINTK1(KERN_ERR
534 "xfrm6_tunnel close: can't remove protocol\n"); 481 "xfrm6_tunnel close: can't remove handler\n");
535 if (xfrm_unregister_type(&xfrm6_tunnel_type, AF_INET6) < 0) 482 if (xfrm_unregister_type(&xfrm6_tunnel_type, AF_INET6) < 0)
536 X6TPRINTK1(KERN_ERR 483 X6TPRINTK1(KERN_ERR
537 "xfrm6_tunnel close: can't remove xfrm type\n"); 484 "xfrm6_tunnel close: can't remove xfrm type\n");
diff --git a/net/ipx/af_ipx.c b/net/ipx/af_ipx.c
index 0fb513a34d11..2dbf134d5266 100644
--- a/net/ipx/af_ipx.c
+++ b/net/ipx/af_ipx.c
@@ -1892,6 +1892,29 @@ static int ipx_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
1892 return rc; 1892 return rc;
1893} 1893}
1894 1894
1895
1896#ifdef CONFIG_COMPAT
1897static int ipx_compat_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
1898{
1899 /*
1900 * These 4 commands use same structure on 32bit and 64bit. Rest of IPX
1901 * commands is handled by generic ioctl code. As these commands are
1902 * SIOCPROTOPRIVATE..SIOCPROTOPRIVATE+3, they cannot be handled by generic
1903 * code.
1904 */
1905 switch (cmd) {
1906 case SIOCAIPXITFCRT:
1907 case SIOCAIPXPRISLT:
1908 case SIOCIPXCFGDATA:
1909 case SIOCIPXNCPCONN:
1910 return ipx_ioctl(sock, cmd, arg);
1911 default:
1912 return -ENOIOCTLCMD;
1913 }
1914}
1915#endif
1916
1917
1895/* 1918/*
1896 * Socket family declarations 1919 * Socket family declarations
1897 */ 1920 */
@@ -1913,6 +1936,9 @@ static const struct proto_ops SOCKOPS_WRAPPED(ipx_dgram_ops) = {
1913 .getname = ipx_getname, 1936 .getname = ipx_getname,
1914 .poll = datagram_poll, 1937 .poll = datagram_poll,
1915 .ioctl = ipx_ioctl, 1938 .ioctl = ipx_ioctl,
1939#ifdef CONFIG_COMPAT
1940 .compat_ioctl = ipx_compat_ioctl,
1941#endif
1916 .listen = sock_no_listen, 1942 .listen = sock_no_listen,
1917 .shutdown = sock_no_shutdown, /* FIXME: support shutdown */ 1943 .shutdown = sock_no_shutdown, /* FIXME: support shutdown */
1918 .setsockopt = ipx_setsockopt, 1944 .setsockopt = ipx_setsockopt,
diff --git a/net/irda/af_irda.c b/net/irda/af_irda.c
index 627b11342233..2f37c9f35e27 100644
--- a/net/irda/af_irda.c
+++ b/net/irda/af_irda.c
@@ -1830,6 +1830,19 @@ static int irda_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
1830 return 0; 1830 return 0;
1831} 1831}
1832 1832
1833#ifdef CONFIG_COMPAT
1834/*
1835 * Function irda_ioctl (sock, cmd, arg)
1836 */
1837static int irda_compat_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
1838{
1839 /*
1840 * All IRDA's ioctl are standard ones.
1841 */
1842 return -ENOIOCTLCMD;
1843}
1844#endif
1845
1833/* 1846/*
1834 * Function irda_setsockopt (sock, level, optname, optval, optlen) 1847 * Function irda_setsockopt (sock, level, optname, optval, optlen)
1835 * 1848 *
@@ -2476,6 +2489,9 @@ static const struct proto_ops SOCKOPS_WRAPPED(irda_stream_ops) = {
2476 .getname = irda_getname, 2489 .getname = irda_getname,
2477 .poll = irda_poll, 2490 .poll = irda_poll,
2478 .ioctl = irda_ioctl, 2491 .ioctl = irda_ioctl,
2492#ifdef CONFIG_COMPAT
2493 .compat_ioctl = irda_compat_ioctl,
2494#endif
2479 .listen = irda_listen, 2495 .listen = irda_listen,
2480 .shutdown = irda_shutdown, 2496 .shutdown = irda_shutdown,
2481 .setsockopt = irda_setsockopt, 2497 .setsockopt = irda_setsockopt,
@@ -2497,6 +2513,9 @@ static const struct proto_ops SOCKOPS_WRAPPED(irda_seqpacket_ops) = {
2497 .getname = irda_getname, 2513 .getname = irda_getname,
2498 .poll = datagram_poll, 2514 .poll = datagram_poll,
2499 .ioctl = irda_ioctl, 2515 .ioctl = irda_ioctl,
2516#ifdef CONFIG_COMPAT
2517 .compat_ioctl = irda_compat_ioctl,
2518#endif
2500 .listen = irda_listen, 2519 .listen = irda_listen,
2501 .shutdown = irda_shutdown, 2520 .shutdown = irda_shutdown,
2502 .setsockopt = irda_setsockopt, 2521 .setsockopt = irda_setsockopt,
@@ -2518,6 +2537,9 @@ static const struct proto_ops SOCKOPS_WRAPPED(irda_dgram_ops) = {
2518 .getname = irda_getname, 2537 .getname = irda_getname,
2519 .poll = datagram_poll, 2538 .poll = datagram_poll,
2520 .ioctl = irda_ioctl, 2539 .ioctl = irda_ioctl,
2540#ifdef CONFIG_COMPAT
2541 .compat_ioctl = irda_compat_ioctl,
2542#endif
2521 .listen = irda_listen, 2543 .listen = irda_listen,
2522 .shutdown = irda_shutdown, 2544 .shutdown = irda_shutdown,
2523 .setsockopt = irda_setsockopt, 2545 .setsockopt = irda_setsockopt,
@@ -2540,6 +2562,9 @@ static const struct proto_ops SOCKOPS_WRAPPED(irda_ultra_ops) = {
2540 .getname = irda_getname, 2562 .getname = irda_getname,
2541 .poll = datagram_poll, 2563 .poll = datagram_poll,
2542 .ioctl = irda_ioctl, 2564 .ioctl = irda_ioctl,
2565#ifdef CONFIG_COMPAT
2566 .compat_ioctl = irda_compat_ioctl,
2567#endif
2543 .listen = sock_no_listen, 2568 .listen = sock_no_listen,
2544 .shutdown = irda_shutdown, 2569 .shutdown = irda_shutdown,
2545 .setsockopt = irda_setsockopt, 2570 .setsockopt = irda_setsockopt,
diff --git a/net/netfilter/nf_conntrack_ftp.c b/net/netfilter/nf_conntrack_ftp.c
index cd191b0d4ac7..e38a4b5a3089 100644
--- a/net/netfilter/nf_conntrack_ftp.c
+++ b/net/netfilter/nf_conntrack_ftp.c
@@ -624,7 +624,7 @@ static struct nf_conntrack_helper ftp[MAX_PORTS][2];
624static char ftp_names[MAX_PORTS][2][sizeof("ftp-65535")]; 624static char ftp_names[MAX_PORTS][2][sizeof("ftp-65535")];
625 625
626/* don't make this __exit, since it's called from __init ! */ 626/* don't make this __exit, since it's called from __init ! */
627static void fini(void) 627static void nf_conntrack_ftp_fini(void)
628{ 628{
629 int i, j; 629 int i, j;
630 for (i = 0; i < ports_c; i++) { 630 for (i = 0; i < ports_c; i++) {
@@ -642,7 +642,7 @@ static void fini(void)
642 kfree(ftp_buffer); 642 kfree(ftp_buffer);
643} 643}
644 644
645static int __init init(void) 645static int __init nf_conntrack_ftp_init(void)
646{ 646{
647 int i, j = -1, ret = 0; 647 int i, j = -1, ret = 0;
648 char *tmpname; 648 char *tmpname;
@@ -683,7 +683,7 @@ static int __init init(void)
683 printk("nf_ct_ftp: failed to register helper " 683 printk("nf_ct_ftp: failed to register helper "
684 " for pf: %d port: %d\n", 684 " for pf: %d port: %d\n",
685 ftp[i][j].tuple.src.l3num, ports[i]); 685 ftp[i][j].tuple.src.l3num, ports[i]);
686 fini(); 686 nf_conntrack_ftp_fini();
687 return ret; 687 return ret;
688 } 688 }
689 } 689 }
@@ -692,5 +692,5 @@ static int __init init(void)
692 return 0; 692 return 0;
693} 693}
694 694
695module_init(init); 695module_init(nf_conntrack_ftp_init);
696module_exit(fini); 696module_exit(nf_conntrack_ftp_fini);
diff --git a/net/netfilter/nf_conntrack_proto_sctp.c b/net/netfilter/nf_conntrack_proto_sctp.c
index cf798e61e379..9cccc325b687 100644
--- a/net/netfilter/nf_conntrack_proto_sctp.c
+++ b/net/netfilter/nf_conntrack_proto_sctp.c
@@ -615,7 +615,7 @@ static ctl_table nf_ct_net_table[] = {
615static struct ctl_table_header *nf_ct_sysctl_header; 615static struct ctl_table_header *nf_ct_sysctl_header;
616#endif 616#endif
617 617
618int __init init(void) 618int __init nf_conntrack_proto_sctp_init(void)
619{ 619{
620 int ret; 620 int ret;
621 621
@@ -652,7 +652,7 @@ int __init init(void)
652 return ret; 652 return ret;
653} 653}
654 654
655void __exit fini(void) 655void __exit nf_conntrack_proto_sctp_fini(void)
656{ 656{
657 nf_conntrack_protocol_unregister(&nf_conntrack_protocol_sctp6); 657 nf_conntrack_protocol_unregister(&nf_conntrack_protocol_sctp6);
658 nf_conntrack_protocol_unregister(&nf_conntrack_protocol_sctp4); 658 nf_conntrack_protocol_unregister(&nf_conntrack_protocol_sctp4);
@@ -662,8 +662,8 @@ void __exit fini(void)
662 DEBUGP("SCTP conntrack module unloaded\n"); 662 DEBUGP("SCTP conntrack module unloaded\n");
663} 663}
664 664
665module_init(init); 665module_init(nf_conntrack_proto_sctp_init);
666module_exit(fini); 666module_exit(nf_conntrack_proto_sctp_fini);
667 667
668MODULE_LICENSE("GPL"); 668MODULE_LICENSE("GPL");
669MODULE_AUTHOR("Kiran Kumar Immidi"); 669MODULE_AUTHOR("Kiran Kumar Immidi");
diff --git a/net/netfilter/nf_conntrack_standalone.c b/net/netfilter/nf_conntrack_standalone.c
index 75577e175b35..c72aa3cd22e4 100644
--- a/net/netfilter/nf_conntrack_standalone.c
+++ b/net/netfilter/nf_conntrack_standalone.c
@@ -806,18 +806,18 @@ void nf_conntrack_protocol_unregister(struct nf_conntrack_protocol *proto)
806 nf_ct_iterate_cleanup(kill_proto, proto); 806 nf_ct_iterate_cleanup(kill_proto, proto);
807} 807}
808 808
809static int __init init(void) 809static int __init nf_conntrack_standalone_init(void)
810{ 810{
811 return init_or_cleanup(1); 811 return init_or_cleanup(1);
812} 812}
813 813
814static void __exit fini(void) 814static void __exit nf_conntrack_standalone_fini(void)
815{ 815{
816 init_or_cleanup(0); 816 init_or_cleanup(0);
817} 817}
818 818
819module_init(init); 819module_init(nf_conntrack_standalone_init);
820module_exit(fini); 820module_exit(nf_conntrack_standalone_fini);
821 821
822/* Some modules need us, but don't depend directly on any symbol. 822/* Some modules need us, but don't depend directly on any symbol.
823 They should call this. */ 823 They should call this. */
diff --git a/net/netfilter/nfnetlink_log.c b/net/netfilter/nfnetlink_log.c
index 54cbbaa712dc..3e3f5448bacb 100644
--- a/net/netfilter/nfnetlink_log.c
+++ b/net/netfilter/nfnetlink_log.c
@@ -1081,13 +1081,13 @@ cleanup_netlink_notifier:
1081 return status; 1081 return status;
1082} 1082}
1083 1083
1084static int __init init(void) 1084static int __init nfnetlink_log_init(void)
1085{ 1085{
1086 1086
1087 return init_or_cleanup(1); 1087 return init_or_cleanup(1);
1088} 1088}
1089 1089
1090static void __exit fini(void) 1090static void __exit nfnetlink_log_fini(void)
1091{ 1091{
1092 init_or_cleanup(0); 1092 init_or_cleanup(0);
1093} 1093}
@@ -1097,5 +1097,5 @@ MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>");
1097MODULE_LICENSE("GPL"); 1097MODULE_LICENSE("GPL");
1098MODULE_ALIAS_NFNL_SUBSYS(NFNL_SUBSYS_ULOG); 1098MODULE_ALIAS_NFNL_SUBSYS(NFNL_SUBSYS_ULOG);
1099 1099
1100module_init(init); 1100module_init(nfnetlink_log_init);
1101module_exit(fini); 1101module_exit(nfnetlink_log_fini);
diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c
index b5701662182e..d0e62f68139f 100644
--- a/net/netfilter/nfnetlink_queue.c
+++ b/net/netfilter/nfnetlink_queue.c
@@ -1117,13 +1117,13 @@ cleanup_netlink_notifier:
1117 return status; 1117 return status;
1118} 1118}
1119 1119
1120static int __init init(void) 1120static int __init nfnetlink_queue_init(void)
1121{ 1121{
1122 1122
1123 return init_or_cleanup(1); 1123 return init_or_cleanup(1);
1124} 1124}
1125 1125
1126static void __exit fini(void) 1126static void __exit nfnetlink_queue_fini(void)
1127{ 1127{
1128 init_or_cleanup(0); 1128 init_or_cleanup(0);
1129} 1129}
@@ -1133,5 +1133,5 @@ MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>");
1133MODULE_LICENSE("GPL"); 1133MODULE_LICENSE("GPL");
1134MODULE_ALIAS_NFNL_SUBSYS(NFNL_SUBSYS_QUEUE); 1134MODULE_ALIAS_NFNL_SUBSYS(NFNL_SUBSYS_QUEUE);
1135 1135
1136module_init(init); 1136module_init(nfnetlink_queue_init);
1137module_exit(fini); 1137module_exit(nfnetlink_queue_fini);
diff --git a/net/netfilter/xt_CLASSIFY.c b/net/netfilter/xt_CLASSIFY.c
index 3cd2ac90a25b..e54e57730012 100644
--- a/net/netfilter/xt_CLASSIFY.c
+++ b/net/netfilter/xt_CLASSIFY.c
@@ -62,7 +62,7 @@ static struct xt_target classify6_reg = {
62}; 62};
63 63
64 64
65static int __init init(void) 65static int __init xt_classify_init(void)
66{ 66{
67 int ret; 67 int ret;
68 68
@@ -77,11 +77,11 @@ static int __init init(void)
77 return ret; 77 return ret;
78} 78}
79 79
80static void __exit fini(void) 80static void __exit xt_classify_fini(void)
81{ 81{
82 xt_unregister_target(&classify_reg); 82 xt_unregister_target(&classify_reg);
83 xt_unregister_target(&classify6_reg); 83 xt_unregister_target(&classify6_reg);
84} 84}
85 85
86module_init(init); 86module_init(xt_classify_init);
87module_exit(fini); 87module_exit(xt_classify_fini);
diff --git a/net/netfilter/xt_CONNMARK.c b/net/netfilter/xt_CONNMARK.c
index 35448b8e6883..60c375d36f01 100644
--- a/net/netfilter/xt_CONNMARK.c
+++ b/net/netfilter/xt_CONNMARK.c
@@ -115,7 +115,7 @@ static struct xt_target connmark6_reg = {
115 .me = THIS_MODULE 115 .me = THIS_MODULE
116}; 116};
117 117
118static int __init init(void) 118static int __init xt_connmark_init(void)
119{ 119{
120 int ret; 120 int ret;
121 121
@@ -132,11 +132,11 @@ static int __init init(void)
132 return ret; 132 return ret;
133} 133}
134 134
135static void __exit fini(void) 135static void __exit xt_connmark_fini(void)
136{ 136{
137 xt_unregister_target(&connmark_reg); 137 xt_unregister_target(&connmark_reg);
138 xt_unregister_target(&connmark6_reg); 138 xt_unregister_target(&connmark6_reg);
139} 139}
140 140
141module_init(init); 141module_init(xt_connmark_init);
142module_exit(fini); 142module_exit(xt_connmark_fini);
diff --git a/net/netfilter/xt_MARK.c b/net/netfilter/xt_MARK.c
index 73bdd5c80e17..ee9c34edc76c 100644
--- a/net/netfilter/xt_MARK.c
+++ b/net/netfilter/xt_MARK.c
@@ -145,7 +145,7 @@ static struct xt_target ip6t_mark_reg_v0 = {
145 .revision = 0, 145 .revision = 0,
146}; 146};
147 147
148static int __init init(void) 148static int __init xt_mark_init(void)
149{ 149{
150 int err; 150 int err;
151 151
@@ -166,12 +166,12 @@ static int __init init(void)
166 return err; 166 return err;
167} 167}
168 168
169static void __exit fini(void) 169static void __exit xt_mark_fini(void)
170{ 170{
171 xt_unregister_target(&ipt_mark_reg_v0); 171 xt_unregister_target(&ipt_mark_reg_v0);
172 xt_unregister_target(&ipt_mark_reg_v1); 172 xt_unregister_target(&ipt_mark_reg_v1);
173 xt_unregister_target(&ip6t_mark_reg_v0); 173 xt_unregister_target(&ip6t_mark_reg_v0);
174} 174}
175 175
176module_init(init); 176module_init(xt_mark_init);
177module_exit(fini); 177module_exit(xt_mark_fini);
diff --git a/net/netfilter/xt_NFQUEUE.c b/net/netfilter/xt_NFQUEUE.c
index 2873e1c60f68..86ccceb61fdd 100644
--- a/net/netfilter/xt_NFQUEUE.c
+++ b/net/netfilter/xt_NFQUEUE.c
@@ -61,7 +61,7 @@ static struct xt_target arpt_NFQ_reg = {
61 .me = THIS_MODULE, 61 .me = THIS_MODULE,
62}; 62};
63 63
64static int __init init(void) 64static int __init xt_nfqueue_init(void)
65{ 65{
66 int ret; 66 int ret;
67 ret = xt_register_target(&ipt_NFQ_reg); 67 ret = xt_register_target(&ipt_NFQ_reg);
@@ -83,12 +83,12 @@ out_ip:
83 return ret; 83 return ret;
84} 84}
85 85
86static void __exit fini(void) 86static void __exit xt_nfqueue_fini(void)
87{ 87{
88 xt_unregister_target(&arpt_NFQ_reg); 88 xt_unregister_target(&arpt_NFQ_reg);
89 xt_unregister_target(&ip6t_NFQ_reg); 89 xt_unregister_target(&ip6t_NFQ_reg);
90 xt_unregister_target(&ipt_NFQ_reg); 90 xt_unregister_target(&ipt_NFQ_reg);
91} 91}
92 92
93module_init(init); 93module_init(xt_nfqueue_init);
94module_exit(fini); 94module_exit(xt_nfqueue_fini);
diff --git a/net/netfilter/xt_NOTRACK.c b/net/netfilter/xt_NOTRACK.c
index cf2ebd76fd6f..98f4b5363ce8 100644
--- a/net/netfilter/xt_NOTRACK.c
+++ b/net/netfilter/xt_NOTRACK.c
@@ -52,7 +52,7 @@ static struct xt_target notrack6_reg = {
52 .me = THIS_MODULE, 52 .me = THIS_MODULE,
53}; 53};
54 54
55static int __init init(void) 55static int __init xt_notrack_init(void)
56{ 56{
57 int ret; 57 int ret;
58 58
@@ -67,11 +67,11 @@ static int __init init(void)
67 return ret; 67 return ret;
68} 68}
69 69
70static void __exit fini(void) 70static void __exit xt_notrack_fini(void)
71{ 71{
72 xt_unregister_target(&notrack6_reg); 72 xt_unregister_target(&notrack6_reg);
73 xt_unregister_target(&notrack_reg); 73 xt_unregister_target(&notrack_reg);
74} 74}
75 75
76module_init(init); 76module_init(xt_notrack_init);
77module_exit(fini); 77module_exit(xt_notrack_fini);
diff --git a/net/netfilter/xt_comment.c b/net/netfilter/xt_comment.c
index 2637724b498d..197609cb06d7 100644
--- a/net/netfilter/xt_comment.c
+++ b/net/netfilter/xt_comment.c
@@ -45,7 +45,7 @@ static struct xt_match comment6_match = {
45 .me = THIS_MODULE 45 .me = THIS_MODULE
46}; 46};
47 47
48static int __init init(void) 48static int __init xt_comment_init(void)
49{ 49{
50 int ret; 50 int ret;
51 51
@@ -60,11 +60,11 @@ static int __init init(void)
60 return ret; 60 return ret;
61} 61}
62 62
63static void __exit fini(void) 63static void __exit xt_comment_fini(void)
64{ 64{
65 xt_unregister_match(&comment_match); 65 xt_unregister_match(&comment_match);
66 xt_unregister_match(&comment6_match); 66 xt_unregister_match(&comment6_match);
67} 67}
68 68
69module_init(init); 69module_init(xt_comment_init);
70module_exit(fini); 70module_exit(xt_comment_fini);
diff --git a/net/netfilter/xt_connbytes.c b/net/netfilter/xt_connbytes.c
index 4985f5ec58ca..1396fe2d07c1 100644
--- a/net/netfilter/xt_connbytes.c
+++ b/net/netfilter/xt_connbytes.c
@@ -160,7 +160,7 @@ static struct xt_match connbytes6_match = {
160 .me = THIS_MODULE 160 .me = THIS_MODULE
161}; 161};
162 162
163static int __init init(void) 163static int __init xt_connbytes_init(void)
164{ 164{
165 int ret; 165 int ret;
166 ret = xt_register_match(&connbytes_match); 166 ret = xt_register_match(&connbytes_match);
@@ -173,11 +173,11 @@ static int __init init(void)
173 return ret; 173 return ret;
174} 174}
175 175
176static void __exit fini(void) 176static void __exit xt_connbytes_fini(void)
177{ 177{
178 xt_unregister_match(&connbytes_match); 178 xt_unregister_match(&connbytes_match);
179 xt_unregister_match(&connbytes6_match); 179 xt_unregister_match(&connbytes6_match);
180} 180}
181 181
182module_init(init); 182module_init(xt_connbytes_init);
183module_exit(fini); 183module_exit(xt_connbytes_fini);
diff --git a/net/netfilter/xt_connmark.c b/net/netfilter/xt_connmark.c
index 7b16f1ee16b4..dc26a27cbcaf 100644
--- a/net/netfilter/xt_connmark.c
+++ b/net/netfilter/xt_connmark.c
@@ -102,7 +102,7 @@ static struct xt_match connmark6_match = {
102 .me = THIS_MODULE 102 .me = THIS_MODULE
103}; 103};
104 104
105static int __init init(void) 105static int __init xt_connmark_init(void)
106{ 106{
107 int ret; 107 int ret;
108 108
@@ -118,11 +118,11 @@ static int __init init(void)
118 return ret; 118 return ret;
119} 119}
120 120
121static void __exit fini(void) 121static void __exit xt_connmark_fini(void)
122{ 122{
123 xt_unregister_match(&connmark6_match); 123 xt_unregister_match(&connmark6_match);
124 xt_unregister_match(&connmark_match); 124 xt_unregister_match(&connmark_match);
125} 125}
126 126
127module_init(init); 127module_init(xt_connmark_init);
128module_exit(fini); 128module_exit(xt_connmark_fini);
diff --git a/net/netfilter/xt_conntrack.c b/net/netfilter/xt_conntrack.c
index 65a84809fd30..145489a4c3f2 100644
--- a/net/netfilter/xt_conntrack.c
+++ b/net/netfilter/xt_conntrack.c
@@ -239,7 +239,7 @@ static struct xt_match conntrack_match = {
239 .me = THIS_MODULE, 239 .me = THIS_MODULE,
240}; 240};
241 241
242static int __init init(void) 242static int __init xt_conntrack_init(void)
243{ 243{
244 int ret; 244 int ret;
245 need_conntrack(); 245 need_conntrack();
@@ -248,10 +248,10 @@ static int __init init(void)
248 return ret; 248 return ret;
249} 249}
250 250
251static void __exit fini(void) 251static void __exit xt_conntrack_fini(void)
252{ 252{
253 xt_unregister_match(&conntrack_match); 253 xt_unregister_match(&conntrack_match);
254} 254}
255 255
256module_init(init); 256module_init(xt_conntrack_init);
257module_exit(fini); 257module_exit(xt_conntrack_fini);
diff --git a/net/netfilter/xt_dccp.c b/net/netfilter/xt_dccp.c
index 2f331decd151..dfb10b648e57 100644
--- a/net/netfilter/xt_dccp.c
+++ b/net/netfilter/xt_dccp.c
@@ -164,7 +164,7 @@ static struct xt_match dccp6_match =
164}; 164};
165 165
166 166
167static int __init init(void) 167static int __init xt_dccp_init(void)
168{ 168{
169 int ret; 169 int ret;
170 170
@@ -191,12 +191,12 @@ out_kfree:
191 return ret; 191 return ret;
192} 192}
193 193
194static void __exit fini(void) 194static void __exit xt_dccp_fini(void)
195{ 195{
196 xt_unregister_match(&dccp6_match); 196 xt_unregister_match(&dccp6_match);
197 xt_unregister_match(&dccp_match); 197 xt_unregister_match(&dccp_match);
198 kfree(dccp_optbuf); 198 kfree(dccp_optbuf);
199} 199}
200 200
201module_init(init); 201module_init(xt_dccp_init);
202module_exit(fini); 202module_exit(xt_dccp_fini);
diff --git a/net/netfilter/xt_helper.c b/net/netfilter/xt_helper.c
index 101f0005e987..799c2a43e3b9 100644
--- a/net/netfilter/xt_helper.c
+++ b/net/netfilter/xt_helper.c
@@ -182,7 +182,7 @@ static struct xt_match helper6_match = {
182 .me = THIS_MODULE, 182 .me = THIS_MODULE,
183}; 183};
184 184
185static int __init init(void) 185static int __init xt_helper_init(void)
186{ 186{
187 int ret; 187 int ret;
188 need_conntrack(); 188 need_conntrack();
@@ -198,12 +198,12 @@ static int __init init(void)
198 return ret; 198 return ret;
199} 199}
200 200
201static void __exit fini(void) 201static void __exit xt_helper_fini(void)
202{ 202{
203 xt_unregister_match(&helper_match); 203 xt_unregister_match(&helper_match);
204 xt_unregister_match(&helper6_match); 204 xt_unregister_match(&helper6_match);
205} 205}
206 206
207module_init(init); 207module_init(xt_helper_init);
208module_exit(fini); 208module_exit(xt_helper_fini);
209 209
diff --git a/net/netfilter/xt_length.c b/net/netfilter/xt_length.c
index 38560caef757..109132c9a146 100644
--- a/net/netfilter/xt_length.c
+++ b/net/netfilter/xt_length.c
@@ -68,7 +68,7 @@ static struct xt_match length6_match = {
68 .me = THIS_MODULE, 68 .me = THIS_MODULE,
69}; 69};
70 70
71static int __init init(void) 71static int __init xt_length_init(void)
72{ 72{
73 int ret; 73 int ret;
74 ret = xt_register_match(&length_match); 74 ret = xt_register_match(&length_match);
@@ -81,11 +81,11 @@ static int __init init(void)
81 return ret; 81 return ret;
82} 82}
83 83
84static void __exit fini(void) 84static void __exit xt_length_fini(void)
85{ 85{
86 xt_unregister_match(&length_match); 86 xt_unregister_match(&length_match);
87 xt_unregister_match(&length6_match); 87 xt_unregister_match(&length6_match);
88} 88}
89 89
90module_init(init); 90module_init(xt_length_init);
91module_exit(fini); 91module_exit(xt_length_fini);
diff --git a/net/netfilter/xt_limit.c b/net/netfilter/xt_limit.c
index e91c1a444e77..ce7fdb7e4e07 100644
--- a/net/netfilter/xt_limit.c
+++ b/net/netfilter/xt_limit.c
@@ -153,7 +153,7 @@ static struct xt_match limit6_reg = {
153 .me = THIS_MODULE, 153 .me = THIS_MODULE,
154}; 154};
155 155
156static int __init init(void) 156static int __init xt_limit_init(void)
157{ 157{
158 int ret; 158 int ret;
159 159
@@ -168,11 +168,11 @@ static int __init init(void)
168 return ret; 168 return ret;
169} 169}
170 170
171static void __exit fini(void) 171static void __exit xt_limit_fini(void)
172{ 172{
173 xt_unregister_match(&ipt_limit_reg); 173 xt_unregister_match(&ipt_limit_reg);
174 xt_unregister_match(&limit6_reg); 174 xt_unregister_match(&limit6_reg);
175} 175}
176 176
177module_init(init); 177module_init(xt_limit_init);
178module_exit(fini); 178module_exit(xt_limit_fini);
diff --git a/net/netfilter/xt_mac.c b/net/netfilter/xt_mac.c
index f4defa28a6ec..356290ffe386 100644
--- a/net/netfilter/xt_mac.c
+++ b/net/netfilter/xt_mac.c
@@ -62,7 +62,7 @@ static struct xt_match mac6_match = {
62 .me = THIS_MODULE, 62 .me = THIS_MODULE,
63}; 63};
64 64
65static int __init init(void) 65static int __init xt_mac_init(void)
66{ 66{
67 int ret; 67 int ret;
68 ret = xt_register_match(&mac_match); 68 ret = xt_register_match(&mac_match);
@@ -76,11 +76,11 @@ static int __init init(void)
76 return ret; 76 return ret;
77} 77}
78 78
79static void __exit fini(void) 79static void __exit xt_mac_fini(void)
80{ 80{
81 xt_unregister_match(&mac_match); 81 xt_unregister_match(&mac_match);
82 xt_unregister_match(&mac6_match); 82 xt_unregister_match(&mac6_match);
83} 83}
84 84
85module_init(init); 85module_init(xt_mac_init);
86module_exit(fini); 86module_exit(xt_mac_fini);
diff --git a/net/netfilter/xt_mark.c b/net/netfilter/xt_mark.c
index ce0badfeef9a..8b385a34886d 100644
--- a/net/netfilter/xt_mark.c
+++ b/net/netfilter/xt_mark.c
@@ -69,7 +69,7 @@ static struct xt_match mark6_match = {
69 .me = THIS_MODULE, 69 .me = THIS_MODULE,
70}; 70};
71 71
72static int __init init(void) 72static int __init xt_mark_init(void)
73{ 73{
74 int ret; 74 int ret;
75 ret = xt_register_match(&mark_match); 75 ret = xt_register_match(&mark_match);
@@ -83,11 +83,11 @@ static int __init init(void)
83 return ret; 83 return ret;
84} 84}
85 85
86static void __exit fini(void) 86static void __exit xt_mark_fini(void)
87{ 87{
88 xt_unregister_match(&mark_match); 88 xt_unregister_match(&mark_match);
89 xt_unregister_match(&mark6_match); 89 xt_unregister_match(&mark6_match);
90} 90}
91 91
92module_init(init); 92module_init(xt_mark_init);
93module_exit(fini); 93module_exit(xt_mark_fini);
diff --git a/net/netfilter/xt_physdev.c b/net/netfilter/xt_physdev.c
index 089f4f7e8636..5fe4c9df17f5 100644
--- a/net/netfilter/xt_physdev.c
+++ b/net/netfilter/xt_physdev.c
@@ -134,7 +134,7 @@ static struct xt_match physdev6_match = {
134 .me = THIS_MODULE, 134 .me = THIS_MODULE,
135}; 135};
136 136
137static int __init init(void) 137static int __init xt_physdev_init(void)
138{ 138{
139 int ret; 139 int ret;
140 140
@@ -149,11 +149,11 @@ static int __init init(void)
149 return ret; 149 return ret;
150} 150}
151 151
152static void __exit fini(void) 152static void __exit xt_physdev_fini(void)
153{ 153{
154 xt_unregister_match(&physdev_match); 154 xt_unregister_match(&physdev_match);
155 xt_unregister_match(&physdev6_match); 155 xt_unregister_match(&physdev6_match);
156} 156}
157 157
158module_init(init); 158module_init(xt_physdev_init);
159module_exit(fini); 159module_exit(xt_physdev_fini);
diff --git a/net/netfilter/xt_pkttype.c b/net/netfilter/xt_pkttype.c
index 8b8bca988ac6..3ac703b5cb8f 100644
--- a/net/netfilter/xt_pkttype.c
+++ b/net/netfilter/xt_pkttype.c
@@ -49,7 +49,7 @@ static struct xt_match pkttype6_match = {
49 .me = THIS_MODULE, 49 .me = THIS_MODULE,
50}; 50};
51 51
52static int __init init(void) 52static int __init xt_pkttype_init(void)
53{ 53{
54 int ret; 54 int ret;
55 ret = xt_register_match(&pkttype_match); 55 ret = xt_register_match(&pkttype_match);
@@ -63,11 +63,11 @@ static int __init init(void)
63 return ret; 63 return ret;
64} 64}
65 65
66static void __exit fini(void) 66static void __exit xt_pkttype_fini(void)
67{ 67{
68 xt_unregister_match(&pkttype_match); 68 xt_unregister_match(&pkttype_match);
69 xt_unregister_match(&pkttype6_match); 69 xt_unregister_match(&pkttype6_match);
70} 70}
71 71
72module_init(init); 72module_init(xt_pkttype_init);
73module_exit(fini); 73module_exit(xt_pkttype_fini);
diff --git a/net/netfilter/xt_realm.c b/net/netfilter/xt_realm.c
index 5e31a4a835bf..a80b7d132b65 100644
--- a/net/netfilter/xt_realm.c
+++ b/net/netfilter/xt_realm.c
@@ -49,15 +49,15 @@ static struct xt_match realm_match = {
49 .me = THIS_MODULE 49 .me = THIS_MODULE
50}; 50};
51 51
52static int __init init(void) 52static int __init xt_realm_init(void)
53{ 53{
54 return xt_register_match(&realm_match); 54 return xt_register_match(&realm_match);
55} 55}
56 56
57static void __exit fini(void) 57static void __exit xt_realm_fini(void)
58{ 58{
59 xt_unregister_match(&realm_match); 59 xt_unregister_match(&realm_match);
60} 60}
61 61
62module_init(init); 62module_init(xt_realm_init);
63module_exit(fini); 63module_exit(xt_realm_fini);
diff --git a/net/netfilter/xt_sctp.c b/net/netfilter/xt_sctp.c
index c6eb24a2fe13..34bd87259a09 100644
--- a/net/netfilter/xt_sctp.c
+++ b/net/netfilter/xt_sctp.c
@@ -200,7 +200,7 @@ static struct xt_match sctp6_match = {
200 .me = THIS_MODULE 200 .me = THIS_MODULE
201}; 201};
202 202
203static int __init init(void) 203static int __init xt_sctp_init(void)
204{ 204{
205 int ret; 205 int ret;
206 ret = xt_register_match(&sctp_match); 206 ret = xt_register_match(&sctp_match);
@@ -214,11 +214,11 @@ static int __init init(void)
214 return ret; 214 return ret;
215} 215}
216 216
217static void __exit fini(void) 217static void __exit xt_sctp_fini(void)
218{ 218{
219 xt_unregister_match(&sctp6_match); 219 xt_unregister_match(&sctp6_match);
220 xt_unregister_match(&sctp_match); 220 xt_unregister_match(&sctp_match);
221} 221}
222 222
223module_init(init); 223module_init(xt_sctp_init);
224module_exit(fini); 224module_exit(xt_sctp_fini);
diff --git a/net/netfilter/xt_state.c b/net/netfilter/xt_state.c
index e6c0be9d94d2..f9e304dc4504 100644
--- a/net/netfilter/xt_state.c
+++ b/net/netfilter/xt_state.c
@@ -89,7 +89,7 @@ static struct xt_match state6_match = {
89 .me = THIS_MODULE, 89 .me = THIS_MODULE,
90}; 90};
91 91
92static int __init init(void) 92static int __init xt_state_init(void)
93{ 93{
94 int ret; 94 int ret;
95 95
@@ -106,11 +106,11 @@ static int __init init(void)
106 return ret; 106 return ret;
107} 107}
108 108
109static void __exit fini(void) 109static void __exit xt_state_fini(void)
110{ 110{
111 xt_unregister_match(&state_match); 111 xt_unregister_match(&state_match);
112 xt_unregister_match(&state6_match); 112 xt_unregister_match(&state6_match);
113} 113}
114 114
115module_init(init); 115module_init(xt_state_init);
116module_exit(fini); 116module_exit(xt_state_fini);
diff --git a/net/netfilter/xt_string.c b/net/netfilter/xt_string.c
index 703d80fccacf..79d9ea6964ba 100644
--- a/net/netfilter/xt_string.c
+++ b/net/netfilter/xt_string.c
@@ -91,7 +91,7 @@ static struct xt_match string6_match = {
91 .me = THIS_MODULE 91 .me = THIS_MODULE
92}; 92};
93 93
94static int __init init(void) 94static int __init xt_string_init(void)
95{ 95{
96 int ret; 96 int ret;
97 97
@@ -105,11 +105,11 @@ static int __init init(void)
105 return ret; 105 return ret;
106} 106}
107 107
108static void __exit fini(void) 108static void __exit xt_string_fini(void)
109{ 109{
110 xt_unregister_match(&string_match); 110 xt_unregister_match(&string_match);
111 xt_unregister_match(&string6_match); 111 xt_unregister_match(&string6_match);
112} 112}
113 113
114module_init(init); 114module_init(xt_string_init);
115module_exit(fini); 115module_exit(xt_string_fini);
diff --git a/net/netfilter/xt_tcpmss.c b/net/netfilter/xt_tcpmss.c
index 70a8858ae3f1..cf7d335cadcd 100644
--- a/net/netfilter/xt_tcpmss.c
+++ b/net/netfilter/xt_tcpmss.c
@@ -112,7 +112,7 @@ static struct xt_match tcpmss6_match = {
112}; 112};
113 113
114 114
115static int __init init(void) 115static int __init xt_tcpmss_init(void)
116{ 116{
117 int ret; 117 int ret;
118 ret = xt_register_match(&tcpmss_match); 118 ret = xt_register_match(&tcpmss_match);
@@ -126,11 +126,11 @@ static int __init init(void)
126 return ret; 126 return ret;
127} 127}
128 128
129static void __exit fini(void) 129static void __exit xt_tcpmss_fini(void)
130{ 130{
131 xt_unregister_match(&tcpmss6_match); 131 xt_unregister_match(&tcpmss6_match);
132 xt_unregister_match(&tcpmss_match); 132 xt_unregister_match(&tcpmss_match);
133} 133}
134 134
135module_init(init); 135module_init(xt_tcpmss_init);
136module_exit(fini); 136module_exit(xt_tcpmss_fini);
diff --git a/net/netfilter/xt_tcpudp.c b/net/netfilter/xt_tcpudp.c
index 14a990eb666a..1b61dac9c873 100644
--- a/net/netfilter/xt_tcpudp.c
+++ b/net/netfilter/xt_tcpudp.c
@@ -238,7 +238,7 @@ static struct xt_match udp6_matchstruct = {
238 .me = THIS_MODULE, 238 .me = THIS_MODULE,
239}; 239};
240 240
241static int __init init(void) 241static int __init xt_tcpudp_init(void)
242{ 242{
243 int ret; 243 int ret;
244 ret = xt_register_match(&tcp_matchstruct); 244 ret = xt_register_match(&tcp_matchstruct);
@@ -268,7 +268,7 @@ out_unreg_tcp:
268 return ret; 268 return ret;
269} 269}
270 270
271static void __exit fini(void) 271static void __exit xt_tcpudp_fini(void)
272{ 272{
273 xt_unregister_match(&udp6_matchstruct); 273 xt_unregister_match(&udp6_matchstruct);
274 xt_unregister_match(&udp_matchstruct); 274 xt_unregister_match(&udp_matchstruct);
@@ -276,5 +276,5 @@ static void __exit fini(void)
276 xt_unregister_match(&tcp_matchstruct); 276 xt_unregister_match(&tcp_matchstruct);
277} 277}
278 278
279module_init(init); 279module_init(xt_tcpudp_init);
280module_exit(fini); 280module_exit(xt_tcpudp_fini);
diff --git a/net/socket.c b/net/socket.c
index fcd77eac0ccf..b13042f68c02 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -119,6 +119,9 @@ static ssize_t sock_writev(struct file *file, const struct iovec *vector,
119static ssize_t sock_sendpage(struct file *file, struct page *page, 119static ssize_t sock_sendpage(struct file *file, struct page *page,
120 int offset, size_t size, loff_t *ppos, int more); 120 int offset, size_t size, loff_t *ppos, int more);
121 121
122extern ssize_t generic_splice_sendpage(struct inode *inode, struct file *out,
123 size_t len, unsigned int flags);
124
122 125
123/* 126/*
124 * Socket files have a set of 'special' operations as well as the generic file ones. These don't appear 127 * Socket files have a set of 'special' operations as well as the generic file ones. These don't appear
@@ -141,7 +144,8 @@ static struct file_operations socket_file_ops = {
141 .fasync = sock_fasync, 144 .fasync = sock_fasync,
142 .readv = sock_readv, 145 .readv = sock_readv,
143 .writev = sock_writev, 146 .writev = sock_writev,
144 .sendpage = sock_sendpage 147 .sendpage = sock_sendpage,
148 .splice_write = generic_splice_sendpage,
145}; 149};
146 150
147/* 151/*
diff --git a/sound/oss/dmasound/dmasound_awacs.c b/sound/oss/dmasound/dmasound_awacs.c
index 3bbc8105e9f1..c8e210326893 100644
--- a/sound/oss/dmasound/dmasound_awacs.c
+++ b/sound/oss/dmasound/dmasound_awacs.c
@@ -2814,7 +2814,7 @@ int __init dmasound_awacs_init(void)
2814 struct device_node *io = NULL, *info = NULL; 2814 struct device_node *io = NULL, *info = NULL;
2815 int vol, res; 2815 int vol, res;
2816 2816
2817 if (_machine != _MACH_Pmac) 2817 if (!machine_is(powermac))
2818 return -ENODEV; 2818 return -ENODEV;
2819 2819
2820 awacs_subframe = 0; 2820 awacs_subframe = 0;
diff --git a/sound/ppc/pmac.c b/sound/ppc/pmac.c
index aa57170101fd..f0794ef9d1ac 100644
--- a/sound/ppc/pmac.c
+++ b/sound/ppc/pmac.c
@@ -869,7 +869,7 @@ static int __init snd_pmac_detect(struct snd_pmac *chip)
869 869
870 u32 layout_id = 0; 870 u32 layout_id = 0;
871 871
872 if (_machine != _MACH_Pmac) 872 if (!machine_is(powermac))
873 return -ENODEV; 873 return -ENODEV;
874 874
875 chip->subframe = 0; 875 chip->subframe = 0;