From b5e5c7c26f6a5516b2727e6d84c74404e54d94de Mon Sep 17 00:00:00 2001 From: Russell King Date: Wed, 29 Mar 2006 22:03:38 +0100 Subject: [PATCH] --- yaml --- r: 25011 b: refs/heads/master c: 0cff260a42c051ee64c184ed05d96d18d243f7f6 h: refs/heads/master i: 25009: 4762e3570df1a3189b2186b671fd8ee75aa698eb 25007: 7e3ee42439e18e885499a56c238ac2634654dd1c v: v3 --- [refs] | 2 +- trunk/Documentation/DocBook/libata.tmpl | 47 +- .../feature-removal-schedule.txt | 19 +- trunk/Documentation/leds-class.txt | 71 - trunk/Documentation/memory-barriers.txt | 1913 -------- trunk/Documentation/networking/TODO | 18 + trunk/Documentation/networking/bcm43xx.txt | 36 - .../powerpc/booting-without-of.txt | 5 - trunk/MAINTAINERS | 1 - trunk/arch/alpha/kernel/alpha_ksyms.c | 2 + trunk/arch/alpha/kernel/core_marvel.c | 2 +- trunk/arch/arm/Kconfig | 10 - trunk/arch/arm/Kconfig-nommu | 44 - trunk/arch/arm/Makefile | 9 +- trunk/arch/arm/boot/compressed/head.S | 106 - trunk/arch/arm/common/sharpsl_pm.c | 10 +- trunk/arch/arm/kernel/entry-armv.S | 2 +- trunk/arch/arm/kernel/head-common.S | 217 - trunk/arch/arm/kernel/head-nommu.S | 83 - trunk/arch/arm/kernel/head.S | 207 +- trunk/arch/arm/kernel/process.c | 1 + trunk/arch/arm/kernel/signal.h | 2 +- trunk/arch/arm/kernel/traps.c | 9 +- trunk/arch/arm/mach-pxa/corgi.c | 11 - trunk/arch/arm/mach-pxa/spitz.c | 11 - trunk/arch/arm/mach-pxa/tosa.c | 9 - trunk/arch/arm/mm/proc-xsc3.S | 1 - trunk/arch/arm26/kernel/armksyms.c | 2 + trunk/arch/frv/kernel/frv_ksyms.c | 2 + trunk/arch/h8300/kernel/h8300_ksyms.c | 2 + trunk/arch/i386/kernel/apic.c | 22 +- trunk/arch/i386/kernel/cpu/mcheck/mce.c | 4 +- trunk/arch/i386/kernel/io_apic.c | 2 +- trunk/arch/i386/kernel/process.c | 1 + trunk/arch/i386/kernel/syscall_table.S | 2 - trunk/arch/i386/kernel/traps.c | 2 +- trunk/arch/i386/kernel/vsyscall-sigreturn.S | 2 +- trunk/arch/ia64/kernel/entry.S | 1 - trunk/arch/ia64/kernel/gate.lds.S | 1 - trunk/arch/ia64/kernel/iosapic.c | 265 +- trunk/arch/ia64/kernel/palinfo.c | 8 +- trunk/arch/ia64/kernel/time.c | 2 +- trunk/arch/ia64/kernel/topology.c | 367 -- trunk/arch/ia64/kernel/vmlinux.lds.S | 18 +- trunk/arch/ia64/mm/init.c | 8 +- trunk/arch/ia64/mm/ioremap.c | 6 +- trunk/arch/ia64/mm/tlb.c | 12 +- trunk/arch/ia64/sn/kernel/sn2/sn_hwperf.c | 8 +- trunk/arch/m68k/kernel/m68k_ksyms.c | 1 + trunk/arch/m68knommu/kernel/m68k_ksyms.c | 2 + trunk/arch/mips/kernel/process.c | 1 + trunk/arch/parisc/Kconfig | 6 +- trunk/arch/parisc/configs/712_defconfig | 160 +- trunk/arch/parisc/configs/a500_defconfig | 4 +- trunk/arch/parisc/configs/b180_defconfig | 12 +- trunk/arch/parisc/configs/c3000_defconfig | 252 +- trunk/arch/parisc/defconfig | 165 +- trunk/arch/parisc/kernel/cache.c | 6 +- trunk/arch/parisc/kernel/entry.S | 45 +- trunk/arch/parisc/kernel/pacache.S | 4 +- trunk/arch/parisc/kernel/parisc_ksyms.c | 19 + trunk/arch/parisc/kernel/pdc_chassis.c | 5 +- trunk/arch/parisc/kernel/perf.c | 2 +- trunk/arch/parisc/kernel/syscall_table.S | 2 +- trunk/arch/parisc/lib/iomap.c | 4 + trunk/arch/parisc/mm/init.c | 7 +- trunk/arch/parisc/mm/ioremap.c | 54 +- trunk/arch/powerpc/Kconfig | 4 +- trunk/arch/powerpc/Kconfig.debug | 5 + trunk/arch/powerpc/Makefile | 7 +- trunk/arch/powerpc/configs/cell_defconfig | 133 +- .../powerpc/configs/mpc8540_ads_defconfig | 43 +- trunk/arch/powerpc/kernel/Makefile | 11 +- trunk/arch/powerpc/kernel/asm-offsets.c | 2 + trunk/arch/powerpc/kernel/crash_dump.c | 4 +- trunk/arch/powerpc/kernel/entry_32.S | 8 +- trunk/arch/powerpc/kernel/entry_64.S | 6 - trunk/arch/powerpc/kernel/firmware.c | 4 +- trunk/arch/powerpc/kernel/head_64.S | 32 +- .../arch/powerpc/kernel/{idle.c => idle_64.c} | 79 +- trunk/arch/powerpc/kernel/idle_6xx.S | 18 +- trunk/arch/powerpc/kernel/idle_power4.S | 38 +- trunk/arch/powerpc/kernel/irq.c | 2 +- trunk/arch/powerpc/kernel/legacy_serial.c | 42 +- trunk/arch/powerpc/kernel/lparcfg.c | 4 +- trunk/arch/powerpc/kernel/nvram_64.c | 7 +- trunk/arch/powerpc/kernel/paca.c | 21 +- trunk/arch/powerpc/kernel/pci_32.c | 4 +- trunk/arch/powerpc/kernel/pci_64.c | 1 - trunk/arch/powerpc/kernel/proc_ppc64.c | 3 +- trunk/arch/powerpc/kernel/process.c | 12 +- trunk/arch/powerpc/kernel/prom.c | 154 +- trunk/arch/powerpc/kernel/prom_init.c | 68 +- trunk/arch/powerpc/kernel/rtas-proc.c | 2 +- trunk/arch/powerpc/kernel/rtas.c | 8 +- trunk/arch/powerpc/kernel/setup-common.c | 70 +- trunk/arch/powerpc/kernel/setup_32.c | 75 +- trunk/arch/powerpc/kernel/setup_64.c | 78 +- trunk/arch/powerpc/kernel/signal_32.c | 1 - trunk/arch/powerpc/kernel/signal_64.c | 3 +- trunk/arch/powerpc/kernel/smp.c | 2 +- trunk/arch/powerpc/kernel/syscalls.c | 1 - trunk/arch/powerpc/kernel/sysfs.c | 12 +- trunk/arch/powerpc/kernel/time.c | 4 +- trunk/arch/powerpc/kernel/traps.c | 35 +- trunk/arch/powerpc/kernel/vdso.c | 9 +- trunk/arch/powerpc/kernel/vdso32/sigtramp.S | 2 +- trunk/arch/powerpc/kernel/vdso64/sigtramp.S | 2 +- trunk/arch/powerpc/kernel/vmlinux.lds.S | 381 +- trunk/arch/powerpc/lib/sstep.c | 2 +- trunk/arch/powerpc/mm/fault.c | 30 +- trunk/arch/powerpc/mm/hash_utils_64.c | 7 +- trunk/arch/powerpc/mm/mem.c | 2 +- trunk/arch/powerpc/mm/numa.c | 2 - trunk/arch/powerpc/mm/pgtable_32.c | 6 +- trunk/arch/powerpc/mm/stab.c | 2 +- trunk/arch/powerpc/oprofile/Makefile | 2 +- trunk/arch/powerpc/oprofile/backtrace.c | 126 - trunk/arch/powerpc/oprofile/common.c | 9 +- trunk/arch/powerpc/oprofile/op_model_7450.c | 4 +- .../powerpc/oprofile/op_model_fsl_booke.c | 4 +- trunk/arch/powerpc/oprofile/op_model_power4.c | 45 +- trunk/arch/powerpc/oprofile/op_model_rs64.c | 5 +- trunk/arch/powerpc/platforms/85xx/Kconfig | 1 - trunk/arch/powerpc/platforms/cell/Kconfig | 5 - trunk/arch/powerpc/platforms/cell/Makefile | 10 +- trunk/arch/powerpc/platforms/cell/interrupt.c | 133 +- trunk/arch/powerpc/platforms/cell/interrupt.h | 2 +- trunk/arch/powerpc/platforms/cell/iommu.c | 16 +- trunk/arch/powerpc/platforms/cell/pervasive.c | 4 +- trunk/arch/powerpc/platforms/cell/setup.c | 11 +- .../arch/powerpc/platforms/cell/spider-pic.c | 108 +- trunk/arch/powerpc/platforms/cell/spu_base.c | 17 +- .../powerpc/platforms/cell/spu_callbacks.c | 345 -- .../platforms/cell/spufs/backing_ops.c | 47 - .../powerpc/platforms/cell/spufs/context.c | 24 +- .../arch/powerpc/platforms/cell/spufs/file.c | 523 +-- .../powerpc/platforms/cell/spufs/hw_ops.c | 57 - .../arch/powerpc/platforms/cell/spufs/inode.c | 6 +- trunk/arch/powerpc/platforms/cell/spufs/run.c | 91 - .../arch/powerpc/platforms/cell/spufs/sched.c | 2 - .../arch/powerpc/platforms/cell/spufs/spufs.h | 28 +- .../powerpc/platforms/cell/spufs/switch.c | 3 +- trunk/arch/powerpc/platforms/chrp/chrp.h | 2 +- trunk/arch/powerpc/platforms/chrp/setup.c | 77 +- trunk/arch/powerpc/platforms/iseries/setup.c | 13 +- trunk/arch/powerpc/platforms/maple/setup.c | 10 +- .../powerpc/platforms/powermac/bootx_init.c | 6 +- .../arch/powerpc/platforms/powermac/feature.c | 2 +- .../arch/powerpc/platforms/powermac/low_i2c.c | 3 - trunk/arch/powerpc/platforms/powermac/nvram.c | 14 +- trunk/arch/powerpc/platforms/powermac/pci.c | 5 +- .../powerpc/platforms/powermac/pfunc_base.c | 2 - trunk/arch/powerpc/platforms/powermac/setup.c | 74 +- trunk/arch/powerpc/platforms/powermac/time.c | 4 +- .../powerpc/platforms/powermac/udbg_scc.c | 2 +- trunk/arch/powerpc/platforms/pseries/eeh.c | 2 +- .../powerpc/platforms/pseries/eeh_driver.c | 16 +- .../arch/powerpc/platforms/pseries/firmware.c | 2 +- .../powerpc/platforms/pseries/hvconsole.c | 5 - trunk/arch/powerpc/platforms/pseries/pci.c | 2 +- .../powerpc/platforms/pseries/pci_dlpar.c | 11 +- trunk/arch/powerpc/platforms/pseries/ras.c | 2 +- .../arch/powerpc/platforms/pseries/reconfig.c | 5 +- trunk/arch/powerpc/platforms/pseries/rtasd.c | 3 +- trunk/arch/powerpc/platforms/pseries/setup.c | 231 +- trunk/arch/powerpc/platforms/pseries/xics.c | 4 +- trunk/arch/ppc/Kconfig | 93 +- trunk/arch/ppc/Kconfig.debug | 7 + trunk/arch/ppc/Makefile | 6 +- trunk/arch/ppc/boot/Makefile | 7 +- trunk/arch/ppc/boot/openfirmware/Makefile | 109 + trunk/arch/ppc/boot/openfirmware/chrpmain.c | 101 + trunk/arch/ppc/boot/openfirmware/common.c | 146 + trunk/arch/ppc/boot/openfirmware/dummy.c | 4 + trunk/arch/ppc/boot/openfirmware/misc.S | 67 + trunk/arch/ppc/boot/openfirmware/start.c | 172 + trunk/arch/ppc/boot/simple/mpc10x_memory.c | 4 +- trunk/arch/ppc/boot/simple/relocate.S | 2 +- trunk/arch/ppc/boot/utils/addnote.c | 175 + trunk/arch/ppc/boot/utils/hack-coff.c | 84 + trunk/arch/ppc/boot/utils/mknote.c | 44 + .../{prep_defconfig => common_defconfig} | 0 trunk/arch/ppc/configs/ibmchrp_defconfig | 875 ++++ trunk/arch/ppc/configs/pmac_defconfig | 1591 +++++++ trunk/arch/ppc/configs/power3_defconfig | 1035 +++++ trunk/arch/ppc/kernel/Makefile | 28 +- .../{powerpc => ppc}/kernel/cpu_setup_6xx.S | 0 trunk/arch/ppc/kernel/entry.S | 60 +- trunk/arch/ppc/kernel/head.S | 183 +- trunk/arch/ppc/kernel/idle.c | 112 + trunk/arch/ppc/kernel/idle_6xx.S | 233 + trunk/arch/ppc/kernel/idle_power4.S | 91 + .../kernel/l2cr_6xx.S => ppc/kernel/l2cr.S} | 0 .../module_32.c => ppc/kernel/module.c} | 0 trunk/arch/ppc/kernel/pci.c | 396 ++ .../kernel/perfmon_fsl_booke.c | 0 trunk/arch/ppc/kernel/ppc_htab.c | 8 +- trunk/arch/ppc/kernel/ppc_ksyms.c | 26 + trunk/arch/ppc/kernel/setup.c | 256 +- trunk/arch/ppc/kernel/smp.c | 2 +- .../swsusp_32.S => ppc/kernel/swsusp.S} | 0 .../kernel/tau_6xx.c => ppc/kernel/temp.c} | 0 trunk/arch/ppc/lib/strcase.c | 3 +- trunk/arch/{powerpc => ppc}/math-emu/Makefile | 0 trunk/arch/{powerpc => ppc}/math-emu/double.h | 0 trunk/arch/{powerpc => ppc}/math-emu/fabs.c | 0 trunk/arch/{powerpc => ppc}/math-emu/fadd.c | 0 trunk/arch/{powerpc => ppc}/math-emu/fadds.c | 0 trunk/arch/{powerpc => ppc}/math-emu/fcmpo.c | 0 trunk/arch/{powerpc => ppc}/math-emu/fcmpu.c | 0 trunk/arch/{powerpc => ppc}/math-emu/fctiw.c | 0 trunk/arch/{powerpc => ppc}/math-emu/fctiwz.c | 0 trunk/arch/{powerpc => ppc}/math-emu/fdiv.c | 0 trunk/arch/{powerpc => ppc}/math-emu/fdivs.c | 0 trunk/arch/{powerpc => ppc}/math-emu/fmadd.c | 0 trunk/arch/{powerpc => ppc}/math-emu/fmadds.c | 0 trunk/arch/{powerpc => ppc}/math-emu/fmr.c | 0 trunk/arch/{powerpc => ppc}/math-emu/fmsub.c | 0 trunk/arch/{powerpc => ppc}/math-emu/fmsubs.c | 0 trunk/arch/{powerpc => ppc}/math-emu/fmul.c | 0 trunk/arch/{powerpc => ppc}/math-emu/fmuls.c | 0 trunk/arch/{powerpc => ppc}/math-emu/fnabs.c | 0 trunk/arch/{powerpc => ppc}/math-emu/fneg.c | 0 trunk/arch/{powerpc => ppc}/math-emu/fnmadd.c | 0 .../arch/{powerpc => ppc}/math-emu/fnmadds.c | 0 trunk/arch/{powerpc => ppc}/math-emu/fnmsub.c | 0 .../arch/{powerpc => ppc}/math-emu/fnmsubs.c | 0 trunk/arch/{powerpc => ppc}/math-emu/fres.c | 0 trunk/arch/{powerpc => ppc}/math-emu/frsp.c | 0 .../arch/{powerpc => ppc}/math-emu/frsqrte.c | 0 trunk/arch/{powerpc => ppc}/math-emu/fsel.c | 0 trunk/arch/{powerpc => ppc}/math-emu/fsqrt.c | 0 trunk/arch/{powerpc => ppc}/math-emu/fsqrts.c | 0 trunk/arch/{powerpc => ppc}/math-emu/fsub.c | 0 trunk/arch/{powerpc => ppc}/math-emu/fsubs.c | 0 trunk/arch/{powerpc => ppc}/math-emu/lfd.c | 0 trunk/arch/{powerpc => ppc}/math-emu/lfs.c | 0 trunk/arch/{powerpc => ppc}/math-emu/math.c | 0 trunk/arch/{powerpc => ppc}/math-emu/mcrfs.c | 0 trunk/arch/{powerpc => ppc}/math-emu/mffs.c | 0 trunk/arch/{powerpc => ppc}/math-emu/mtfsb0.c | 0 trunk/arch/{powerpc => ppc}/math-emu/mtfsb1.c | 0 trunk/arch/{powerpc => ppc}/math-emu/mtfsf.c | 0 trunk/arch/{powerpc => ppc}/math-emu/mtfsfi.c | 0 trunk/arch/{powerpc => ppc}/math-emu/op-1.h | 0 trunk/arch/{powerpc => ppc}/math-emu/op-2.h | 0 trunk/arch/{powerpc => ppc}/math-emu/op-4.h | 0 .../{powerpc => ppc}/math-emu/op-common.h | 0 .../{powerpc => ppc}/math-emu/sfp-machine.h | 0 trunk/arch/{powerpc => ppc}/math-emu/single.h | 0 .../arch/{powerpc => ppc}/math-emu/soft-fp.h | 0 trunk/arch/{powerpc => ppc}/math-emu/stfd.c | 0 trunk/arch/{powerpc => ppc}/math-emu/stfiwx.c | 0 trunk/arch/{powerpc => ppc}/math-emu/stfs.c | 0 trunk/arch/{powerpc => ppc}/math-emu/types.c | 0 .../{powerpc => ppc}/math-emu/udivmodti4.c | 0 trunk/arch/ppc/mm/fault.c | 30 +- trunk/arch/ppc/mm/hashtable.S | 34 + trunk/arch/ppc/mm/init.c | 13 + trunk/arch/ppc/mm/mmu_context.c | 2 +- trunk/arch/ppc/mm/pgtable.c | 8 +- trunk/arch/ppc/mm/ppc_mmu.c | 28 +- trunk/arch/ppc/platforms/Makefile | 12 + trunk/arch/ppc/platforms/chrp_nvram.c | 83 + trunk/arch/ppc/platforms/chrp_pci.c | 309 ++ trunk/arch/ppc/platforms/chrp_pegasos_eth.c | 211 + trunk/arch/ppc/platforms/chrp_setup.c | 669 +++ trunk/arch/ppc/platforms/chrp_smp.c | 99 + trunk/arch/ppc/platforms/chrp_time.c | 235 + trunk/arch/ppc/platforms/lite5200.c | 71 +- trunk/arch/ppc/platforms/prep_setup.c | 12 +- trunk/arch/ppc/syslib/Makefile | 2 + trunk/arch/ppc/syslib/mpc52xx_pci.c | 3 +- trunk/arch/ppc/syslib/mpc52xx_setup.c | 48 - trunk/arch/ppc/syslib/open_pic.c | 2 +- trunk/arch/ppc/syslib/prom.c | 1429 ++++++ trunk/arch/ppc/syslib/prom_init.c | 1011 +++++ trunk/arch/ppc/xmon/start.c | 2 +- trunk/arch/s390/kernel/smp.c | 6 +- trunk/arch/sh/kernel/cpu/init.c | 2 +- trunk/arch/sh/kernel/setup.c | 2 +- trunk/arch/um/Kconfig | 3 - trunk/arch/um/Makefile | 7 +- trunk/arch/um/Makefile-x86_64 | 2 +- trunk/arch/um/drivers/daemon_kern.c | 13 +- trunk/arch/um/drivers/harddog_kern.c | 8 +- trunk/arch/um/drivers/hostaudio_kern.c | 10 +- trunk/arch/um/drivers/mcast_kern.c | 13 +- trunk/arch/um/drivers/mconsole_kern.c | 140 +- trunk/arch/um/drivers/pcap_kern.c | 13 +- trunk/arch/um/drivers/slip_kern.c | 13 +- trunk/arch/um/drivers/slirp_kern.c | 15 +- trunk/arch/um/drivers/ubd_kern.c | 2 +- trunk/arch/um/include/kern_util.h | 6 +- trunk/arch/um/include/line.h | 18 +- trunk/arch/um/include/mem_user.h | 1 + trunk/arch/um/include/os.h | 10 +- trunk/arch/um/include/sysdep-i386/checksum.h | 5 +- trunk/arch/um/include/sysdep-i386/ptrace.h | 5 - trunk/arch/um/include/sysdep-i386/tls.h | 32 - trunk/arch/um/include/sysdep-x86_64/tls.h | 29 - trunk/arch/um/include/user_util.h | 5 +- trunk/arch/um/kernel/exec_kern.c | 16 +- trunk/arch/um/kernel/mem.c | 2 +- trunk/arch/um/kernel/process_kern.c | 26 +- trunk/arch/um/kernel/ptrace.c | 44 +- trunk/arch/um/kernel/skas/process_kern.c | 11 - trunk/arch/um/kernel/syscall_kern.c | 4 +- trunk/arch/um/kernel/trap_kern.c | 8 +- trunk/arch/um/kernel/tt/process_kern.c | 10 +- trunk/arch/um/os-Linux/Makefile | 7 +- .../arch/um/os-Linux/drivers/ethertap_kern.c | 13 +- trunk/arch/um/os-Linux/drivers/tuntap_kern.c | 13 +- trunk/arch/um/os-Linux/mem.c | 27 +- trunk/arch/um/os-Linux/process.c | 44 - trunk/arch/um/os-Linux/start_up.c | 20 + trunk/arch/um/os-Linux/sys-i386/Makefile | 2 +- trunk/arch/um/os-Linux/sys-i386/tls.c | 33 - trunk/arch/um/os-Linux/tls.c | 76 - trunk/arch/um/scripts/Makefile.rules | 26 +- trunk/arch/um/scripts/Makefile.unmap | 22 + trunk/arch/um/sys-i386/Makefile | 23 +- trunk/arch/um/sys-i386/ptrace.c | 45 +- trunk/arch/um/sys-i386/ptrace_user.c | 10 +- trunk/arch/um/sys-i386/signal.c | 48 +- trunk/arch/um/sys-i386/sys_call_table.S | 2 + trunk/arch/um/sys-i386/syscalls.c | 16 +- trunk/arch/um/sys-i386/tls.c | 384 -- trunk/arch/um/sys-x86_64/Makefile | 34 +- trunk/arch/um/sys-x86_64/tls.c | 14 - trunk/arch/x86_64/ia32/vsyscall-sigreturn.S | 23 +- trunk/arch/x86_64/kernel/apic.c | 14 +- trunk/arch/x86_64/kernel/early_printk.c | 2 +- trunk/arch/x86_64/kernel/mce.c | 4 +- trunk/arch/x86_64/kernel/pmtimer.c | 2 +- trunk/arch/x86_64/kernel/setup.c | 2 +- trunk/arch/x86_64/kernel/setup64.c | 4 +- trunk/arch/x86_64/kernel/smpboot.c | 2 +- trunk/arch/x86_64/kernel/time.c | 4 +- trunk/arch/x86_64/kernel/traps.c | 4 +- trunk/arch/x86_64/kernel/x8664_ksyms.c | 2 + trunk/arch/x86_64/mm/fault.c | 2 +- trunk/arch/xtensa/kernel/xtensa_ksyms.c | 2 + trunk/block/Kconfig | 8 +- trunk/block/elevator.c | 2 +- trunk/block/genhd.c | 103 +- trunk/drivers/Kconfig | 2 - trunk/drivers/Makefile | 1 - trunk/drivers/acpi/ec.c | 4 +- trunk/drivers/block/amiflop.c | 1 - trunk/drivers/char/Kconfig | 17 - trunk/drivers/char/Makefile | 4 +- trunk/drivers/char/drm/drmP.h | 16 +- trunk/drivers/char/drm/drm_bufs.c | 20 +- trunk/drivers/char/drm/drm_dma.c | 4 +- trunk/drivers/char/drm/drm_memory.c | 59 + trunk/drivers/char/drm/drm_memory_debug.h | 70 + trunk/drivers/char/drm/drm_pci.c | 29 +- trunk/drivers/char/drm/drm_pciids.h | 116 +- trunk/drivers/char/drm/i915_dma.c | 2 + trunk/drivers/char/drm/i915_irq.c | 2 - trunk/drivers/char/drm/r300_cmdbuf.c | 86 +- trunk/drivers/char/drm/r300_reg.h | 39 +- trunk/drivers/char/drm/radeon_cp.c | 151 +- trunk/drivers/char/drm/radeon_drm.h | 5 - trunk/drivers/char/drm/radeon_drv.h | 25 +- trunk/drivers/char/drm/radeon_state.c | 105 +- trunk/drivers/char/drm/sis_mm.c | 2 +- trunk/drivers/char/generic_nvram.c | 5 +- trunk/drivers/char/hvc_console.c | 101 +- trunk/drivers/char/hvc_console.h | 63 - trunk/drivers/char/hvc_rtas.c | 138 - trunk/drivers/char/hvc_vio.c | 11 - trunk/drivers/char/hvcs.c | 1 + trunk/drivers/char/ipmi/ipmi_devintf.c | 18 +- trunk/drivers/char/ipmi/ipmi_kcs_sm.c | 8 +- trunk/drivers/char/ipmi/ipmi_msghandler.c | 80 +- trunk/drivers/char/ipmi/ipmi_poweroff.c | 2 +- trunk/drivers/char/ipmi/ipmi_si_intf.c | 85 +- trunk/drivers/char/ipmi/ipmi_watchdog.c | 61 +- trunk/drivers/char/istallion.c | 32 +- trunk/drivers/char/stallion.c | 46 +- trunk/drivers/char/tty_io.c | 2 +- trunk/drivers/char/vt.c | 4 - trunk/drivers/edac/Kconfig | 2 +- trunk/drivers/ide/ide-disk.c | 3 - trunk/drivers/ide/ide-taskfile.c | 8 +- trunk/drivers/ide/pci/via82cxxx.c | 2 +- trunk/drivers/ide/ppc/pmac.c | 2 +- trunk/drivers/ieee1394/ohci1394.c | 4 +- trunk/drivers/infiniband/core/mad.c | 112 +- trunk/drivers/infiniband/core/mad_priv.h | 3 +- trunk/drivers/infiniband/core/mad_rmpp.c | 54 +- trunk/drivers/infiniband/core/user_mad.c | 30 +- trunk/drivers/infiniband/hw/mthca/mthca_av.c | 2 +- trunk/drivers/infiniband/hw/mthca/mthca_cq.c | 2 +- trunk/drivers/infiniband/hw/mthca/mthca_eq.c | 6 +- trunk/drivers/infiniband/hw/mthca/mthca_mad.c | 2 +- trunk/drivers/infiniband/hw/mthca/mthca_mcg.c | 2 +- trunk/drivers/infiniband/hw/mthca/mthca_mr.c | 4 +- trunk/drivers/infiniband/hw/mthca/mthca_pd.c | 2 +- trunk/drivers/infiniband/hw/mthca/mthca_qp.c | 2 +- trunk/drivers/infiniband/hw/mthca/mthca_srq.c | 4 +- .../drivers/infiniband/ulp/ipoib/ipoib_main.c | 2 +- trunk/drivers/infiniband/ulp/srp/ib_srp.c | 4 +- trunk/drivers/input/keyboard/hil_kbd.c | 56 +- trunk/drivers/input/keyboard/hilkbd.c | 53 +- trunk/drivers/input/mouse/hil_ptr.c | 90 +- trunk/drivers/input/serio/gscps2.c | 4 +- trunk/drivers/isdn/sc/ioctl.c | 9 +- trunk/drivers/leds/Kconfig | 77 - trunk/drivers/leds/Makefile | 16 - trunk/drivers/leds/led-class.c | 167 - trunk/drivers/leds/led-core.c | 25 - trunk/drivers/leds/led-triggers.c | 239 - trunk/drivers/leds/leds-corgi.c | 121 - trunk/drivers/leds/leds-ixp4xx-gpio.c | 215 - trunk/drivers/leds/leds-locomo.c | 95 - trunk/drivers/leds/leds-spitz.c | 125 - trunk/drivers/leds/leds-tosa.c | 131 - trunk/drivers/leds/leds.h | 44 - trunk/drivers/leds/ledtrig-ide-disk.c | 62 - trunk/drivers/leds/ledtrig-timer.c | 170 - trunk/drivers/macintosh/adb.c | 3 +- trunk/drivers/macintosh/adbhid.c | 4 +- trunk/drivers/macintosh/mediabay.c | 4 +- trunk/drivers/md/md.c | 8 +- trunk/drivers/md/raid1.c | 13 +- trunk/drivers/md/raid6main.c | 2 - trunk/drivers/media/video/cpia_pp.c | 2 +- trunk/drivers/media/video/planb.c | 2 +- trunk/drivers/mmc/Kconfig | 11 - trunk/drivers/mmc/Makefile | 5 - trunk/drivers/mmc/au1xmmc.c | 19 +- trunk/drivers/mmc/mmc.c | 19 +- trunk/drivers/mmc/mmci.c | 4 + trunk/drivers/mmc/omap.c | 1226 ----- trunk/drivers/mmc/omap.h | 55 - trunk/drivers/mmc/pxamci.c | 24 +- trunk/drivers/mmc/sdhci.c | 6 +- trunk/drivers/mmc/wbsd.c | 9 +- trunk/drivers/mtd/chips/amd_flash.c | 4 +- trunk/drivers/mtd/chips/jedec_probe.c | 19 +- trunk/drivers/mtd/chips/sharp.c | 7 +- trunk/drivers/mtd/cmdlinepart.c | 7 +- trunk/drivers/mtd/devices/blkmtd.c | 13 +- trunk/drivers/mtd/devices/block2mtd.c | 13 +- trunk/drivers/mtd/devices/doc2000.c | 37 +- trunk/drivers/mtd/devices/lart.c | 10 +- trunk/drivers/mtd/devices/m25p80.c | 2 +- trunk/drivers/mtd/devices/ms02-nv.c | 2 +- trunk/drivers/mtd/inftlcore.c | 7 +- trunk/drivers/mtd/maps/alchemy-flash.c | 4 +- trunk/drivers/mtd/maps/cfi_flagadm.c | 2 +- trunk/drivers/mtd/maps/dbox2-flash.c | 2 +- trunk/drivers/mtd/maps/dilnetpc.c | 4 +- trunk/drivers/mtd/maps/dmv182.c | 2 +- trunk/drivers/mtd/maps/h720x-flash.c | 2 +- trunk/drivers/mtd/maps/netsc520.c | 4 +- trunk/drivers/mtd/maps/nettel.c | 3 +- trunk/drivers/mtd/maps/ocotea.c | 6 +- trunk/drivers/mtd/maps/pci.c | 3 + trunk/drivers/mtd/maps/pcmciamtd.c | 2 +- trunk/drivers/mtd/maps/redwood.c | 3 +- trunk/drivers/mtd/maps/sbc8240.c | 8 +- trunk/drivers/mtd/maps/sc520cdp.c | 2 +- trunk/drivers/mtd/maps/scx200_docflash.c | 2 +- trunk/drivers/mtd/maps/sharpsl-flash.c | 4 +- trunk/drivers/mtd/maps/ts5500_flash.c | 2 +- trunk/drivers/mtd/maps/uclinux.c | 2 +- trunk/drivers/mtd/maps/vmax301.c | 2 +- trunk/drivers/mtd/mtd_blkdevs.c | 32 +- trunk/drivers/mtd/mtdblock.c | 14 +- trunk/drivers/mtd/mtdcore.c | 45 +- trunk/drivers/mtd/nand/Kconfig | 17 +- trunk/drivers/mtd/nand/au1550nd.c | 4 +- trunk/drivers/mtd/nand/nand_base.c | 26 +- trunk/drivers/mtd/redboot.c | 6 +- trunk/drivers/net/3c59x.c | 33 +- trunk/drivers/net/8390.h | 2 +- trunk/drivers/net/Kconfig | 2 + trunk/drivers/net/acenic_firmware.h | 10 +- trunk/drivers/net/b44.c | 14 - trunk/drivers/net/bonding/bond_3ad.c | 28 - trunk/drivers/net/bonding/bond_3ad.h | 1 - trunk/drivers/net/bonding/bond_main.c | 97 +- trunk/drivers/net/bonding/bonding.h | 4 +- trunk/drivers/net/ixp2000/ixpdev.c | 5 +- trunk/drivers/net/natsemi.c | 18 +- trunk/drivers/net/netconsole.c | 2 +- trunk/drivers/net/pcmcia/axnet_cs.c | 61 +- trunk/drivers/net/pcmcia/xirc2ps_cs.c | 2 +- trunk/drivers/net/pcnet32.c | 4 +- trunk/drivers/net/spider_net.c | 4 +- trunk/drivers/net/tg3.c | 118 +- trunk/drivers/net/tokenring/Kconfig | 2 +- trunk/drivers/net/tulip/de4x5.c | 2 +- trunk/drivers/net/via-rhine.c | 21 - trunk/drivers/net/wireless/Kconfig | 9 +- trunk/drivers/net/wireless/Makefile | 1 - trunk/drivers/net/wireless/bcm43xx/Kconfig | 62 - trunk/drivers/net/wireless/bcm43xx/Makefile | 12 - trunk/drivers/net/wireless/bcm43xx/bcm43xx.h | 926 ---- .../net/wireless/bcm43xx/bcm43xx_debugfs.c | 499 --- .../net/wireless/bcm43xx/bcm43xx_debugfs.h | 117 - .../net/wireless/bcm43xx/bcm43xx_dma.c | 968 ---- .../net/wireless/bcm43xx/bcm43xx_dma.h | 218 - .../net/wireless/bcm43xx/bcm43xx_ethtool.c | 50 - .../net/wireless/bcm43xx/bcm43xx_ethtool.h | 8 - .../net/wireless/bcm43xx/bcm43xx_ilt.c | 337 -- .../net/wireless/bcm43xx/bcm43xx_ilt.h | 32 - .../net/wireless/bcm43xx/bcm43xx_leds.c | 293 -- .../net/wireless/bcm43xx/bcm43xx_leds.h | 56 - .../net/wireless/bcm43xx/bcm43xx_main.c | 3973 ----------------- .../net/wireless/bcm43xx/bcm43xx_main.h | 168 - .../net/wireless/bcm43xx/bcm43xx_phy.c | 2345 ---------- .../net/wireless/bcm43xx/bcm43xx_phy.h | 74 - .../net/wireless/bcm43xx/bcm43xx_pio.c | 606 --- .../net/wireless/bcm43xx/bcm43xx_pio.h | 138 - .../net/wireless/bcm43xx/bcm43xx_power.c | 358 -- .../net/wireless/bcm43xx/bcm43xx_power.h | 47 - .../net/wireless/bcm43xx/bcm43xx_radio.c | 2026 --------- .../net/wireless/bcm43xx/bcm43xx_radio.h | 99 - .../net/wireless/bcm43xx/bcm43xx_sysfs.c | 322 -- .../net/wireless/bcm43xx/bcm43xx_sysfs.h | 25 - .../drivers/net/wireless/bcm43xx/bcm43xx_wx.c | 1002 ----- .../drivers/net/wireless/bcm43xx/bcm43xx_wx.h | 36 - .../net/wireless/bcm43xx/bcm43xx_xmit.c | 582 --- .../net/wireless/bcm43xx/bcm43xx_xmit.h | 156 - .../net/wireless/hostap/hostap_80211.h | 2 + .../net/wireless/hostap/hostap_80211_tx.c | 9 +- trunk/drivers/parisc/ccio-dma.c | 2 +- trunk/drivers/parisc/dino.c | 5 +- trunk/drivers/parisc/eisa.c | 2 +- trunk/drivers/parisc/iosapic.c | 2 +- trunk/drivers/parisc/lba_pci.c | 8 +- trunk/drivers/parisc/pdc_stable.c | 5 +- trunk/drivers/parisc/sba_iommu.c | 6 +- trunk/drivers/parisc/superio.c | 48 +- trunk/drivers/pcmcia/vrc4171_card.c | 12 +- trunk/drivers/pcmcia/vrc4173_cardu.c | 8 +- trunk/drivers/scsi/ahci.c | 4 - trunk/drivers/scsi/ata_piix.c | 4 +- trunk/drivers/scsi/ibmmca.c | 2 +- trunk/drivers/scsi/lasi700.c | 2 +- trunk/drivers/scsi/libata-bmdma.c | 26 +- trunk/drivers/scsi/libata-core.c | 196 +- trunk/drivers/scsi/libata-scsi.c | 8 +- trunk/drivers/scsi/libata.h | 2 +- trunk/drivers/scsi/mesh.c | 2 +- trunk/drivers/scsi/sata_mv.c | 42 +- trunk/drivers/scsi/zalon.c | 2 +- trunk/drivers/serial/8250_gsc.c | 15 +- trunk/drivers/serial/Kconfig | 27 + trunk/drivers/serial/Makefile | 12 +- trunk/drivers/serial/jsm/jsm_tty.c | 29 +- trunk/drivers/serial/mux.c | 4 +- trunk/drivers/usb/core/hcd-pci.c | 4 +- trunk/drivers/usb/net/zd1201.c | 2 +- trunk/drivers/video/Kconfig | 12 + trunk/drivers/video/Makefile | 1 + trunk/drivers/video/aty/aty128fb.c | 7 +- trunk/drivers/video/aty/atyfb_base.c | 7 +- trunk/drivers/video/aty/radeon_pm.c | 4 +- trunk/drivers/video/backlight/Kconfig | 4 +- trunk/drivers/video/backlight/backlight.c | 84 +- trunk/drivers/video/backlight/corgi_bl.c | 124 +- trunk/drivers/video/backlight/hp680_bl.c | 139 +- trunk/drivers/video/cfbimgblt.c | 2 +- trunk/drivers/video/cirrusfb.c | 4 +- trunk/drivers/video/console/fbcon.c | 11 +- trunk/drivers/video/console/sticore.c | 22 +- trunk/drivers/video/fbmem.c | 2 +- trunk/drivers/video/matrox/matroxfb_base.c | 3 +- trunk/drivers/video/nvidia/nvidia.c | 5 +- trunk/drivers/video/pxafb.c | 8 +- trunk/drivers/video/radeonfb.c | 3167 +++++++++++++ trunk/drivers/video/riva/fbdev.c | 9 +- trunk/drivers/video/sticore.h | 37 +- trunk/drivers/video/stifb.c | 95 +- trunk/drivers/video/w100fb.c | 162 +- trunk/drivers/video/w100fb.h | 748 ++-- trunk/fs/Makefile | 2 +- trunk/fs/char_dev.c | 87 +- trunk/fs/cifs/CHANGES | 18 - trunk/fs/cifs/Makefile | 2 +- trunk/fs/cifs/README | 7 - trunk/fs/cifs/cifsencrypt.c | 42 +- trunk/fs/cifs/cifsfs.c | 5 +- trunk/fs/cifs/cifsfs.h | 2 +- trunk/fs/cifs/cifsglob.h | 11 +- trunk/fs/cifs/cifspdu.h | 13 +- trunk/fs/cifs/cifsproto.h | 15 +- trunk/fs/cifs/cifssmb.c | 135 +- trunk/fs/cifs/connect.c | 99 +- trunk/fs/cifs/dir.c | 7 +- trunk/fs/cifs/file.c | 94 +- trunk/fs/cifs/inode.c | 22 +- trunk/fs/cifs/link.c | 2 +- trunk/fs/cifs/misc.c | 46 +- trunk/fs/cifs/ntlmssp.c | 129 - trunk/fs/cifs/ntlmssp.h | 2 +- trunk/fs/cifs/readdir.c | 7 +- trunk/fs/cifs/transport.c | 22 +- trunk/fs/dcache.c | 50 +- trunk/fs/direct-io.c | 7 +- trunk/fs/ext2/file.c | 2 - trunk/fs/ext3/file.c | 2 - trunk/fs/hppfs/hppfs_kern.c | 14 +- trunk/fs/locks.c | 45 +- trunk/fs/msdos/namei.c | 15 +- trunk/fs/namei.c | 3 +- trunk/fs/partitions/mac.c | 3 +- trunk/fs/pipe.c | 41 +- trunk/fs/proc/base.c | 13 +- trunk/fs/proc/proc_devtree.c | 103 +- trunk/fs/proc/proc_misc.c | 163 +- trunk/fs/reiserfs/file.c | 2 - trunk/fs/select.c | 8 +- trunk/fs/splice.c | 663 --- trunk/fs/sync.c | 164 - trunk/fs/vfat/namei.c | 18 + trunk/fs/xfs/linux-2.6/mrlock.h | 2 +- trunk/fs/xfs/linux-2.6/xfs_aops.c | 67 +- trunk/fs/xfs/linux-2.6/xfs_aops.h | 2 +- trunk/fs/xfs/linux-2.6/xfs_export.h | 2 +- trunk/fs/xfs/linux-2.6/xfs_ioctl32.c | 22 +- trunk/fs/xfs/linux-2.6/xfs_iops.c | 2 +- trunk/fs/xfs/linux-2.6/xfs_lrw.c | 2 +- trunk/fs/xfs/linux-2.6/xfs_vfs.h | 2 +- trunk/fs/xfs/quota/xfs_dquot_item.c | 2 +- trunk/fs/xfs/quota/xfs_qm.c | 14 +- trunk/fs/xfs/quota/xfs_qm_syscalls.c | 2 +- trunk/fs/xfs/quota/xfs_trans_dquot.c | 2 +- trunk/fs/xfs/xfs_acl.c | 2 +- trunk/fs/xfs/xfs_ag.h | 2 +- trunk/fs/xfs/xfs_alloc.c | 6 +- trunk/fs/xfs/xfs_alloc.h | 2 +- trunk/fs/xfs/xfs_attr.c | 6 +- trunk/fs/xfs/xfs_attr_leaf.c | 4 +- trunk/fs/xfs/xfs_behavior.c | 4 +- trunk/fs/xfs/xfs_behavior.h | 4 +- trunk/fs/xfs/xfs_bmap.c | 107 + trunk/fs/xfs/xfs_bmap.h | 8 + trunk/fs/xfs/xfs_buf_item.c | 4 +- trunk/fs/xfs/xfs_cap.h | 2 +- trunk/fs/xfs/xfs_da_btree.c | 2 +- trunk/fs/xfs/xfs_dir2_block.c | 2 +- trunk/fs/xfs/xfs_dir2_leaf.c | 2 +- trunk/fs/xfs/xfs_dir2_node.c | 2 +- trunk/fs/xfs/xfs_dir_leaf.c | 2 +- trunk/fs/xfs/xfs_fsops.c | 2 +- trunk/fs/xfs/xfs_ialloc.c | 110 +- trunk/fs/xfs/xfs_iget.c | 2 +- trunk/fs/xfs/xfs_inode.c | 14 +- trunk/fs/xfs/xfs_inode_item.c | 2 +- trunk/fs/xfs/xfs_itable.c | 4 +- trunk/fs/xfs/xfs_itable.h | 2 +- trunk/fs/xfs/xfs_log.c | 22 +- trunk/fs/xfs/xfs_log.h | 2 +- trunk/fs/xfs/xfs_log_recover.c | 4 +- trunk/fs/xfs/xfs_mount.c | 4 +- trunk/fs/xfs/xfs_mount.h | 2 +- trunk/fs/xfs/xfs_quota.h | 4 +- trunk/fs/xfs/xfs_trans.c | 6 +- trunk/fs/xfs/xfs_trans.h | 2 +- trunk/fs/xfs/xfs_trans_inode.c | 2 +- trunk/fs/xfs/xfs_vfsops.c | 10 +- trunk/fs/xfs/xfs_vnodeops.c | 12 +- .../include/asm-arm/arch-ixp23xx/uncompress.h | 11 +- trunk/include/asm-arm/arch-pxa/pxa-regs.h | 2 +- trunk/include/asm-arm/arch-pxa/sharpsl.h | 2 - trunk/include/asm-arm/unistd.h | 11 + trunk/include/asm-generic/local.h | 13 +- trunk/include/asm-generic/mutex-dec.h | 30 +- trunk/include/asm-generic/mutex-xchg.h | 33 +- trunk/include/asm-i386/apicdef.h | 1 - trunk/include/asm-i386/floppy.h | 34 + trunk/include/asm-i386/local.h | 6 +- trunk/include/asm-i386/unistd.h | 4 +- trunk/include/asm-ia64/asmmacro.h | 4 - trunk/include/asm-ia64/pal.h | 34 +- trunk/include/asm-ia64/unistd.h | 3 +- trunk/include/asm-parisc/atomic.h | 3 - trunk/include/asm-parisc/cache.h | 2 +- trunk/include/asm-parisc/cacheflush.h | 17 +- trunk/include/asm-parisc/io.h | 95 + trunk/include/asm-parisc/local.h | 16 +- trunk/include/asm-parisc/page.h | 58 +- trunk/include/asm-parisc/pci.h | 5 - trunk/include/asm-parisc/pdc_chassis.h | 5 +- trunk/include/asm-parisc/spinlock.h | 16 +- trunk/include/asm-parisc/thread_info.h | 3 +- trunk/include/asm-powerpc/bug.h | 36 +- trunk/include/asm-powerpc/cputable.h | 299 +- trunk/include/asm-powerpc/firmware.h | 10 +- trunk/include/asm-powerpc/floppy.h | 5 +- trunk/include/asm-powerpc/hvcall.h | 1 - trunk/include/asm-powerpc/hvconsole.h | 26 +- trunk/include/asm-powerpc/machdep.h | 43 +- trunk/include/asm-powerpc/oprofile_impl.h | 17 +- trunk/include/asm-powerpc/paca.h | 2 - trunk/include/asm-powerpc/percpu.h | 2 +- trunk/include/asm-powerpc/pmac_feature.h | 2 +- trunk/include/asm-powerpc/processor.h | 43 +- trunk/include/asm-powerpc/prom.h | 14 +- trunk/include/asm-powerpc/reg.h | 4 - trunk/include/asm-powerpc/smp.h | 2 +- trunk/include/asm-powerpc/spu.h | 11 +- trunk/include/asm-powerpc/syscalls.h | 58 - trunk/include/asm-powerpc/system.h | 5 +- trunk/include/asm-powerpc/unistd.h | 38 +- trunk/include/asm-powerpc/vdso_datapage.h | 3 - trunk/include/asm-ppc/machdep.h | 17 +- trunk/include/asm-ppc/mpc52xx.h | 4 - trunk/include/asm-ppc/pgtable.h | 3 +- trunk/include/asm-ppc/prom.h | 156 +- trunk/include/asm-ppc/serial.h | 7 +- trunk/include/asm-s390/percpu.h | 2 +- trunk/include/asm-um/desc.h | 12 +- trunk/include/asm-um/host_ldt-i386.h | 34 - trunk/include/asm-um/ldt-i386.h | 69 + .../{host_ldt-x86_64.h => ldt-x86_64.h} | 39 +- trunk/include/asm-um/ldt.h | 41 - trunk/include/asm-um/processor-i386.h | 35 +- trunk/include/asm-um/processor-x86_64.h | 9 - trunk/include/asm-um/ptrace-generic.h | 16 +- trunk/include/asm-um/ptrace-i386.h | 41 +- trunk/include/asm-um/ptrace-x86_64.h | 35 +- trunk/include/asm-um/segment.h | 6 - trunk/include/asm-um/thread_info.h | 16 +- trunk/include/asm-um/uaccess.h | 2 +- trunk/include/asm-x86_64/local.h | 10 +- trunk/include/asm-x86_64/unistd.h | 4 +- trunk/include/linux/backlight.h | 25 +- trunk/include/linux/dcache.h | 1 - trunk/include/linux/fadvise.h | 6 + trunk/include/linux/fb.h | 2 + trunk/include/linux/fs.h | 26 +- trunk/include/linux/hrtimer.h | 16 - trunk/include/linux/ipmi_smi.h | 16 +- trunk/include/linux/leds.h | 111 - trunk/include/linux/libata.h | 10 +- trunk/include/linux/migrate.h | 5 +- trunk/include/linux/mtd/blktrans.h | 4 +- trunk/include/linux/mtd/doc2000.h | 4 +- trunk/include/linux/mtd/inftl.h | 5 - trunk/include/linux/namei.h | 1 + trunk/include/linux/netdevice.h | 55 +- trunk/include/linux/pagemap.h | 4 +- trunk/include/linux/pci_ids.h | 1 - trunk/include/linux/pid.h | 96 +- trunk/include/linux/pipe_fs_i.h | 8 - trunk/include/linux/sched.h | 18 +- trunk/include/linux/skbuff.h | 29 +- trunk/include/linux/syscalls.h | 4 - trunk/include/linux/timer.h | 8 +- trunk/include/linux/tiocl.h | 1 - trunk/include/net/sock.h | 91 +- trunk/include/net/tcp.h | 3 + trunk/include/net/xfrm.h | 16 +- trunk/include/rdma/ib_mad.h | 27 +- trunk/kernel/acct.c | 12 +- trunk/kernel/audit.c | 2 +- trunk/kernel/cpuset.c | 69 +- trunk/kernel/exit.c | 7 +- trunk/kernel/fork.c | 28 +- trunk/kernel/futex.c | 4 +- trunk/kernel/futex_compat.c | 4 +- trunk/kernel/hrtimer.c | 49 +- trunk/kernel/module.c | 1 - trunk/kernel/pid.c | 212 +- trunk/kernel/power/process.c | 3 +- trunk/kernel/sched.c | 84 +- trunk/kernel/signal.c | 1 - trunk/kernel/sys.c | 19 +- trunk/kernel/timer.c | 92 +- trunk/lib/Kconfig.debug | 13 + trunk/mm/fadvise.c | 20 + trunk/mm/hugetlb.c | 6 +- trunk/mm/memory.c | 2 +- trunk/mm/swapfile.c | 14 +- trunk/net/appletalk/ddp.c | 19 - trunk/net/bridge/netfilter/ebt_802_3.c | 8 +- trunk/net/bridge/netfilter/ebt_among.c | 8 +- trunk/net/bridge/netfilter/ebt_arp.c | 8 +- trunk/net/bridge/netfilter/ebt_arpreply.c | 8 +- trunk/net/bridge/netfilter/ebt_dnat.c | 8 +- trunk/net/bridge/netfilter/ebt_ip.c | 8 +- trunk/net/bridge/netfilter/ebt_limit.c | 8 +- trunk/net/bridge/netfilter/ebt_log.c | 8 +- trunk/net/bridge/netfilter/ebt_mark.c | 8 +- trunk/net/bridge/netfilter/ebt_mark_m.c | 8 +- trunk/net/bridge/netfilter/ebt_pkttype.c | 8 +- trunk/net/bridge/netfilter/ebt_redirect.c | 8 +- trunk/net/bridge/netfilter/ebt_snat.c | 8 +- trunk/net/bridge/netfilter/ebt_stp.c | 8 +- trunk/net/bridge/netfilter/ebt_ulog.c | 8 +- trunk/net/bridge/netfilter/ebt_vlan.c | 8 +- trunk/net/bridge/netfilter/ebtable_broute.c | 8 +- trunk/net/bridge/netfilter/ebtable_filter.c | 8 +- trunk/net/bridge/netfilter/ebtable_nat.c | 8 +- trunk/net/bridge/netfilter/ebtables.c | 8 +- trunk/net/core/dev.c | 64 - trunk/net/core/sock.c | 109 +- trunk/net/dccp/feat.c | 6 +- trunk/net/decnet/dn_dev.c | 2 +- trunk/net/decnet/netfilter/dn_rtmsg.c | 8 +- trunk/net/econet/af_econet.c | 124 +- trunk/net/ieee80211/ieee80211_wx.c | 4 +- .../softmac/ieee80211softmac_module.c | 17 +- .../ieee80211/softmac/ieee80211softmac_priv.h | 2 +- .../ieee80211/softmac/ieee80211softmac_wx.c | 12 +- trunk/net/ipv4/Kconfig | 17 +- trunk/net/ipv4/Makefile | 3 +- trunk/net/ipv4/ipip.c | 79 +- trunk/net/ipv4/netfilter.c | 8 +- trunk/net/ipv4/netfilter/arp_tables.c | 8 +- trunk/net/ipv4/netfilter/arpt_mangle.c | 8 +- trunk/net/ipv4/netfilter/arptable_filter.c | 8 +- .../net/ipv4/netfilter/ip_conntrack_amanda.c | 8 +- trunk/net/ipv4/netfilter/ip_conntrack_ftp.c | 10 +- .../ipv4/netfilter/ip_conntrack_helper_pptp.c | 8 +- trunk/net/ipv4/netfilter/ip_conntrack_irc.c | 12 +- .../ipv4/netfilter/ip_conntrack_netbios_ns.c | 8 +- .../ipv4/netfilter/ip_conntrack_proto_sctp.c | 8 +- .../ipv4/netfilter/ip_conntrack_standalone.c | 8 +- trunk/net/ipv4/netfilter/ip_conntrack_tftp.c | 10 +- trunk/net/ipv4/netfilter/ip_nat_amanda.c | 8 +- trunk/net/ipv4/netfilter/ip_nat_ftp.c | 8 +- trunk/net/ipv4/netfilter/ip_nat_helper_pptp.c | 8 +- trunk/net/ipv4/netfilter/ip_nat_irc.c | 8 +- trunk/net/ipv4/netfilter/ip_nat_snmp_basic.c | 8 +- trunk/net/ipv4/netfilter/ip_nat_standalone.c | 8 +- trunk/net/ipv4/netfilter/ip_nat_tftp.c | 8 +- trunk/net/ipv4/netfilter/ip_queue.c | 8 +- trunk/net/ipv4/netfilter/ip_tables.c | 8 +- trunk/net/ipv4/netfilter/ipt_CLUSTERIP.c | 8 +- trunk/net/ipv4/netfilter/ipt_DSCP.c | 8 +- trunk/net/ipv4/netfilter/ipt_ECN.c | 8 +- trunk/net/ipv4/netfilter/ipt_LOG.c | 8 +- trunk/net/ipv4/netfilter/ipt_MASQUERADE.c | 8 +- trunk/net/ipv4/netfilter/ipt_NETMAP.c | 8 +- trunk/net/ipv4/netfilter/ipt_REDIRECT.c | 8 +- trunk/net/ipv4/netfilter/ipt_REJECT.c | 8 +- trunk/net/ipv4/netfilter/ipt_SAME.c | 8 +- trunk/net/ipv4/netfilter/ipt_TCPMSS.c | 8 +- trunk/net/ipv4/netfilter/ipt_TOS.c | 8 +- trunk/net/ipv4/netfilter/ipt_TTL.c | 8 +- trunk/net/ipv4/netfilter/ipt_ULOG.c | 8 +- trunk/net/ipv4/netfilter/ipt_addrtype.c | 8 +- trunk/net/ipv4/netfilter/ipt_ah.c | 8 +- trunk/net/ipv4/netfilter/ipt_dscp.c | 8 +- trunk/net/ipv4/netfilter/ipt_ecn.c | 8 +- trunk/net/ipv4/netfilter/ipt_esp.c | 8 +- trunk/net/ipv4/netfilter/ipt_hashlimit.c | 8 +- trunk/net/ipv4/netfilter/ipt_iprange.c | 8 +- trunk/net/ipv4/netfilter/ipt_multiport.c | 8 +- trunk/net/ipv4/netfilter/ipt_owner.c | 8 +- trunk/net/ipv4/netfilter/ipt_recent.c | 8 +- trunk/net/ipv4/netfilter/ipt_tos.c | 8 +- trunk/net/ipv4/netfilter/ipt_ttl.c | 8 +- trunk/net/ipv4/netfilter/iptable_filter.c | 8 +- trunk/net/ipv4/netfilter/iptable_mangle.c | 8 +- trunk/net/ipv4/netfilter/iptable_raw.c | 8 +- .../netfilter/nf_conntrack_l3proto_ipv4.c | 8 +- trunk/net/ipv4/tcp_cong.c | 2 +- trunk/net/ipv4/tunnel4.c | 113 - trunk/net/ipv4/xfrm4_tunnel.c | 79 +- trunk/net/ipv6/Kconfig | 19 +- trunk/net/ipv6/Makefile | 3 +- trunk/net/ipv6/ip6_tunnel.c | 45 +- trunk/net/ipv6/netfilter/ip6_queue.c | 8 +- trunk/net/ipv6/netfilter/ip6_tables.c | 8 +- trunk/net/ipv6/netfilter/ip6t_HL.c | 8 +- trunk/net/ipv6/netfilter/ip6t_LOG.c | 8 +- trunk/net/ipv6/netfilter/ip6t_REJECT.c | 8 +- trunk/net/ipv6/netfilter/ip6t_ah.c | 8 +- trunk/net/ipv6/netfilter/ip6t_dst.c | 8 +- trunk/net/ipv6/netfilter/ip6t_esp.c | 8 +- trunk/net/ipv6/netfilter/ip6t_eui64.c | 8 +- trunk/net/ipv6/netfilter/ip6t_frag.c | 8 +- trunk/net/ipv6/netfilter/ip6t_hbh.c | 8 +- trunk/net/ipv6/netfilter/ip6t_hl.c | 8 +- trunk/net/ipv6/netfilter/ip6t_multiport.c | 8 +- trunk/net/ipv6/netfilter/ip6t_owner.c | 8 +- trunk/net/ipv6/netfilter/ip6t_rt.c | 8 +- trunk/net/ipv6/netfilter/ip6table_filter.c | 8 +- trunk/net/ipv6/netfilter/ip6table_mangle.c | 8 +- trunk/net/ipv6/netfilter/ip6table_raw.c | 8 +- .../netfilter/nf_conntrack_l3proto_ipv6.c | 8 +- trunk/net/ipv6/tunnel6.c | 131 - trunk/net/ipv6/xfrm6_input.c | 5 +- trunk/net/ipv6/xfrm6_tunnel.c | 81 +- trunk/net/ipx/af_ipx.c | 26 - trunk/net/irda/af_irda.c | 25 - trunk/net/netfilter/nf_conntrack_ftp.c | 10 +- trunk/net/netfilter/nf_conntrack_proto_sctp.c | 8 +- trunk/net/netfilter/nf_conntrack_standalone.c | 8 +- trunk/net/netfilter/nfnetlink_log.c | 8 +- trunk/net/netfilter/nfnetlink_queue.c | 8 +- trunk/net/netfilter/xt_CLASSIFY.c | 8 +- trunk/net/netfilter/xt_CONNMARK.c | 8 +- trunk/net/netfilter/xt_MARK.c | 8 +- trunk/net/netfilter/xt_NFQUEUE.c | 8 +- trunk/net/netfilter/xt_NOTRACK.c | 8 +- trunk/net/netfilter/xt_comment.c | 8 +- trunk/net/netfilter/xt_connbytes.c | 8 +- trunk/net/netfilter/xt_connmark.c | 8 +- trunk/net/netfilter/xt_conntrack.c | 8 +- trunk/net/netfilter/xt_dccp.c | 8 +- trunk/net/netfilter/xt_helper.c | 8 +- trunk/net/netfilter/xt_length.c | 8 +- trunk/net/netfilter/xt_limit.c | 8 +- trunk/net/netfilter/xt_mac.c | 8 +- trunk/net/netfilter/xt_mark.c | 8 +- trunk/net/netfilter/xt_physdev.c | 8 +- trunk/net/netfilter/xt_pkttype.c | 8 +- trunk/net/netfilter/xt_realm.c | 8 +- trunk/net/netfilter/xt_sctp.c | 8 +- trunk/net/netfilter/xt_state.c | 8 +- trunk/net/netfilter/xt_string.c | 8 +- trunk/net/netfilter/xt_tcpmss.c | 8 +- trunk/net/netfilter/xt_tcpudp.c | 8 +- trunk/net/socket.c | 6 +- trunk/sound/oss/dmasound/dmasound_awacs.c | 2 +- trunk/sound/ppc/pmac.c | 2 +- 928 files changed, 20486 insertions(+), 32754 deletions(-) delete mode 100644 trunk/Documentation/leds-class.txt delete mode 100644 trunk/Documentation/memory-barriers.txt create mode 100644 trunk/Documentation/networking/TODO delete mode 100644 trunk/Documentation/networking/bcm43xx.txt delete mode 100644 trunk/arch/arm/Kconfig-nommu delete mode 100644 trunk/arch/arm/kernel/head-common.S delete mode 100644 trunk/arch/arm/kernel/head-nommu.S rename trunk/arch/powerpc/kernel/{idle.c => idle_64.c} (65%) delete mode 100644 trunk/arch/powerpc/oprofile/backtrace.c delete mode 100644 trunk/arch/powerpc/platforms/cell/spu_callbacks.c create mode 100644 trunk/arch/ppc/boot/openfirmware/Makefile create mode 100644 trunk/arch/ppc/boot/openfirmware/chrpmain.c create mode 100644 trunk/arch/ppc/boot/openfirmware/common.c create mode 100644 trunk/arch/ppc/boot/openfirmware/dummy.c create mode 100644 trunk/arch/ppc/boot/openfirmware/misc.S create mode 100644 trunk/arch/ppc/boot/openfirmware/start.c create mode 100644 trunk/arch/ppc/boot/utils/addnote.c create mode 100644 trunk/arch/ppc/boot/utils/hack-coff.c create mode 100644 trunk/arch/ppc/boot/utils/mknote.c rename trunk/arch/ppc/configs/{prep_defconfig => common_defconfig} (100%) create mode 100644 trunk/arch/ppc/configs/ibmchrp_defconfig create mode 100644 trunk/arch/ppc/configs/pmac_defconfig create mode 100644 trunk/arch/ppc/configs/power3_defconfig rename trunk/arch/{powerpc => ppc}/kernel/cpu_setup_6xx.S (100%) create mode 100644 trunk/arch/ppc/kernel/idle.c create mode 100644 trunk/arch/ppc/kernel/idle_6xx.S create mode 100644 trunk/arch/ppc/kernel/idle_power4.S rename trunk/arch/{powerpc/kernel/l2cr_6xx.S => ppc/kernel/l2cr.S} (100%) rename trunk/arch/{powerpc/kernel/module_32.c => ppc/kernel/module.c} (100%) rename trunk/arch/{powerpc => ppc}/kernel/perfmon_fsl_booke.c (100%) rename trunk/arch/{powerpc/kernel/swsusp_32.S => ppc/kernel/swsusp.S} (100%) rename trunk/arch/{powerpc/kernel/tau_6xx.c => ppc/kernel/temp.c} (100%) rename trunk/arch/{powerpc => ppc}/math-emu/Makefile (100%) rename trunk/arch/{powerpc => ppc}/math-emu/double.h (100%) rename trunk/arch/{powerpc => ppc}/math-emu/fabs.c (100%) rename trunk/arch/{powerpc => ppc}/math-emu/fadd.c (100%) rename trunk/arch/{powerpc => ppc}/math-emu/fadds.c (100%) rename trunk/arch/{powerpc => ppc}/math-emu/fcmpo.c (100%) rename trunk/arch/{powerpc => ppc}/math-emu/fcmpu.c (100%) rename trunk/arch/{powerpc => ppc}/math-emu/fctiw.c (100%) rename trunk/arch/{powerpc => ppc}/math-emu/fctiwz.c (100%) rename trunk/arch/{powerpc => ppc}/math-emu/fdiv.c (100%) rename trunk/arch/{powerpc => ppc}/math-emu/fdivs.c (100%) rename trunk/arch/{powerpc => ppc}/math-emu/fmadd.c (100%) rename trunk/arch/{powerpc => ppc}/math-emu/fmadds.c (100%) rename trunk/arch/{powerpc => ppc}/math-emu/fmr.c (100%) rename trunk/arch/{powerpc => ppc}/math-emu/fmsub.c (100%) rename trunk/arch/{powerpc => ppc}/math-emu/fmsubs.c (100%) rename trunk/arch/{powerpc => ppc}/math-emu/fmul.c (100%) rename trunk/arch/{powerpc => ppc}/math-emu/fmuls.c (100%) rename trunk/arch/{powerpc => ppc}/math-emu/fnabs.c (100%) rename trunk/arch/{powerpc => ppc}/math-emu/fneg.c (100%) rename trunk/arch/{powerpc => ppc}/math-emu/fnmadd.c (100%) rename trunk/arch/{powerpc => ppc}/math-emu/fnmadds.c (100%) rename trunk/arch/{powerpc => ppc}/math-emu/fnmsub.c (100%) rename trunk/arch/{powerpc => ppc}/math-emu/fnmsubs.c (100%) rename trunk/arch/{powerpc => ppc}/math-emu/fres.c (100%) rename trunk/arch/{powerpc => ppc}/math-emu/frsp.c (100%) rename trunk/arch/{powerpc => ppc}/math-emu/frsqrte.c (100%) rename trunk/arch/{powerpc => ppc}/math-emu/fsel.c (100%) rename trunk/arch/{powerpc => ppc}/math-emu/fsqrt.c (100%) rename trunk/arch/{powerpc => ppc}/math-emu/fsqrts.c (100%) rename trunk/arch/{powerpc => ppc}/math-emu/fsub.c (100%) rename trunk/arch/{powerpc => ppc}/math-emu/fsubs.c (100%) rename trunk/arch/{powerpc => ppc}/math-emu/lfd.c (100%) rename trunk/arch/{powerpc => ppc}/math-emu/lfs.c (100%) rename trunk/arch/{powerpc => ppc}/math-emu/math.c (100%) rename trunk/arch/{powerpc => ppc}/math-emu/mcrfs.c (100%) rename trunk/arch/{powerpc => ppc}/math-emu/mffs.c (100%) rename trunk/arch/{powerpc => ppc}/math-emu/mtfsb0.c (100%) rename trunk/arch/{powerpc => ppc}/math-emu/mtfsb1.c (100%) rename trunk/arch/{powerpc => ppc}/math-emu/mtfsf.c (100%) rename trunk/arch/{powerpc => ppc}/math-emu/mtfsfi.c (100%) rename trunk/arch/{powerpc => ppc}/math-emu/op-1.h (100%) rename trunk/arch/{powerpc => ppc}/math-emu/op-2.h (100%) rename trunk/arch/{powerpc => ppc}/math-emu/op-4.h (100%) rename trunk/arch/{powerpc => ppc}/math-emu/op-common.h (100%) rename trunk/arch/{powerpc => ppc}/math-emu/sfp-machine.h (100%) rename trunk/arch/{powerpc => ppc}/math-emu/single.h (100%) rename trunk/arch/{powerpc => ppc}/math-emu/soft-fp.h (100%) rename trunk/arch/{powerpc => ppc}/math-emu/stfd.c (100%) rename trunk/arch/{powerpc => ppc}/math-emu/stfiwx.c (100%) rename trunk/arch/{powerpc => ppc}/math-emu/stfs.c (100%) rename trunk/arch/{powerpc => ppc}/math-emu/types.c (100%) rename trunk/arch/{powerpc => ppc}/math-emu/udivmodti4.c (100%) create mode 100644 trunk/arch/ppc/platforms/chrp_nvram.c create mode 100644 trunk/arch/ppc/platforms/chrp_pci.c create mode 100644 trunk/arch/ppc/platforms/chrp_pegasos_eth.c create mode 100644 trunk/arch/ppc/platforms/chrp_setup.c create mode 100644 trunk/arch/ppc/platforms/chrp_smp.c create mode 100644 trunk/arch/ppc/platforms/chrp_time.c create mode 100644 trunk/arch/ppc/syslib/prom.c create mode 100644 trunk/arch/ppc/syslib/prom_init.c delete mode 100644 trunk/arch/um/include/sysdep-i386/tls.h delete mode 100644 trunk/arch/um/include/sysdep-x86_64/tls.h delete mode 100644 trunk/arch/um/os-Linux/sys-i386/tls.c delete mode 100644 trunk/arch/um/os-Linux/tls.c create mode 100644 trunk/arch/um/scripts/Makefile.unmap delete mode 100644 trunk/arch/um/sys-i386/tls.c delete mode 100644 trunk/arch/um/sys-x86_64/tls.c delete mode 100644 trunk/drivers/char/hvc_console.h delete mode 100644 trunk/drivers/char/hvc_rtas.c delete mode 100644 trunk/drivers/leds/Kconfig delete mode 100644 trunk/drivers/leds/Makefile delete mode 100644 trunk/drivers/leds/led-class.c delete mode 100644 trunk/drivers/leds/led-core.c delete mode 100644 trunk/drivers/leds/led-triggers.c delete mode 100644 trunk/drivers/leds/leds-corgi.c delete mode 100644 trunk/drivers/leds/leds-ixp4xx-gpio.c delete mode 100644 trunk/drivers/leds/leds-locomo.c delete mode 100644 trunk/drivers/leds/leds-spitz.c delete mode 100644 trunk/drivers/leds/leds-tosa.c delete mode 100644 trunk/drivers/leds/leds.h delete mode 100644 trunk/drivers/leds/ledtrig-ide-disk.c delete mode 100644 trunk/drivers/leds/ledtrig-timer.c delete mode 100644 trunk/drivers/mmc/omap.c delete mode 100644 trunk/drivers/mmc/omap.h delete mode 100644 trunk/drivers/net/wireless/bcm43xx/Kconfig delete mode 100644 trunk/drivers/net/wireless/bcm43xx/Makefile delete mode 100644 trunk/drivers/net/wireless/bcm43xx/bcm43xx.h delete mode 100644 trunk/drivers/net/wireless/bcm43xx/bcm43xx_debugfs.c delete mode 100644 trunk/drivers/net/wireless/bcm43xx/bcm43xx_debugfs.h delete mode 100644 trunk/drivers/net/wireless/bcm43xx/bcm43xx_dma.c delete mode 100644 trunk/drivers/net/wireless/bcm43xx/bcm43xx_dma.h delete mode 100644 trunk/drivers/net/wireless/bcm43xx/bcm43xx_ethtool.c delete mode 100644 trunk/drivers/net/wireless/bcm43xx/bcm43xx_ethtool.h delete mode 100644 trunk/drivers/net/wireless/bcm43xx/bcm43xx_ilt.c delete mode 100644 trunk/drivers/net/wireless/bcm43xx/bcm43xx_ilt.h delete mode 100644 trunk/drivers/net/wireless/bcm43xx/bcm43xx_leds.c delete mode 100644 trunk/drivers/net/wireless/bcm43xx/bcm43xx_leds.h delete mode 100644 trunk/drivers/net/wireless/bcm43xx/bcm43xx_main.c delete mode 100644 trunk/drivers/net/wireless/bcm43xx/bcm43xx_main.h delete mode 100644 trunk/drivers/net/wireless/bcm43xx/bcm43xx_phy.c delete mode 100644 trunk/drivers/net/wireless/bcm43xx/bcm43xx_phy.h delete mode 100644 trunk/drivers/net/wireless/bcm43xx/bcm43xx_pio.c delete mode 100644 trunk/drivers/net/wireless/bcm43xx/bcm43xx_pio.h delete mode 100644 trunk/drivers/net/wireless/bcm43xx/bcm43xx_power.c delete mode 100644 trunk/drivers/net/wireless/bcm43xx/bcm43xx_power.h delete mode 100644 trunk/drivers/net/wireless/bcm43xx/bcm43xx_radio.c delete mode 100644 trunk/drivers/net/wireless/bcm43xx/bcm43xx_radio.h delete mode 100644 trunk/drivers/net/wireless/bcm43xx/bcm43xx_sysfs.c delete mode 100644 trunk/drivers/net/wireless/bcm43xx/bcm43xx_sysfs.h delete mode 100644 trunk/drivers/net/wireless/bcm43xx/bcm43xx_wx.c delete mode 100644 trunk/drivers/net/wireless/bcm43xx/bcm43xx_wx.h delete mode 100644 trunk/drivers/net/wireless/bcm43xx/bcm43xx_xmit.c delete mode 100644 trunk/drivers/net/wireless/bcm43xx/bcm43xx_xmit.h create mode 100644 trunk/drivers/video/radeonfb.c delete mode 100644 trunk/fs/cifs/ntlmssp.c delete mode 100644 trunk/fs/splice.c delete mode 100644 trunk/fs/sync.c delete mode 100644 trunk/include/asm-powerpc/syscalls.h delete mode 100644 trunk/include/asm-um/host_ldt-i386.h create mode 100644 trunk/include/asm-um/ldt-i386.h rename trunk/include/asm-um/{host_ldt-x86_64.h => ldt-x86_64.h} (53%) delete mode 100644 trunk/include/asm-um/ldt.h delete mode 100644 trunk/include/linux/leds.h delete mode 100644 trunk/net/ipv4/tunnel4.c delete mode 100644 trunk/net/ipv6/tunnel6.c diff --git a/[refs] b/[refs] index d1e6dfab4a84..08d64de78241 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 500156a0f0e81e24991f5f0db56e859db1fbdacf +refs/heads/master: 0cff260a42c051ee64c184ed05d96d18d243f7f6 diff --git a/trunk/Documentation/DocBook/libata.tmpl b/trunk/Documentation/DocBook/libata.tmpl index 5bcbb6ee3bc0..d260d92089ad 100644 --- a/trunk/Documentation/DocBook/libata.tmpl +++ b/trunk/Documentation/DocBook/libata.tmpl @@ -120,27 +120,14 @@ void (*dev_config) (struct ata_port *, struct ata_device *); void (*set_piomode) (struct ata_port *, struct ata_device *); void (*set_dmamode) (struct ata_port *, struct ata_device *); -void (*post_set_mode) (struct ata_port *); -unsigned int (*mode_filter) (struct ata_port *, struct ata_device *, unsigned int); +void (*post_set_mode) (struct ata_port *ap); Hooks called prior to the issue of SET FEATURES - XFER MODE - command. The optional ->mode_filter() hook is called when libata - has built a mask of the possible modes. This is passed to the - ->mode_filter() function which should return a mask of valid modes - after filtering those unsuitable due to hardware limits. It is not - valid to use this interface to add modes. - - - dev->pio_mode and dev->dma_mode are guaranteed to be valid when - ->set_piomode() and when ->set_dmamode() is called. The timings for - any other drive sharing the cable will also be valid at this point. - That is the library records the decisions for the modes of each - drive on a channel before it attempts to set any of them. - - - ->post_set_mode() is + command. dev->pio_mode is guaranteed to be valid when + ->set_piomode() is called, and dev->dma_mode is guaranteed to be + valid when ->set_dmamode() is called. ->post_set_mode() is called unconditionally, after the SET FEATURES - XFER MODE command completes successfully. @@ -243,32 +230,6 @@ void (*dev_select)(struct ata_port *ap, unsigned int device); - Private tuning method - -void (*set_mode) (struct ata_port *ap); - - - - By default libata performs drive and controller tuning in - accordance with the ATA timing rules and also applies blacklists - and cable limits. Some controllers need special handling and have - custom tuning rules, typically raid controllers that use ATA - commands but do not actually do drive timing. - - - - - This hook should not be used to replace the standard controller - tuning logic when a controller has quirks. Replacing the default - tuning logic in that case would bypass handling for drive and - bridge quirks that may be important to data reliability. If a - controller needs to filter the mode selection it should use the - mode_filter hook instead. - - - - - Reset ATA bus void (*phy_reset) (struct ata_port *ap); diff --git a/trunk/Documentation/feature-removal-schedule.txt b/trunk/Documentation/feature-removal-schedule.txt index 59d0c74c79c9..495858b236b6 100644 --- a/trunk/Documentation/feature-removal-schedule.txt +++ b/trunk/Documentation/feature-removal-schedule.txt @@ -127,6 +127,13 @@ Who: Christoph Hellwig --------------------------- +What: EXPORT_SYMBOL(lookup_hash) +When: January 2006 +Why: Too low-level interface. Use lookup_one_len or lookup_create instead. +Who: Christoph Hellwig + +--------------------------- + What: CONFIG_FORCED_INLINING When: June 2006 Why: Config option is there to see if gcc is good enough. (in january @@ -234,15 +241,3 @@ Why: The USB subsystem has changed a lot over time, and it has been Who: Greg Kroah-Hartman --------------------------- - -What: find_trylock_page -When: January 2007 -Why: The interface no longer has any callers left in the kernel. It - is an odd interface (compared with other find_*_page functions), in - that it does not take a refcount to the page, only the page lock. - It should be replaced with find_get_page or find_lock_page if possible. - This feature removal can be reevaluated if users of the interface - cannot cleanly use something else. -Who: Nick Piggin - ---------------------------- diff --git a/trunk/Documentation/leds-class.txt b/trunk/Documentation/leds-class.txt deleted file mode 100644 index 8c35c0426110..000000000000 --- a/trunk/Documentation/leds-class.txt +++ /dev/null @@ -1,71 +0,0 @@ -LED handling under Linux -======================== - -If you're reading this and thinking about keyboard leds, these are -handled by the input subsystem and the led class is *not* needed. - -In its simplest form, the LED class just allows control of LEDs from -userspace. LEDs appear in /sys/class/leds/. The brightness file will -set the brightness of the LED (taking a value 0-255). Most LEDs don't -have hardware brightness support so will just be turned on for non-zero -brightness settings. - -The class also introduces the optional concept of an LED trigger. A trigger -is a kernel based source of led events. Triggers can either be simple or -complex. A simple trigger isn't configurable and is designed to slot into -existing subsystems with minimal additional code. Examples are the ide-disk, -nand-disk and sharpsl-charge triggers. With led triggers disabled, the code -optimises away. - -Complex triggers whilst available to all LEDs have LED specific -parameters and work on a per LED basis. The timer trigger is an example. - -You can change triggers in a similar manner to the way an IO scheduler -is chosen (via /sys/class/leds//trigger). Trigger specific -parameters can appear in /sys/class/leds/ once a given trigger is -selected. - - -Design Philosophy -================= - -The underlying design philosophy is simplicity. LEDs are simple devices -and the aim is to keep a small amount of code giving as much functionality -as possible. Please keep this in mind when suggesting enhancements. - - -LED Device Naming -================= - -Is currently of the form: - -"devicename:colour" - -There have been calls for LED properties such as colour to be exported as -individual led class attributes. As a solution which doesn't incur as much -overhead, I suggest these become part of the device name. The naming scheme -above leaves scope for further attributes should they be needed. - - -Known Issues -============ - -The LED Trigger core cannot be a module as the simple trigger functions -would cause nightmare dependency issues. I see this as a minor issue -compared to the benefits the simple trigger functionality brings. The -rest of the LED subsystem can be modular. - -Some leds can be programmed to flash in hardware. As this isn't a generic -LED device property, this should be exported as a device specific sysfs -attribute rather than part of the class if this functionality is required. - - -Future Development -================== - -At the moment, a trigger can't be created specifically for a single LED. -There are a number of cases where a trigger might only be mappable to a -particular LED (ACPI?). The addition of triggers provided by the LED driver -should cover this option and be possible to add without breaking the -current interface. - diff --git a/trunk/Documentation/memory-barriers.txt b/trunk/Documentation/memory-barriers.txt deleted file mode 100644 index f8550310a6d5..000000000000 --- a/trunk/Documentation/memory-barriers.txt +++ /dev/null @@ -1,1913 +0,0 @@ - ============================ - LINUX KERNEL MEMORY BARRIERS - ============================ - -By: David Howells - -Contents: - - (*) Abstract memory access model. - - - Device operations. - - Guarantees. - - (*) What are memory barriers? - - - Varieties of memory barrier. - - What may not be assumed about memory barriers? - - Data dependency barriers. - - Control dependencies. - - SMP barrier pairing. - - Examples of memory barrier sequences. - - (*) Explicit kernel barriers. - - - Compiler barrier. - - The CPU memory barriers. - - MMIO write barrier. - - (*) Implicit kernel memory barriers. - - - Locking functions. - - Interrupt disabling functions. - - Miscellaneous functions. - - (*) Inter-CPU locking barrier effects. - - - Locks vs memory accesses. - - Locks vs I/O accesses. - - (*) Where are memory barriers needed? - - - Interprocessor interaction. - - Atomic operations. - - Accessing devices. - - Interrupts. - - (*) Kernel I/O barrier effects. - - (*) Assumed minimum execution ordering model. - - (*) The effects of the cpu cache. - - - Cache coherency. - - Cache coherency vs DMA. - - Cache coherency vs MMIO. - - (*) The things CPUs get up to. - - - And then there's the Alpha. - - (*) References. - - -============================ -ABSTRACT MEMORY ACCESS MODEL -============================ - -Consider the following abstract model of the system: - - : : - : : - : : - +-------+ : +--------+ : +-------+ - | | : | | : | | - | | : | | : | | - | CPU 1 |<----->| Memory |<----->| CPU 2 | - | | : | | : | | - | | : | | : | | - +-------+ : +--------+ : +-------+ - ^ : ^ : ^ - | : | : | - | : | : | - | : v : | - | : +--------+ : | - | : | | : | - | : | | : | - +---------->| Device |<----------+ - : | | : - : | | : - : +--------+ : - : : - -Each CPU executes a program that generates memory access operations. In the -abstract CPU, memory operation ordering is very relaxed, and a CPU may actually -perform the memory operations in any order it likes, provided program causality -appears to be maintained. Similarly, the compiler may also arrange the -instructions it emits in any order it likes, provided it doesn't affect the -apparent operation of the program. - -So in the above diagram, the effects of the memory operations performed by a -CPU are perceived by the rest of the system as the operations cross the -interface between the CPU and rest of the system (the dotted lines). - - -For example, consider the following sequence of events: - - CPU 1 CPU 2 - =============== =============== - { A == 1; B == 2 } - A = 3; x = A; - B = 4; y = B; - -The set of accesses as seen by the memory system in the middle can be arranged -in 24 different combinations: - - STORE A=3, STORE B=4, x=LOAD A->3, y=LOAD B->4 - STORE A=3, STORE B=4, y=LOAD B->4, x=LOAD A->3 - STORE A=3, x=LOAD A->3, STORE B=4, y=LOAD B->4 - STORE A=3, x=LOAD A->3, y=LOAD B->2, STORE B=4 - STORE A=3, y=LOAD B->2, STORE B=4, x=LOAD A->3 - STORE A=3, y=LOAD B->2, x=LOAD A->3, STORE B=4 - STORE B=4, STORE A=3, x=LOAD A->3, y=LOAD B->4 - STORE B=4, ... - ... - -and can thus result in four different combinations of values: - - x == 1, y == 2 - x == 1, y == 4 - x == 3, y == 2 - x == 3, y == 4 - - -Furthermore, the stores committed by a CPU to the memory system may not be -perceived by the loads made by another CPU in the same order as the stores were -committed. - - -As a further example, consider this sequence of events: - - CPU 1 CPU 2 - =============== =============== - { A == 1, B == 2, C = 3, P == &A, Q == &C } - B = 4; Q = P; - P = &B D = *Q; - -There is an obvious data dependency here, as the value loaded into D depends on -the address retrieved from P by CPU 2. At the end of the sequence, any of the -following results are possible: - - (Q == &A) and (D == 1) - (Q == &B) and (D == 2) - (Q == &B) and (D == 4) - -Note that CPU 2 will never try and load C into D because the CPU will load P -into Q before issuing the load of *Q. - - -DEVICE OPERATIONS ------------------ - -Some devices present their control interfaces as collections of memory -locations, but the order in which the control registers are accessed is very -important. For instance, imagine an ethernet card with a set of internal -registers that are accessed through an address port register (A) and a data -port register (D). To read internal register 5, the following code might then -be used: - - *A = 5; - x = *D; - -but this might show up as either of the following two sequences: - - STORE *A = 5, x = LOAD *D - x = LOAD *D, STORE *A = 5 - -the second of which will almost certainly result in a malfunction, since it set -the address _after_ attempting to read the register. - - -GUARANTEES ----------- - -There are some minimal guarantees that may be expected of a CPU: - - (*) On any given CPU, dependent memory accesses will be issued in order, with - respect to itself. This means that for: - - Q = P; D = *Q; - - the CPU will issue the following memory operations: - - Q = LOAD P, D = LOAD *Q - - and always in that order. - - (*) Overlapping loads and stores within a particular CPU will appear to be - ordered within that CPU. This means that for: - - a = *X; *X = b; - - the CPU will only issue the following sequence of memory operations: - - a = LOAD *X, STORE *X = b - - And for: - - *X = c; d = *X; - - the CPU will only issue: - - STORE *X = c, d = LOAD *X - - (Loads and stores overlap if they are targetted at overlapping pieces of - memory). - -And there are a number of things that _must_ or _must_not_ be assumed: - - (*) It _must_not_ be assumed that independent loads and stores will be issued - in the order given. This means that for: - - X = *A; Y = *B; *D = Z; - - we may get any of the following sequences: - - X = LOAD *A, Y = LOAD *B, STORE *D = Z - X = LOAD *A, STORE *D = Z, Y = LOAD *B - Y = LOAD *B, X = LOAD *A, STORE *D = Z - Y = LOAD *B, STORE *D = Z, X = LOAD *A - STORE *D = Z, X = LOAD *A, Y = LOAD *B - STORE *D = Z, Y = LOAD *B, X = LOAD *A - - (*) It _must_ be assumed that overlapping memory accesses may be merged or - discarded. This means that for: - - X = *A; Y = *(A + 4); - - we may get any one of the following sequences: - - X = LOAD *A; Y = LOAD *(A + 4); - Y = LOAD *(A + 4); X = LOAD *A; - {X, Y} = LOAD {*A, *(A + 4) }; - - And for: - - *A = X; Y = *A; - - we may get either of: - - STORE *A = X; Y = LOAD *A; - STORE *A = Y; - - -========================= -WHAT ARE MEMORY BARRIERS? -========================= - -As can be seen above, independent memory operations are effectively performed -in random order, but this can be a problem for CPU-CPU interaction and for I/O. -What is required is some way of intervening to instruct the compiler and the -CPU to restrict the order. - -Memory barriers are such interventions. They impose a perceived partial -ordering between the memory operations specified on either side of the barrier. -They request that the sequence of memory events generated appears to other -parts of the system as if the barrier is effective on that CPU. - - -VARIETIES OF MEMORY BARRIER ---------------------------- - -Memory barriers come in four basic varieties: - - (1) Write (or store) memory barriers. - - A write memory barrier gives a guarantee that all the STORE operations - specified before the barrier will appear to happen before all the STORE - operations specified after the barrier with respect to the other - components of the system. - - A write barrier is a partial ordering on stores only; it is not required - to have any effect on loads. - - A CPU can be viewed as as commiting a sequence of store operations to the - memory system as time progresses. All stores before a write barrier will - occur in the sequence _before_ all the stores after the write barrier. - - [!] Note that write barriers should normally be paired with read or data - dependency barriers; see the "SMP barrier pairing" subsection. - - - (2) Data dependency barriers. - - A data dependency barrier is a weaker form of read barrier. In the case - where two loads are performed such that the second depends on the result - of the first (eg: the first load retrieves the address to which the second - load will be directed), a data dependency barrier would be required to - make sure that the target of the second load is updated before the address - obtained by the first load is accessed. - - A data dependency barrier is a partial ordering on interdependent loads - only; it is not required to have any effect on stores, independent loads - or overlapping loads. - - As mentioned in (1), the other CPUs in the system can be viewed as - committing sequences of stores to the memory system that the CPU being - considered can then perceive. A data dependency barrier issued by the CPU - under consideration guarantees that for any load preceding it, if that - load touches one of a sequence of stores from another CPU, then by the - time the barrier completes, the effects of all the stores prior to that - touched by the load will be perceptible to any loads issued after the data - dependency barrier. - - See the "Examples of memory barrier sequences" subsection for diagrams - showing the ordering constraints. - - [!] Note that the first load really has to have a _data_ dependency and - not a control dependency. If the address for the second load is dependent - on the first load, but the dependency is through a conditional rather than - actually loading the address itself, then it's a _control_ dependency and - a full read barrier or better is required. See the "Control dependencies" - subsection for more information. - - [!] Note that data dependency barriers should normally be paired with - write barriers; see the "SMP barrier pairing" subsection. - - - (3) Read (or load) memory barriers. - - A read barrier is a data dependency barrier plus a guarantee that all the - LOAD operations specified before the barrier will appear to happen before - all the LOAD operations specified after the barrier with respect to the - other components of the system. - - A read barrier is a partial ordering on loads only; it is not required to - have any effect on stores. - - Read memory barriers imply data dependency barriers, and so can substitute - for them. - - [!] Note that read barriers should normally be paired with write barriers; - see the "SMP barrier pairing" subsection. - - - (4) General memory barriers. - - A general memory barrier is a combination of both a read memory barrier - and a write memory barrier. It is a partial ordering over both loads and - stores. - - General memory barriers imply both read and write memory barriers, and so - can substitute for either. - - -And a couple of implicit varieties: - - (5) LOCK operations. - - This acts as a one-way permeable barrier. It guarantees that all memory - operations after the LOCK operation will appear to happen after the LOCK - operation with respect to the other components of the system. - - Memory operations that occur before a LOCK operation may appear to happen - after it completes. - - A LOCK operation should almost always be paired with an UNLOCK operation. - - - (6) UNLOCK operations. - - This also acts as a one-way permeable barrier. It guarantees that all - memory operations before the UNLOCK operation will appear to happen before - the UNLOCK operation with respect to the other components of the system. - - Memory operations that occur after an UNLOCK operation may appear to - happen before it completes. - - LOCK and UNLOCK operations are guaranteed to appear with respect to each - other strictly in the order specified. - - The use of LOCK and UNLOCK operations generally precludes the need for - other sorts of memory barrier (but note the exceptions mentioned in the - subsection "MMIO write barrier"). - - -Memory barriers are only required where there's a possibility of interaction -between two CPUs or between a CPU and a device. If it can be guaranteed that -there won't be any such interaction in any particular piece of code, then -memory barriers are unnecessary in that piece of code. - - -Note that these are the _minimum_ guarantees. Different architectures may give -more substantial guarantees, but they may _not_ be relied upon outside of arch -specific code. - - -WHAT MAY NOT BE ASSUMED ABOUT MEMORY BARRIERS? ----------------------------------------------- - -There are certain things that the Linux kernel memory barriers do not guarantee: - - (*) There is no guarantee that any of the memory accesses specified before a - memory barrier will be _complete_ by the completion of a memory barrier - instruction; the barrier can be considered to draw a line in that CPU's - access queue that accesses of the appropriate type may not cross. - - (*) There is no guarantee that issuing a memory barrier on one CPU will have - any direct effect on another CPU or any other hardware in the system. The - indirect effect will be the order in which the second CPU sees the effects - of the first CPU's accesses occur, but see the next point: - - (*) There is no guarantee that the a CPU will see the correct order of effects - from a second CPU's accesses, even _if_ the second CPU uses a memory - barrier, unless the first CPU _also_ uses a matching memory barrier (see - the subsection on "SMP Barrier Pairing"). - - (*) There is no guarantee that some intervening piece of off-the-CPU - hardware[*] will not reorder the memory accesses. CPU cache coherency - mechanisms should propagate the indirect effects of a memory barrier - between CPUs, but might not do so in order. - - [*] For information on bus mastering DMA and coherency please read: - - Documentation/pci.txt - Documentation/DMA-mapping.txt - Documentation/DMA-API.txt - - -DATA DEPENDENCY BARRIERS ------------------------- - -The usage requirements of data dependency barriers are a little subtle, and -it's not always obvious that they're needed. To illustrate, consider the -following sequence of events: - - CPU 1 CPU 2 - =============== =============== - { A == 1, B == 2, C = 3, P == &A, Q == &C } - B = 4; - - P = &B - Q = P; - D = *Q; - -There's a clear data dependency here, and it would seem that by the end of the -sequence, Q must be either &A or &B, and that: - - (Q == &A) implies (D == 1) - (Q == &B) implies (D == 4) - -But! CPU 2's perception of P may be updated _before_ its perception of B, thus -leading to the following situation: - - (Q == &B) and (D == 2) ???? - -Whilst this may seem like a failure of coherency or causality maintenance, it -isn't, and this behaviour can be observed on certain real CPUs (such as the DEC -Alpha). - -To deal with this, a data dependency barrier must be inserted between the -address load and the data load: - - CPU 1 CPU 2 - =============== =============== - { A == 1, B == 2, C = 3, P == &A, Q == &C } - B = 4; - - P = &B - Q = P; - - D = *Q; - -This enforces the occurrence of one of the two implications, and prevents the -third possibility from arising. - -[!] Note that this extremely counterintuitive situation arises most easily on -machines with split caches, so that, for example, one cache bank processes -even-numbered cache lines and the other bank processes odd-numbered cache -lines. The pointer P might be stored in an odd-numbered cache line, and the -variable B might be stored in an even-numbered cache line. Then, if the -even-numbered bank of the reading CPU's cache is extremely busy while the -odd-numbered bank is idle, one can see the new value of the pointer P (&B), -but the old value of the variable B (1). - - -Another example of where data dependency barriers might by required is where a -number is read from memory and then used to calculate the index for an array -access: - - CPU 1 CPU 2 - =============== =============== - { M[0] == 1, M[1] == 2, M[3] = 3, P == 0, Q == 3 } - M[1] = 4; - - P = 1 - Q = P; - - D = M[Q]; - - -The data dependency barrier is very important to the RCU system, for example. -See rcu_dereference() in include/linux/rcupdate.h. This permits the current -target of an RCU'd pointer to be replaced with a new modified target, without -the replacement target appearing to be incompletely initialised. - -See also the subsection on "Cache Coherency" for a more thorough example. - - -CONTROL DEPENDENCIES --------------------- - -A control dependency requires a full read memory barrier, not simply a data -dependency barrier to make it work correctly. Consider the following bit of -code: - - q = &a; - if (p) - q = &b; - - x = *q; - -This will not have the desired effect because there is no actual data -dependency, but rather a control dependency that the CPU may short-circuit by -attempting to predict the outcome in advance. In such a case what's actually -required is: - - q = &a; - if (p) - q = &b; - - x = *q; - - -SMP BARRIER PAIRING -------------------- - -When dealing with CPU-CPU interactions, certain types of memory barrier should -always be paired. A lack of appropriate pairing is almost certainly an error. - -A write barrier should always be paired with a data dependency barrier or read -barrier, though a general barrier would also be viable. Similarly a read -barrier or a data dependency barrier should always be paired with at least an -write barrier, though, again, a general barrier is viable: - - CPU 1 CPU 2 - =============== =============== - a = 1; - - b = 2; x = a; - - y = b; - -Or: - - CPU 1 CPU 2 - =============== =============================== - a = 1; - - b = &a; x = b; - - y = *x; - -Basically, the read barrier always has to be there, even though it can be of -the "weaker" type. - - -EXAMPLES OF MEMORY BARRIER SEQUENCES ------------------------------------- - -Firstly, write barriers act as a partial orderings on store operations. -Consider the following sequence of events: - - CPU 1 - ======================= - STORE A = 1 - STORE B = 2 - STORE C = 3 - - STORE D = 4 - STORE E = 5 - -This sequence of events is committed to the memory coherence system in an order -that the rest of the system might perceive as the unordered set of { STORE A, -STORE B, STORE C } all occuring before the unordered set of { STORE D, STORE E -}: - - +-------+ : : - | | +------+ - | |------>| C=3 | } /\ - | | : +------+ }----- \ -----> Events perceptible - | | : | A=1 | } \/ to rest of system - | | : +------+ } - | CPU 1 | : | B=2 | } - | | +------+ } - | | wwwwwwwwwwwwwwww } <--- At this point the write barrier - | | +------+ } requires all stores prior to the - | | : | E=5 | } barrier to be committed before - | | : +------+ } further stores may be take place. - | |------>| D=4 | } - | | +------+ - +-------+ : : - | - | Sequence in which stores committed to memory system - | by CPU 1 - V - - -Secondly, data dependency barriers act as a partial orderings on data-dependent -loads. Consider the following sequence of events: - - CPU 1 CPU 2 - ======================= ======================= - STORE A = 1 - STORE B = 2 - - STORE C = &B LOAD X - STORE D = 4 LOAD C (gets &B) - LOAD *C (reads B) - -Without intervention, CPU 2 may perceive the events on CPU 1 in some -effectively random order, despite the write barrier issued by CPU 1: - - +-------+ : : : : - | | +------+ +-------+ | Sequence of update - | |------>| B=2 |----- --->| Y->8 | | of perception on - | | : +------+ \ +-------+ | CPU 2 - | CPU 1 | : | A=1 | \ --->| C->&Y | V - | | +------+ | +-------+ - | | wwwwwwwwwwwwwwww | : : - | | +------+ | : : - | | : | C=&B |--- | : : +-------+ - | | : +------+ \ | +-------+ | | - | |------>| D=4 | ----------->| C->&B |------>| | - | | +------+ | +-------+ | | - +-------+ : : | : : | | - | : : | | - | : : | CPU 2 | - | +-------+ | | - Apparently incorrect ---> | | B->7 |------>| | - perception of B (!) | +-------+ | | - | : : | | - | +-------+ | | - The load of X holds ---> \ | X->9 |------>| | - up the maintenance \ +-------+ | | - of coherence of B ----->| B->2 | +-------+ - +-------+ - : : - - -In the above example, CPU 2 perceives that B is 7, despite the load of *C -(which would be B) coming after the the LOAD of C. - -If, however, a data dependency barrier were to be placed between the load of C -and the load of *C (ie: B) on CPU 2, then the following will occur: - - +-------+ : : : : - | | +------+ +-------+ - | |------>| B=2 |----- --->| Y->8 | - | | : +------+ \ +-------+ - | CPU 1 | : | A=1 | \ --->| C->&Y | - | | +------+ | +-------+ - | | wwwwwwwwwwwwwwww | : : - | | +------+ | : : - | | : | C=&B |--- | : : +-------+ - | | : +------+ \ | +-------+ | | - | |------>| D=4 | ----------->| C->&B |------>| | - | | +------+ | +-------+ | | - +-------+ : : | : : | | - | : : | | - | : : | CPU 2 | - | +-------+ | | - \ | X->9 |------>| | - \ +-------+ | | - ----->| B->2 | | | - +-------+ | | - Makes sure all effects ---> ddddddddddddddddd | | - prior to the store of C +-------+ | | - are perceptible to | B->2 |------>| | - successive loads +-------+ | | - : : +-------+ - - -And thirdly, a read barrier acts as a partial order on loads. Consider the -following sequence of events: - - CPU 1 CPU 2 - ======================= ======================= - STORE A=1 - STORE B=2 - STORE C=3 - - STORE D=4 - STORE E=5 - LOAD A - LOAD B - LOAD C - LOAD D - LOAD E - -Without intervention, CPU 2 may then choose to perceive the events on CPU 1 in -some effectively random order, despite the write barrier issued by CPU 1: - - +-------+ : : - | | +------+ - | |------>| C=3 | } - | | : +------+ } - | | : | A=1 | } - | | : +------+ } - | CPU 1 | : | B=2 | }--- - | | +------+ } \ - | | wwwwwwwwwwwww} \ - | | +------+ } \ : : +-------+ - | | : | E=5 | } \ +-------+ | | - | | : +------+ } \ { | C->3 |------>| | - | |------>| D=4 | } \ { +-------+ : | | - | | +------+ \ { | E->5 | : | | - +-------+ : : \ { +-------+ : | | - Transfer -->{ | A->1 | : | CPU 2 | - from CPU 1 { +-------+ : | | - to CPU 2 { | D->4 | : | | - { +-------+ : | | - { | B->2 |------>| | - +-------+ | | - : : +-------+ - - -If, however, a read barrier were to be placed between the load of C and the -load of D on CPU 2, then the partial ordering imposed by CPU 1 will be -perceived correctly by CPU 2. - - +-------+ : : - | | +------+ - | |------>| C=3 | } - | | : +------+ } - | | : | A=1 | }--- - | | : +------+ } \ - | CPU 1 | : | B=2 | } \ - | | +------+ \ - | | wwwwwwwwwwwwwwww \ - | | +------+ \ : : +-------+ - | | : | E=5 | } \ +-------+ | | - | | : +------+ }--- \ { | C->3 |------>| | - | |------>| D=4 | } \ \ { +-------+ : | | - | | +------+ \ -->{ | B->2 | : | | - +-------+ : : \ { +-------+ : | | - \ { | A->1 | : | CPU 2 | - \ +-------+ | | - At this point the read ----> \ rrrrrrrrrrrrrrrrr | | - barrier causes all effects \ +-------+ | | - prior to the storage of C \ { | E->5 | : | | - to be perceptible to CPU 2 -->{ +-------+ : | | - { | D->4 |------>| | - +-------+ | | - : : +-------+ - - -======================== -EXPLICIT KERNEL BARRIERS -======================== - -The Linux kernel has a variety of different barriers that act at different -levels: - - (*) Compiler barrier. - - (*) CPU memory barriers. - - (*) MMIO write barrier. - - -COMPILER BARRIER ----------------- - -The Linux kernel has an explicit compiler barrier function that prevents the -compiler from moving the memory accesses either side of it to the other side: - - barrier(); - -This a general barrier - lesser varieties of compiler barrier do not exist. - -The compiler barrier has no direct effect on the CPU, which may then reorder -things however it wishes. - - -CPU MEMORY BARRIERS -------------------- - -The Linux kernel has eight basic CPU memory barriers: - - TYPE MANDATORY SMP CONDITIONAL - =============== ======================= =========================== - GENERAL mb() smp_mb() - WRITE wmb() smp_wmb() - READ rmb() smp_rmb() - DATA DEPENDENCY read_barrier_depends() smp_read_barrier_depends() - - -All CPU memory barriers unconditionally imply compiler barriers. - -SMP memory barriers are reduced to compiler barriers on uniprocessor compiled -systems because it is assumed that a CPU will be appear to be self-consistent, -and will order overlapping accesses correctly with respect to itself. - -[!] Note that SMP memory barriers _must_ be used to control the ordering of -references to shared memory on SMP systems, though the use of locking instead -is sufficient. - -Mandatory barriers should not be used to control SMP effects, since mandatory -barriers unnecessarily impose overhead on UP systems. They may, however, be -used to control MMIO effects on accesses through relaxed memory I/O windows. -These are required even on non-SMP systems as they affect the order in which -memory operations appear to a device by prohibiting both the compiler and the -CPU from reordering them. - - -There are some more advanced barrier functions: - - (*) set_mb(var, value) - (*) set_wmb(var, value) - - These assign the value to the variable and then insert at least a write - barrier after it, depending on the function. They aren't guaranteed to - insert anything more than a compiler barrier in a UP compilation. - - - (*) smp_mb__before_atomic_dec(); - (*) smp_mb__after_atomic_dec(); - (*) smp_mb__before_atomic_inc(); - (*) smp_mb__after_atomic_inc(); - - These are for use with atomic add, subtract, increment and decrement - functions, especially when used for reference counting. These functions - do not imply memory barriers. - - As an example, consider a piece of code that marks an object as being dead - and then decrements the object's reference count: - - obj->dead = 1; - smp_mb__before_atomic_dec(); - atomic_dec(&obj->ref_count); - - This makes sure that the death mark on the object is perceived to be set - *before* the reference counter is decremented. - - See Documentation/atomic_ops.txt for more information. See the "Atomic - operations" subsection for information on where to use these. - - - (*) smp_mb__before_clear_bit(void); - (*) smp_mb__after_clear_bit(void); - - These are for use similar to the atomic inc/dec barriers. These are - typically used for bitwise unlocking operations, so care must be taken as - there are no implicit memory barriers here either. - - Consider implementing an unlock operation of some nature by clearing a - locking bit. The clear_bit() would then need to be barriered like this: - - smp_mb__before_clear_bit(); - clear_bit( ... ); - - This prevents memory operations before the clear leaking to after it. See - the subsection on "Locking Functions" with reference to UNLOCK operation - implications. - - See Documentation/atomic_ops.txt for more information. See the "Atomic - operations" subsection for information on where to use these. - - -MMIO WRITE BARRIER ------------------- - -The Linux kernel also has a special barrier for use with memory-mapped I/O -writes: - - mmiowb(); - -This is a variation on the mandatory write barrier that causes writes to weakly -ordered I/O regions to be partially ordered. Its effects may go beyond the -CPU->Hardware interface and actually affect the hardware at some level. - -See the subsection "Locks vs I/O accesses" for more information. - - -=============================== -IMPLICIT KERNEL MEMORY BARRIERS -=============================== - -Some of the other functions in the linux kernel imply memory barriers, amongst -which are locking, scheduling and memory allocation functions. - -This specification is a _minimum_ guarantee; any particular architecture may -provide more substantial guarantees, but these may not be relied upon outside -of arch specific code. - - -LOCKING FUNCTIONS ------------------ - -The Linux kernel has a number of locking constructs: - - (*) spin locks - (*) R/W spin locks - (*) mutexes - (*) semaphores - (*) R/W semaphores - (*) RCU - -In all cases there are variants on "LOCK" operations and "UNLOCK" operations -for each construct. These operations all imply certain barriers: - - (1) LOCK operation implication: - - Memory operations issued after the LOCK will be completed after the LOCK - operation has completed. - - Memory operations issued before the LOCK may be completed after the LOCK - operation has completed. - - (2) UNLOCK operation implication: - - Memory operations issued before the UNLOCK will be completed before the - UNLOCK operation has completed. - - Memory operations issued after the UNLOCK may be completed before the - UNLOCK operation has completed. - - (3) LOCK vs LOCK implication: - - All LOCK operations issued before another LOCK operation will be completed - before that LOCK operation. - - (4) LOCK vs UNLOCK implication: - - All LOCK operations issued before an UNLOCK operation will be completed - before the UNLOCK operation. - - All UNLOCK operations issued before a LOCK operation will be completed - before the LOCK operation. - - (5) Failed conditional LOCK implication: - - Certain variants of the LOCK operation may fail, either due to being - unable to get the lock immediately, or due to receiving an unblocked - signal whilst asleep waiting for the lock to become available. Failed - locks do not imply any sort of barrier. - -Therefore, from (1), (2) and (4) an UNLOCK followed by an unconditional LOCK is -equivalent to a full barrier, but a LOCK followed by an UNLOCK is not. - -[!] Note: one of the consequence of LOCKs and UNLOCKs being only one-way - barriers is that the effects instructions outside of a critical section may - seep into the inside of the critical section. - -Locks and semaphores may not provide any guarantee of ordering on UP compiled -systems, and so cannot be counted on in such a situation to actually achieve -anything at all - especially with respect to I/O accesses - unless combined -with interrupt disabling operations. - -See also the section on "Inter-CPU locking barrier effects". - - -As an example, consider the following: - - *A = a; - *B = b; - LOCK - *C = c; - *D = d; - UNLOCK - *E = e; - *F = f; - -The following sequence of events is acceptable: - - LOCK, {*F,*A}, *E, {*C,*D}, *B, UNLOCK - - [+] Note that {*F,*A} indicates a combined access. - -But none of the following are: - - {*F,*A}, *B, LOCK, *C, *D, UNLOCK, *E - *A, *B, *C, LOCK, *D, UNLOCK, *E, *F - *A, *B, LOCK, *C, UNLOCK, *D, *E, *F - *B, LOCK, *C, *D, UNLOCK, {*F,*A}, *E - - - -INTERRUPT DISABLING FUNCTIONS ------------------------------ - -Functions that disable interrupts (LOCK equivalent) and enable interrupts -(UNLOCK equivalent) will act as compiler barriers only. So if memory or I/O -barriers are required in such a situation, they must be provided from some -other means. - - -MISCELLANEOUS FUNCTIONS ------------------------ - -Other functions that imply barriers: - - (*) schedule() and similar imply full memory barriers. - - (*) Memory allocation and release functions imply full memory barriers. - - -================================= -INTER-CPU LOCKING BARRIER EFFECTS -================================= - -On SMP systems locking primitives give a more substantial form of barrier: one -that does affect memory access ordering on other CPUs, within the context of -conflict on any particular lock. - - -LOCKS VS MEMORY ACCESSES ------------------------- - -Consider the following: the system has a pair of spinlocks (N) and (Q), and -three CPUs; then should the following sequence of events occur: - - CPU 1 CPU 2 - =============================== =============================== - *A = a; *E = e; - LOCK M LOCK Q - *B = b; *F = f; - *C = c; *G = g; - UNLOCK M UNLOCK Q - *D = d; *H = h; - -Then there is no guarantee as to what order CPU #3 will see the accesses to *A -through *H occur in, other than the constraints imposed by the separate locks -on the separate CPUs. It might, for example, see: - - *E, LOCK M, LOCK Q, *G, *C, *F, *A, *B, UNLOCK Q, *D, *H, UNLOCK M - -But it won't see any of: - - *B, *C or *D preceding LOCK M - *A, *B or *C following UNLOCK M - *F, *G or *H preceding LOCK Q - *E, *F or *G following UNLOCK Q - - -However, if the following occurs: - - CPU 1 CPU 2 - =============================== =============================== - *A = a; - LOCK M [1] - *B = b; - *C = c; - UNLOCK M [1] - *D = d; *E = e; - LOCK M [2] - *F = f; - *G = g; - UNLOCK M [2] - *H = h; - -CPU #3 might see: - - *E, LOCK M [1], *C, *B, *A, UNLOCK M [1], - LOCK M [2], *H, *F, *G, UNLOCK M [2], *D - -But assuming CPU #1 gets the lock first, it won't see any of: - - *B, *C, *D, *F, *G or *H preceding LOCK M [1] - *A, *B or *C following UNLOCK M [1] - *F, *G or *H preceding LOCK M [2] - *A, *B, *C, *E, *F or *G following UNLOCK M [2] - - -LOCKS VS I/O ACCESSES ---------------------- - -Under certain circumstances (especially involving NUMA), I/O accesses within -two spinlocked sections on two different CPUs may be seen as interleaved by the -PCI bridge, because the PCI bridge does not necessarily participate in the -cache-coherence protocol, and is therefore incapable of issuing the required -read memory barriers. - -For example: - - CPU 1 CPU 2 - =============================== =============================== - spin_lock(Q) - writel(0, ADDR) - writel(1, DATA); - spin_unlock(Q); - spin_lock(Q); - writel(4, ADDR); - writel(5, DATA); - spin_unlock(Q); - -may be seen by the PCI bridge as follows: - - STORE *ADDR = 0, STORE *ADDR = 4, STORE *DATA = 1, STORE *DATA = 5 - -which would probably cause the hardware to malfunction. - - -What is necessary here is to intervene with an mmiowb() before dropping the -spinlock, for example: - - CPU 1 CPU 2 - =============================== =============================== - spin_lock(Q) - writel(0, ADDR) - writel(1, DATA); - mmiowb(); - spin_unlock(Q); - spin_lock(Q); - writel(4, ADDR); - writel(5, DATA); - mmiowb(); - spin_unlock(Q); - -this will ensure that the two stores issued on CPU #1 appear at the PCI bridge -before either of the stores issued on CPU #2. - - -Furthermore, following a store by a load to the same device obviates the need -for an mmiowb(), because the load forces the store to complete before the load -is performed: - - CPU 1 CPU 2 - =============================== =============================== - spin_lock(Q) - writel(0, ADDR) - a = readl(DATA); - spin_unlock(Q); - spin_lock(Q); - writel(4, ADDR); - b = readl(DATA); - spin_unlock(Q); - - -See Documentation/DocBook/deviceiobook.tmpl for more information. - - -================================= -WHERE ARE MEMORY BARRIERS NEEDED? -================================= - -Under normal operation, memory operation reordering is generally not going to -be a problem as a single-threaded linear piece of code will still appear to -work correctly, even if it's in an SMP kernel. There are, however, three -circumstances in which reordering definitely _could_ be a problem: - - (*) Interprocessor interaction. - - (*) Atomic operations. - - (*) Accessing devices (I/O). - - (*) Interrupts. - - -INTERPROCESSOR INTERACTION --------------------------- - -When there's a system with more than one processor, more than one CPU in the -system may be working on the same data set at the same time. This can cause -synchronisation problems, and the usual way of dealing with them is to use -locks. Locks, however, are quite expensive, and so it may be preferable to -operate without the use of a lock if at all possible. In such a case -operations that affect both CPUs may have to be carefully ordered to prevent -a malfunction. - -Consider, for example, the R/W semaphore slow path. Here a waiting process is -queued on the semaphore, by virtue of it having a piece of its stack linked to -the semaphore's list of waiting processes: - - struct rw_semaphore { - ... - spinlock_t lock; - struct list_head waiters; - }; - - struct rwsem_waiter { - struct list_head list; - struct task_struct *task; - }; - -To wake up a particular waiter, the up_read() or up_write() functions have to: - - (1) read the next pointer from this waiter's record to know as to where the - next waiter record is; - - (4) read the pointer to the waiter's task structure; - - (3) clear the task pointer to tell the waiter it has been given the semaphore; - - (4) call wake_up_process() on the task; and - - (5) release the reference held on the waiter's task struct. - -In otherwords, it has to perform this sequence of events: - - LOAD waiter->list.next; - LOAD waiter->task; - STORE waiter->task; - CALL wakeup - RELEASE task - -and if any of these steps occur out of order, then the whole thing may -malfunction. - -Once it has queued itself and dropped the semaphore lock, the waiter does not -get the lock again; it instead just waits for its task pointer to be cleared -before proceeding. Since the record is on the waiter's stack, this means that -if the task pointer is cleared _before_ the next pointer in the list is read, -another CPU might start processing the waiter and might clobber the waiter's -stack before the up*() function has a chance to read the next pointer. - -Consider then what might happen to the above sequence of events: - - CPU 1 CPU 2 - =============================== =============================== - down_xxx() - Queue waiter - Sleep - up_yyy() - LOAD waiter->task; - STORE waiter->task; - Woken up by other event - - Resume processing - down_xxx() returns - call foo() - foo() clobbers *waiter - - LOAD waiter->list.next; - --- OOPS --- - -This could be dealt with using the semaphore lock, but then the down_xxx() -function has to needlessly get the spinlock again after being woken up. - -The way to deal with this is to insert a general SMP memory barrier: - - LOAD waiter->list.next; - LOAD waiter->task; - smp_mb(); - STORE waiter->task; - CALL wakeup - RELEASE task - -In this case, the barrier makes a guarantee that all memory accesses before the -barrier will appear to happen before all the memory accesses after the barrier -with respect to the other CPUs on the system. It does _not_ guarantee that all -the memory accesses before the barrier will be complete by the time the barrier -instruction itself is complete. - -On a UP system - where this wouldn't be a problem - the smp_mb() is just a -compiler barrier, thus making sure the compiler emits the instructions in the -right order without actually intervening in the CPU. Since there there's only -one CPU, that CPU's dependency ordering logic will take care of everything -else. - - -ATOMIC OPERATIONS ------------------ - -Though they are technically interprocessor interaction considerations, atomic -operations are noted specially as they do _not_ generally imply memory -barriers. The possible offenders include: - - xchg(); - cmpxchg(); - test_and_set_bit(); - test_and_clear_bit(); - test_and_change_bit(); - atomic_cmpxchg(); - atomic_inc_return(); - atomic_dec_return(); - atomic_add_return(); - atomic_sub_return(); - atomic_inc_and_test(); - atomic_dec_and_test(); - atomic_sub_and_test(); - atomic_add_negative(); - atomic_add_unless(); - -These may be used for such things as implementing LOCK operations or controlling -the lifetime of objects by decreasing their reference counts. In such cases -they need preceding memory barriers. - -The following may also be possible offenders as they may be used as UNLOCK -operations. - - set_bit(); - clear_bit(); - change_bit(); - atomic_set(); - - -The following are a little tricky: - - atomic_add(); - atomic_sub(); - atomic_inc(); - atomic_dec(); - -If they're used for statistics generation, then they probably don't need memory -barriers, unless there's a coupling between statistical data. - -If they're used for reference counting on an object to control its lifetime, -they probably don't need memory barriers because either the reference count -will be adjusted inside a locked section, or the caller will already hold -sufficient references to make the lock, and thus a memory barrier unnecessary. - -If they're used for constructing a lock of some description, then they probably -do need memory barriers as a lock primitive generally has to do things in a -specific order. - - -Basically, each usage case has to be carefully considered as to whether memory -barriers are needed or not. The simplest rule is probably: if the atomic -operation is protected by a lock, then it does not require a barrier unless -there's another operation within the critical section with respect to which an -ordering must be maintained. - -See Documentation/atomic_ops.txt for more information. - - -ACCESSING DEVICES ------------------ - -Many devices can be memory mapped, and so appear to the CPU as if they're just -a set of memory locations. To control such a device, the driver usually has to -make the right memory accesses in exactly the right order. - -However, having a clever CPU or a clever compiler creates a potential problem -in that the carefully sequenced accesses in the driver code won't reach the -device in the requisite order if the CPU or the compiler thinks it is more -efficient to reorder, combine or merge accesses - something that would cause -the device to malfunction. - -Inside of the Linux kernel, I/O should be done through the appropriate accessor -routines - such as inb() or writel() - which know how to make such accesses -appropriately sequential. Whilst this, for the most part, renders the explicit -use of memory barriers unnecessary, there are a couple of situations where they -might be needed: - - (1) On some systems, I/O stores are not strongly ordered across all CPUs, and - so for _all_ general drivers locks should be used and mmiowb() must be - issued prior to unlocking the critical section. - - (2) If the accessor functions are used to refer to an I/O memory window with - relaxed memory access properties, then _mandatory_ memory barriers are - required to enforce ordering. - -See Documentation/DocBook/deviceiobook.tmpl for more information. - - -INTERRUPTS ----------- - -A driver may be interrupted by its own interrupt service routine, and thus the -two parts of the driver may interfere with each other's attempts to control or -access the device. - -This may be alleviated - at least in part - by disabling local interrupts (a -form of locking), such that the critical operations are all contained within -the interrupt-disabled section in the driver. Whilst the driver's interrupt -routine is executing, the driver's core may not run on the same CPU, and its -interrupt is not permitted to happen again until the current interrupt has been -handled, thus the interrupt handler does not need to lock against that. - -However, consider a driver that was talking to an ethernet card that sports an -address register and a data register. If that driver's core talks to the card -under interrupt-disablement and then the driver's interrupt handler is invoked: - - LOCAL IRQ DISABLE - writew(ADDR, 3); - writew(DATA, y); - LOCAL IRQ ENABLE - - writew(ADDR, 4); - q = readw(DATA); - - -The store to the data register might happen after the second store to the -address register if ordering rules are sufficiently relaxed: - - STORE *ADDR = 3, STORE *ADDR = 4, STORE *DATA = y, q = LOAD *DATA - - -If ordering rules are relaxed, it must be assumed that accesses done inside an -interrupt disabled section may leak outside of it and may interleave with -accesses performed in an interrupt - and vice versa - unless implicit or -explicit barriers are used. - -Normally this won't be a problem because the I/O accesses done inside such -sections will include synchronous load operations on strictly ordered I/O -registers that form implicit I/O barriers. If this isn't sufficient then an -mmiowb() may need to be used explicitly. - - -A similar situation may occur between an interrupt routine and two routines -running on separate CPUs that communicate with each other. If such a case is -likely, then interrupt-disabling locks should be used to guarantee ordering. - - -========================== -KERNEL I/O BARRIER EFFECTS -========================== - -When accessing I/O memory, drivers should use the appropriate accessor -functions: - - (*) inX(), outX(): - - These are intended to talk to I/O space rather than memory space, but - that's primarily a CPU-specific concept. The i386 and x86_64 processors do - indeed have special I/O space access cycles and instructions, but many - CPUs don't have such a concept. - - The PCI bus, amongst others, defines an I/O space concept - which on such - CPUs as i386 and x86_64 cpus readily maps to the CPU's concept of I/O - space. However, it may also mapped as a virtual I/O space in the CPU's - memory map, particularly on those CPUs that don't support alternate - I/O spaces. - - Accesses to this space may be fully synchronous (as on i386), but - intermediary bridges (such as the PCI host bridge) may not fully honour - that. - - They are guaranteed to be fully ordered with respect to each other. - - They are not guaranteed to be fully ordered with respect to other types of - memory and I/O operation. - - (*) readX(), writeX(): - - Whether these are guaranteed to be fully ordered and uncombined with - respect to each other on the issuing CPU depends on the characteristics - defined for the memory window through which they're accessing. On later - i386 architecture machines, for example, this is controlled by way of the - MTRR registers. - - Ordinarily, these will be guaranteed to be fully ordered and uncombined,, - provided they're not accessing a prefetchable device. - - However, intermediary hardware (such as a PCI bridge) may indulge in - deferral if it so wishes; to flush a store, a load from the same location - is preferred[*], but a load from the same device or from configuration - space should suffice for PCI. - - [*] NOTE! attempting to load from the same location as was written to may - cause a malfunction - consider the 16550 Rx/Tx serial registers for - example. - - Used with prefetchable I/O memory, an mmiowb() barrier may be required to - force stores to be ordered. - - Please refer to the PCI specification for more information on interactions - between PCI transactions. - - (*) readX_relaxed() - - These are similar to readX(), but are not guaranteed to be ordered in any - way. Be aware that there is no I/O read barrier available. - - (*) ioreadX(), iowriteX() - - These will perform as appropriate for the type of access they're actually - doing, be it inX()/outX() or readX()/writeX(). - - -======================================== -ASSUMED MINIMUM EXECUTION ORDERING MODEL -======================================== - -It has to be assumed that the conceptual CPU is weakly-ordered but that it will -maintain the appearance of program causality with respect to itself. Some CPUs -(such as i386 or x86_64) are more constrained than others (such as powerpc or -frv), and so the most relaxed case (namely DEC Alpha) must be assumed outside -of arch-specific code. - -This means that it must be considered that the CPU will execute its instruction -stream in any order it feels like - or even in parallel - provided that if an -instruction in the stream depends on the an earlier instruction, then that -earlier instruction must be sufficiently complete[*] before the later -instruction may proceed; in other words: provided that the appearance of -causality is maintained. - - [*] Some instructions have more than one effect - such as changing the - condition codes, changing registers or changing memory - and different - instructions may depend on different effects. - -A CPU may also discard any instruction sequence that winds up having no -ultimate effect. For example, if two adjacent instructions both load an -immediate value into the same register, the first may be discarded. - - -Similarly, it has to be assumed that compiler might reorder the instruction -stream in any way it sees fit, again provided the appearance of causality is -maintained. - - -============================ -THE EFFECTS OF THE CPU CACHE -============================ - -The way cached memory operations are perceived across the system is affected to -a certain extent by the caches that lie between CPUs and memory, and by the -memory coherence system that maintains the consistency of state in the system. - -As far as the way a CPU interacts with another part of the system through the -caches goes, the memory system has to include the CPU's caches, and memory -barriers for the most part act at the interface between the CPU and its cache -(memory barriers logically act on the dotted line in the following diagram): - - <--- CPU ---> : <----------- Memory -----------> - : - +--------+ +--------+ : +--------+ +-----------+ - | | | | : | | | | +--------+ - | CPU | | Memory | : | CPU | | | | | - | Core |--->| Access |----->| Cache |<-->| | | | - | | | Queue | : | | | |--->| Memory | - | | | | : | | | | | | - +--------+ +--------+ : +--------+ | | | | - : | Cache | +--------+ - : | Coherency | - : | Mechanism | +--------+ - +--------+ +--------+ : +--------+ | | | | - | | | | : | | | | | | - | CPU | | Memory | : | CPU | | |--->| Device | - | Core |--->| Access |----->| Cache |<-->| | | | - | | | Queue | : | | | | | | - | | | | : | | | | +--------+ - +--------+ +--------+ : +--------+ +-----------+ - : - : - -Although any particular load or store may not actually appear outside of the -CPU that issued it since it may have been satisfied within the CPU's own cache, -it will still appear as if the full memory access had taken place as far as the -other CPUs are concerned since the cache coherency mechanisms will migrate the -cacheline over to the accessing CPU and propagate the effects upon conflict. - -The CPU core may execute instructions in any order it deems fit, provided the -expected program causality appears to be maintained. Some of the instructions -generate load and store operations which then go into the queue of memory -accesses to be performed. The core may place these in the queue in any order -it wishes, and continue execution until it is forced to wait for an instruction -to complete. - -What memory barriers are concerned with is controlling the order in which -accesses cross from the CPU side of things to the memory side of things, and -the order in which the effects are perceived to happen by the other observers -in the system. - -[!] Memory barriers are _not_ needed within a given CPU, as CPUs always see -their own loads and stores as if they had happened in program order. - -[!] MMIO or other device accesses may bypass the cache system. This depends on -the properties of the memory window through which devices are accessed and/or -the use of any special device communication instructions the CPU may have. - - -CACHE COHERENCY ---------------- - -Life isn't quite as simple as it may appear above, however: for while the -caches are expected to be coherent, there's no guarantee that that coherency -will be ordered. This means that whilst changes made on one CPU will -eventually become visible on all CPUs, there's no guarantee that they will -become apparent in the same order on those other CPUs. - - -Consider dealing with a system that has pair of CPUs (1 & 2), each of which has -a pair of parallel data caches (CPU 1 has A/B, and CPU 2 has C/D): - - : - : +--------+ - : +---------+ | | - +--------+ : +--->| Cache A |<------->| | - | | : | +---------+ | | - | CPU 1 |<---+ | | - | | : | +---------+ | | - +--------+ : +--->| Cache B |<------->| | - : +---------+ | | - : | Memory | - : +---------+ | System | - +--------+ : +--->| Cache C |<------->| | - | | : | +---------+ | | - | CPU 2 |<---+ | | - | | : | +---------+ | | - +--------+ : +--->| Cache D |<------->| | - : +---------+ | | - : +--------+ - : - -Imagine the system has the following properties: - - (*) an odd-numbered cache line may be in cache A, cache C or it may still be - resident in memory; - - (*) an even-numbered cache line may be in cache B, cache D or it may still be - resident in memory; - - (*) whilst the CPU core is interrogating one cache, the other cache may be - making use of the bus to access the rest of the system - perhaps to - displace a dirty cacheline or to do a speculative load; - - (*) each cache has a queue of operations that need to be applied to that cache - to maintain coherency with the rest of the system; - - (*) the coherency queue is not flushed by normal loads to lines already - present in the cache, even though the contents of the queue may - potentially effect those loads. - -Imagine, then, that two writes are made on the first CPU, with a write barrier -between them to guarantee that they will appear to reach that CPU's caches in -the requisite order: - - CPU 1 CPU 2 COMMENT - =============== =============== ======================================= - u == 0, v == 1 and p == &u, q == &u - v = 2; - smp_wmb(); Make sure change to v visible before - change to p - v is now in cache A exclusively - p = &v; - p is now in cache B exclusively - -The write memory barrier forces the other CPUs in the system to perceive that -the local CPU's caches have apparently been updated in the correct order. But -now imagine that the second CPU that wants to read those values: - - CPU 1 CPU 2 COMMENT - =============== =============== ======================================= - ... - q = p; - x = *q; - -The above pair of reads may then fail to happen in expected order, as the -cacheline holding p may get updated in one of the second CPU's caches whilst -the update to the cacheline holding v is delayed in the other of the second -CPU's caches by some other cache event: - - CPU 1 CPU 2 COMMENT - =============== =============== ======================================= - u == 0, v == 1 and p == &u, q == &u - v = 2; - smp_wmb(); - - - p = &b; q = p; - - - - x = *q; - Reads from v before v updated in cache - - - -Basically, whilst both cachelines will be updated on CPU 2 eventually, there's -no guarantee that, without intervention, the order of update will be the same -as that committed on CPU 1. - - -To intervene, we need to interpolate a data dependency barrier or a read -barrier between the loads. This will force the cache to commit its coherency -queue before processing any further requests: - - CPU 1 CPU 2 COMMENT - =============== =============== ======================================= - u == 0, v == 1 and p == &u, q == &u - v = 2; - smp_wmb(); - - - p = &b; q = p; - - - - smp_read_barrier_depends() - - - x = *q; - Reads from v after v updated in cache - - -This sort of problem can be encountered on DEC Alpha processors as they have a -split cache that improves performance by making better use of the data bus. -Whilst most CPUs do imply a data dependency barrier on the read when a memory -access depends on a read, not all do, so it may not be relied on. - -Other CPUs may also have split caches, but must coordinate between the various -cachelets for normal memory accesss. The semantics of the Alpha removes the -need for coordination in absence of memory barriers. - - -CACHE COHERENCY VS DMA ----------------------- - -Not all systems maintain cache coherency with respect to devices doing DMA. In -such cases, a device attempting DMA may obtain stale data from RAM because -dirty cache lines may be resident in the caches of various CPUs, and may not -have been written back to RAM yet. To deal with this, the appropriate part of -the kernel must flush the overlapping bits of cache on each CPU (and maybe -invalidate them as well). - -In addition, the data DMA'd to RAM by a device may be overwritten by dirty -cache lines being written back to RAM from a CPU's cache after the device has -installed its own data, or cache lines simply present in a CPUs cache may -simply obscure the fact that RAM has been updated, until at such time as the -cacheline is discarded from the CPU's cache and reloaded. To deal with this, -the appropriate part of the kernel must invalidate the overlapping bits of the -cache on each CPU. - -See Documentation/cachetlb.txt for more information on cache management. - - -CACHE COHERENCY VS MMIO ------------------------ - -Memory mapped I/O usually takes place through memory locations that are part of -a window in the CPU's memory space that have different properties assigned than -the usual RAM directed window. - -Amongst these properties is usually the fact that such accesses bypass the -caching entirely and go directly to the device buses. This means MMIO accesses -may, in effect, overtake accesses to cached memory that were emitted earlier. -A memory barrier isn't sufficient in such a case, but rather the cache must be -flushed between the cached memory write and the MMIO access if the two are in -any way dependent. - - -========================= -THE THINGS CPUS GET UP TO -========================= - -A programmer might take it for granted that the CPU will perform memory -operations in exactly the order specified, so that if a CPU is, for example, -given the following piece of code to execute: - - a = *A; - *B = b; - c = *C; - d = *D; - *E = e; - -They would then expect that the CPU will complete the memory operation for each -instruction before moving on to the next one, leading to a definite sequence of -operations as seen by external observers in the system: - - LOAD *A, STORE *B, LOAD *C, LOAD *D, STORE *E. - - -Reality is, of course, much messier. With many CPUs and compilers, the above -assumption doesn't hold because: - - (*) loads are more likely to need to be completed immediately to permit - execution progress, whereas stores can often be deferred without a - problem; - - (*) loads may be done speculatively, and the result discarded should it prove - to have been unnecessary; - - (*) loads may be done speculatively, leading to the result having being - fetched at the wrong time in the expected sequence of events; - - (*) the order of the memory accesses may be rearranged to promote better use - of the CPU buses and caches; - - (*) loads and stores may be combined to improve performance when talking to - memory or I/O hardware that can do batched accesses of adjacent locations, - thus cutting down on transaction setup costs (memory and PCI devices may - both be able to do this); and - - (*) the CPU's data cache may affect the ordering, and whilst cache-coherency - mechanisms may alleviate this - once the store has actually hit the cache - - there's no guarantee that the coherency management will be propagated in - order to other CPUs. - -So what another CPU, say, might actually observe from the above piece of code -is: - - LOAD *A, ..., LOAD {*C,*D}, STORE *E, STORE *B - - (Where "LOAD {*C,*D}" is a combined load) - - -However, it is guaranteed that a CPU will be self-consistent: it will see its -_own_ accesses appear to be correctly ordered, without the need for a memory -barrier. For instance with the following code: - - U = *A; - *A = V; - *A = W; - X = *A; - *A = Y; - Z = *A; - -and assuming no intervention by an external influence, it can be assumed that -the final result will appear to be: - - U == the original value of *A - X == W - Z == Y - *A == Y - -The code above may cause the CPU to generate the full sequence of memory -accesses: - - U=LOAD *A, STORE *A=V, STORE *A=W, X=LOAD *A, STORE *A=Y, Z=LOAD *A - -in that order, but, without intervention, the sequence may have almost any -combination of elements combined or discarded, provided the program's view of -the world remains consistent. - -The compiler may also combine, discard or defer elements of the sequence before -the CPU even sees them. - -For instance: - - *A = V; - *A = W; - -may be reduced to: - - *A = W; - -since, without a write barrier, it can be assumed that the effect of the -storage of V to *A is lost. Similarly: - - *A = Y; - Z = *A; - -may, without a memory barrier, be reduced to: - - *A = Y; - Z = Y; - -and the LOAD operation never appear outside of the CPU. - - -AND THEN THERE'S THE ALPHA --------------------------- - -The DEC Alpha CPU is one of the most relaxed CPUs there is. Not only that, -some versions of the Alpha CPU have a split data cache, permitting them to have -two semantically related cache lines updating at separate times. This is where -the data dependency barrier really becomes necessary as this synchronises both -caches with the memory coherence system, thus making it seem like pointer -changes vs new data occur in the right order. - -The Alpha defines the Linux's kernel's memory barrier model. - -See the subsection on "Cache Coherency" above. - - -========== -REFERENCES -========== - -Alpha AXP Architecture Reference Manual, Second Edition (Sites & Witek, -Digital Press) - Chapter 5.2: Physical Address Space Characteristics - Chapter 5.4: Caches and Write Buffers - Chapter 5.5: Data Sharing - Chapter 5.6: Read/Write Ordering - -AMD64 Architecture Programmer's Manual Volume 2: System Programming - Chapter 7.1: Memory-Access Ordering - Chapter 7.4: Buffering and Combining Memory Writes - -IA-32 Intel Architecture Software Developer's Manual, Volume 3: -System Programming Guide - Chapter 7.1: Locked Atomic Operations - Chapter 7.2: Memory Ordering - Chapter 7.4: Serializing Instructions - -The SPARC Architecture Manual, Version 9 - Chapter 8: Memory Models - Appendix D: Formal Specification of the Memory Models - Appendix J: Programming with the Memory Models - -UltraSPARC Programmer Reference Manual - Chapter 5: Memory Accesses and Cacheability - Chapter 15: Sparc-V9 Memory Models - -UltraSPARC III Cu User's Manual - Chapter 9: Memory Models - -UltraSPARC IIIi Processor User's Manual - Chapter 8: Memory Models - -UltraSPARC Architecture 2005 - Chapter 9: Memory - Appendix D: Formal Specifications of the Memory Models - -UltraSPARC T1 Supplement to the UltraSPARC Architecture 2005 - Chapter 8: Memory Models - Appendix F: Caches and Cache Coherency - -Solaris Internals, Core Kernel Architecture, p63-68: - Chapter 3.3: Hardware Considerations for Locks and - Synchronization - -Unix Systems for Modern Architectures, Symmetric Multiprocessing and Caching -for Kernel Programmers: - Chapter 13: Other Memory Models - -Intel Itanium Architecture Software Developer's Manual: Volume 1: - Section 2.6: Speculation - Section 4.4: Memory Access diff --git a/trunk/Documentation/networking/TODO b/trunk/Documentation/networking/TODO new file mode 100644 index 000000000000..66d36ff14bae --- /dev/null +++ b/trunk/Documentation/networking/TODO @@ -0,0 +1,18 @@ +To-do items for network drivers +------------------------------- + +* Move ethernet crc routine to generic code + +* (for 2.5) Integrate Jamal Hadi Salim's netdev Rx polling API change + +* Audit all net drivers to make sure magic packet / wake-on-lan / + similar features are disabled in the driver by default. + +* Audit all net drivers to make sure the module always prints out a + version string when loaded as a module, but only prints a version + string when built into the kernel if a device is detected. + +* Add ETHTOOL_GDRVINFO ioctl support to all ethernet drivers. + +* dmfe PCI DMA is totally wrong and only works on x86 + diff --git a/trunk/Documentation/networking/bcm43xx.txt b/trunk/Documentation/networking/bcm43xx.txt deleted file mode 100644 index 28541d2bee1e..000000000000 --- a/trunk/Documentation/networking/bcm43xx.txt +++ /dev/null @@ -1,36 +0,0 @@ - - BCM43xx Linux Driver Project - ============================ - -About this software -------------------- - -The goal of this project is to develop a linux driver for Broadcom -BCM43xx chips, based on the specification at -http://bcm-specs.sipsolutions.net/ - -The project page is http://bcm43xx.berlios.de/ - - -Requirements ------------- - -1) Linux Kernel 2.6.16 or later - http://www.kernel.org/ - - You may want to configure your kernel with: - - CONFIG_DEBUG_FS (optional): - -> Kernel hacking - -> Debug Filesystem - -2) SoftMAC IEEE 802.11 Networking Stack extension and patched ieee80211 - modules: - http://softmac.sipsolutions.net/ - -3) Firmware Files - - Please try fwcutter. Fwcutter can extract the firmware from various - binary driver files. It supports driver files from Windows, MacOS and - Linux. You can get fwcutter from http://bcm43xx.berlios.de/. - Also, fwcutter comes with a README file for further instructions. diff --git a/trunk/Documentation/powerpc/booting-without-of.txt b/trunk/Documentation/powerpc/booting-without-of.txt index 217e51768b87..ee551c6ea235 100644 --- a/trunk/Documentation/powerpc/booting-without-of.txt +++ b/trunk/Documentation/powerpc/booting-without-of.txt @@ -719,11 +719,6 @@ address which can extend beyond that limit. - model : this is your board name/model - #address-cells : address representation for "root" devices - #size-cells: the size representation for "root" devices - - device_type : This property shouldn't be necessary. However, if - you decide to create a device_type for your root node, make sure it - is _not_ "chrp" unless your platform is a pSeries or PAPR compliant - one for 64-bit, or a CHRP-type machine for 32-bit as this will - matched by the kernel this way. Additionally, some recommended properties are: diff --git a/trunk/MAINTAINERS b/trunk/MAINTAINERS index c9465811addc..e5b051f0e27e 100644 --- a/trunk/MAINTAINERS +++ b/trunk/MAINTAINERS @@ -1885,7 +1885,6 @@ NETWORKING [GENERAL] P: Networking Team M: netdev@vger.kernel.org L: netdev@vger.kernel.org -W: http://linux-net.osdl.org/ S: Maintained NETWORKING [IPv4/IPv6] diff --git a/trunk/arch/alpha/kernel/alpha_ksyms.c b/trunk/arch/alpha/kernel/alpha_ksyms.c index 9d6186d50245..1898ea79d0e2 100644 --- a/trunk/arch/alpha/kernel/alpha_ksyms.c +++ b/trunk/arch/alpha/kernel/alpha_ksyms.c @@ -216,6 +216,8 @@ EXPORT_SYMBOL(memcpy); EXPORT_SYMBOL(memset); EXPORT_SYMBOL(memchr); +EXPORT_SYMBOL(get_wchan); + #ifdef CONFIG_ALPHA_IRONGATE EXPORT_SYMBOL(irongate_ioremap); EXPORT_SYMBOL(irongate_iounmap); diff --git a/trunk/arch/alpha/kernel/core_marvel.c b/trunk/arch/alpha/kernel/core_marvel.c index 7f6a98455e74..44866cb26a80 100644 --- a/trunk/arch/alpha/kernel/core_marvel.c +++ b/trunk/arch/alpha/kernel/core_marvel.c @@ -435,7 +435,7 @@ marvel_specify_io7(char *str) str = pchar; } while(*str); - return 1; + return 0; } __setup("io7=", marvel_specify_io7); diff --git a/trunk/arch/arm/Kconfig b/trunk/arch/arm/Kconfig index dc5a9332c915..ba46d779ede7 100644 --- a/trunk/arch/arm/Kconfig +++ b/trunk/arch/arm/Kconfig @@ -77,14 +77,6 @@ config FIQ config ARCH_MTD_XIP bool -config VECTORS_BASE - hex - default 0xffff0000 if MMU - default DRAM_BASE if REMAP_VECTORS_TO_RAM - default 0x00000000 - help - The base address of exception vectors. - source "init/Kconfig" menu "System Type" @@ -847,8 +839,6 @@ source "drivers/misc/Kconfig" source "drivers/mfd/Kconfig" -source "drivers/leds/Kconfig" - source "drivers/media/Kconfig" source "drivers/video/Kconfig" diff --git a/trunk/arch/arm/Kconfig-nommu b/trunk/arch/arm/Kconfig-nommu deleted file mode 100644 index e1574be2ded6..000000000000 --- a/trunk/arch/arm/Kconfig-nommu +++ /dev/null @@ -1,44 +0,0 @@ -# -# Kconfig for uClinux(non-paged MM) depend configurations -# Hyok S. Choi -# - -config SET_MEM_PARAM - bool "Set flash/sdram size and base addr" - help - Say Y to manually set the base addresses and sizes. - otherwise, the default values are assigned. - -config DRAM_BASE - hex '(S)DRAM Base Address' if SET_MEM_PARAM - default 0x00800000 - -config DRAM_SIZE - hex '(S)DRAM SIZE' if SET_MEM_PARAM - default 0x00800000 - -config FLASH_MEM_BASE - hex 'FLASH Base Address' if SET_MEM_PARAM - default 0x00400000 - -config FLASH_SIZE - hex 'FLASH Size' if SET_MEM_PARAM - default 0x00400000 - -config REMAP_VECTORS_TO_RAM - bool 'Install vectors to the begining of RAM' if DRAM_BASE - depends on DRAM_BASE - help - The kernel needs to change the hardware exception vectors. - In nommu mode, the hardware exception vectors are normally - placed at address 0x00000000. However, this region may be - occupied by read-only memory depending on H/W design. - - If the region contains read-write memory, say 'n' here. - - If your CPU provides a remap facility which allows the exception - vectors to be mapped to writable memory, say 'n' here. - - Otherwise, say 'y' here. In this case, the kernel will require - external support to redirect the hardware exception vectors to - the writable versions located at DRAM_BASE. diff --git a/trunk/arch/arm/Makefile b/trunk/arch/arm/Makefile index 95a96275f88a..ce3e804ea0f3 100644 --- a/trunk/arch/arm/Makefile +++ b/trunk/arch/arm/Makefile @@ -20,11 +20,6 @@ GZFLAGS :=-9 # Select a platform tht is kept up-to-date KBUILD_DEFCONFIG := versatile_defconfig -# defines filename extension depending memory manement type. -ifeq ($(CONFIG_MMU),) -MMUEXT := -nommu -endif - ifeq ($(CONFIG_FRAME_POINTER),y) CFLAGS +=-fno-omit-frame-pointer -mapcs -mno-sched-prolog endif @@ -78,7 +73,7 @@ AFLAGS +=$(CFLAGS_ABI) $(arch-y) $(tune-y) -msoft-float CHECKFLAGS += -D__arm__ #Default value -head-y := arch/arm/kernel/head$(MMUEXT).o arch/arm/kernel/init_task.o +head-y := arch/arm/kernel/head.o arch/arm/kernel/init_task.o textofs-y := 0x00008000 machine-$(CONFIG_ARCH_RPC) := rpc @@ -138,7 +133,7 @@ else MACHINE := endif -export TEXT_OFFSET GZFLAGS MMUEXT +export TEXT_OFFSET GZFLAGS # Do we have FASTFPE? FASTFPE :=arch/arm/fastfpe diff --git a/trunk/arch/arm/boot/compressed/head.S b/trunk/arch/arm/boot/compressed/head.S index b56f5e691d65..491c7e4c9ac6 100644 --- a/trunk/arch/arm/boot/compressed/head.S +++ b/trunk/arch/arm/boot/compressed/head.S @@ -2,7 +2,6 @@ * linux/arch/arm/boot/compressed/head.S * * Copyright (C) 1996-2002 Russell King - * Copyright (C) 2004 Hyok S. Choi (MPU support) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -321,62 +320,6 @@ params: ldr r0, =params_phys cache_on: mov r3, #8 @ cache_on function b call_cache_fn -/* - * Initialize the highest priority protection region, PR7 - * to cover all 32bit address and cacheable and bufferable. - */ -__armv4_mpu_cache_on: - mov r0, #0x3f @ 4G, the whole - mcr p15, 0, r0, c6, c7, 0 @ PR7 Area Setting - mcr p15, 0, r0, c6, c7, 1 - - mov r0, #0x80 @ PR7 - mcr p15, 0, r0, c2, c0, 0 @ D-cache on - mcr p15, 0, r0, c2, c0, 1 @ I-cache on - mcr p15, 0, r0, c3, c0, 0 @ write-buffer on - - mov r0, #0xc000 - mcr p15, 0, r0, c5, c0, 1 @ I-access permission - mcr p15, 0, r0, c5, c0, 0 @ D-access permission - - mov r0, #0 - mcr p15, 0, r0, c7, c10, 4 @ drain write buffer - mcr p15, 0, r0, c7, c5, 0 @ flush(inval) I-Cache - mcr p15, 0, r0, c7, c6, 0 @ flush(inval) D-Cache - mrc p15, 0, r0, c1, c0, 0 @ read control reg - @ ...I .... ..D. WC.M - orr r0, r0, #0x002d @ .... .... ..1. 11.1 - orr r0, r0, #0x1000 @ ...1 .... .... .... - - mcr p15, 0, r0, c1, c0, 0 @ write control reg - - mov r0, #0 - mcr p15, 0, r0, c7, c5, 0 @ flush(inval) I-Cache - mcr p15, 0, r0, c7, c6, 0 @ flush(inval) D-Cache - mov pc, lr - -__armv3_mpu_cache_on: - mov r0, #0x3f @ 4G, the whole - mcr p15, 0, r0, c6, c7, 0 @ PR7 Area Setting - - mov r0, #0x80 @ PR7 - mcr p15, 0, r0, c2, c0, 0 @ cache on - mcr p15, 0, r0, c3, c0, 0 @ write-buffer on - - mov r0, #0xc000 - mcr p15, 0, r0, c5, c0, 0 @ access permission - - mov r0, #0 - mcr p15, 0, r0, c7, c0, 0 @ invalidate whole cache v3 - mrc p15, 0, r0, c1, c0, 0 @ read control reg - @ .... .... .... WC.M - orr r0, r0, #0x000d @ .... .... .... 11.1 - mov r0, #0 - mcr p15, 0, r0, c1, c0, 0 @ write control reg - - mcr p15, 0, r0, c7, c0, 0 @ invalidate whole cache v3 - mov pc, lr - __setup_mmu: sub r3, r4, #16384 @ Page directory size bic r3, r3, #0xff @ Align the pointer bic r3, r3, #0x3f00 @@ -553,18 +496,6 @@ proc_types: b __armv4_mmu_cache_off mov pc, lr - .word 0x41007400 @ ARM74x - .word 0xff00ff00 - b __armv3_mpu_cache_on - b __armv3_mpu_cache_off - b __armv3_mpu_cache_flush - - .word 0x41009400 @ ARM94x - .word 0xff00ff00 - b __armv4_mpu_cache_on - b __armv4_mpu_cache_off - b __armv4_mpu_cache_flush - .word 0x00007000 @ ARM7 IDs .word 0x0000f000 mov pc, lr @@ -631,24 +562,6 @@ proc_types: cache_off: mov r3, #12 @ cache_off function b call_cache_fn -__armv4_mpu_cache_off: - mrc p15, 0, r0, c1, c0 - bic r0, r0, #0x000d - mcr p15, 0, r0, c1, c0 @ turn MPU and cache off - mov r0, #0 - mcr p15, 0, r0, c7, c10, 4 @ drain write buffer - mcr p15, 0, r0, c7, c6, 0 @ flush D-Cache - mcr p15, 0, r0, c7, c5, 0 @ flush I-Cache - mov pc, lr - -__armv3_mpu_cache_off: - mrc p15, 0, r0, c1, c0 - bic r0, r0, #0x000d - mcr p15, 0, r0, c1, c0, 0 @ turn MPU and cache off - mov r0, #0 - mcr p15, 0, r0, c7, c0, 0 @ invalidate whole cache v3 - mov pc, lr - __armv4_mmu_cache_off: mrc p15, 0, r0, c1, c0 bic r0, r0, #0x000d @@ -688,24 +601,6 @@ cache_clean_flush: mov r3, #16 b call_cache_fn -__armv4_mpu_cache_flush: - mov r2, #1 - mov r3, #0 - mcr p15, 0, ip, c7, c6, 0 @ invalidate D cache - mov r1, #7 << 5 @ 8 segments -1: orr r3, r1, #63 << 26 @ 64 entries -2: mcr p15, 0, r3, c7, c14, 2 @ clean & invalidate D index - subs r3, r3, #1 << 26 - bcs 2b @ entries 63 to 0 - subs r1, r1, #1 << 5 - bcs 1b @ segments 7 to 0 - - teq r2, #0 - mcrne p15, 0, ip, c7, c5, 0 @ invalidate I cache - mcr p15, 0, ip, c7, c10, 4 @ drain WB - mov pc, lr - - __armv6_mmu_cache_flush: mov r1, #0 mcr p15, 0, r1, c7, c14, 0 @ clean+invalidate D @@ -743,7 +638,6 @@ no_cache_id: mov pc, lr __armv3_mmu_cache_flush: -__armv3_mpu_cache_flush: mov r1, #0 mcr p15, 0, r0, c7, c0, 0 @ invalidate whole cache v3 mov pc, lr diff --git a/trunk/arch/arm/common/sharpsl_pm.c b/trunk/arch/arm/common/sharpsl_pm.c index 3cd8c9ee4510..978d32e82d39 100644 --- a/trunk/arch/arm/common/sharpsl_pm.c +++ b/trunk/arch/arm/common/sharpsl_pm.c @@ -22,7 +22,6 @@ #include #include #include -#include #include #include @@ -76,7 +75,6 @@ static void sharpsl_battery_thread(void *private_); struct sharpsl_pm_status sharpsl_pm; DECLARE_WORK(toggle_charger, sharpsl_charge_toggle, NULL); DECLARE_WORK(sharpsl_bat, sharpsl_battery_thread, NULL); -DEFINE_LED_TRIGGER(sharpsl_charge_led_trigger); static int get_percentage(int voltage) @@ -192,10 +190,10 @@ void sharpsl_pm_led(int val) dev_err(sharpsl_pm.dev, "Charging Error!\n"); } else if (val == SHARPSL_LED_ON) { dev_dbg(sharpsl_pm.dev, "Charge LED On\n"); - led_trigger_event(sharpsl_charge_led_trigger, LED_FULL); + } else { dev_dbg(sharpsl_pm.dev, "Charge LED Off\n"); - led_trigger_event(sharpsl_charge_led_trigger, LED_OFF); + } } @@ -788,8 +786,6 @@ static int __init sharpsl_pm_probe(struct platform_device *pdev) init_timer(&sharpsl_pm.chrg_full_timer); sharpsl_pm.chrg_full_timer.function = sharpsl_chrg_full_timer; - led_trigger_register_simple("sharpsl-charge", &sharpsl_charge_led_trigger); - sharpsl_pm.machinfo->init(); device_create_file(&pdev->dev, &dev_attr_battery_percentage); @@ -811,8 +807,6 @@ static int sharpsl_pm_remove(struct platform_device *pdev) device_remove_file(&pdev->dev, &dev_attr_battery_percentage); device_remove_file(&pdev->dev, &dev_attr_battery_voltage); - led_trigger_unregister_simple(sharpsl_charge_led_trigger); - sharpsl_pm.machinfo->exit(); del_timer_sync(&sharpsl_pm.chrg_full_timer); diff --git a/trunk/arch/arm/kernel/entry-armv.S b/trunk/arch/arm/kernel/entry-armv.S index ab8e600c18c8..355914ffb192 100644 --- a/trunk/arch/arm/kernel/entry-armv.S +++ b/trunk/arch/arm/kernel/entry-armv.S @@ -666,7 +666,7 @@ __kuser_helper_start: * * #define __kernel_dmb() \ * asm volatile ( "mov r0, #0xffff0fff; mov lr, pc; sub pc, r0, #95" \ - * : : : "r0", "lr","cc" ) + * : : : "lr","cc" ) */ __kuser_memory_barrier: @ 0xffff0fa0 diff --git a/trunk/arch/arm/kernel/head-common.S b/trunk/arch/arm/kernel/head-common.S deleted file mode 100644 index a52da0ddb43d..000000000000 --- a/trunk/arch/arm/kernel/head-common.S +++ /dev/null @@ -1,217 +0,0 @@ -/* - * linux/arch/arm/kernel/head-common.S - * - * Copyright (C) 1994-2002 Russell King - * Copyright (c) 2003 ARM Limited - * All Rights Reserved - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - */ - - .type __switch_data, %object -__switch_data: - .long __mmap_switched - .long __data_loc @ r4 - .long __data_start @ r5 - .long __bss_start @ r6 - .long _end @ r7 - .long processor_id @ r4 - .long __machine_arch_type @ r5 - .long cr_alignment @ r6 - .long init_thread_union + THREAD_START_SP @ sp - -/* - * The following fragment of code is executed with the MMU on in MMU mode, - * and uses absolute addresses; this is not position independent. - * - * r0 = cp#15 control register - * r1 = machine ID - * r9 = processor ID - */ - .type __mmap_switched, %function -__mmap_switched: - adr r3, __switch_data + 4 - - ldmia r3!, {r4, r5, r6, r7} - cmp r4, r5 @ Copy data segment if needed -1: cmpne r5, r6 - ldrne fp, [r4], #4 - strne fp, [r5], #4 - bne 1b - - mov fp, #0 @ Clear BSS (and zero fp) -1: cmp r6, r7 - strcc fp, [r6],#4 - bcc 1b - - ldmia r3, {r4, r5, r6, sp} - str r9, [r4] @ Save processor ID - str r1, [r5] @ Save machine type - bic r4, r0, #CR_A @ Clear 'A' bit - stmia r6, {r0, r4} @ Save control register values - b start_kernel - -/* - * Exception handling. Something went wrong and we can't proceed. We - * ought to tell the user, but since we don't have any guarantee that - * we're even running on the right architecture, we do virtually nothing. - * - * If CONFIG_DEBUG_LL is set we try to print out something about the error - * and hope for the best (useful if bootloader fails to pass a proper - * machine ID for example). - */ - - .type __error_p, %function -__error_p: -#ifdef CONFIG_DEBUG_LL - adr r0, str_p1 - bl printascii - b __error -str_p1: .asciz "\nError: unrecognized/unsupported processor variant.\n" - .align -#endif - - .type __error_a, %function -__error_a: -#ifdef CONFIG_DEBUG_LL - mov r4, r1 @ preserve machine ID - adr r0, str_a1 - bl printascii - mov r0, r4 - bl printhex8 - adr r0, str_a2 - bl printascii - adr r3, 3f - ldmia r3, {r4, r5, r6} @ get machine desc list - sub r4, r3, r4 @ get offset between virt&phys - add r5, r5, r4 @ convert virt addresses to - add r6, r6, r4 @ physical address space -1: ldr r0, [r5, #MACHINFO_TYPE] @ get machine type - bl printhex8 - mov r0, #'\t' - bl printch - ldr r0, [r5, #MACHINFO_NAME] @ get machine name - add r0, r0, r4 - bl printascii - mov r0, #'\n' - bl printch - add r5, r5, #SIZEOF_MACHINE_DESC @ next machine_desc - cmp r5, r6 - blo 1b - adr r0, str_a3 - bl printascii - b __error -str_a1: .asciz "\nError: unrecognized/unsupported machine ID (r1 = 0x" -str_a2: .asciz ").\n\nAvailable machine support:\n\nID (hex)\tNAME\n" -str_a3: .asciz "\nPlease check your kernel config and/or bootloader.\n" - .align -#endif - - .type __error, %function -__error: -#ifdef CONFIG_ARCH_RPC -/* - * Turn the screen red on a error - RiscPC only. - */ - mov r0, #0x02000000 - mov r3, #0x11 - orr r3, r3, r3, lsl #8 - orr r3, r3, r3, lsl #16 - str r3, [r0], #4 - str r3, [r0], #4 - str r3, [r0], #4 - str r3, [r0], #4 -#endif -1: mov r0, r0 - b 1b - - -/* - * Read processor ID register (CP#15, CR0), and look up in the linker-built - * supported processor list. Note that we can't use the absolute addresses - * for the __proc_info lists since we aren't running with the MMU on - * (and therefore, we are not in the correct address space). We have to - * calculate the offset. - * - * r9 = cpuid - * Returns: - * r3, r4, r6 corrupted - * r5 = proc_info pointer in physical address space - * r9 = cpuid (preserved) - */ - .type __lookup_processor_type, %function -__lookup_processor_type: - adr r3, 3f - ldmda r3, {r5 - r7} - sub r3, r3, r7 @ get offset between virt&phys - add r5, r5, r3 @ convert virt addresses to - add r6, r6, r3 @ physical address space -1: ldmia r5, {r3, r4} @ value, mask - and r4, r4, r9 @ mask wanted bits - teq r3, r4 - beq 2f - add r5, r5, #PROC_INFO_SZ @ sizeof(proc_info_list) - cmp r5, r6 - blo 1b - mov r5, #0 @ unknown processor -2: mov pc, lr - -/* - * This provides a C-API version of the above function. - */ -ENTRY(lookup_processor_type) - stmfd sp!, {r4 - r7, r9, lr} - mov r9, r0 - bl __lookup_processor_type - mov r0, r5 - ldmfd sp!, {r4 - r7, r9, pc} - -/* - * Look in include/asm-arm/procinfo.h and arch/arm/kernel/arch.[ch] for - * more information about the __proc_info and __arch_info structures. - */ - .long __proc_info_begin - .long __proc_info_end -3: .long . - .long __arch_info_begin - .long __arch_info_end - -/* - * Lookup machine architecture in the linker-build list of architectures. - * Note that we can't use the absolute addresses for the __arch_info - * lists since we aren't running with the MMU on (and therefore, we are - * not in the correct address space). We have to calculate the offset. - * - * r1 = machine architecture number - * Returns: - * r3, r4, r6 corrupted - * r5 = mach_info pointer in physical address space - */ - .type __lookup_machine_type, %function -__lookup_machine_type: - adr r3, 3b - ldmia r3, {r4, r5, r6} - sub r3, r3, r4 @ get offset between virt&phys - add r5, r5, r3 @ convert virt addresses to - add r6, r6, r3 @ physical address space -1: ldr r3, [r5, #MACHINFO_TYPE] @ get machine type - teq r3, r1 @ matches loader number? - beq 2f @ found - add r5, r5, #SIZEOF_MACHINE_DESC @ next machine_desc - cmp r5, r6 - blo 1b - mov r5, #0 @ unknown machine -2: mov pc, lr - -/* - * This provides a C-API version of the above function. - */ -ENTRY(lookup_machine_type) - stmfd sp!, {r4 - r6, lr} - mov r1, r0 - bl __lookup_machine_type - mov r0, r5 - ldmfd sp!, {r4 - r6, pc} diff --git a/trunk/arch/arm/kernel/head-nommu.S b/trunk/arch/arm/kernel/head-nommu.S deleted file mode 100644 index b093ab8738b5..000000000000 --- a/trunk/arch/arm/kernel/head-nommu.S +++ /dev/null @@ -1,83 +0,0 @@ -/* - * linux/arch/arm/kernel/head-nommu.S - * - * Copyright (C) 1994-2002 Russell King - * Copyright (C) 2003-2006 Hyok S. Choi - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * Common kernel startup code (non-paged MM) - * for 32-bit CPUs which has a process ID register(CP15). - * - */ -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#define PROCINFO_INITFUNC 12 - -/* - * Kernel startup entry point. - * --------------------------- - * - * This is normally called from the decompressor code. The requirements - * are: MMU = off, D-cache = off, I-cache = dont care, r0 = 0, - * r1 = machine nr. - * - * See linux/arch/arm/tools/mach-types for the complete list of machine - * numbers for r1. - * - */ - __INIT - .type stext, %function -ENTRY(stext) - msr cpsr_c, #PSR_F_BIT | PSR_I_BIT | MODE_SVC @ ensure svc mode - @ and irqs disabled - mrc p15, 0, r9, c0, c0 @ get processor id - bl __lookup_processor_type @ r5=procinfo r9=cpuid - movs r10, r5 @ invalid processor (r5=0)? - beq __error_p @ yes, error 'p' - bl __lookup_machine_type @ r5=machinfo - movs r8, r5 @ invalid machine (r5=0)? - beq __error_a @ yes, error 'a' - - ldr r13, __switch_data @ address to jump to after - @ the initialization is done - adr lr, __after_proc_init @ return (PIC) address - add pc, r10, #PROCINFO_INITFUNC - -/* - * Set the Control Register and Read the process ID. - */ - .type __after_proc_init, %function -__after_proc_init: - mrc p15, 0, r0, c1, c0, 0 @ read control reg -#ifdef CONFIG_ALIGNMENT_TRAP - orr r0, r0, #CR_A -#else - bic r0, r0, #CR_A -#endif -#ifdef CONFIG_CPU_DCACHE_DISABLE - bic r0, r0, #CR_C -#endif -#ifdef CONFIG_CPU_BPREDICT_DISABLE - bic r0, r0, #CR_Z -#endif -#ifdef CONFIG_CPU_ICACHE_DISABLE - bic r0, r0, #CR_I -#endif - mcr p15, 0, r0, c1, c0, 0 @ write control reg - - mov pc, r13 @ clear the BSS and jump - @ to start_kernel - -#include "head-common.S" diff --git a/trunk/arch/arm/kernel/head.S b/trunk/arch/arm/kernel/head.S index 04b66a9328ef..53b6901f70a6 100644 --- a/trunk/arch/arm/kernel/head.S +++ b/trunk/arch/arm/kernel/head.S @@ -102,6 +102,49 @@ ENTRY(stext) adr lr, __enable_mmu @ return (PIC) address add pc, r10, #PROCINFO_INITFUNC + .type __switch_data, %object +__switch_data: + .long __mmap_switched + .long __data_loc @ r4 + .long __data_start @ r5 + .long __bss_start @ r6 + .long _end @ r7 + .long processor_id @ r4 + .long __machine_arch_type @ r5 + .long cr_alignment @ r6 + .long init_thread_union + THREAD_START_SP @ sp + +/* + * The following fragment of code is executed with the MMU on, and uses + * absolute addresses; this is not position independent. + * + * r0 = cp#15 control register + * r1 = machine ID + * r9 = processor ID + */ + .type __mmap_switched, %function +__mmap_switched: + adr r3, __switch_data + 4 + + ldmia r3!, {r4, r5, r6, r7} + cmp r4, r5 @ Copy data segment if needed +1: cmpne r5, r6 + ldrne fp, [r4], #4 + strne fp, [r5], #4 + bne 1b + + mov fp, #0 @ Clear BSS (and zero fp) +1: cmp r6, r7 + strcc fp, [r6],#4 + bcc 1b + + ldmia r3, {r4, r5, r6, sp} + str r9, [r4] @ Save processor ID + str r1, [r5] @ Save machine type + bic r4, r0, #CR_A @ Clear 'A' bit + stmia r6, {r0, r4} @ Save control register values + b start_kernel + #if defined(CONFIG_SMP) .type secondary_startup, #function ENTRY(secondary_startup) @@ -324,4 +367,166 @@ __create_page_tables: mov pc, lr .ltorg -#include "head-common.S" + + +/* + * Exception handling. Something went wrong and we can't proceed. We + * ought to tell the user, but since we don't have any guarantee that + * we're even running on the right architecture, we do virtually nothing. + * + * If CONFIG_DEBUG_LL is set we try to print out something about the error + * and hope for the best (useful if bootloader fails to pass a proper + * machine ID for example). + */ + + .type __error_p, %function +__error_p: +#ifdef CONFIG_DEBUG_LL + adr r0, str_p1 + bl printascii + b __error +str_p1: .asciz "\nError: unrecognized/unsupported processor variant.\n" + .align +#endif + + .type __error_a, %function +__error_a: +#ifdef CONFIG_DEBUG_LL + mov r4, r1 @ preserve machine ID + adr r0, str_a1 + bl printascii + mov r0, r4 + bl printhex8 + adr r0, str_a2 + bl printascii + adr r3, 3f + ldmia r3, {r4, r5, r6} @ get machine desc list + sub r4, r3, r4 @ get offset between virt&phys + add r5, r5, r4 @ convert virt addresses to + add r6, r6, r4 @ physical address space +1: ldr r0, [r5, #MACHINFO_TYPE] @ get machine type + bl printhex8 + mov r0, #'\t' + bl printch + ldr r0, [r5, #MACHINFO_NAME] @ get machine name + add r0, r0, r4 + bl printascii + mov r0, #'\n' + bl printch + add r5, r5, #SIZEOF_MACHINE_DESC @ next machine_desc + cmp r5, r6 + blo 1b + adr r0, str_a3 + bl printascii + b __error +str_a1: .asciz "\nError: unrecognized/unsupported machine ID (r1 = 0x" +str_a2: .asciz ").\n\nAvailable machine support:\n\nID (hex)\tNAME\n" +str_a3: .asciz "\nPlease check your kernel config and/or bootloader.\n" + .align +#endif + + .type __error, %function +__error: +#ifdef CONFIG_ARCH_RPC +/* + * Turn the screen red on a error - RiscPC only. + */ + mov r0, #0x02000000 + mov r3, #0x11 + orr r3, r3, r3, lsl #8 + orr r3, r3, r3, lsl #16 + str r3, [r0], #4 + str r3, [r0], #4 + str r3, [r0], #4 + str r3, [r0], #4 +#endif +1: mov r0, r0 + b 1b + + +/* + * Read processor ID register (CP#15, CR0), and look up in the linker-built + * supported processor list. Note that we can't use the absolute addresses + * for the __proc_info lists since we aren't running with the MMU on + * (and therefore, we are not in the correct address space). We have to + * calculate the offset. + * + * r9 = cpuid + * Returns: + * r3, r4, r6 corrupted + * r5 = proc_info pointer in physical address space + * r9 = cpuid (preserved) + */ + .type __lookup_processor_type, %function +__lookup_processor_type: + adr r3, 3f + ldmda r3, {r5 - r7} + sub r3, r3, r7 @ get offset between virt&phys + add r5, r5, r3 @ convert virt addresses to + add r6, r6, r3 @ physical address space +1: ldmia r5, {r3, r4} @ value, mask + and r4, r4, r9 @ mask wanted bits + teq r3, r4 + beq 2f + add r5, r5, #PROC_INFO_SZ @ sizeof(proc_info_list) + cmp r5, r6 + blo 1b + mov r5, #0 @ unknown processor +2: mov pc, lr + +/* + * This provides a C-API version of the above function. + */ +ENTRY(lookup_processor_type) + stmfd sp!, {r4 - r7, r9, lr} + mov r9, r0 + bl __lookup_processor_type + mov r0, r5 + ldmfd sp!, {r4 - r7, r9, pc} + +/* + * Look in include/asm-arm/procinfo.h and arch/arm/kernel/arch.[ch] for + * more information about the __proc_info and __arch_info structures. + */ + .long __proc_info_begin + .long __proc_info_end +3: .long . + .long __arch_info_begin + .long __arch_info_end + +/* + * Lookup machine architecture in the linker-build list of architectures. + * Note that we can't use the absolute addresses for the __arch_info + * lists since we aren't running with the MMU on (and therefore, we are + * not in the correct address space). We have to calculate the offset. + * + * r1 = machine architecture number + * Returns: + * r3, r4, r6 corrupted + * r5 = mach_info pointer in physical address space + */ + .type __lookup_machine_type, %function +__lookup_machine_type: + adr r3, 3b + ldmia r3, {r4, r5, r6} + sub r3, r3, r4 @ get offset between virt&phys + add r5, r5, r3 @ convert virt addresses to + add r6, r6, r3 @ physical address space +1: ldr r3, [r5, #MACHINFO_TYPE] @ get machine type + teq r3, r1 @ matches loader number? + beq 2f @ found + add r5, r5, #SIZEOF_MACHINE_DESC @ next machine_desc + cmp r5, r6 + blo 1b + mov r5, #0 @ unknown machine +2: mov pc, lr + +/* + * This provides a C-API version of the above function. + */ +ENTRY(lookup_machine_type) + stmfd sp!, {r4 - r6, lr} + mov r1, r0 + bl __lookup_machine_type + mov r0, r5 + ldmfd sp!, {r4 - r6, pc} diff --git a/trunk/arch/arm/kernel/process.c b/trunk/arch/arm/kernel/process.c index 1ff75cee4b0d..489c069e5c3e 100644 --- a/trunk/arch/arm/kernel/process.c +++ b/trunk/arch/arm/kernel/process.c @@ -474,3 +474,4 @@ unsigned long get_wchan(struct task_struct *p) } while (count ++ < 16); return 0; } +EXPORT_SYMBOL(get_wchan); diff --git a/trunk/arch/arm/kernel/signal.h b/trunk/arch/arm/kernel/signal.h index 27beece15502..9991049c522d 100644 --- a/trunk/arch/arm/kernel/signal.h +++ b/trunk/arch/arm/kernel/signal.h @@ -7,6 +7,6 @@ * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ -#define KERN_SIGRETURN_CODE (CONFIG_VECTORS_BASE + 0x00000500) +#define KERN_SIGRETURN_CODE 0xffff0500 extern const unsigned long sigreturn_codes[7]; diff --git a/trunk/arch/arm/kernel/traps.c b/trunk/arch/arm/kernel/traps.c index 35230a060108..d566d5f4574d 100644 --- a/trunk/arch/arm/kernel/traps.c +++ b/trunk/arch/arm/kernel/traps.c @@ -688,7 +688,6 @@ EXPORT_SYMBOL(abort); void __init trap_init(void) { - unsigned long vectors = CONFIG_VECTORS_BASE; extern char __stubs_start[], __stubs_end[]; extern char __vectors_start[], __vectors_end[]; extern char __kuser_helper_start[], __kuser_helper_end[]; @@ -699,9 +698,9 @@ void __init trap_init(void) * into the vector page, mapped at 0xffff0000, and ensure these * are visible to the instruction stream. */ - memcpy((void *)vectors, __vectors_start, __vectors_end - __vectors_start); - memcpy((void *)vectors + 0x200, __stubs_start, __stubs_end - __stubs_start); - memcpy((void *)vectors + 0x1000 - kuser_sz, __kuser_helper_start, kuser_sz); + memcpy((void *)0xffff0000, __vectors_start, __vectors_end - __vectors_start); + memcpy((void *)0xffff0200, __stubs_start, __stubs_end - __stubs_start); + memcpy((void *)0xffff1000 - kuser_sz, __kuser_helper_start, kuser_sz); /* * Copy signal return handlers into the vector page, and @@ -710,6 +709,6 @@ void __init trap_init(void) memcpy((void *)KERN_SIGRETURN_CODE, sigreturn_codes, sizeof(sigreturn_codes)); - flush_icache_range(vectors, vectors + PAGE_SIZE); + flush_icache_range(0xffff0000, 0xffff0000 + PAGE_SIZE); modify_domain(DOMAIN_USER, DOMAIN_CLIENT); } diff --git a/trunk/arch/arm/mach-pxa/corgi.c b/trunk/arch/arm/mach-pxa/corgi.c index d6d726036361..68923b1d2b62 100644 --- a/trunk/arch/arm/mach-pxa/corgi.c +++ b/trunk/arch/arm/mach-pxa/corgi.c @@ -141,8 +141,6 @@ struct corgissp_machinfo corgi_ssp_machinfo = { */ static struct corgibl_machinfo corgi_bl_machinfo = { .max_intensity = 0x2f, - .default_intensity = 0x1f, - .limit_mask = 0x0b, .set_bl_intensity = corgi_bl_set_intensity, }; @@ -165,14 +163,6 @@ static struct platform_device corgikbd_device = { }; -/* - * Corgi LEDs - */ -static struct platform_device corgiled_device = { - .name = "corgi-led", - .id = -1, -}; - /* * Corgi Touch Screen Device */ @@ -307,7 +297,6 @@ static struct platform_device *devices[] __initdata = { &corgikbd_device, &corgibl_device, &corgits_device, - &corgiled_device, }; static void __init corgi_init(void) diff --git a/trunk/arch/arm/mach-pxa/spitz.c b/trunk/arch/arm/mach-pxa/spitz.c index 19b372df544a..0dbb079ecd25 100644 --- a/trunk/arch/arm/mach-pxa/spitz.c +++ b/trunk/arch/arm/mach-pxa/spitz.c @@ -220,8 +220,6 @@ struct corgissp_machinfo spitz_ssp_machinfo = { * Spitz Backlight Device */ static struct corgibl_machinfo spitz_bl_machinfo = { - .default_intensity = 0x1f, - .limit_mask = 0x0b, .max_intensity = 0x2f, }; @@ -243,14 +241,6 @@ static struct platform_device spitzkbd_device = { }; -/* - * Spitz LEDs - */ -static struct platform_device spitzled_device = { - .name = "spitz-led", - .id = -1, -}; - /* * Spitz Touch Screen Device */ @@ -428,7 +418,6 @@ static struct platform_device *devices[] __initdata = { &spitzkbd_device, &spitzts_device, &spitzbl_device, - &spitzled_device, }; static void __init common_init(void) diff --git a/trunk/arch/arm/mach-pxa/tosa.c b/trunk/arch/arm/mach-pxa/tosa.c index 76c0e7f0a219..66ec71756d0f 100644 --- a/trunk/arch/arm/mach-pxa/tosa.c +++ b/trunk/arch/arm/mach-pxa/tosa.c @@ -251,19 +251,10 @@ static struct platform_device tosakbd_device = { .id = -1, }; -/* - * Tosa LEDs - */ -static struct platform_device tosaled_device = { - .name = "tosa-led", - .id = -1, -}; - static struct platform_device *devices[] __initdata = { &tosascoop_device, &tosascoop_jc_device, &tosakbd_device, - &tosaled_device, }; static void __init tosa_init(void) diff --git a/trunk/arch/arm/mm/proc-xsc3.S b/trunk/arch/arm/mm/proc-xsc3.S index b9dfce57c272..f90513e9af0c 100644 --- a/trunk/arch/arm/mm/proc-xsc3.S +++ b/trunk/arch/arm/mm/proc-xsc3.S @@ -30,7 +30,6 @@ #include #include #include -#include #include #include #include "proc-macros.S" diff --git a/trunk/arch/arm26/kernel/armksyms.c b/trunk/arch/arm26/kernel/armksyms.c index a6a1b3373444..811a6376c624 100644 --- a/trunk/arch/arm26/kernel/armksyms.c +++ b/trunk/arch/arm26/kernel/armksyms.c @@ -212,6 +212,8 @@ EXPORT_SYMBOL(sys_open); EXPORT_SYMBOL(sys_exit); EXPORT_SYMBOL(sys_wait4); +EXPORT_SYMBOL(get_wchan); + #ifdef CONFIG_PREEMPT EXPORT_SYMBOL(kernel_flag); #endif diff --git a/trunk/arch/frv/kernel/frv_ksyms.c b/trunk/arch/frv/kernel/frv_ksyms.c index 07c8ffa0dd39..aa6b7d0a2109 100644 --- a/trunk/arch/frv/kernel/frv_ksyms.c +++ b/trunk/arch/frv/kernel/frv_ksyms.c @@ -79,6 +79,8 @@ EXPORT_SYMBOL(memmove); EXPORT_SYMBOL(__outsl_ns); EXPORT_SYMBOL(__insl_ns); +EXPORT_SYMBOL(get_wchan); + #ifdef CONFIG_FRV_OUTOFLINE_ATOMIC_OPS EXPORT_SYMBOL(atomic_test_and_ANDNOT_mask); EXPORT_SYMBOL(atomic_test_and_OR_mask); diff --git a/trunk/arch/h8300/kernel/h8300_ksyms.c b/trunk/arch/h8300/kernel/h8300_ksyms.c index b6cd78c972bb..69d6ad32d56c 100644 --- a/trunk/arch/h8300/kernel/h8300_ksyms.c +++ b/trunk/arch/h8300/kernel/h8300_ksyms.c @@ -55,6 +55,8 @@ EXPORT_SYMBOL(memcmp); EXPORT_SYMBOL(memscan); EXPORT_SYMBOL(memmove); +EXPORT_SYMBOL(get_wchan); + /* * libgcc functions - functions that are used internally by the * compiler... (prototypes are not correct though, but that diff --git a/trunk/arch/i386/kernel/apic.c b/trunk/arch/i386/kernel/apic.c index 6273bf74c203..eb5279d23b7f 100644 --- a/trunk/arch/i386/kernel/apic.c +++ b/trunk/arch/i386/kernel/apic.c @@ -415,7 +415,6 @@ void __init init_bsp_APIC(void) void __devinit setup_local_APIC(void) { unsigned long oldvalue, value, ver, maxlvt; - int i, j; /* Pound the ESR really hard over the head with a big hammer - mbligh */ if (esr_disable) { @@ -452,25 +451,6 @@ void __devinit setup_local_APIC(void) value &= ~APIC_TPRI_MASK; apic_write_around(APIC_TASKPRI, value); - /* - * After a crash, we no longer service the interrupts and a pending - * interrupt from previous kernel might still have ISR bit set. - * - * Most probably by now CPU has serviced that pending interrupt and - * it might not have done the ack_APIC_irq() because it thought, - * interrupt came from i8259 as ExtInt. LAPIC did not get EOI so it - * does not clear the ISR bit and cpu thinks it has already serivced - * the interrupt. Hence a vector might get locked. It was noticed - * for timer irq (vector 0x31). Issue an extra EOI to clear ISR. - */ - for (i = APIC_ISR_NR - 1; i >= 0; i--) { - value = apic_read(APIC_ISR + i*0x10); - for (j = 31; j >= 0; j--) { - if (value & (1< * - * 00/04/19 D. Mosberger Rewritten to mirror more closely the x86 I/O - * APIC code. In particular, we now have separate - * handlers for edge and level triggered - * interrupts. - * 00/10/27 Asit Mallick, Goutham Rao IRQ vector - * allocation PCI to vector mapping, shared PCI - * interrupts. - * 00/10/27 D. Mosberger Document things a bit more to make them more - * understandable. Clean up much of the old - * IOSAPIC cruft. - * 01/07/27 J.I. Lee PCI irq routing, Platform/Legacy interrupts - * and fixes for ACPI S5(SoftOff) support. + * 00/04/19 D. Mosberger Rewritten to mirror more closely the x86 I/O APIC code. + * In particular, we now have separate handlers for edge + * and level triggered interrupts. + * 00/10/27 Asit Mallick, Goutham Rao IRQ vector allocation + * PCI to vector mapping, shared PCI interrupts. + * 00/10/27 D. Mosberger Document things a bit more to make them more understandable. + * Clean up much of the old IOSAPIC cruft. + * 01/07/27 J.I. Lee PCI irq routing, Platform/Legacy interrupts and fixes for + * ACPI S5(SoftOff) support. * 02/01/23 J.I. Lee iosapic pgm fixes for PCI irq routing from _PRT - * 02/01/07 E. Focht Redirectable interrupt - * vectors in iosapic_set_affinity(), - * initializations for /proc/irq/#/smp_affinity + * 02/01/07 E. Focht Redirectable interrupt vectors in + * iosapic_set_affinity(), initializations for + * /proc/irq/#/smp_affinity * 02/04/02 P. Diefenbaugh Cleaned up ACPI PCI IRQ routing. * 02/04/18 J.I. Lee bug fix in iosapic_init_pci_irq - * 02/04/30 J.I. Lee bug fix in find_iosapic to fix ACPI PCI IRQ to - * IOSAPIC mapping error + * 02/04/30 J.I. Lee bug fix in find_iosapic to fix ACPI PCI IRQ to IOSAPIC mapping + * error * 02/07/29 T. Kochi Allocate interrupt vectors dynamically - * 02/08/04 T. Kochi Cleaned up terminology (irq, global system - * interrupt, vector, etc.) - * 02/09/20 D. Mosberger Simplified by taking advantage of ACPI's - * pci_irq code. + * 02/08/04 T. Kochi Cleaned up terminology (irq, global system interrupt, vector, etc.) + * 02/09/20 D. Mosberger Simplified by taking advantage of ACPI's pci_irq code. * 03/02/19 B. Helgaas Make pcat_compat system-wide, not per-IOSAPIC. - * Remove iosapic_address & gsi_base from - * external interfaces. Rationalize - * __init/__devinit attributes. + * Remove iosapic_address & gsi_base from external interfaces. + * Rationalize __init/__devinit attributes. * 04/12/04 Ashok Raj Intel Corporation 2004 - * Updated to work with irq migration necessary - * for CPU Hotplug + * Updated to work with irq migration necessary for CPU Hotplug */ /* - * Here is what the interrupt logic between a PCI device and the kernel looks - * like: + * Here is what the interrupt logic between a PCI device and the kernel looks like: * - * (1) A PCI device raises one of the four interrupt pins (INTA, INTB, INTC, - * INTD). The device is uniquely identified by its bus-, and slot-number - * (the function number does not matter here because all functions share - * the same interrupt lines). + * (1) A PCI device raises one of the four interrupt pins (INTA, INTB, INTC, INTD). The + * device is uniquely identified by its bus--, and slot-number (the function + * number does not matter here because all functions share the same interrupt + * lines). * - * (2) The motherboard routes the interrupt line to a pin on a IOSAPIC - * controller. Multiple interrupt lines may have to share the same - * IOSAPIC pin (if they're level triggered and use the same polarity). - * Each interrupt line has a unique Global System Interrupt (GSI) number - * which can be calculated as the sum of the controller's base GSI number - * and the IOSAPIC pin number to which the line connects. + * (2) The motherboard routes the interrupt line to a pin on a IOSAPIC controller. + * Multiple interrupt lines may have to share the same IOSAPIC pin (if they're level + * triggered and use the same polarity). Each interrupt line has a unique Global + * System Interrupt (GSI) number which can be calculated as the sum of the controller's + * base GSI number and the IOSAPIC pin number to which the line connects. * - * (3) The IOSAPIC uses an internal routing table entries (RTEs) to map the - * IOSAPIC pin into the IA-64 interrupt vector. This interrupt vector is then - * sent to the CPU. + * (3) The IOSAPIC uses an internal routing table entries (RTEs) to map the IOSAPIC pin + * into the IA-64 interrupt vector. This interrupt vector is then sent to the CPU. * - * (4) The kernel recognizes an interrupt as an IRQ. The IRQ interface is - * used as architecture-independent interrupt handling mechanism in Linux. - * As an IRQ is a number, we have to have - * IA-64 interrupt vector number <-> IRQ number mapping. On smaller - * systems, we use one-to-one mapping between IA-64 vector and IRQ. A - * platform can implement platform_irq_to_vector(irq) and + * (4) The kernel recognizes an interrupt as an IRQ. The IRQ interface is used as + * architecture-independent interrupt handling mechanism in Linux. As an + * IRQ is a number, we have to have IA-64 interrupt vector number <-> IRQ number + * mapping. On smaller systems, we use one-to-one mapping between IA-64 vector and + * IRQ. A platform can implement platform_irq_to_vector(irq) and * platform_local_vector_to_irq(vector) APIs to differentiate the mapping. * Please see also include/asm-ia64/hw_irq.h for those APIs. * @@ -75,9 +64,9 @@ * * PCI pin -> global system interrupt (GSI) -> IA-64 vector <-> IRQ * - * Note: The term "IRQ" is loosely used everywhere in Linux kernel to - * describeinterrupts. Now we use "IRQ" only for Linux IRQ's. ISA IRQ - * (isa_irq) is the only exception in this source code. + * Note: The term "IRQ" is loosely used everywhere in Linux kernel to describe interrupts. + * Now we use "IRQ" only for Linux IRQ's. ISA IRQ (isa_irq) is the only exception in this + * source code. */ #include @@ -101,6 +90,7 @@ #include #include + #undef DEBUG_INTERRUPT_ROUTING #ifdef DEBUG_INTERRUPT_ROUTING @@ -109,46 +99,36 @@ #define DBG(fmt...) #endif -#define NR_PREALLOCATE_RTE_ENTRIES \ - (PAGE_SIZE / sizeof(struct iosapic_rte_info)) +#define NR_PREALLOCATE_RTE_ENTRIES (PAGE_SIZE / sizeof(struct iosapic_rte_info)) #define RTE_PREALLOCATED (1) static DEFINE_SPINLOCK(iosapic_lock); -/* - * These tables map IA-64 vectors to the IOSAPIC pin that generates this - * vector. - */ +/* These tables map IA-64 vectors to the IOSAPIC pin that generates this vector. */ struct iosapic_rte_info { - struct list_head rte_list; /* node in list of RTEs sharing the - * same vector */ + struct list_head rte_list; /* node in list of RTEs sharing the same vector */ char __iomem *addr; /* base address of IOSAPIC */ - unsigned int gsi_base; /* first GSI assigned to this - * IOSAPIC */ + unsigned int gsi_base; /* first GSI assigned to this IOSAPIC */ char rte_index; /* IOSAPIC RTE index */ int refcnt; /* reference counter */ unsigned int flags; /* flags */ } ____cacheline_aligned; static struct iosapic_intr_info { - struct list_head rtes; /* RTEs using this vector (empty => - * not an IOSAPIC interrupt) */ + struct list_head rtes; /* RTEs using this vector (empty => not an IOSAPIC interrupt) */ int count; /* # of RTEs that shares this vector */ - u32 low32; /* current value of low word of - * Redirection table entry */ + u32 low32; /* current value of low word of Redirection table entry */ unsigned int dest; /* destination CPU physical ID */ unsigned char dmode : 3; /* delivery mode (see iosapic.h) */ - unsigned char polarity: 1; /* interrupt polarity - * (see iosapic.h) */ + unsigned char polarity: 1; /* interrupt polarity (see iosapic.h) */ unsigned char trigger : 1; /* trigger mode (see iosapic.h) */ } iosapic_intr_info[IA64_NUM_VECTORS]; static struct iosapic { char __iomem *addr; /* base address of IOSAPIC */ - unsigned int gsi_base; /* first GSI assigned to this - * IOSAPIC */ - unsigned short num_rte; /* # of RTEs on this IOSAPIC */ + unsigned int gsi_base; /* first GSI assigned to this IOSAPIC */ + unsigned short num_rte; /* number of RTE in this IOSAPIC */ int rtes_inuse; /* # of RTEs in use on this IOSAPIC */ #ifdef CONFIG_NUMA unsigned short node; /* numa node association via pxm */ @@ -169,8 +149,7 @@ find_iosapic (unsigned int gsi) int i; for (i = 0; i < NR_IOSAPICS; i++) { - if ((unsigned) (gsi - iosapic_lists[i].gsi_base) < - iosapic_lists[i].num_rte) + if ((unsigned) (gsi - iosapic_lists[i].gsi_base) < iosapic_lists[i].num_rte) return i; } @@ -183,8 +162,7 @@ _gsi_to_vector (unsigned int gsi) struct iosapic_intr_info *info; struct iosapic_rte_info *rte; - for (info = iosapic_intr_info; info < - iosapic_intr_info + IA64_NUM_VECTORS; ++info) + for (info = iosapic_intr_info; info < iosapic_intr_info + IA64_NUM_VECTORS; ++info) list_for_each_entry(rte, &info->rtes, rte_list) if (rte->gsi_base + rte->rte_index == gsi) return info - iosapic_intr_info; @@ -207,8 +185,8 @@ gsi_to_irq (unsigned int gsi) unsigned long flags; int irq; /* - * XXX fix me: this assumes an identity mapping between IA-64 vector - * and Linux irq numbers... + * XXX fix me: this assumes an identity mapping vetween IA-64 vector and Linux irq + * numbers... */ spin_lock_irqsave(&iosapic_lock, flags); { @@ -219,8 +197,7 @@ gsi_to_irq (unsigned int gsi) return irq; } -static struct iosapic_rte_info *gsi_vector_to_rte(unsigned int gsi, - unsigned int vec) +static struct iosapic_rte_info *gsi_vector_to_rte(unsigned int gsi, unsigned int vec) { struct iosapic_rte_info *rte; @@ -260,9 +237,7 @@ set_rte (unsigned int gsi, unsigned int vector, unsigned int dest, int mask) for (irq = 0; irq < NR_IRQS; ++irq) if (irq_to_vector(irq) == vector) { - set_irq_affinity_info(irq, - (int)(dest & 0xffff), - redir); + set_irq_affinity_info(irq, (int)(dest & 0xffff), redir); break; } } @@ -284,7 +259,7 @@ set_rte (unsigned int gsi, unsigned int vector, unsigned int dest, int mask) } static void -nop (unsigned int irq) +nop (unsigned int vector) { /* do nothing... */ } @@ -306,8 +281,7 @@ mask_irq (unsigned int irq) { /* set only the mask bit */ low32 = iosapic_intr_info[vec].low32 |= IOSAPIC_MASK; - list_for_each_entry(rte, &iosapic_intr_info[vec].rtes, - rte_list) { + list_for_each_entry(rte, &iosapic_intr_info[vec].rtes, rte_list) { addr = rte->addr; rte_index = rte->rte_index; iosapic_write(addr, IOSAPIC_RTE_LOW(rte_index), low32); @@ -332,8 +306,7 @@ unmask_irq (unsigned int irq) spin_lock_irqsave(&iosapic_lock, flags); { low32 = iosapic_intr_info[vec].low32 &= ~IOSAPIC_MASK; - list_for_each_entry(rte, &iosapic_intr_info[vec].rtes, - rte_list) { + list_for_each_entry(rte, &iosapic_intr_info[vec].rtes, rte_list) { addr = rte->addr; rte_index = rte->rte_index; iosapic_write(addr, IOSAPIC_RTE_LOW(rte_index), low32); @@ -373,25 +346,21 @@ iosapic_set_affinity (unsigned int irq, cpumask_t mask) spin_lock_irqsave(&iosapic_lock, flags); { - low32 = iosapic_intr_info[vec].low32 & - ~(7 << IOSAPIC_DELIVERY_SHIFT); + low32 = iosapic_intr_info[vec].low32 & ~(7 << IOSAPIC_DELIVERY_SHIFT); if (redir) /* change delivery mode to lowest priority */ - low32 |= (IOSAPIC_LOWEST_PRIORITY << - IOSAPIC_DELIVERY_SHIFT); + low32 |= (IOSAPIC_LOWEST_PRIORITY << IOSAPIC_DELIVERY_SHIFT); else /* change delivery mode to fixed */ low32 |= (IOSAPIC_FIXED << IOSAPIC_DELIVERY_SHIFT); iosapic_intr_info[vec].low32 = low32; iosapic_intr_info[vec].dest = dest; - list_for_each_entry(rte, &iosapic_intr_info[vec].rtes, - rte_list) { + list_for_each_entry(rte, &iosapic_intr_info[vec].rtes, rte_list) { addr = rte->addr; rte_index = rte->rte_index; - iosapic_write(addr, IOSAPIC_RTE_HIGH(rte_index), - high32); + iosapic_write(addr, IOSAPIC_RTE_HIGH(rte_index), high32); iosapic_write(addr, IOSAPIC_RTE_LOW(rte_index), low32); } } @@ -464,8 +433,7 @@ iosapic_ack_edge_irq (unsigned int irq) * interrupt for real. This prevents IRQ storms from unhandled * devices. */ - if ((idesc->status & (IRQ_PENDING|IRQ_DISABLED)) == - (IRQ_PENDING|IRQ_DISABLED)) + if ((idesc->status & (IRQ_PENDING|IRQ_DISABLED)) == (IRQ_PENDING|IRQ_DISABLED)) mask_irq(irq); } @@ -499,8 +467,7 @@ iosapic_version (char __iomem *addr) return iosapic_read(addr, IOSAPIC_VERSION); } -static int iosapic_find_sharable_vector (unsigned long trigger, - unsigned long pol) +static int iosapic_find_sharable_vector (unsigned long trigger, unsigned long pol) { int i, vector = -1, min_count = -1; struct iosapic_intr_info *info; @@ -515,8 +482,7 @@ static int iosapic_find_sharable_vector (unsigned long trigger, for (i = IA64_FIRST_DEVICE_VECTOR; i <= IA64_LAST_DEVICE_VECTOR; i++) { info = &iosapic_intr_info[i]; if (info->trigger == trigger && info->polarity == pol && - (info->dmode == IOSAPIC_FIXED || info->dmode == - IOSAPIC_LOWEST_PRIORITY)) { + (info->dmode == IOSAPIC_FIXED || info->dmode == IOSAPIC_LOWEST_PRIORITY)) { if (min_count == -1 || info->count < min_count) { vector = i; min_count = info->count; @@ -540,15 +506,12 @@ iosapic_reassign_vector (int vector) new_vector = assign_irq_vector(AUTO_ASSIGN); if (new_vector < 0) panic("%s: out of interrupt vectors!\n", __FUNCTION__); - printk(KERN_INFO "Reassigning vector %d to %d\n", - vector, new_vector); + printk(KERN_INFO "Reassigning vector %d to %d\n", vector, new_vector); memcpy(&iosapic_intr_info[new_vector], &iosapic_intr_info[vector], sizeof(struct iosapic_intr_info)); INIT_LIST_HEAD(&iosapic_intr_info[new_vector].rtes); - list_move(iosapic_intr_info[vector].rtes.next, - &iosapic_intr_info[new_vector].rtes); - memset(&iosapic_intr_info[vector], 0, - sizeof(struct iosapic_intr_info)); + list_move(iosapic_intr_info[vector].rtes.next, &iosapic_intr_info[new_vector].rtes); + memset(&iosapic_intr_info[vector], 0, sizeof(struct iosapic_intr_info)); iosapic_intr_info[vector].low32 = IOSAPIC_MASK; INIT_LIST_HEAD(&iosapic_intr_info[vector].rtes); } @@ -561,8 +524,7 @@ static struct iosapic_rte_info *iosapic_alloc_rte (void) int preallocated = 0; if (!iosapic_kmalloc_ok && list_empty(&free_rte_list)) { - rte = alloc_bootmem(sizeof(struct iosapic_rte_info) * - NR_PREALLOCATE_RTE_ENTRIES); + rte = alloc_bootmem(sizeof(struct iosapic_rte_info) * NR_PREALLOCATE_RTE_ENTRIES); if (!rte) return NULL; for (i = 0; i < NR_PREALLOCATE_RTE_ENTRIES; i++, rte++) @@ -570,8 +532,7 @@ static struct iosapic_rte_info *iosapic_alloc_rte (void) } if (!list_empty(&free_rte_list)) { - rte = list_entry(free_rte_list.next, struct iosapic_rte_info, - rte_list); + rte = list_entry(free_rte_list.next, struct iosapic_rte_info, rte_list); list_del(&rte->rte_list); preallocated++; } else { @@ -614,8 +575,7 @@ register_intr (unsigned int gsi, int vector, unsigned char delivery, index = find_iosapic(gsi); if (index < 0) { - printk(KERN_WARNING "%s: No IOSAPIC for GSI %u\n", - __FUNCTION__, gsi); + printk(KERN_WARNING "%s: No IOSAPIC for GSI %u\n", __FUNCTION__, gsi); return -ENODEV; } @@ -626,8 +586,7 @@ register_intr (unsigned int gsi, int vector, unsigned char delivery, if (!rte) { rte = iosapic_alloc_rte(); if (!rte) { - printk(KERN_WARNING "%s: cannot allocate memory\n", - __FUNCTION__); + printk(KERN_WARNING "%s: cannot allocate memory\n", __FUNCTION__); return -ENOMEM; } @@ -643,9 +602,7 @@ register_intr (unsigned int gsi, int vector, unsigned char delivery, else if (vector_is_shared(vector)) { struct iosapic_intr_info *info = &iosapic_intr_info[vector]; if (info->trigger != trigger || info->polarity != polarity) { - printk (KERN_WARNING - "%s: cannot override the interrupt\n", - __FUNCTION__); + printk (KERN_WARNING "%s: cannot override the interrupt\n", __FUNCTION__); return -EINVAL; } } @@ -662,10 +619,8 @@ register_intr (unsigned int gsi, int vector, unsigned char delivery, idesc = irq_descp(vector); if (idesc->handler != irq_type) { if (idesc->handler != &no_irq_type) - printk(KERN_WARNING - "%s: changing vector %d from %s to %s\n", - __FUNCTION__, vector, - idesc->handler->typename, irq_type->typename); + printk(KERN_WARNING "%s: changing vector %d from %s to %s\n", + __FUNCTION__, vector, idesc->handler->typename, irq_type->typename); idesc->handler = irq_type; } return 0; @@ -726,7 +681,7 @@ get_target_cpu (unsigned int gsi, int vector) if (!num_cpus) goto skip_numa_setup; - /* Use vector assignment to distribute across cpus in node */ + /* Use vector assigment to distribute across cpus in node */ cpu_index = vector % num_cpus; for (numa_cpu = first_cpu(cpu_mask) ; i < cpu_index ; i++) @@ -748,7 +703,7 @@ get_target_cpu (unsigned int gsi, int vector) } while (!cpu_online(cpu)); return cpu_physical_id(cpu); -#else /* CONFIG_SMP */ +#else return cpu_physical_id(smp_processor_id()); #endif } @@ -800,8 +755,7 @@ iosapic_register_intr (unsigned int gsi, if (list_empty(&iosapic_intr_info[vector].rtes)) free_irq_vector(vector); spin_unlock(&iosapic_lock); - spin_unlock_irqrestore(&irq_descp(vector)->lock, - flags); + spin_unlock_irqrestore(&irq_descp(vector)->lock, flags); goto again; } @@ -810,8 +764,7 @@ iosapic_register_intr (unsigned int gsi, polarity, trigger); if (err < 0) { spin_unlock(&iosapic_lock); - spin_unlock_irqrestore(&irq_descp(vector)->lock, - flags); + spin_unlock_irqrestore(&irq_descp(vector)->lock, flags); return err; } @@ -853,8 +806,7 @@ iosapic_unregister_intr (unsigned int gsi) */ irq = gsi_to_irq(gsi); if (irq < 0) { - printk(KERN_ERR "iosapic_unregister_intr(%u) unbalanced\n", - gsi); + printk(KERN_ERR "iosapic_unregister_intr(%u) unbalanced\n", gsi); WARN_ON(1); return; } @@ -865,9 +817,7 @@ iosapic_unregister_intr (unsigned int gsi) spin_lock(&iosapic_lock); { if ((rte = gsi_vector_to_rte(gsi, vector)) == NULL) { - printk(KERN_ERR - "iosapic_unregister_intr(%u) unbalanced\n", - gsi); + printk(KERN_ERR "iosapic_unregister_intr(%u) unbalanced\n", gsi); WARN_ON(1); goto out; } @@ -877,8 +827,7 @@ iosapic_unregister_intr (unsigned int gsi) /* Mask the interrupt */ low32 = iosapic_intr_info[vector].low32 | IOSAPIC_MASK; - iosapic_write(rte->addr, IOSAPIC_RTE_LOW(rte->rte_index), - low32); + iosapic_write(rte->addr, IOSAPIC_RTE_LOW(rte->rte_index), low32); /* Remove the rte entry from the list */ list_del(&rte->rte_list); @@ -891,9 +840,7 @@ iosapic_unregister_intr (unsigned int gsi) trigger = iosapic_intr_info[vector].trigger; polarity = iosapic_intr_info[vector].polarity; dest = iosapic_intr_info[vector].dest; - printk(KERN_INFO - "GSI %u (%s, %s) -> CPU %d (0x%04x)" - " vector %d unregistered\n", + printk(KERN_INFO "GSI %u (%s, %s) -> CPU %d (0x%04x) vector %d unregistered\n", gsi, (trigger == IOSAPIC_EDGE ? "edge" : "level"), (polarity == IOSAPIC_POL_HIGH ? "high" : "low"), cpu_logical_id(dest), dest, vector); @@ -906,15 +853,12 @@ iosapic_unregister_intr (unsigned int gsi) idesc->handler = &no_irq_type; /* Clear the interrupt information */ - memset(&iosapic_intr_info[vector], 0, - sizeof(struct iosapic_intr_info)); + memset(&iosapic_intr_info[vector], 0, sizeof(struct iosapic_intr_info)); iosapic_intr_info[vector].low32 |= IOSAPIC_MASK; INIT_LIST_HEAD(&iosapic_intr_info[vector].rtes); if (idesc->action) { - printk(KERN_ERR - "interrupt handlers still exist on" - "IRQ %u\n", irq); + printk(KERN_ERR "interrupt handlers still exist on IRQ %u\n", irq); WARN_ON(1); } @@ -929,6 +873,7 @@ iosapic_unregister_intr (unsigned int gsi) /* * ACPI calls this when it finds an entry for a platform interrupt. + * Note that the irq_base and IOSAPIC address must be set in iosapic_init(). */ int __init iosapic_register_platform_intr (u32 int_type, unsigned int gsi, @@ -962,16 +907,13 @@ iosapic_register_platform_intr (u32 int_type, unsigned int gsi, mask = 1; break; default: - printk(KERN_ERR "%s: invalid int type 0x%x\n", __FUNCTION__, - int_type); + printk(KERN_ERR "iosapic_register_platform_irq(): invalid int type 0x%x\n", int_type); return -1; } register_intr(gsi, vector, delivery, polarity, trigger); - printk(KERN_INFO - "PLATFORM int %s (0x%x): GSI %u (%s, %s) -> CPU %d (0x%04x)" - " vector %d\n", + printk(KERN_INFO "PLATFORM int %s (0x%x): GSI %u (%s, %s) -> CPU %d (0x%04x) vector %d\n", int_type < ARRAY_SIZE(name) ? name[int_type] : "unknown", int_type, gsi, (trigger == IOSAPIC_EDGE ? "edge" : "level"), (polarity == IOSAPIC_POL_HIGH ? "high" : "low"), @@ -981,8 +923,10 @@ iosapic_register_platform_intr (u32 int_type, unsigned int gsi, return vector; } + /* * ACPI calls this when it finds an entry for a legacy ISA IRQ override. + * Note that the gsi_base and IOSAPIC address must be set in iosapic_init(). */ void __init iosapic_override_isa_irq (unsigned int isa_irq, unsigned int gsi, @@ -1011,19 +955,16 @@ iosapic_system_init (int system_pcat_compat) for (vector = 0; vector < IA64_NUM_VECTORS; ++vector) { iosapic_intr_info[vector].low32 = IOSAPIC_MASK; - /* mark as unused */ - INIT_LIST_HEAD(&iosapic_intr_info[vector].rtes); + INIT_LIST_HEAD(&iosapic_intr_info[vector].rtes); /* mark as unused */ } pcat_compat = system_pcat_compat; if (pcat_compat) { /* - * Disable the compatibility mode interrupts (8259 style), - * needs IN/OUT support enabled. + * Disable the compatibility mode interrupts (8259 style), needs IN/OUT support + * enabled. */ - printk(KERN_INFO - "%s: Disabling PC-AT compatible 8259 interrupts\n", - __FUNCTION__); + printk(KERN_INFO "%s: Disabling PC-AT compatible 8259 interrupts\n", __FUNCTION__); outb(0xff, 0xA1); outb(0xff, 0x21); } @@ -1063,7 +1004,10 @@ iosapic_check_gsi_range (unsigned int gsi_base, unsigned int ver) base = iosapic_lists[index].gsi_base; end = base + iosapic_lists[index].num_rte - 1; - if (gsi_end < base || end < gsi_base) + if (gsi_base < base && gsi_end < base) + continue;/* OK */ + + if (gsi_base > end && gsi_end > end) continue; /* OK */ return -EBUSY; @@ -1109,14 +1053,12 @@ iosapic_init (unsigned long phys_addr, unsigned int gsi_base) if ((gsi_base == 0) && pcat_compat) { /* - * Map the legacy ISA devices into the IOSAPIC data. Some of - * these may get reprogrammed later on with data from the ACPI - * Interrupt Source Override table. + * Map the legacy ISA devices into the IOSAPIC data. Some of these may + * get reprogrammed later on with data from the ACPI Interrupt Source + * Override table. */ for (isa_irq = 0; isa_irq < 16; ++isa_irq) - iosapic_override_isa_irq(isa_irq, isa_irq, - IOSAPIC_POL_HIGH, - IOSAPIC_EDGE); + iosapic_override_isa_irq(isa_irq, isa_irq, IOSAPIC_POL_HIGH, IOSAPIC_EDGE); } return 0; } @@ -1139,8 +1081,7 @@ iosapic_remove (unsigned int gsi_base) if (iosapic_lists[index].rtes_inuse) { err = -EBUSY; - printk(KERN_WARNING - "%s: IOSAPIC for GSI base %u is busy\n", + printk(KERN_WARNING "%s: IOSAPIC for GSI base %u is busy\n", __FUNCTION__, gsi_base); goto out; } diff --git a/trunk/arch/ia64/kernel/palinfo.c b/trunk/arch/ia64/kernel/palinfo.c index 6386f63c413e..89faa603c6be 100644 --- a/trunk/arch/ia64/kernel/palinfo.c +++ b/trunk/arch/ia64/kernel/palinfo.c @@ -240,7 +240,7 @@ cache_info(char *page) } p += sprintf(p, "%s Cache level %lu:\n" - "\tSize : %u bytes\n" + "\tSize : %lu bytes\n" "\tAttributes : ", cache_types[j+cci.pcci_unified], i+1, cci.pcci_cache_size); @@ -648,9 +648,9 @@ frequency_info(char *page) if (ia64_pal_freq_ratios(&proc, &bus, &itc) != 0) return 0; p += sprintf(p, - "Processor/Clock ratio : %d/%d\n" - "Bus/Clock ratio : %d/%d\n" - "ITC/Clock ratio : %d/%d\n", + "Processor/Clock ratio : %ld/%ld\n" + "Bus/Clock ratio : %ld/%ld\n" + "ITC/Clock ratio : %ld/%ld\n", proc.num, proc.den, bus.num, bus.den, itc.num, itc.den); return p - page; diff --git a/trunk/arch/ia64/kernel/time.c b/trunk/arch/ia64/kernel/time.c index 49958904045b..ac167436e936 100644 --- a/trunk/arch/ia64/kernel/time.c +++ b/trunk/arch/ia64/kernel/time.c @@ -188,7 +188,7 @@ ia64_init_itm (void) itc_freq = (platform_base_freq*itc_ratio.num)/itc_ratio.den; local_cpu_data->itm_delta = (itc_freq + HZ/2) / HZ; - printk(KERN_DEBUG "CPU %d: base freq=%lu.%03luMHz, ITC ratio=%u/%u, " + printk(KERN_DEBUG "CPU %d: base freq=%lu.%03luMHz, ITC ratio=%lu/%lu, " "ITC freq=%lu.%03luMHz", smp_processor_id(), platform_base_freq / 1000000, (platform_base_freq / 1000) % 1000, itc_ratio.num, itc_ratio.den, itc_freq / 1000000, (itc_freq / 1000) % 1000); diff --git a/trunk/arch/ia64/kernel/topology.c b/trunk/arch/ia64/kernel/topology.c index b47476d655f1..3b6fd798c4d6 100644 --- a/trunk/arch/ia64/kernel/topology.c +++ b/trunk/arch/ia64/kernel/topology.c @@ -9,8 +9,6 @@ * 2002/08/07 Erich Focht * Populate cpu entries in sysfs for non-numa systems as well * Intel Corporation - Ashok Raj - * 02/27/2006 Zhang, Yanmin - * Populate cpu cache entries in sysfs for cpu cache info */ #include @@ -21,7 +19,6 @@ #include #include #include -#include #include #include #include @@ -104,367 +101,3 @@ static int __init topology_init(void) } subsys_initcall(topology_init); - - -/* - * Export cpu cache information through sysfs - */ - -/* - * A bunch of string array to get pretty printing - */ -static const char *cache_types[] = { - "", /* not used */ - "Instruction", - "Data", - "Unified" /* unified */ -}; - -static const char *cache_mattrib[]={ - "WriteThrough", - "WriteBack", - "", /* reserved */ - "" /* reserved */ -}; - -struct cache_info { - pal_cache_config_info_t cci; - cpumask_t shared_cpu_map; - int level; - int type; - struct kobject kobj; -}; - -struct cpu_cache_info { - struct cache_info *cache_leaves; - int num_cache_leaves; - struct kobject kobj; -}; - -static struct cpu_cache_info all_cpu_cache_info[NR_CPUS]; -#define LEAF_KOBJECT_PTR(x,y) (&all_cpu_cache_info[x].cache_leaves[y]) - -#ifdef CONFIG_SMP -static void cache_shared_cpu_map_setup( unsigned int cpu, - struct cache_info * this_leaf) -{ - pal_cache_shared_info_t csi; - int num_shared, i = 0; - unsigned int j; - - if (cpu_data(cpu)->threads_per_core <= 1 && - cpu_data(cpu)->cores_per_socket <= 1) { - cpu_set(cpu, this_leaf->shared_cpu_map); - return; - } - - if (ia64_pal_cache_shared_info(this_leaf->level, - this_leaf->type, - 0, - &csi) != PAL_STATUS_SUCCESS) - return; - - num_shared = (int) csi.num_shared; - do { - for_each_cpu(j) - if (cpu_data(cpu)->socket_id == cpu_data(j)->socket_id - && cpu_data(j)->core_id == csi.log1_cid - && cpu_data(j)->thread_id == csi.log1_tid) - cpu_set(j, this_leaf->shared_cpu_map); - - i++; - } while (i < num_shared && - ia64_pal_cache_shared_info(this_leaf->level, - this_leaf->type, - i, - &csi) == PAL_STATUS_SUCCESS); -} -#else -static void cache_shared_cpu_map_setup(unsigned int cpu, - struct cache_info * this_leaf) -{ - cpu_set(cpu, this_leaf->shared_cpu_map); - return; -} -#endif - -static ssize_t show_coherency_line_size(struct cache_info *this_leaf, - char *buf) -{ - return sprintf(buf, "%u\n", 1 << this_leaf->cci.pcci_line_size); -} - -static ssize_t show_ways_of_associativity(struct cache_info *this_leaf, - char *buf) -{ - return sprintf(buf, "%u\n", this_leaf->cci.pcci_assoc); -} - -static ssize_t show_attributes(struct cache_info *this_leaf, char *buf) -{ - return sprintf(buf, - "%s\n", - cache_mattrib[this_leaf->cci.pcci_cache_attr]); -} - -static ssize_t show_size(struct cache_info *this_leaf, char *buf) -{ - return sprintf(buf, "%uK\n", this_leaf->cci.pcci_cache_size / 1024); -} - -static ssize_t show_number_of_sets(struct cache_info *this_leaf, char *buf) -{ - unsigned number_of_sets = this_leaf->cci.pcci_cache_size; - number_of_sets /= this_leaf->cci.pcci_assoc; - number_of_sets /= 1 << this_leaf->cci.pcci_line_size; - - return sprintf(buf, "%u\n", number_of_sets); -} - -static ssize_t show_shared_cpu_map(struct cache_info *this_leaf, char *buf) -{ - ssize_t len; - cpumask_t shared_cpu_map; - - cpus_and(shared_cpu_map, this_leaf->shared_cpu_map, cpu_online_map); - len = cpumask_scnprintf(buf, NR_CPUS+1, shared_cpu_map); - len += sprintf(buf+len, "\n"); - return len; -} - -static ssize_t show_type(struct cache_info *this_leaf, char *buf) -{ - int type = this_leaf->type + this_leaf->cci.pcci_unified; - return sprintf(buf, "%s\n", cache_types[type]); -} - -static ssize_t show_level(struct cache_info *this_leaf, char *buf) -{ - return sprintf(buf, "%u\n", this_leaf->level); -} - -struct cache_attr { - struct attribute attr; - ssize_t (*show)(struct cache_info *, char *); - ssize_t (*store)(struct cache_info *, const char *, size_t count); -}; - -#ifdef define_one_ro - #undef define_one_ro -#endif -#define define_one_ro(_name) \ - static struct cache_attr _name = \ -__ATTR(_name, 0444, show_##_name, NULL) - -define_one_ro(level); -define_one_ro(type); -define_one_ro(coherency_line_size); -define_one_ro(ways_of_associativity); -define_one_ro(size); -define_one_ro(number_of_sets); -define_one_ro(shared_cpu_map); -define_one_ro(attributes); - -static struct attribute * cache_default_attrs[] = { - &type.attr, - &level.attr, - &coherency_line_size.attr, - &ways_of_associativity.attr, - &attributes.attr, - &size.attr, - &number_of_sets.attr, - &shared_cpu_map.attr, - NULL -}; - -#define to_object(k) container_of(k, struct cache_info, kobj) -#define to_attr(a) container_of(a, struct cache_attr, attr) - -static ssize_t cache_show(struct kobject * kobj, struct attribute * attr, char * buf) -{ - struct cache_attr *fattr = to_attr(attr); - struct cache_info *this_leaf = to_object(kobj); - ssize_t ret; - - ret = fattr->show ? fattr->show(this_leaf, buf) : 0; - return ret; -} - -static struct sysfs_ops cache_sysfs_ops = { - .show = cache_show -}; - -static struct kobj_type cache_ktype = { - .sysfs_ops = &cache_sysfs_ops, - .default_attrs = cache_default_attrs, -}; - -static struct kobj_type cache_ktype_percpu_entry = { - .sysfs_ops = &cache_sysfs_ops, -}; - -static void __cpuinit cpu_cache_sysfs_exit(unsigned int cpu) -{ - if (all_cpu_cache_info[cpu].cache_leaves) { - kfree(all_cpu_cache_info[cpu].cache_leaves); - all_cpu_cache_info[cpu].cache_leaves = NULL; - } - all_cpu_cache_info[cpu].num_cache_leaves = 0; - memset(&all_cpu_cache_info[cpu].kobj, 0, sizeof(struct kobject)); - - return; -} - -static int __cpuinit cpu_cache_sysfs_init(unsigned int cpu) -{ - u64 i, levels, unique_caches; - pal_cache_config_info_t cci; - int j; - s64 status; - struct cache_info *this_cache; - int num_cache_leaves = 0; - - if ((status = ia64_pal_cache_summary(&levels, &unique_caches)) != 0) { - printk(KERN_ERR "ia64_pal_cache_summary=%ld\n", status); - return -1; - } - - this_cache=kzalloc(sizeof(struct cache_info)*unique_caches, - GFP_KERNEL); - if (this_cache == NULL) - return -ENOMEM; - - for (i=0; i < levels; i++) { - for (j=2; j >0 ; j--) { - if ((status=ia64_pal_cache_config_info(i,j, &cci)) != - PAL_STATUS_SUCCESS) - continue; - - this_cache[num_cache_leaves].cci = cci; - this_cache[num_cache_leaves].level = i + 1; - this_cache[num_cache_leaves].type = j; - - cache_shared_cpu_map_setup(cpu, - &this_cache[num_cache_leaves]); - num_cache_leaves ++; - } - } - - all_cpu_cache_info[cpu].cache_leaves = this_cache; - all_cpu_cache_info[cpu].num_cache_leaves = num_cache_leaves; - - memset(&all_cpu_cache_info[cpu].kobj, 0, sizeof(struct kobject)); - - return 0; -} - -/* Add cache interface for CPU device */ -static int __cpuinit cache_add_dev(struct sys_device * sys_dev) -{ - unsigned int cpu = sys_dev->id; - unsigned long i, j; - struct cache_info *this_object; - int retval = 0; - cpumask_t oldmask; - - if (all_cpu_cache_info[cpu].kobj.parent) - return 0; - - oldmask = current->cpus_allowed; - retval = set_cpus_allowed(current, cpumask_of_cpu(cpu)); - if (unlikely(retval)) - return retval; - - retval = cpu_cache_sysfs_init(cpu); - set_cpus_allowed(current, oldmask); - if (unlikely(retval < 0)) - return retval; - - all_cpu_cache_info[cpu].kobj.parent = &sys_dev->kobj; - kobject_set_name(&all_cpu_cache_info[cpu].kobj, "%s", "cache"); - all_cpu_cache_info[cpu].kobj.ktype = &cache_ktype_percpu_entry; - retval = kobject_register(&all_cpu_cache_info[cpu].kobj); - - for (i = 0; i < all_cpu_cache_info[cpu].num_cache_leaves; i++) { - this_object = LEAF_KOBJECT_PTR(cpu,i); - this_object->kobj.parent = &all_cpu_cache_info[cpu].kobj; - kobject_set_name(&(this_object->kobj), "index%1lu", i); - this_object->kobj.ktype = &cache_ktype; - retval = kobject_register(&(this_object->kobj)); - if (unlikely(retval)) { - for (j = 0; j < i; j++) { - kobject_unregister( - &(LEAF_KOBJECT_PTR(cpu,j)->kobj)); - } - kobject_unregister(&all_cpu_cache_info[cpu].kobj); - cpu_cache_sysfs_exit(cpu); - break; - } - } - return retval; -} - -/* Remove cache interface for CPU device */ -static int __cpuinit cache_remove_dev(struct sys_device * sys_dev) -{ - unsigned int cpu = sys_dev->id; - unsigned long i; - - for (i = 0; i < all_cpu_cache_info[cpu].num_cache_leaves; i++) - kobject_unregister(&(LEAF_KOBJECT_PTR(cpu,i)->kobj)); - - if (all_cpu_cache_info[cpu].kobj.parent) { - kobject_unregister(&all_cpu_cache_info[cpu].kobj); - memset(&all_cpu_cache_info[cpu].kobj, - 0, - sizeof(struct kobject)); - } - - cpu_cache_sysfs_exit(cpu); - - return 0; -} - -/* - * When a cpu is hot-plugged, do a check and initiate - * cache kobject if necessary - */ -static int __cpuinit cache_cpu_callback(struct notifier_block *nfb, - unsigned long action, void *hcpu) -{ - unsigned int cpu = (unsigned long)hcpu; - struct sys_device *sys_dev; - - sys_dev = get_cpu_sysdev(cpu); - switch (action) { - case CPU_ONLINE: - cache_add_dev(sys_dev); - break; - case CPU_DEAD: - cache_remove_dev(sys_dev); - break; - } - return NOTIFY_OK; -} - -static struct notifier_block cache_cpu_notifier = -{ - .notifier_call = cache_cpu_callback -}; - -static int __cpuinit cache_sysfs_init(void) -{ - int i; - - for_each_online_cpu(i) { - cache_cpu_callback(&cache_cpu_notifier, CPU_ONLINE, - (void *)(long)i); - } - - register_cpu_notifier(&cache_cpu_notifier); - - return 0; -} - -device_initcall(cache_sysfs_init); - diff --git a/trunk/arch/ia64/kernel/vmlinux.lds.S b/trunk/arch/ia64/kernel/vmlinux.lds.S index 783600fe52b2..0b9e56dd7f05 100644 --- a/trunk/arch/ia64/kernel/vmlinux.lds.S +++ b/trunk/arch/ia64/kernel/vmlinux.lds.S @@ -70,15 +70,6 @@ SECTIONS __stop___ex_table = .; } - /* MCA table */ - . = ALIGN(16); - __mca_table : AT(ADDR(__mca_table) - LOAD_OFFSET) - { - __start___mca_table = .; - *(__mca_table) - __stop___mca_table = .; - } - /* Global data */ _data = .; @@ -139,6 +130,15 @@ SECTIONS __initcall_end = .; } + /* MCA table */ + . = ALIGN(16); + __mca_table : AT(ADDR(__mca_table) - LOAD_OFFSET) + { + __start___mca_table = .; + *(__mca_table) + __stop___mca_table = .; + } + .data.patch.vtop : AT(ADDR(.data.patch.vtop) - LOAD_OFFSET) { __start___vtop_patchlist = .; diff --git a/trunk/arch/ia64/mm/init.c b/trunk/arch/ia64/mm/init.c index cafa8776a53d..2ef1151cde90 100644 --- a/trunk/arch/ia64/mm/init.c +++ b/trunk/arch/ia64/mm/init.c @@ -109,7 +109,6 @@ lazy_mmu_prot_update (pte_t pte) { unsigned long addr; struct page *page; - unsigned long order; if (!pte_exec(pte)) return; /* not an executable page... */ @@ -120,12 +119,7 @@ lazy_mmu_prot_update (pte_t pte) if (test_bit(PG_arch_1, &page->flags)) return; /* i-cache is already coherent with d-cache */ - if (PageCompound(page)) { - order = (unsigned long) (page[1].lru.prev); - flush_icache_range(addr, addr + (1UL << order << PAGE_SHIFT)); - } - else - flush_icache_range(addr, addr + PAGE_SIZE); + flush_icache_range(addr, addr + PAGE_SIZE); set_bit(PG_arch_1, &page->flags); /* mark page as clean */ } diff --git a/trunk/arch/ia64/mm/ioremap.c b/trunk/arch/ia64/mm/ioremap.c index 643ccc6960ce..62328621f99c 100644 --- a/trunk/arch/ia64/mm/ioremap.c +++ b/trunk/arch/ia64/mm/ioremap.c @@ -21,12 +21,12 @@ __ioremap (unsigned long offset, unsigned long size) void __iomem * ioremap (unsigned long offset, unsigned long size) { - if (efi_mem_attribute_range(offset, size, EFI_MEMORY_WB)) - return phys_to_virt(offset); - if (efi_mem_attribute_range(offset, size, EFI_MEMORY_UC)) return __ioremap(offset, size); + if (efi_mem_attribute_range(offset, size, EFI_MEMORY_WB)) + return phys_to_virt(offset); + /* * Someday this should check ACPI resources so we * can do the right thing for hot-plugged regions. diff --git a/trunk/arch/ia64/mm/tlb.c b/trunk/arch/ia64/mm/tlb.c index 4dbbca0b5e9c..6a4eec9113e8 100644 --- a/trunk/arch/ia64/mm/tlb.c +++ b/trunk/arch/ia64/mm/tlb.c @@ -156,19 +156,17 @@ flush_tlb_range (struct vm_area_struct *vma, unsigned long start, nbits = purge.max_bits; start &= ~((1UL << nbits) - 1); +# ifdef CONFIG_SMP + platform_global_tlb_purge(mm, start, end, nbits); +# else preempt_disable(); -#ifdef CONFIG_SMP - if (mm != current->active_mm || cpus_weight(mm->cpu_vm_mask) != 1) { - platform_global_tlb_purge(mm, start, end, nbits); - preempt_enable(); - return; - } -#endif do { ia64_ptcl(start, (nbits<<2)); start += (1UL << nbits); } while (start < end); preempt_enable(); +# endif + ia64_srlz_i(); /* srlz.i implies srlz.d */ } EXPORT_SYMBOL(flush_tlb_range); diff --git a/trunk/arch/ia64/sn/kernel/sn2/sn_hwperf.c b/trunk/arch/ia64/sn/kernel/sn2/sn_hwperf.c index d917afa30b27..70db21f3df21 100644 --- a/trunk/arch/ia64/sn/kernel/sn2/sn_hwperf.c +++ b/trunk/arch/ia64/sn/kernel/sn2/sn_hwperf.c @@ -110,11 +110,7 @@ static int sn_hwperf_geoid_to_cnode(char *location) if (sn_hwperf_location_to_bpos(location, &rack, &bay, &slot, &slab)) return -1; - /* - * FIXME: replace with cleaner for_each_XXX macro which addresses - * both compute and IO nodes once ACPI3.0 is available. - */ - for (cnode = 0; cnode < num_cnodes; cnode++) { + for_each_node(cnode) { geoid = cnodeid_get_geoid(cnode); module_id = geo_module(geoid); this_rack = MODULE_GET_RACK(module_id); @@ -609,7 +605,7 @@ static int sn_hwperf_op_cpu(struct sn_hwperf_op_info *op_info) op_info->a->arg &= SN_HWPERF_ARG_OBJID_MASK; if (cpu != SN_HWPERF_ARG_ANY_CPU) { - if (cpu >= NR_CPUS || !cpu_online(cpu)) { + if (cpu >= num_online_cpus() || !cpu_online(cpu)) { r = -EINVAL; goto out; } diff --git a/trunk/arch/m68k/kernel/m68k_ksyms.c b/trunk/arch/m68k/kernel/m68k_ksyms.c index c3319514a85e..3d7f2000b714 100644 --- a/trunk/arch/m68k/kernel/m68k_ksyms.c +++ b/trunk/arch/m68k/kernel/m68k_ksyms.c @@ -79,3 +79,4 @@ EXPORT_SYMBOL(__down_failed_interruptible); EXPORT_SYMBOL(__down_failed_trylock); EXPORT_SYMBOL(__up_wakeup); +EXPORT_SYMBOL(get_wchan); diff --git a/trunk/arch/m68knommu/kernel/m68k_ksyms.c b/trunk/arch/m68knommu/kernel/m68k_ksyms.c index f9b4ea16c099..d844c755945a 100644 --- a/trunk/arch/m68knommu/kernel/m68k_ksyms.c +++ b/trunk/arch/m68knommu/kernel/m68k_ksyms.c @@ -57,6 +57,8 @@ EXPORT_SYMBOL(__down_failed_interruptible); EXPORT_SYMBOL(__down_failed_trylock); EXPORT_SYMBOL(__up_wakeup); +EXPORT_SYMBOL(get_wchan); + /* * libgcc functions - functions that are used internally by the * compiler... (prototypes are not correct though, but that diff --git a/trunk/arch/mips/kernel/process.c b/trunk/arch/mips/kernel/process.c index c66db5e5ab62..a8f435d82940 100644 --- a/trunk/arch/mips/kernel/process.c +++ b/trunk/arch/mips/kernel/process.c @@ -419,3 +419,4 @@ unsigned long get_wchan(struct task_struct *p) return pc; } +EXPORT_SYMBOL(get_wchan); diff --git a/trunk/arch/parisc/Kconfig b/trunk/arch/parisc/Kconfig index 2fdf21989dc2..6b3c50964ca9 100644 --- a/trunk/arch/parisc/Kconfig +++ b/trunk/arch/parisc/Kconfig @@ -177,10 +177,14 @@ config ARCH_DISCONTIGMEM_DEFAULT def_bool y depends on ARCH_DISCONTIGMEM_ENABLE -source "kernel/Kconfig.preempt" source "kernel/Kconfig.hz" source "mm/Kconfig" +config PREEMPT + bool +# bool "Preemptible Kernel" + default n + config COMPAT def_bool y depends on 64BIT diff --git a/trunk/arch/parisc/configs/712_defconfig b/trunk/arch/parisc/configs/712_defconfig index 41fd0696bbe7..3e013f55df64 100644 --- a/trunk/arch/parisc/configs/712_defconfig +++ b/trunk/arch/parisc/configs/712_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.16-pa6 -# Sun Mar 26 19:59:51 2006 +# Linux kernel version: 2.6.14-rc5-pa1 +# Fri Oct 21 23:04:34 2005 # CONFIG_PARISC=y CONFIG_MMU=y @@ -10,11 +10,14 @@ CONFIG_RWSEM_GENERIC_SPINLOCK=y CONFIG_GENERIC_CALIBRATE_DELAY=y CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_ARCH_MAY_HAVE_PC_FDC=y # # Code maturity level options # CONFIG_EXPERIMENTAL=y +# CONFIG_CLEAN_COMPILE is not set +CONFIG_BROKEN=y CONFIG_BROKEN_ON_SMP=y CONFIG_INIT_ENV_ARG_LIMIT=32 @@ -29,18 +32,17 @@ CONFIG_POSIX_MQUEUE=y # CONFIG_BSD_PROCESS_ACCT is not set CONFIG_SYSCTL=y # CONFIG_AUDIT is not set +CONFIG_HOTPLUG=y +CONFIG_KOBJECT_UEVENT=y CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_INITRAMFS_SOURCE="" -CONFIG_CC_OPTIMIZE_FOR_SIZE=y # CONFIG_EMBEDDED is not set CONFIG_KALLSYMS=y CONFIG_KALLSYMS_ALL=y # CONFIG_KALLSYMS_EXTRA_PASS is not set -CONFIG_HOTPLUG=y CONFIG_PRINTK=y CONFIG_BUG=y -CONFIG_ELF_CORE=y CONFIG_BASE_FULL=y CONFIG_FUTEX=y CONFIG_EPOLL=y @@ -49,10 +51,8 @@ CONFIG_CC_ALIGN_FUNCTIONS=0 CONFIG_CC_ALIGN_LABELS=0 CONFIG_CC_ALIGN_LOOPS=0 CONFIG_CC_ALIGN_JUMPS=0 -CONFIG_SLAB=y # CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=0 -# CONFIG_SLOB is not set # # Loadable module support @@ -65,23 +65,6 @@ CONFIG_OBSOLETE_MODPARM=y # CONFIG_MODULE_SRCVERSION_ALL is not set CONFIG_KMOD=y -# -# Block layer -# - -# -# IO Schedulers -# -CONFIG_IOSCHED_NOOP=y -CONFIG_IOSCHED_AS=y -CONFIG_IOSCHED_DEADLINE=y -CONFIG_IOSCHED_CFQ=y -CONFIG_DEFAULT_AS=y -# CONFIG_DEFAULT_DEADLINE is not set -# CONFIG_DEFAULT_CFQ is not set -# CONFIG_DEFAULT_NOOP is not set -CONFIG_DEFAULT_IOSCHED="anticipatory" - # # Processor type and features # @@ -92,10 +75,6 @@ CONFIG_PA7100LC=y # CONFIG_PA8X00 is not set CONFIG_PA11=y # CONFIG_SMP is not set -CONFIG_ARCH_FLATMEM_ENABLE=y -# CONFIG_PREEMPT_NONE is not set -CONFIG_PREEMPT_VOLUNTARY=y -# CONFIG_PREEMPT is not set # CONFIG_HZ_100 is not set CONFIG_HZ_250=y # CONFIG_HZ_1000 is not set @@ -107,7 +86,7 @@ CONFIG_FLATMEM_MANUAL=y CONFIG_FLATMEM=y CONFIG_FLAT_NODE_MEM_MAP=y # CONFIG_SPARSEMEM_STATIC is not set -CONFIG_SPLIT_PTLOCK_CPUS=4096 +# CONFIG_PREEMPT is not set # CONFIG_HPUX is not set # @@ -151,7 +130,6 @@ CONFIG_NET=y # # Networking options # -# CONFIG_NETDEBUG is not set CONFIG_PACKET=y CONFIG_PACKET_MMAP=y CONFIG_UNIX=y @@ -187,12 +165,7 @@ CONFIG_TCP_CONG_BIC=y # CONFIG_IPV6 is not set CONFIG_NETFILTER=y # CONFIG_NETFILTER_DEBUG is not set - -# -# Core Netfilter Configuration -# # CONFIG_NETFILTER_NETLINK is not set -# CONFIG_NETFILTER_XTABLES is not set # # IP: Netfilter Configuration @@ -209,6 +182,64 @@ CONFIG_IP_NF_TFTP=m CONFIG_IP_NF_AMANDA=m # CONFIG_IP_NF_PPTP is not set CONFIG_IP_NF_QUEUE=m +CONFIG_IP_NF_IPTABLES=m +CONFIG_IP_NF_MATCH_LIMIT=m +CONFIG_IP_NF_MATCH_IPRANGE=m +CONFIG_IP_NF_MATCH_MAC=m +CONFIG_IP_NF_MATCH_PKTTYPE=m +CONFIG_IP_NF_MATCH_MARK=m +CONFIG_IP_NF_MATCH_MULTIPORT=m +CONFIG_IP_NF_MATCH_TOS=m +CONFIG_IP_NF_MATCH_RECENT=m +CONFIG_IP_NF_MATCH_ECN=m +CONFIG_IP_NF_MATCH_DSCP=m +CONFIG_IP_NF_MATCH_AH_ESP=m +CONFIG_IP_NF_MATCH_LENGTH=m +CONFIG_IP_NF_MATCH_TTL=m +CONFIG_IP_NF_MATCH_TCPMSS=m +CONFIG_IP_NF_MATCH_HELPER=m +CONFIG_IP_NF_MATCH_STATE=m +CONFIG_IP_NF_MATCH_CONNTRACK=m +CONFIG_IP_NF_MATCH_OWNER=m +# CONFIG_IP_NF_MATCH_ADDRTYPE is not set +# CONFIG_IP_NF_MATCH_REALM is not set +CONFIG_IP_NF_MATCH_SCTP=m +# CONFIG_IP_NF_MATCH_DCCP is not set +CONFIG_IP_NF_MATCH_COMMENT=m +CONFIG_IP_NF_MATCH_CONNMARK=m +CONFIG_IP_NF_MATCH_HASHLIMIT=m +# CONFIG_IP_NF_MATCH_STRING is not set +CONFIG_IP_NF_FILTER=m +CONFIG_IP_NF_TARGET_REJECT=m +CONFIG_IP_NF_TARGET_LOG=m +CONFIG_IP_NF_TARGET_ULOG=m +CONFIG_IP_NF_TARGET_TCPMSS=m +# CONFIG_IP_NF_TARGET_NFQUEUE is not set +CONFIG_IP_NF_NAT=m +CONFIG_IP_NF_NAT_NEEDED=y +CONFIG_IP_NF_TARGET_MASQUERADE=m +CONFIG_IP_NF_TARGET_REDIRECT=m +CONFIG_IP_NF_TARGET_NETMAP=m +CONFIG_IP_NF_TARGET_SAME=m +CONFIG_IP_NF_NAT_SNMP_BASIC=m +CONFIG_IP_NF_NAT_IRC=m +CONFIG_IP_NF_NAT_FTP=m +CONFIG_IP_NF_NAT_TFTP=m +CONFIG_IP_NF_NAT_AMANDA=m +CONFIG_IP_NF_MANGLE=m +CONFIG_IP_NF_TARGET_TOS=m +CONFIG_IP_NF_TARGET_ECN=m +CONFIG_IP_NF_TARGET_DSCP=m +CONFIG_IP_NF_TARGET_MARK=m +CONFIG_IP_NF_TARGET_CLASSIFY=m +# CONFIG_IP_NF_TARGET_TTL is not set +CONFIG_IP_NF_TARGET_CONNMARK=m +CONFIG_IP_NF_TARGET_CLUSTERIP=m +CONFIG_IP_NF_RAW=m +CONFIG_IP_NF_TARGET_NOTRACK=m +CONFIG_IP_NF_ARPTABLES=m +CONFIG_IP_NF_ARPFILTER=m +CONFIG_IP_NF_ARP_MANGLE=m # # DCCP Configuration (EXPERIMENTAL) @@ -219,11 +250,6 @@ CONFIG_IP_NF_QUEUE=m # SCTP Configuration (EXPERIMENTAL) # # CONFIG_IP_SCTP is not set - -# -# TIPC Configuration (EXPERIMENTAL) -# -# CONFIG_TIPC is not set # CONFIG_ATM is not set # CONFIG_BRIDGE is not set # CONFIG_VLAN_8021Q is not set @@ -237,11 +263,8 @@ CONFIG_LLC2=m # CONFIG_NET_DIVERT is not set # CONFIG_ECONET is not set # CONFIG_WAN_ROUTER is not set - -# -# QoS and/or fair queueing -# # CONFIG_NET_SCHED is not set +# CONFIG_NET_CLS_ROUTE is not set # # Network testing @@ -281,7 +304,6 @@ CONFIG_PARPORT=y CONFIG_PARPORT_PC=m # CONFIG_PARPORT_PC_FIFO is not set # CONFIG_PARPORT_PC_SUPERIO is not set -CONFIG_PARPORT_NOT_PC=y CONFIG_PARPORT_GSC=y # CONFIG_PARPORT_1284 is not set @@ -292,6 +314,7 @@ CONFIG_PARPORT_GSC=y # # Block devices # +# CONFIG_BLK_DEV_FD is not set # CONFIG_PARIDE is not set # CONFIG_BLK_DEV_COW_COMMON is not set CONFIG_BLK_DEV_LOOP=y @@ -302,6 +325,14 @@ CONFIG_BLK_DEV_RAM_COUNT=16 CONFIG_BLK_DEV_RAM_SIZE=6144 CONFIG_BLK_DEV_INITRD=y # CONFIG_CDROM_PKTCDVD is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y CONFIG_ATA_OVER_ETH=m # @@ -345,7 +376,6 @@ CONFIG_SCSI_ISCSI_ATTRS=m # # SCSI low-level drivers # -# CONFIG_ISCSI_TCP is not set # CONFIG_SCSI_SATA is not set # CONFIG_SCSI_PPA is not set # CONFIG_SCSI_IMM is not set @@ -377,6 +407,7 @@ CONFIG_MD_RAID1=m # # IEEE 1394 (FireWire) support # +# CONFIG_IEEE1394 is not set # # I2O device support @@ -440,7 +471,6 @@ CONFIG_PPP_ASYNC=m CONFIG_PPP_SYNC_TTY=m CONFIG_PPP_DEFLATE=m CONFIG_PPP_BSDCOMP=m -CONFIG_PPP_MPPE=m CONFIG_PPPOE=m # CONFIG_SLIP is not set # CONFIG_SHAPER is not set @@ -486,8 +516,8 @@ CONFIG_KEYBOARD_ATKBD_HP_KEYCODES=y # CONFIG_KEYBOARD_LKKBD is not set # CONFIG_KEYBOARD_XTKBD is not set # CONFIG_KEYBOARD_NEWTON is not set -# CONFIG_KEYBOARD_HIL_OLD is not set -CONFIG_KEYBOARD_HIL=y +CONFIG_KEYBOARD_HIL_OLD=y +# CONFIG_KEYBOARD_HIL is not set CONFIG_INPUT_MOUSE=y CONFIG_MOUSE_PS2=y CONFIG_MOUSE_SERIAL=m @@ -524,7 +554,6 @@ CONFIG_HW_CONSOLE=y CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_8250_NR_UARTS=17 -CONFIG_SERIAL_8250_RUNTIME_UARTS=4 CONFIG_SERIAL_8250_EXTENDED=y CONFIG_SERIAL_8250_MANY_PORTS=y CONFIG_SERIAL_8250_SHARE_IRQ=y @@ -569,20 +598,12 @@ CONFIG_MAX_RAW_DEVS=256 # # TPM devices # -# CONFIG_TCG_TPM is not set -# CONFIG_TELCLOCK is not set # # I2C support # # CONFIG_I2C is not set -# -# SPI support -# -# CONFIG_SPI is not set -# CONFIG_SPI_MASTER is not set - # # Dallas's 1-wire bus # @@ -619,6 +640,7 @@ CONFIG_FB=y CONFIG_FB_CFB_FILLRECT=y CONFIG_FB_CFB_COPYAREA=y CONFIG_FB_CFB_IMAGEBLIT=y +CONFIG_FB_SOFT_CURSOR=y # CONFIG_FB_MACMODES is not set CONFIG_FB_MODE_HELPERS=y CONFIG_FB_TILEBLITTING=y @@ -633,7 +655,6 @@ CONFIG_DUMMY_CONSOLE=y CONFIG_DUMMY_CONSOLE_COLUMNS=128 CONFIG_DUMMY_CONSOLE_ROWS=48 CONFIG_FRAMEBUFFER_CONSOLE=y -# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set CONFIG_STI_CONSOLE=y CONFIG_FONTS=y CONFIG_FONT_8x8=y @@ -674,8 +695,6 @@ CONFIG_SND_OSSEMUL=y CONFIG_SND_MIXER_OSS=y CONFIG_SND_PCM_OSS=y CONFIG_SND_SEQUENCER_OSS=y -# CONFIG_SND_DYNAMIC_MINORS is not set -CONFIG_SND_SUPPORT_OLD_API=y # CONFIG_SND_VERBOSE_PRINTK is not set # CONFIG_SND_DEBUG is not set @@ -704,10 +723,6 @@ CONFIG_SND_HARMONY=y # CONFIG_USB_ARCH_HAS_HCD is not set # CONFIG_USB_ARCH_HAS_OHCI is not set -# -# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' -# - # # USB Gadget Support # @@ -721,9 +736,10 @@ CONFIG_SND_HARMONY=y # # InfiniBand support # +# CONFIG_INFINIBAND is not set # -# EDAC - error detection and reporting (RAS) (EXPERIMENTAL) +# SN Devices # # @@ -749,7 +765,6 @@ CONFIG_XFS_EXPORT=y # CONFIG_XFS_SECURITY is not set # CONFIG_XFS_POSIX_ACL is not set # CONFIG_XFS_RT is not set -# CONFIG_OCFS2_FS is not set # CONFIG_MINIX_FS is not set # CONFIG_ROMFS_FS is not set CONFIG_INOTIFY=y @@ -785,10 +800,10 @@ CONFIG_PROC_FS=y CONFIG_PROC_KCORE=y CONFIG_SYSFS=y CONFIG_TMPFS=y +# CONFIG_HUGETLBFS is not set # CONFIG_HUGETLB_PAGE is not set CONFIG_RAMFS=y # CONFIG_RELAYFS_FS is not set -# CONFIG_CONFIGFS_FS is not set # # Miscellaneous filesystems @@ -806,6 +821,7 @@ CONFIG_RAMFS=y # CONFIG_QNX4FS_FS is not set # CONFIG_SYSV_FS is not set CONFIG_UFS_FS=m +# CONFIG_UFS_FS_WRITE is not set # # Network File Systems @@ -901,22 +917,18 @@ CONFIG_OPROFILE=m # Kernel hacking # # CONFIG_PRINTK_TIME is not set -CONFIG_MAGIC_SYSRQ=y CONFIG_DEBUG_KERNEL=y +CONFIG_MAGIC_SYSRQ=y CONFIG_LOG_BUF_SHIFT=16 CONFIG_DETECT_SOFTLOCKUP=y # CONFIG_SCHEDSTATS is not set # CONFIG_DEBUG_SLAB is not set -CONFIG_DEBUG_MUTEXES=y # CONFIG_DEBUG_SPINLOCK is not set # CONFIG_DEBUG_SPINLOCK_SLEEP is not set # CONFIG_DEBUG_KOBJECT is not set # CONFIG_DEBUG_INFO is not set +# CONFIG_DEBUG_IOREMAP is not set # CONFIG_DEBUG_FS is not set -# CONFIG_DEBUG_VM is not set -CONFIG_FORCED_INLINING=y -# CONFIG_RCU_TORTURE_TEST is not set -CONFIG_DEBUG_RODATA=y # # Security options diff --git a/trunk/arch/parisc/configs/a500_defconfig b/trunk/arch/parisc/configs/a500_defconfig index f3b812f04592..959ad3c4e372 100644 --- a/trunk/arch/parisc/configs/a500_defconfig +++ b/trunk/arch/parisc/configs/a500_defconfig @@ -1031,8 +1031,8 @@ CONFIG_NLS_CODEPAGE_850=m # CONFIG_NLS_ISO8859_8 is not set # CONFIG_NLS_CODEPAGE_1250 is not set # CONFIG_NLS_CODEPAGE_1251 is not set -CONFIG_NLS_ASCII=m -CONFIG_NLS_ISO8859_1=m +# CONFIG_NLS_ASCII is not set +# CONFIG_NLS_ISO8859_1 is not set # CONFIG_NLS_ISO8859_2 is not set # CONFIG_NLS_ISO8859_3 is not set # CONFIG_NLS_ISO8859_4 is not set diff --git a/trunk/arch/parisc/configs/b180_defconfig b/trunk/arch/parisc/configs/b180_defconfig index 35093612ad2c..37e98241ce4b 100644 --- a/trunk/arch/parisc/configs/b180_defconfig +++ b/trunk/arch/parisc/configs/b180_defconfig @@ -939,10 +939,10 @@ CONFIG_MSDOS_PARTITION=y # CONFIG_NLS=y CONFIG_NLS_DEFAULT="iso8859-1" -CONFIG_NLS_CODEPAGE_437=m +# CONFIG_NLS_CODEPAGE_437 is not set # CONFIG_NLS_CODEPAGE_737 is not set # CONFIG_NLS_CODEPAGE_775 is not set -CONFIG_NLS_CODEPAGE_850=m +# CONFIG_NLS_CODEPAGE_850 is not set # CONFIG_NLS_CODEPAGE_852 is not set # CONFIG_NLS_CODEPAGE_855 is not set # CONFIG_NLS_CODEPAGE_857 is not set @@ -962,8 +962,8 @@ CONFIG_NLS_CODEPAGE_850=m # CONFIG_NLS_ISO8859_8 is not set # CONFIG_NLS_CODEPAGE_1250 is not set # CONFIG_NLS_CODEPAGE_1251 is not set -CONFIG_NLS_ASCII=m -CONFIG_NLS_ISO8859_1=m +# CONFIG_NLS_ASCII is not set +# CONFIG_NLS_ISO8859_1 is not set # CONFIG_NLS_ISO8859_2 is not set # CONFIG_NLS_ISO8859_3 is not set # CONFIG_NLS_ISO8859_4 is not set @@ -973,10 +973,10 @@ CONFIG_NLS_ISO8859_1=m # CONFIG_NLS_ISO8859_9 is not set # CONFIG_NLS_ISO8859_13 is not set # CONFIG_NLS_ISO8859_14 is not set -CONFIG_NLS_ISO8859_15=m +# CONFIG_NLS_ISO8859_15 is not set # CONFIG_NLS_KOI8_R is not set # CONFIG_NLS_KOI8_U is not set -CONFIG_NLS_UTF8=m +# CONFIG_NLS_UTF8 is not set # # Kernel hacking diff --git a/trunk/arch/parisc/configs/c3000_defconfig b/trunk/arch/parisc/configs/c3000_defconfig index 782906b644dd..0b1c8c1fa8a3 100644 --- a/trunk/arch/parisc/configs/c3000_defconfig +++ b/trunk/arch/parisc/configs/c3000_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.16-pa6 -# Sun Mar 26 20:03:29 2006 +# Linux kernel version: 2.6.14-rc5-pa1 +# Fri Oct 21 23:06:31 2005 # CONFIG_PARISC=y CONFIG_MMU=y @@ -10,11 +10,14 @@ CONFIG_RWSEM_GENERIC_SPINLOCK=y CONFIG_GENERIC_CALIBRATE_DELAY=y CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_ARCH_MAY_HAVE_PC_FDC=y # # Code maturity level options # CONFIG_EXPERIMENTAL=y +# CONFIG_CLEAN_COMPILE is not set +CONFIG_BROKEN=y CONFIG_BROKEN_ON_SMP=y CONFIG_INIT_ENV_ARG_LIMIT=32 @@ -29,30 +32,28 @@ CONFIG_SYSVIPC=y # CONFIG_BSD_PROCESS_ACCT is not set CONFIG_SYSCTL=y # CONFIG_AUDIT is not set +CONFIG_HOTPLUG=y +CONFIG_KOBJECT_UEVENT=y CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_INITRAMFS_SOURCE="" -# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set CONFIG_EMBEDDED=y CONFIG_KALLSYMS=y CONFIG_KALLSYMS_ALL=y # CONFIG_KALLSYMS_EXTRA_PASS is not set -CONFIG_HOTPLUG=y CONFIG_PRINTK=y CONFIG_BUG=y -CONFIG_ELF_CORE=y CONFIG_BASE_FULL=y CONFIG_FUTEX=y CONFIG_EPOLL=y +# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set CONFIG_SHMEM=y CONFIG_CC_ALIGN_FUNCTIONS=0 CONFIG_CC_ALIGN_LABELS=0 CONFIG_CC_ALIGN_LOOPS=0 CONFIG_CC_ALIGN_JUMPS=0 -CONFIG_SLAB=y # CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=0 -# CONFIG_SLOB is not set # # Loadable module support @@ -65,23 +66,6 @@ CONFIG_OBSOLETE_MODPARM=y # CONFIG_MODULE_SRCVERSION_ALL is not set CONFIG_KMOD=y -# -# Block layer -# - -# -# IO Schedulers -# -CONFIG_IOSCHED_NOOP=y -CONFIG_IOSCHED_AS=y -CONFIG_IOSCHED_DEADLINE=y -CONFIG_IOSCHED_CFQ=y -CONFIG_DEFAULT_AS=y -# CONFIG_DEFAULT_DEADLINE is not set -# CONFIG_DEFAULT_CFQ is not set -# CONFIG_DEFAULT_NOOP is not set -CONFIG_DEFAULT_IOSCHED="anticipatory" - # # Processor type and features # @@ -94,10 +78,6 @@ CONFIG_PA20=y CONFIG_PREFETCH=y # CONFIG_64BIT is not set # CONFIG_SMP is not set -CONFIG_ARCH_FLATMEM_ENABLE=y -# CONFIG_PREEMPT_NONE is not set -CONFIG_PREEMPT_VOLUNTARY=y -# CONFIG_PREEMPT is not set # CONFIG_HZ_100 is not set CONFIG_HZ_250=y # CONFIG_HZ_1000 is not set @@ -109,7 +89,7 @@ CONFIG_FLATMEM_MANUAL=y CONFIG_FLATMEM=y CONFIG_FLAT_NODE_MEM_MAP=y # CONFIG_SPARSEMEM_STATIC is not set -CONFIG_SPLIT_PTLOCK_CPUS=4 +# CONFIG_PREEMPT is not set # CONFIG_HPUX is not set # @@ -155,7 +135,6 @@ CONFIG_NET=y # # Networking options # -# CONFIG_NETDEBUG is not set CONFIG_PACKET=y CONFIG_PACKET_MMAP=y CONFIG_UNIX=y @@ -196,12 +175,7 @@ CONFIG_INET6_TUNNEL=m CONFIG_IPV6_TUNNEL=m CONFIG_NETFILTER=y CONFIG_NETFILTER_DEBUG=y - -# -# Core Netfilter Configuration -# # CONFIG_NETFILTER_NETLINK is not set -# CONFIG_NETFILTER_XTABLES is not set # # IP: Netfilter Configuration @@ -218,11 +192,87 @@ CONFIG_IP_NF_TFTP=m CONFIG_IP_NF_AMANDA=m # CONFIG_IP_NF_PPTP is not set CONFIG_IP_NF_QUEUE=m +CONFIG_IP_NF_IPTABLES=m +CONFIG_IP_NF_MATCH_LIMIT=m +CONFIG_IP_NF_MATCH_IPRANGE=m +CONFIG_IP_NF_MATCH_MAC=m +CONFIG_IP_NF_MATCH_PKTTYPE=m +CONFIG_IP_NF_MATCH_MARK=m +CONFIG_IP_NF_MATCH_MULTIPORT=m +CONFIG_IP_NF_MATCH_TOS=m +CONFIG_IP_NF_MATCH_RECENT=m +CONFIG_IP_NF_MATCH_ECN=m +CONFIG_IP_NF_MATCH_DSCP=m +CONFIG_IP_NF_MATCH_AH_ESP=m +CONFIG_IP_NF_MATCH_LENGTH=m +CONFIG_IP_NF_MATCH_TTL=m +CONFIG_IP_NF_MATCH_TCPMSS=m +CONFIG_IP_NF_MATCH_HELPER=m +CONFIG_IP_NF_MATCH_STATE=m +CONFIG_IP_NF_MATCH_CONNTRACK=m +CONFIG_IP_NF_MATCH_OWNER=m +# CONFIG_IP_NF_MATCH_ADDRTYPE is not set +# CONFIG_IP_NF_MATCH_REALM is not set +# CONFIG_IP_NF_MATCH_SCTP is not set +# CONFIG_IP_NF_MATCH_DCCP is not set +# CONFIG_IP_NF_MATCH_COMMENT is not set +# CONFIG_IP_NF_MATCH_HASHLIMIT is not set +# CONFIG_IP_NF_MATCH_STRING is not set +CONFIG_IP_NF_FILTER=m +CONFIG_IP_NF_TARGET_REJECT=m +CONFIG_IP_NF_TARGET_LOG=m +CONFIG_IP_NF_TARGET_ULOG=m +CONFIG_IP_NF_TARGET_TCPMSS=m +# CONFIG_IP_NF_TARGET_NFQUEUE is not set +CONFIG_IP_NF_NAT=m +CONFIG_IP_NF_NAT_NEEDED=y +CONFIG_IP_NF_TARGET_MASQUERADE=m +CONFIG_IP_NF_TARGET_REDIRECT=m +CONFIG_IP_NF_TARGET_NETMAP=m +CONFIG_IP_NF_TARGET_SAME=m +CONFIG_IP_NF_NAT_SNMP_BASIC=m +CONFIG_IP_NF_NAT_IRC=m +CONFIG_IP_NF_NAT_FTP=m +CONFIG_IP_NF_NAT_TFTP=m +CONFIG_IP_NF_NAT_AMANDA=m +CONFIG_IP_NF_MANGLE=m +CONFIG_IP_NF_TARGET_TOS=m +CONFIG_IP_NF_TARGET_ECN=m +CONFIG_IP_NF_TARGET_DSCP=m +CONFIG_IP_NF_TARGET_MARK=m +CONFIG_IP_NF_TARGET_CLASSIFY=m +# CONFIG_IP_NF_TARGET_TTL is not set +# CONFIG_IP_NF_RAW is not set +CONFIG_IP_NF_ARPTABLES=m +CONFIG_IP_NF_ARPFILTER=m +CONFIG_IP_NF_ARP_MANGLE=m # # IPv6: Netfilter Configuration (EXPERIMENTAL) # # CONFIG_IP6_NF_QUEUE is not set +CONFIG_IP6_NF_IPTABLES=m +# CONFIG_IP6_NF_MATCH_LIMIT is not set +CONFIG_IP6_NF_MATCH_MAC=m +CONFIG_IP6_NF_MATCH_RT=m +# CONFIG_IP6_NF_MATCH_OPTS is not set +# CONFIG_IP6_NF_MATCH_FRAG is not set +# CONFIG_IP6_NF_MATCH_HL is not set +# CONFIG_IP6_NF_MATCH_MULTIPORT is not set +CONFIG_IP6_NF_MATCH_OWNER=m +# CONFIG_IP6_NF_MATCH_MARK is not set +CONFIG_IP6_NF_MATCH_IPV6HEADER=m +# CONFIG_IP6_NF_MATCH_AHESP is not set +CONFIG_IP6_NF_MATCH_LENGTH=m +# CONFIG_IP6_NF_MATCH_EUI64 is not set +CONFIG_IP6_NF_FILTER=m +CONFIG_IP6_NF_TARGET_LOG=m +CONFIG_IP6_NF_TARGET_REJECT=m +# CONFIG_IP6_NF_TARGET_NFQUEUE is not set +CONFIG_IP6_NF_MANGLE=m +# CONFIG_IP6_NF_TARGET_MARK is not set +# CONFIG_IP6_NF_TARGET_HL is not set +# CONFIG_IP6_NF_RAW is not set # # DCCP Configuration (EXPERIMENTAL) @@ -233,11 +283,6 @@ CONFIG_IP_NF_QUEUE=m # SCTP Configuration (EXPERIMENTAL) # # CONFIG_IP_SCTP is not set - -# -# TIPC Configuration (EXPERIMENTAL) -# -# CONFIG_TIPC is not set # CONFIG_ATM is not set # CONFIG_BRIDGE is not set # CONFIG_VLAN_8021Q is not set @@ -250,11 +295,8 @@ CONFIG_IP_NF_QUEUE=m # CONFIG_NET_DIVERT is not set # CONFIG_ECONET is not set # CONFIG_WAN_ROUTER is not set - -# -# QoS and/or fair queueing -# # CONFIG_NET_SCHED is not set +# CONFIG_NET_CLS_ROUTE is not set # # Network testing @@ -299,6 +341,7 @@ CONFIG_FW_LOADER=y # # Block devices # +# CONFIG_BLK_DEV_FD is not set # CONFIG_BLK_CPQ_DA is not set # CONFIG_BLK_CPQ_CISS_DA is not set # CONFIG_BLK_DEV_DAC960 is not set @@ -312,6 +355,14 @@ CONFIG_BLK_DEV_CRYPTOLOOP=m # CONFIG_BLK_DEV_RAM is not set CONFIG_BLK_DEV_RAM_COUNT=16 # CONFIG_CDROM_PKTCDVD is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y # CONFIG_ATA_OVER_ETH is not set # @@ -407,7 +458,6 @@ CONFIG_SCSI_ISCSI_ATTRS=m # # SCSI low-level drivers # -# CONFIG_ISCSI_TCP is not set # CONFIG_BLK_DEV_3W_XXXX_RAID is not set # CONFIG_SCSI_3W_9XXX is not set # CONFIG_SCSI_ACARD is not set @@ -416,6 +466,7 @@ CONFIG_SCSI_ISCSI_ATTRS=m # CONFIG_SCSI_AIC7XXX_OLD is not set # CONFIG_SCSI_AIC79XX is not set # CONFIG_SCSI_DPT_I2O is not set +# CONFIG_SCSI_ADVANSYS is not set # CONFIG_MEGARAID_NEWGEN is not set # CONFIG_MEGARAID_LEGACY is not set # CONFIG_MEGARAID_SAS is not set @@ -425,18 +476,18 @@ CONFIG_SCSI_SATA=y CONFIG_SCSI_ATA_PIIX=m # CONFIG_SCSI_SATA_MV is not set # CONFIG_SCSI_SATA_NV is not set -# CONFIG_SCSI_PDC_ADMA is not set -# CONFIG_SCSI_SATA_QSTOR is not set CONFIG_SCSI_SATA_PROMISE=m +# CONFIG_SCSI_SATA_QSTOR is not set # CONFIG_SCSI_SATA_SX4 is not set CONFIG_SCSI_SATA_SIL=m -# CONFIG_SCSI_SATA_SIL24 is not set # CONFIG_SCSI_SATA_SIS is not set # CONFIG_SCSI_SATA_ULI is not set CONFIG_SCSI_SATA_VIA=m # CONFIG_SCSI_SATA_VITESSE is not set CONFIG_SCSI_SATA_INTEL_COMBINED=y +# CONFIG_SCSI_CPQFCTS is not set # CONFIG_SCSI_DMX3191D is not set +# CONFIG_SCSI_EATA_PIO is not set # CONFIG_SCSI_FUTURE_DOMAIN is not set # CONFIG_SCSI_IPS is not set # CONFIG_SCSI_INITIO is not set @@ -445,11 +496,18 @@ CONFIG_SCSI_SYM53C8XX_2=y CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=0 CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16 CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64 -CONFIG_SCSI_SYM53C8XX_MMIO=y +# CONFIG_SCSI_SYM53C8XX_IOMAPPED is not set # CONFIG_SCSI_IPR is not set +# CONFIG_SCSI_QLOGIC_ISP is not set # CONFIG_SCSI_QLOGIC_FC is not set # CONFIG_SCSI_QLOGIC_1280 is not set -# CONFIG_SCSI_QLA_FC is not set +CONFIG_SCSI_QLA2XXX=y +# CONFIG_SCSI_QLA21XX is not set +# CONFIG_SCSI_QLA22XX is not set +# CONFIG_SCSI_QLA2300 is not set +# CONFIG_SCSI_QLA2322 is not set +# CONFIG_SCSI_QLA6312 is not set +# CONFIG_SCSI_QLA24XX is not set # CONFIG_SCSI_LPFC is not set # CONFIG_SCSI_DC395x is not set # CONFIG_SCSI_DC390T is not set @@ -575,7 +633,6 @@ CONFIG_E1000=m # CONFIG_R8169 is not set # CONFIG_SIS190 is not set # CONFIG_SKGE is not set -# CONFIG_SKY2 is not set # CONFIG_SK98LIN is not set # CONFIG_VIA_VELOCITY is not set CONFIG_TIGON3=m @@ -611,7 +668,6 @@ CONFIG_PPP_ASYNC=m CONFIG_PPP_SYNC_TTY=m CONFIG_PPP_DEFLATE=m CONFIG_PPP_BSDCOMP=m -# CONFIG_PPP_MPPE is not set CONFIG_PPPOE=m # CONFIG_SLIP is not set # CONFIG_NET_FC is not set @@ -688,7 +744,6 @@ CONFIG_HW_CONSOLE=y CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_8250_NR_UARTS=13 -CONFIG_SERIAL_8250_RUNTIME_UARTS=4 CONFIG_SERIAL_8250_EXTENDED=y CONFIG_SERIAL_8250_MANY_PORTS=y CONFIG_SERIAL_8250_SHARE_IRQ=y @@ -698,6 +753,7 @@ CONFIG_SERIAL_8250_SHARE_IRQ=y # # Non-8250 serial port support # +# CONFIG_SERIAL_MUX is not set # CONFIG_PDC_CONSOLE is not set CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y @@ -732,19 +788,12 @@ CONFIG_MAX_RAW_DEVS=256 # TPM devices # # CONFIG_TCG_TPM is not set -# CONFIG_TELCLOCK is not set # # I2C support # # CONFIG_I2C is not set -# -# SPI support -# -# CONFIG_SPI is not set -# CONFIG_SPI_MASTER is not set - # # Dallas's 1-wire bus # @@ -781,6 +830,7 @@ CONFIG_FB=y CONFIG_FB_CFB_FILLRECT=y CONFIG_FB_CFB_COPYAREA=y CONFIG_FB_CFB_IMAGEBLIT=y +CONFIG_FB_SOFT_CURSOR=y # CONFIG_FB_MACMODES is not set # CONFIG_FB_MODE_HELPERS is not set # CONFIG_FB_TILEBLITTING is not set @@ -790,7 +840,6 @@ CONFIG_FB_CFB_IMAGEBLIT=y # CONFIG_FB_ASILIANT is not set # CONFIG_FB_IMSTT is not set CONFIG_FB_STI=y -# CONFIG_FB_S1D13XXX is not set # CONFIG_FB_NVIDIA is not set # CONFIG_FB_RIVA is not set # CONFIG_FB_MATROX is not set @@ -804,7 +853,10 @@ CONFIG_FB_STI=y # CONFIG_FB_KYRO is not set # CONFIG_FB_3DFX is not set # CONFIG_FB_VOODOO1 is not set +# CONFIG_FB_CYBLA is not set # CONFIG_FB_TRIDENT is not set +# CONFIG_FB_PM3 is not set +# CONFIG_FB_S1D13XXX is not set # CONFIG_FB_VIRTUAL is not set # @@ -814,7 +866,6 @@ CONFIG_DUMMY_CONSOLE=y CONFIG_DUMMY_CONSOLE_COLUMNS=160 CONFIG_DUMMY_CONSOLE_ROWS=64 CONFIG_FRAMEBUFFER_CONSOLE=y -# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set CONFIG_STI_CONSOLE=y # CONFIG_FONTS is not set CONFIG_FONT_8x8=y @@ -847,27 +898,23 @@ CONFIG_SND_OSSEMUL=y CONFIG_SND_MIXER_OSS=y CONFIG_SND_PCM_OSS=y CONFIG_SND_SEQUENCER_OSS=y -# CONFIG_SND_DYNAMIC_MINORS is not set -CONFIG_SND_SUPPORT_OLD_API=y # CONFIG_SND_VERBOSE_PRINTK is not set # CONFIG_SND_DEBUG is not set # # Generic devices # -CONFIG_SND_AC97_CODEC=y -CONFIG_SND_AC97_BUS=y # CONFIG_SND_DUMMY is not set # CONFIG_SND_VIRMIDI is not set # CONFIG_SND_MTPAV is not set # CONFIG_SND_SERIAL_U16550 is not set # CONFIG_SND_MPU401 is not set +CONFIG_SND_AC97_CODEC=y +CONFIG_SND_AC97_BUS=y # # PCI devices # -CONFIG_SND_AD1889=y -# CONFIG_SND_AD1889_OPL3 is not set # CONFIG_SND_ALI5451 is not set # CONFIG_SND_ATIIXP is not set # CONFIG_SND_ATIIXP_MODEM is not set @@ -876,38 +923,39 @@ CONFIG_SND_AD1889=y # CONFIG_SND_AU8830 is not set # CONFIG_SND_AZT3328 is not set # CONFIG_SND_BT87X is not set -# CONFIG_SND_CA0106 is not set -# CONFIG_SND_CMIPCI is not set -# CONFIG_SND_CS4281 is not set # CONFIG_SND_CS46XX is not set +# CONFIG_SND_CS4281 is not set # CONFIG_SND_EMU10K1 is not set # CONFIG_SND_EMU10K1X is not set +# CONFIG_SND_CA0106 is not set +# CONFIG_SND_KORG1212 is not set +# CONFIG_SND_MIXART is not set +# CONFIG_SND_NM256 is not set +# CONFIG_SND_RME32 is not set +# CONFIG_SND_RME96 is not set +# CONFIG_SND_RME9652 is not set +# CONFIG_SND_HDSP is not set +# CONFIG_SND_HDSPM is not set +# CONFIG_SND_TRIDENT is not set +# CONFIG_SND_YMFPCI is not set +CONFIG_SND_AD1889=y +# CONFIG_SND_AD1889_OPL3 is not set +# CONFIG_SND_CMIPCI is not set # CONFIG_SND_ENS1370 is not set # CONFIG_SND_ENS1371 is not set # CONFIG_SND_ES1938 is not set # CONFIG_SND_ES1968 is not set +# CONFIG_SND_MAESTRO3 is not set # CONFIG_SND_FM801 is not set -# CONFIG_SND_HDA_INTEL is not set -# CONFIG_SND_HDSP is not set -# CONFIG_SND_HDSPM is not set # CONFIG_SND_ICE1712 is not set # CONFIG_SND_ICE1724 is not set # CONFIG_SND_INTEL8X0 is not set # CONFIG_SND_INTEL8X0M is not set -# CONFIG_SND_KORG1212 is not set -# CONFIG_SND_MAESTRO3 is not set -# CONFIG_SND_MIXART is not set -# CONFIG_SND_NM256 is not set -# CONFIG_SND_PCXHR is not set -# CONFIG_SND_RME32 is not set -# CONFIG_SND_RME96 is not set -# CONFIG_SND_RME9652 is not set # CONFIG_SND_SONICVIBES is not set -# CONFIG_SND_TRIDENT is not set # CONFIG_SND_VIA82XX is not set # CONFIG_SND_VIA82XX_MODEM is not set # CONFIG_SND_VX222 is not set -# CONFIG_SND_YMFPCI is not set +# CONFIG_SND_HDA_INTEL is not set # # USB devices @@ -950,15 +998,12 @@ CONFIG_USB_OHCI_LITTLE_ENDIAN=y # USB Device Class drivers # # CONFIG_OBSOLETE_OSS_USB_DRIVER is not set +# CONFIG_USB_BLUETOOTH_TTY is not set # CONFIG_USB_ACM is not set CONFIG_USB_PRINTER=m # -# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' -# - -# -# may also be needed; see USB_STORAGE Help for more information +# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information # CONFIG_USB_STORAGE=m # CONFIG_USB_STORAGE_DEBUG is not set @@ -970,15 +1015,12 @@ CONFIG_USB_STORAGE_USBAT=y CONFIG_USB_STORAGE_SDDR09=y CONFIG_USB_STORAGE_SDDR55=y CONFIG_USB_STORAGE_JUMPSHOT=y -# CONFIG_USB_STORAGE_ALAUDA is not set -# CONFIG_USB_LIBUSUAL is not set # # USB Input Devices # CONFIG_USB_HID=y CONFIG_USB_HIDINPUT=y -# CONFIG_USB_HIDINPUT_POWERBOOK is not set # CONFIG_HID_FF is not set CONFIG_USB_HIDDEV=y # CONFIG_USB_AIPTEK is not set @@ -992,7 +1034,6 @@ CONFIG_USB_HIDDEV=y # CONFIG_USB_YEALINK is not set # CONFIG_USB_XPAD is not set # CONFIG_USB_ATI_REMOTE is not set -# CONFIG_USB_ATI_REMOTE2 is not set # CONFIG_USB_KEYSPAN_REMOTE is not set # CONFIG_USB_APPLETOUCH is not set @@ -1067,7 +1108,7 @@ CONFIG_USB_LEGOTOWER=m # CONFIG_INFINIBAND is not set # -# EDAC - error detection and reporting (RAS) (EXPERIMENTAL) +# SN Devices # # @@ -1089,7 +1130,6 @@ CONFIG_XFS_EXPORT=y # CONFIG_XFS_SECURITY is not set # CONFIG_XFS_POSIX_ACL is not set # CONFIG_XFS_RT is not set -# CONFIG_OCFS2_FS is not set # CONFIG_MINIX_FS is not set # CONFIG_ROMFS_FS is not set CONFIG_INOTIFY=y @@ -1124,10 +1164,10 @@ CONFIG_PROC_FS=y CONFIG_PROC_KCORE=y CONFIG_SYSFS=y CONFIG_TMPFS=y +# CONFIG_HUGETLBFS is not set # CONFIG_HUGETLB_PAGE is not set CONFIG_RAMFS=y # CONFIG_RELAYFS_FS is not set -# CONFIG_CONFIGFS_FS is not set # # Miscellaneous filesystems @@ -1185,10 +1225,10 @@ CONFIG_MSDOS_PARTITION=y # CONFIG_NLS=y CONFIG_NLS_DEFAULT="iso8859-1" -CONFIG_NLS_CODEPAGE_437=m +# CONFIG_NLS_CODEPAGE_437 is not set # CONFIG_NLS_CODEPAGE_737 is not set # CONFIG_NLS_CODEPAGE_775 is not set -CONFIG_NLS_CODEPAGE_850=m +# CONFIG_NLS_CODEPAGE_850 is not set # CONFIG_NLS_CODEPAGE_852 is not set # CONFIG_NLS_CODEPAGE_855 is not set # CONFIG_NLS_CODEPAGE_857 is not set @@ -1208,8 +1248,8 @@ CONFIG_NLS_CODEPAGE_850=m # CONFIG_NLS_ISO8859_8 is not set # CONFIG_NLS_CODEPAGE_1250 is not set # CONFIG_NLS_CODEPAGE_1251 is not set -CONFIG_NLS_ASCII=m -CONFIG_NLS_ISO8859_1=m +# CONFIG_NLS_ASCII is not set +# CONFIG_NLS_ISO8859_1 is not set # CONFIG_NLS_ISO8859_2 is not set # CONFIG_NLS_ISO8859_3 is not set # CONFIG_NLS_ISO8859_4 is not set @@ -1219,10 +1259,10 @@ CONFIG_NLS_ISO8859_1=m # CONFIG_NLS_ISO8859_9 is not set # CONFIG_NLS_ISO8859_13 is not set # CONFIG_NLS_ISO8859_14 is not set -CONFIG_NLS_ISO8859_15=m +# CONFIG_NLS_ISO8859_15 is not set # CONFIG_NLS_KOI8_R is not set # CONFIG_NLS_KOI8_U is not set -CONFIG_NLS_UTF8=m +# CONFIG_NLS_UTF8 is not set # # Profiling support @@ -1234,22 +1274,18 @@ CONFIG_OPROFILE=m # Kernel hacking # # CONFIG_PRINTK_TIME is not set -CONFIG_MAGIC_SYSRQ=y CONFIG_DEBUG_KERNEL=y +CONFIG_MAGIC_SYSRQ=y CONFIG_LOG_BUF_SHIFT=16 CONFIG_DETECT_SOFTLOCKUP=y # CONFIG_SCHEDSTATS is not set # CONFIG_DEBUG_SLAB is not set -CONFIG_DEBUG_MUTEXES=y # CONFIG_DEBUG_SPINLOCK is not set # CONFIG_DEBUG_SPINLOCK_SLEEP is not set # CONFIG_DEBUG_KOBJECT is not set # CONFIG_DEBUG_INFO is not set +# CONFIG_DEBUG_IOREMAP is not set # CONFIG_DEBUG_FS is not set -# CONFIG_DEBUG_VM is not set -CONFIG_FORCED_INLINING=y -# CONFIG_RCU_TORTURE_TEST is not set -CONFIG_DEBUG_RODATA=y # # Security options diff --git a/trunk/arch/parisc/defconfig b/trunk/arch/parisc/defconfig index 59f7bc38e72e..f38a4620d24f 100644 --- a/trunk/arch/parisc/defconfig +++ b/trunk/arch/parisc/defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.16-pa6 -# Sun Mar 26 19:50:07 2006 +# Linux kernel version: 2.6.14-rc5-pa1 +# Fri Oct 21 23:01:33 2005 # CONFIG_PARISC=y CONFIG_MMU=y @@ -15,6 +15,7 @@ CONFIG_GENERIC_IRQ_PROBE=y # Code maturity level options # CONFIG_EXPERIMENTAL=y +CONFIG_CLEAN_COMPILE=y CONFIG_BROKEN_ON_SMP=y CONFIG_INIT_ENV_ARG_LIMIT=32 @@ -29,18 +30,17 @@ CONFIG_SYSVIPC=y # CONFIG_BSD_PROCESS_ACCT is not set CONFIG_SYSCTL=y # CONFIG_AUDIT is not set +# CONFIG_HOTPLUG is not set +CONFIG_KOBJECT_UEVENT=y CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_INITRAMFS_SOURCE="" -CONFIG_CC_OPTIMIZE_FOR_SIZE=y # CONFIG_EMBEDDED is not set CONFIG_KALLSYMS=y # CONFIG_KALLSYMS_ALL is not set # CONFIG_KALLSYMS_EXTRA_PASS is not set -CONFIG_HOTPLUG=y CONFIG_PRINTK=y CONFIG_BUG=y -CONFIG_ELF_CORE=y CONFIG_BASE_FULL=y CONFIG_FUTEX=y CONFIG_EPOLL=y @@ -49,33 +49,14 @@ CONFIG_CC_ALIGN_FUNCTIONS=0 CONFIG_CC_ALIGN_LABELS=0 CONFIG_CC_ALIGN_LOOPS=0 CONFIG_CC_ALIGN_JUMPS=0 -CONFIG_SLAB=y # CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=0 -# CONFIG_SLOB is not set # # Loadable module support # # CONFIG_MODULES is not set -# -# Block layer -# - -# -# IO Schedulers -# -CONFIG_IOSCHED_NOOP=y -CONFIG_IOSCHED_AS=y -CONFIG_IOSCHED_DEADLINE=y -CONFIG_IOSCHED_CFQ=y -CONFIG_DEFAULT_AS=y -# CONFIG_DEFAULT_DEADLINE is not set -# CONFIG_DEFAULT_CFQ is not set -# CONFIG_DEFAULT_NOOP is not set -CONFIG_DEFAULT_IOSCHED="anticipatory" - # # Processor type and features # @@ -86,10 +67,6 @@ CONFIG_PA7000=y # CONFIG_PA8X00 is not set CONFIG_PA11=y # CONFIG_SMP is not set -CONFIG_ARCH_FLATMEM_ENABLE=y -CONFIG_PREEMPT_NONE=y -# CONFIG_PREEMPT_VOLUNTARY is not set -# CONFIG_PREEMPT is not set # CONFIG_HZ_100 is not set CONFIG_HZ_250=y # CONFIG_HZ_1000 is not set @@ -101,7 +78,7 @@ CONFIG_FLATMEM_MANUAL=y CONFIG_FLATMEM=y CONFIG_FLAT_NODE_MEM_MAP=y # CONFIG_SPARSEMEM_STATIC is not set -CONFIG_SPLIT_PTLOCK_CPUS=4096 +# CONFIG_PREEMPT is not set # CONFIG_HPUX is not set # @@ -155,7 +132,6 @@ CONFIG_NET=y # # Networking options # -# CONFIG_NETDEBUG is not set CONFIG_PACKET=y CONFIG_PACKET_MMAP=y CONFIG_UNIX=y @@ -198,11 +174,6 @@ CONFIG_IPV6=y # SCTP Configuration (EXPERIMENTAL) # # CONFIG_IP_SCTP is not set - -# -# TIPC Configuration (EXPERIMENTAL) -# -# CONFIG_TIPC is not set # CONFIG_ATM is not set # CONFIG_BRIDGE is not set # CONFIG_VLAN_8021Q is not set @@ -215,11 +186,8 @@ CONFIG_IPV6=y # CONFIG_NET_DIVERT is not set # CONFIG_ECONET is not set # CONFIG_WAN_ROUTER is not set - -# -# QoS and/or fair queueing -# # CONFIG_NET_SCHED is not set +# CONFIG_NET_CLS_ROUTE is not set # # Network testing @@ -260,7 +228,6 @@ CONFIG_PARPORT_PC=y # CONFIG_PARPORT_SERIAL is not set # CONFIG_PARPORT_PC_FIFO is not set # CONFIG_PARPORT_PC_SUPERIO is not set -CONFIG_PARPORT_NOT_PC=y CONFIG_PARPORT_GSC=y # CONFIG_PARPORT_1284 is not set @@ -287,6 +254,14 @@ CONFIG_BLK_DEV_RAM_COUNT=16 CONFIG_BLK_DEV_RAM_SIZE=4096 CONFIG_BLK_DEV_INITRD=y # CONFIG_CDROM_PKTCDVD is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y # CONFIG_ATA_OVER_ETH is not set # @@ -330,7 +305,6 @@ CONFIG_SCSI_SPI_ATTRS=y # # SCSI low-level drivers # -# CONFIG_ISCSI_TCP is not set # CONFIG_BLK_DEV_3W_XXXX_RAID is not set # CONFIG_SCSI_3W_9XXX is not set # CONFIG_SCSI_ACARD is not set @@ -357,7 +331,7 @@ CONFIG_SCSI_SYM53C8XX_2=y CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=1 CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16 CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64 -CONFIG_SCSI_SYM53C8XX_MMIO=y +# CONFIG_SCSI_SYM53C8XX_IOMAPPED is not set # CONFIG_SCSI_IPR is not set CONFIG_SCSI_ZALON=y CONFIG_SCSI_NCR53C8XX_DEFAULT_TAGS=8 @@ -366,7 +340,13 @@ CONFIG_SCSI_NCR53C8XX_SYNC=20 # CONFIG_SCSI_NCR53C8XX_PROFILE is not set # CONFIG_SCSI_QLOGIC_FC is not set # CONFIG_SCSI_QLOGIC_1280 is not set -# CONFIG_SCSI_QLA_FC is not set +CONFIG_SCSI_QLA2XXX=y +# CONFIG_SCSI_QLA21XX is not set +# CONFIG_SCSI_QLA22XX is not set +# CONFIG_SCSI_QLA2300 is not set +# CONFIG_SCSI_QLA2322 is not set +# CONFIG_SCSI_QLA6312 is not set +# CONFIG_SCSI_QLA24XX is not set # CONFIG_SCSI_LPFC is not set # CONFIG_SCSI_SIM710 is not set # CONFIG_SCSI_DC395x is not set @@ -491,7 +471,6 @@ CONFIG_ACENIC=y # CONFIG_R8169 is not set # CONFIG_SIS190 is not set # CONFIG_SKGE is not set -# CONFIG_SKY2 is not set # CONFIG_SK98LIN is not set # CONFIG_VIA_VELOCITY is not set CONFIG_TIGON3=y @@ -583,13 +562,13 @@ CONFIG_INPUT_KEYBOARD=y # CONFIG_KEYBOARD_LKKBD is not set # CONFIG_KEYBOARD_XTKBD is not set # CONFIG_KEYBOARD_NEWTON is not set -# CONFIG_KEYBOARD_HIL_OLD is not set +CONFIG_KEYBOARD_HIL_OLD=y CONFIG_KEYBOARD_HIL=y CONFIG_INPUT_MOUSE=y # CONFIG_MOUSE_PS2 is not set # CONFIG_MOUSE_SERIAL is not set # CONFIG_MOUSE_VSXXXAA is not set -CONFIG_MOUSE_HIL=y +# CONFIG_MOUSE_HIL is not set CONFIG_INPUT_JOYSTICK=y # CONFIG_JOYSTICK_ANALOG is not set # CONFIG_JOYSTICK_A3D is not set @@ -649,7 +628,6 @@ CONFIG_HW_CONSOLE=y CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_8250_NR_UARTS=13 -CONFIG_SERIAL_8250_RUNTIME_UARTS=4 CONFIG_SERIAL_8250_EXTENDED=y CONFIG_SERIAL_8250_MANY_PORTS=y CONFIG_SERIAL_8250_SHARE_IRQ=y @@ -697,19 +675,12 @@ CONFIG_GEN_RTC=y # TPM devices # # CONFIG_TCG_TPM is not set -# CONFIG_TELCLOCK is not set # # I2C support # # CONFIG_I2C is not set -# -# SPI support -# -# CONFIG_SPI is not set -# CONFIG_SPI_MASTER is not set - # # Dallas's 1-wire bus # @@ -720,7 +691,6 @@ CONFIG_GEN_RTC=y # CONFIG_HWMON=y # CONFIG_HWMON_VID is not set -# CONFIG_SENSORS_F71805F is not set # CONFIG_HWMON_DEBUG_CHIP is not set # @@ -748,6 +718,7 @@ CONFIG_FB=y CONFIG_FB_CFB_FILLRECT=y CONFIG_FB_CFB_COPYAREA=y CONFIG_FB_CFB_IMAGEBLIT=y +CONFIG_FB_SOFT_CURSOR=y # CONFIG_FB_MACMODES is not set # CONFIG_FB_MODE_HELPERS is not set # CONFIG_FB_TILEBLITTING is not set @@ -757,7 +728,6 @@ CONFIG_FB_CFB_IMAGEBLIT=y # CONFIG_FB_ASILIANT is not set # CONFIG_FB_IMSTT is not set CONFIG_FB_STI=y -# CONFIG_FB_S1D13XXX is not set # CONFIG_FB_NVIDIA is not set # CONFIG_FB_RIVA is not set # CONFIG_FB_MATROX is not set @@ -771,7 +741,9 @@ CONFIG_FB_STI=y # CONFIG_FB_KYRO is not set # CONFIG_FB_3DFX is not set # CONFIG_FB_VOODOO1 is not set +# CONFIG_FB_CYBLA is not set # CONFIG_FB_TRIDENT is not set +# CONFIG_FB_S1D13XXX is not set # CONFIG_FB_VIRTUAL is not set # @@ -781,28 +753,15 @@ CONFIG_DUMMY_CONSOLE=y CONFIG_DUMMY_CONSOLE_COLUMNS=160 CONFIG_DUMMY_CONSOLE_ROWS=64 CONFIG_FRAMEBUFFER_CONSOLE=y -# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set CONFIG_STI_CONSOLE=y -CONFIG_FONTS=y -# CONFIG_FONT_8x8 is not set +# CONFIG_FONTS is not set +CONFIG_FONT_8x8=y CONFIG_FONT_8x16=y -# CONFIG_FONT_6x11 is not set -# CONFIG_FONT_7x14 is not set -# CONFIG_FONT_PEARL_8x8 is not set -# CONFIG_FONT_ACORN_8x8 is not set -# CONFIG_FONT_MINI_4x6 is not set -# CONFIG_FONT_SUN8x16 is not set -# CONFIG_FONT_SUN12x22 is not set -# CONFIG_FONT_10x18 is not set # # Logo configuration # -CONFIG_LOGO=y -# CONFIG_LOGO_LINUX_MONO is not set -# CONFIG_LOGO_LINUX_VGA16 is not set -# CONFIG_LOGO_LINUX_CLUT224 is not set -CONFIG_LOGO_PARISC_CLUT224=y +# CONFIG_LOGO is not set # CONFIG_BACKLIGHT_LCD_SUPPORT is not set # @@ -822,27 +781,23 @@ CONFIG_SND_OSSEMUL=y CONFIG_SND_MIXER_OSS=y CONFIG_SND_PCM_OSS=y CONFIG_SND_SEQUENCER_OSS=y -# CONFIG_SND_DYNAMIC_MINORS is not set -CONFIG_SND_SUPPORT_OLD_API=y # CONFIG_SND_VERBOSE_PRINTK is not set # CONFIG_SND_DEBUG is not set # # Generic devices # -CONFIG_SND_AC97_CODEC=y -CONFIG_SND_AC97_BUS=y # CONFIG_SND_DUMMY is not set # CONFIG_SND_VIRMIDI is not set # CONFIG_SND_MTPAV is not set # CONFIG_SND_SERIAL_U16550 is not set # CONFIG_SND_MPU401 is not set +CONFIG_SND_AC97_CODEC=y +CONFIG_SND_AC97_BUS=y # # PCI devices # -CONFIG_SND_AD1889=y -# CONFIG_SND_AD1889_OPL3 is not set # CONFIG_SND_ALI5451 is not set # CONFIG_SND_ATIIXP is not set # CONFIG_SND_ATIIXP_MODEM is not set @@ -851,38 +806,39 @@ CONFIG_SND_AD1889=y # CONFIG_SND_AU8830 is not set # CONFIG_SND_AZT3328 is not set # CONFIG_SND_BT87X is not set -# CONFIG_SND_CA0106 is not set -# CONFIG_SND_CMIPCI is not set -# CONFIG_SND_CS4281 is not set # CONFIG_SND_CS46XX is not set +# CONFIG_SND_CS4281 is not set # CONFIG_SND_EMU10K1 is not set # CONFIG_SND_EMU10K1X is not set +# CONFIG_SND_CA0106 is not set +# CONFIG_SND_KORG1212 is not set +# CONFIG_SND_MIXART is not set +# CONFIG_SND_NM256 is not set +# CONFIG_SND_RME32 is not set +# CONFIG_SND_RME96 is not set +# CONFIG_SND_RME9652 is not set +# CONFIG_SND_HDSP is not set +# CONFIG_SND_HDSPM is not set +# CONFIG_SND_TRIDENT is not set +# CONFIG_SND_YMFPCI is not set +CONFIG_SND_AD1889=y +# CONFIG_SND_AD1889_OPL3 is not set +# CONFIG_SND_CMIPCI is not set # CONFIG_SND_ENS1370 is not set # CONFIG_SND_ENS1371 is not set # CONFIG_SND_ES1938 is not set # CONFIG_SND_ES1968 is not set +# CONFIG_SND_MAESTRO3 is not set # CONFIG_SND_FM801 is not set -# CONFIG_SND_HDA_INTEL is not set -# CONFIG_SND_HDSP is not set -# CONFIG_SND_HDSPM is not set # CONFIG_SND_ICE1712 is not set # CONFIG_SND_ICE1724 is not set # CONFIG_SND_INTEL8X0 is not set # CONFIG_SND_INTEL8X0M is not set -# CONFIG_SND_KORG1212 is not set -# CONFIG_SND_MAESTRO3 is not set -# CONFIG_SND_MIXART is not set -# CONFIG_SND_NM256 is not set -# CONFIG_SND_PCXHR is not set -# CONFIG_SND_RME32 is not set -# CONFIG_SND_RME96 is not set -# CONFIG_SND_RME9652 is not set # CONFIG_SND_SONICVIBES is not set -# CONFIG_SND_TRIDENT is not set # CONFIG_SND_VIA82XX is not set # CONFIG_SND_VIA82XX_MODEM is not set # CONFIG_SND_VX222 is not set -# CONFIG_SND_YMFPCI is not set +# CONFIG_SND_HDA_INTEL is not set # # USB devices @@ -932,18 +888,14 @@ CONFIG_USB_OHCI_LITTLE_ENDIAN=y # USB Device Class drivers # # CONFIG_OBSOLETE_OSS_USB_DRIVER is not set +# CONFIG_USB_BLUETOOTH_TTY is not set # CONFIG_USB_ACM is not set # CONFIG_USB_PRINTER is not set # -# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' -# - -# -# may also be needed; see USB_STORAGE Help for more information +# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information # # CONFIG_USB_STORAGE is not set -# CONFIG_USB_LIBUSUAL is not set # # USB Input Devices @@ -966,7 +918,6 @@ CONFIG_USB_OHCI_LITTLE_ENDIAN=y # CONFIG_USB_YEALINK is not set # CONFIG_USB_XPAD is not set # CONFIG_USB_ATI_REMOTE is not set -# CONFIG_USB_ATI_REMOTE2 is not set # CONFIG_USB_KEYSPAN_REMOTE is not set # CONFIG_USB_APPLETOUCH is not set @@ -1043,7 +994,7 @@ CONFIG_USB_MON=y # CONFIG_INFINIBAND is not set # -# EDAC - error detection and reporting (RAS) (EXPERIMENTAL) +# SN Devices # # @@ -1060,7 +1011,6 @@ CONFIG_JBD=y # CONFIG_JFS_FS is not set # CONFIG_FS_POSIX_ACL is not set # CONFIG_XFS_FS is not set -# CONFIG_OCFS2_FS is not set # CONFIG_MINIX_FS is not set # CONFIG_ROMFS_FS is not set CONFIG_INOTIFY=y @@ -1095,7 +1045,6 @@ CONFIG_TMPFS=y # CONFIG_HUGETLB_PAGE is not set CONFIG_RAMFS=y # CONFIG_RELAYFS_FS is not set -# CONFIG_CONFIGFS_FS is not set # # Miscellaneous filesystems @@ -1202,22 +1151,18 @@ CONFIG_OPROFILE=y # Kernel hacking # # CONFIG_PRINTK_TIME is not set -CONFIG_MAGIC_SYSRQ=y CONFIG_DEBUG_KERNEL=y +CONFIG_MAGIC_SYSRQ=y CONFIG_LOG_BUF_SHIFT=15 CONFIG_DETECT_SOFTLOCKUP=y # CONFIG_SCHEDSTATS is not set # CONFIG_DEBUG_SLAB is not set -CONFIG_DEBUG_MUTEXES=y # CONFIG_DEBUG_SPINLOCK is not set # CONFIG_DEBUG_SPINLOCK_SLEEP is not set # CONFIG_DEBUG_KOBJECT is not set # CONFIG_DEBUG_INFO is not set +# CONFIG_DEBUG_IOREMAP is not set # CONFIG_DEBUG_FS is not set -# CONFIG_DEBUG_VM is not set -CONFIG_FORCED_INLINING=y -# CONFIG_RCU_TORTURE_TEST is not set -CONFIG_DEBUG_RODATA=y # # Security options diff --git a/trunk/arch/parisc/kernel/cache.c b/trunk/arch/parisc/kernel/cache.c index 360b7391cb8c..d8a4ca021aac 100644 --- a/trunk/arch/parisc/kernel/cache.c +++ b/trunk/arch/parisc/kernel/cache.c @@ -89,7 +89,7 @@ update_mmu_cache(struct vm_area_struct *vma, unsigned long address, pte_t pte) if (pfn_valid(page_to_pfn(page)) && page_mapping(page) && test_bit(PG_dcache_dirty, &page->flags)) { - flush_kernel_dcache_page(page); + flush_kernel_dcache_page(page_address(page)); clear_bit(PG_dcache_dirty, &page->flags); } } @@ -278,7 +278,7 @@ void flush_dcache_page(struct page *page) return; } - flush_kernel_dcache_page(page); + flush_kernel_dcache_page(page_address(page)); if (!mapping) return; @@ -317,7 +317,7 @@ EXPORT_SYMBOL(flush_dcache_page); /* Defined in arch/parisc/kernel/pacache.S */ EXPORT_SYMBOL(flush_kernel_dcache_range_asm); -EXPORT_SYMBOL(flush_kernel_dcache_page_asm); +EXPORT_SYMBOL(flush_kernel_dcache_page); EXPORT_SYMBOL(flush_data_cache_local); EXPORT_SYMBOL(flush_kernel_icache_range_asm); diff --git a/trunk/arch/parisc/kernel/entry.S b/trunk/arch/parisc/kernel/entry.S index 7c95d7663c29..9af4b22a6d77 100644 --- a/trunk/arch/parisc/kernel/entry.S +++ b/trunk/arch/parisc/kernel/entry.S @@ -563,10 +563,10 @@ extrd,u,*= \pte,_PAGE_GATEWAY_BIT+32,1,%r0 depd %r0,11,2,\prot /* If Gateway, Set PL2 to 0 */ - /* Get rid of prot bits and convert to page addr for iitlbt and idtlbt */ + /* Get rid of prot bits and convert to page addr for iitlbt */ depd %r0,63,PAGE_SHIFT,\pte - extrd,s \pte,(63-PAGE_SHIFT)+(63-58),64-PAGE_SHIFT,\pte + extrd,u \pte,56,32,\pte .endm /* Identical macro to make_insert_tlb above, except it @@ -584,7 +584,7 @@ /* Get rid of prot bits and convert to page addr for iitlba */ - depi 0,31,PAGE_SHIFT,\pte + depi 0,31,12,\pte extru \pte,24,25,\pte .endm @@ -1014,21 +1014,14 @@ intr_restore: nop nop -#ifndef CONFIG_PREEMPT -# define intr_do_preempt intr_restore -#endif /* !CONFIG_PREEMPT */ - .import schedule,code intr_do_resched: - /* Only call schedule on return to userspace. If we're returning - * to kernel space, we may schedule if CONFIG_PREEMPT, otherwise - * we jump back to intr_restore. - */ + /* Only do reschedule if we are returning to user space */ LDREG PT_IASQ0(%r16), %r20 - CMPIB= 0, %r20, intr_do_preempt + CMPIB= 0,%r20,intr_restore /* backward */ nop LDREG PT_IASQ1(%r16), %r20 - CMPIB= 0, %r20, intr_do_preempt + CMPIB= 0,%r20,intr_restore /* backward */ nop #ifdef CONFIG_64BIT @@ -1044,32 +1037,6 @@ intr_do_resched: #endif ldo R%intr_check_sig(%r2), %r2 - /* preempt the current task on returning to kernel - * mode from an interrupt, iff need_resched is set, - * and preempt_count is 0. otherwise, we continue on - * our merry way back to the current running task. - */ -#ifdef CONFIG_PREEMPT - .import preempt_schedule_irq,code -intr_do_preempt: - rsm PSW_SM_I, %r0 /* disable interrupts */ - - /* current_thread_info()->preempt_count */ - mfctl %cr30, %r1 - LDREG TI_PRE_COUNT(%r1), %r19 - CMPIB<> 0, %r19, intr_restore /* if preempt_count > 0 */ - nop /* prev insn branched backwards */ - - /* check if we interrupted a critical path */ - LDREG PT_PSW(%r16), %r20 - bb,<,n %r20, 31 - PSW_SM_I, intr_restore - nop - - BL preempt_schedule_irq, %r2 - nop - - b intr_restore /* ssm PSW_SM_I done by intr_restore */ -#endif /* CONFIG_PREEMPT */ .import do_signal,code intr_do_signal: diff --git a/trunk/arch/parisc/kernel/pacache.S b/trunk/arch/parisc/kernel/pacache.S index 7a4f07e8d3c3..9534ee17b9be 100644 --- a/trunk/arch/parisc/kernel/pacache.S +++ b/trunk/arch/parisc/kernel/pacache.S @@ -621,9 +621,9 @@ __clear_user_page_asm: .procend - .export flush_kernel_dcache_page_asm + .export flush_kernel_dcache_page -flush_kernel_dcache_page_asm: +flush_kernel_dcache_page: .proc .callinfo NO_CALLS .entry diff --git a/trunk/arch/parisc/kernel/parisc_ksyms.c b/trunk/arch/parisc/kernel/parisc_ksyms.c index 47ca5c0a323b..1d00c365f2b1 100644 --- a/trunk/arch/parisc/kernel/parisc_ksyms.c +++ b/trunk/arch/parisc/kernel/parisc_ksyms.c @@ -30,7 +30,22 @@ #include #include +EXPORT_SYMBOL(memchr); +EXPORT_SYMBOL(memcmp); +EXPORT_SYMBOL(memmove); +EXPORT_SYMBOL(memscan); EXPORT_SYMBOL(memset); +EXPORT_SYMBOL(strcat); +EXPORT_SYMBOL(strchr); +EXPORT_SYMBOL(strcmp); +EXPORT_SYMBOL(strcpy); +EXPORT_SYMBOL(strlen); +EXPORT_SYMBOL(strncat); +EXPORT_SYMBOL(strncmp); +EXPORT_SYMBOL(strncpy); +EXPORT_SYMBOL(strnlen); +EXPORT_SYMBOL(strrchr); +EXPORT_SYMBOL(strstr); EXPORT_SYMBOL(strpbrk); #include @@ -67,12 +82,16 @@ EXPORT_SYMBOL($global$); #endif #include +EXPORT_SYMBOL(__ioremap); +EXPORT_SYMBOL(iounmap); EXPORT_SYMBOL(memcpy_toio); EXPORT_SYMBOL(memcpy_fromio); EXPORT_SYMBOL(memset_io); #include +EXPORT_SYMBOL(sys_open); EXPORT_SYMBOL(sys_lseek); +EXPORT_SYMBOL(sys_read); EXPORT_SYMBOL(sys_write); #include diff --git a/trunk/arch/parisc/kernel/pdc_chassis.c b/trunk/arch/parisc/kernel/pdc_chassis.c index a45e2e2ffd9f..0cea6958f427 100644 --- a/trunk/arch/parisc/kernel/pdc_chassis.c +++ b/trunk/arch/parisc/kernel/pdc_chassis.c @@ -5,8 +5,9 @@ * Copyright (C) 2002-2004 Thibaut VARENE * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License, version 2, as - * published by the Free Software Foundation. + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/trunk/arch/parisc/kernel/perf.c b/trunk/arch/parisc/kernel/perf.c index ac8ee205c351..53f861c82f93 100644 --- a/trunk/arch/parisc/kernel/perf.c +++ b/trunk/arch/parisc/kernel/perf.c @@ -805,7 +805,7 @@ static int perf_write_image(uint64_t *memaddr) return -1; } - runway = ioremap_nocache(cpu_device->hpa.start, 4096); + runway = ioremap(cpu_device->hpa.start, 4096); /* Merge intrigue bits into Runway STATUS 0 */ tmp64 = __raw_readq(runway + RUNWAY_STATUS) & 0xffecfffffffffffful; diff --git a/trunk/arch/parisc/kernel/syscall_table.S b/trunk/arch/parisc/kernel/syscall_table.S index bbeeb614cfab..89b6c56ea0a8 100644 --- a/trunk/arch/parisc/kernel/syscall_table.S +++ b/trunk/arch/parisc/kernel/syscall_table.S @@ -287,7 +287,7 @@ ENTRY_SAME(chown) /* 180 */ /* setsockopt() used by iptables: SO_SET_REPLACE/SO_SET_ADD_COUNTERS */ ENTRY_COMP(setsockopt) - ENTRY_COMP(getsockopt) + ENTRY_SAME(getsockopt) ENTRY_COMP(sendmsg) ENTRY_COMP(recvmsg) ENTRY_SAME(semop) /* 185 */ diff --git a/trunk/arch/parisc/lib/iomap.c b/trunk/arch/parisc/lib/iomap.c index f4a811690ab3..01bec8fcbd0d 100644 --- a/trunk/arch/parisc/lib/iomap.c +++ b/trunk/arch/parisc/lib/iomap.c @@ -263,7 +263,11 @@ static const struct iomap_ops iomem_ops = { const struct iomap_ops *iomap_ops[8] = { [0] = &ioport_ops, +#ifdef CONFIG_DEBUG_IOREMAP + [6] = &iomem_ops, +#else [7] = &iomem_ops +#endif }; diff --git a/trunk/arch/parisc/mm/init.c b/trunk/arch/parisc/mm/init.c index 3796be67cd53..852eda3953dc 100644 --- a/trunk/arch/parisc/mm/init.c +++ b/trunk/arch/parisc/mm/init.c @@ -1013,9 +1013,9 @@ void flush_tlb_all(void) #ifdef CONFIG_BLK_DEV_INITRD void free_initrd_mem(unsigned long start, unsigned long end) { - if (start >= end) - return; - printk(KERN_INFO "Freeing initrd memory: %ldk freed\n", (end - start) >> 10); +#if 0 + if (start < end) + printk(KERN_INFO "Freeing initrd memory: %ldk freed\n", (end - start) >> 10); for (; start < end; start += PAGE_SIZE) { ClearPageReserved(virt_to_page(start)); init_page_count(virt_to_page(start)); @@ -1023,5 +1023,6 @@ void free_initrd_mem(unsigned long start, unsigned long end) num_physpages++; totalram_pages++; } +#endif } #endif diff --git a/trunk/arch/parisc/mm/ioremap.c b/trunk/arch/parisc/mm/ioremap.c index 0db12818d7bc..edd9a9559cba 100644 --- a/trunk/arch/parisc/mm/ioremap.c +++ b/trunk/arch/parisc/mm/ioremap.c @@ -72,6 +72,7 @@ remap_area_pmd(pmd_t *pmd, unsigned long address, unsigned long size, return 0; } +#if USE_HPPA_IOREMAP static int remap_area_pages(unsigned long address, unsigned long phys_addr, unsigned long size, unsigned long flags) @@ -113,6 +114,31 @@ remap_area_pages(unsigned long address, unsigned long phys_addr, return error; } +#endif /* USE_HPPA_IOREMAP */ + +#ifdef CONFIG_DEBUG_IOREMAP +static unsigned long last = 0; + +void gsc_bad_addr(unsigned long addr) +{ + if (time_after(jiffies, last + HZ*10)) { + printk("gsc_foo() called with bad address 0x%lx\n", addr); + dump_stack(); + last = jiffies; + } +} +EXPORT_SYMBOL(gsc_bad_addr); + +void __raw_bad_addr(const volatile void __iomem *addr) +{ + if (time_after(jiffies, last + HZ*10)) { + printk("__raw_foo() called with bad address 0x%p\n", addr); + dump_stack(); + last = jiffies; + } +} +EXPORT_SYMBOL(__raw_bad_addr); +#endif /* * Generic mapping function (not visible outside): @@ -128,19 +154,26 @@ remap_area_pages(unsigned long address, unsigned long phys_addr, */ void __iomem * __ioremap(unsigned long phys_addr, unsigned long size, unsigned long flags) { - void *addr; - struct vm_struct *area; - unsigned long offset, last_addr; +#if !(USE_HPPA_IOREMAP) -#ifdef CONFIG_EISA unsigned long end = phys_addr + size - 1; /* Support EISA addresses */ - if ((phys_addr >= 0x00080000 && end < 0x000fffff) || - (phys_addr >= 0x00500000 && end < 0x03bfffff)) { - phys_addr |= F_EXTEND(0xfc000000); + if ((phys_addr >= 0x00080000 && end < 0x000fffff) + || (phys_addr >= 0x00500000 && end < 0x03bfffff)) { + phys_addr |= 0xfc000000; } + +#ifdef CONFIG_DEBUG_IOREMAP + return (void __iomem *)(phys_addr - (0x1UL << NYBBLE_SHIFT)); +#else + return (void __iomem *)phys_addr; #endif +#else + void *addr; + struct vm_struct *area; + unsigned long offset, last_addr; + /* Don't allow wraparound or zero size */ last_addr = phys_addr + size - 1; if (!size || last_addr < phys_addr) @@ -184,12 +217,15 @@ void __iomem * __ioremap(unsigned long phys_addr, unsigned long size, unsigned l } return (void __iomem *) (offset + (char *)addr); +#endif } -EXPORT_SYMBOL(__ioremap); void iounmap(void __iomem *addr) { +#if !(USE_HPPA_IOREMAP) + return; +#else if (addr > high_memory) return vfree((void *) (PAGE_MASK & (unsigned long __force) addr)); +#endif } -EXPORT_SYMBOL(iounmap); diff --git a/trunk/arch/powerpc/Kconfig b/trunk/arch/powerpc/Kconfig index 2cdc35ce8045..a433b7126d33 100644 --- a/trunk/arch/powerpc/Kconfig +++ b/trunk/arch/powerpc/Kconfig @@ -491,7 +491,7 @@ config PPC601_SYNC_FIX If in doubt, say Y here. config TAU - bool "On-chip CPU temperature sensor support" + bool "Thermal Management Support" depends on 6xx help G3 and G4 processors have an on-chip temperature sensor called the @@ -500,7 +500,7 @@ config TAU on-die temperature in /proc/cpuinfo if the cpu supports it. Unfortunately, on some chip revisions, this sensor is very inaccurate - and in many cases, does not work at all, so don't assume the cpu + and in some cases, does not work at all, so don't assume the cpu temp is actually what /proc/cpuinfo says it is. config TAU_INT diff --git a/trunk/arch/powerpc/Kconfig.debug b/trunk/arch/powerpc/Kconfig.debug index 8d48e9e7162a..9254806f7032 100644 --- a/trunk/arch/powerpc/Kconfig.debug +++ b/trunk/arch/powerpc/Kconfig.debug @@ -110,6 +110,11 @@ config SERIAL_TEXT_DEBUG depends on 4xx || LOPEC || MV64X60 || PPLUS || PRPMC800 || \ PPC_GEN550 || PPC_MPC52xx +config PPC_OCP + bool + depends on IBM_OCP || XILINX_OCP + default y + choice prompt "Early debugging (dangerous)" bool diff --git a/trunk/arch/powerpc/Makefile b/trunk/arch/powerpc/Makefile index 6ec84d37a337..829e017b8a54 100644 --- a/trunk/arch/powerpc/Makefile +++ b/trunk/arch/powerpc/Makefile @@ -129,8 +129,13 @@ core-y += arch/powerpc/kernel/ \ arch/powerpc/lib/ \ arch/powerpc/sysdev/ \ arch/powerpc/platforms/ -core-$(CONFIG_MATH_EMULATION) += arch/powerpc/math-emu/ +core-$(CONFIG_PPC32) += arch/ppc/kernel/ +core-$(CONFIG_MATH_EMULATION) += arch/ppc/math-emu/ core-$(CONFIG_XMON) += arch/powerpc/xmon/ +core-$(CONFIG_APUS) += arch/ppc/amiga/ +drivers-$(CONFIG_8xx) += arch/ppc/8xx_io/ +drivers-$(CONFIG_4xx) += arch/ppc/4xx_io/ +drivers-$(CONFIG_CPM2) += arch/ppc/8260_io/ drivers-$(CONFIG_OPROFILE) += arch/powerpc/oprofile/ diff --git a/trunk/arch/powerpc/configs/cell_defconfig b/trunk/arch/powerpc/configs/cell_defconfig index fe22e54ab2b0..3c2acab63736 100644 --- a/trunk/arch/powerpc/configs/cell_defconfig +++ b/trunk/arch/powerpc/configs/cell_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.16 -# Thu Mar 23 20:48:09 2006 +# Linux kernel version: 2.6.16-rc6 +# Wed Mar 15 16:19:48 2006 # CONFIG_PPC64=y CONFIG_64BIT=y @@ -30,7 +30,6 @@ CONFIG_POWER4=y CONFIG_PPC_FPU=y CONFIG_ALTIVEC=y CONFIG_PPC_STD_MMU=y -CONFIG_VIRT_CPU_ACCOUNTING=y CONFIG_SMP=y CONFIG_NR_CPUS=4 @@ -52,8 +51,7 @@ CONFIG_SYSVIPC=y # CONFIG_BSD_PROCESS_ACCT is not set CONFIG_SYSCTL=y # CONFIG_AUDIT is not set -CONFIG_IKCONFIG=y -CONFIG_IKCONFIG_PROC=y +# CONFIG_IKCONFIG is not set # CONFIG_CPUSETS is not set CONFIG_INITRAMFS_SOURCE="" CONFIG_CC_OPTIMIZE_FOR_SIZE=y @@ -87,7 +85,7 @@ CONFIG_MODULE_UNLOAD=y CONFIG_OBSOLETE_MODPARM=y # CONFIG_MODVERSIONS is not set # CONFIG_MODULE_SRCVERSION_ALL is not set -CONFIG_KMOD=y +# CONFIG_KMOD is not set CONFIG_STOP_MACHINE=y # @@ -132,8 +130,7 @@ CONFIG_CELL_IIC=y # # Cell Broadband Engine options # -CONFIG_SPU_FS=m -CONFIG_SPUFS_MMAP=y +CONFIG_SPU_FS=y # # Kernel options @@ -147,7 +144,7 @@ CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT is not set CONFIG_PREEMPT_BKL=y CONFIG_BINFMT_ELF=y -CONFIG_BINFMT_MISC=m +# CONFIG_BINFMT_MISC is not set CONFIG_FORCE_MAX_ZONEORDER=13 # CONFIG_IOMMU_VMERGE is not set CONFIG_KEXEC=y @@ -158,16 +155,13 @@ CONFIG_ARCH_SELECT_MEMORY_MODEL=y CONFIG_ARCH_FLATMEM_ENABLE=y CONFIG_ARCH_SPARSEMEM_ENABLE=y CONFIG_SELECT_MEMORY_MODEL=y -# CONFIG_FLATMEM_MANUAL is not set +CONFIG_FLATMEM_MANUAL=y # CONFIG_DISCONTIGMEM_MANUAL is not set -CONFIG_SPARSEMEM_MANUAL=y -CONFIG_SPARSEMEM=y -CONFIG_HAVE_MEMORY_PRESENT=y +# CONFIG_SPARSEMEM_MANUAL is not set +CONFIG_FLATMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y # CONFIG_SPARSEMEM_STATIC is not set -CONFIG_SPARSEMEM_EXTREME=y -# CONFIG_MEMORY_HOTPLUG is not set CONFIG_SPLIT_PTLOCK_CPUS=4 -CONFIG_MIGRATION=y # CONFIG_PPC_64K_PAGES is not set CONFIG_SCHED_SMT=y CONFIG_PROC_DEVICETREE=y @@ -238,7 +232,6 @@ CONFIG_TCP_CONG_BIC=y # CONFIG_IP_VS is not set CONFIG_IPV6=y # CONFIG_IPV6_PRIVACY is not set -# CONFIG_IPV6_ROUTER_PREF is not set CONFIG_INET6_AH=m CONFIG_INET6_ESP=m CONFIG_INET6_IPCOMP=m @@ -251,7 +244,25 @@ CONFIG_NETFILTER=y # Core Netfilter Configuration # # CONFIG_NETFILTER_NETLINK is not set -# CONFIG_NETFILTER_XTABLES is not set +CONFIG_NETFILTER_XTABLES=m +CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m +CONFIG_NETFILTER_XT_TARGET_MARK=m +CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m +CONFIG_NETFILTER_XT_TARGET_NOTRACK=m +CONFIG_NETFILTER_XT_MATCH_COMMENT=m +CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m +# CONFIG_NETFILTER_XT_MATCH_DCCP is not set +CONFIG_NETFILTER_XT_MATCH_HELPER=m +CONFIG_NETFILTER_XT_MATCH_LENGTH=m +CONFIG_NETFILTER_XT_MATCH_LIMIT=m +CONFIG_NETFILTER_XT_MATCH_MAC=m +CONFIG_NETFILTER_XT_MATCH_MARK=m +CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m +CONFIG_NETFILTER_XT_MATCH_REALM=m +CONFIG_NETFILTER_XT_MATCH_SCTP=m +CONFIG_NETFILTER_XT_MATCH_STATE=m +CONFIG_NETFILTER_XT_MATCH_STRING=m +CONFIG_NETFILTER_XT_MATCH_TCPMSS=m # # IP: Netfilter Configuration @@ -267,13 +278,51 @@ CONFIG_IP_NF_IRC=m CONFIG_IP_NF_TFTP=m CONFIG_IP_NF_AMANDA=m # CONFIG_IP_NF_PPTP is not set -# CONFIG_IP_NF_H323 is not set CONFIG_IP_NF_QUEUE=m +CONFIG_IP_NF_IPTABLES=m +CONFIG_IP_NF_MATCH_IPRANGE=m +CONFIG_IP_NF_MATCH_MULTIPORT=m +CONFIG_IP_NF_MATCH_TOS=m +CONFIG_IP_NF_MATCH_RECENT=m +CONFIG_IP_NF_MATCH_ECN=m +CONFIG_IP_NF_MATCH_DSCP=m +CONFIG_IP_NF_MATCH_AH_ESP=m +CONFIG_IP_NF_MATCH_TTL=m +CONFIG_IP_NF_MATCH_OWNER=m +CONFIG_IP_NF_MATCH_ADDRTYPE=m +CONFIG_IP_NF_MATCH_HASHLIMIT=m +CONFIG_IP_NF_MATCH_POLICY=m +CONFIG_IP_NF_FILTER=m +CONFIG_IP_NF_TARGET_REJECT=m +CONFIG_IP_NF_TARGET_LOG=m +CONFIG_IP_NF_TARGET_ULOG=m +CONFIG_IP_NF_TARGET_TCPMSS=m +CONFIG_IP_NF_NAT=m +CONFIG_IP_NF_NAT_NEEDED=y +CONFIG_IP_NF_TARGET_MASQUERADE=m +CONFIG_IP_NF_TARGET_REDIRECT=m +CONFIG_IP_NF_TARGET_NETMAP=m +CONFIG_IP_NF_TARGET_SAME=m +CONFIG_IP_NF_NAT_SNMP_BASIC=m +CONFIG_IP_NF_NAT_IRC=m +CONFIG_IP_NF_NAT_FTP=m +CONFIG_IP_NF_NAT_TFTP=m +CONFIG_IP_NF_NAT_AMANDA=m +CONFIG_IP_NF_MANGLE=m +CONFIG_IP_NF_TARGET_TOS=m +CONFIG_IP_NF_TARGET_ECN=m +CONFIG_IP_NF_TARGET_DSCP=m +CONFIG_IP_NF_TARGET_TTL=m +CONFIG_IP_NF_RAW=m +CONFIG_IP_NF_ARPTABLES=m +CONFIG_IP_NF_ARPFILTER=m +CONFIG_IP_NF_ARP_MANGLE=m # # IPv6: Netfilter Configuration (EXPERIMENTAL) # # CONFIG_IP6_NF_QUEUE is not set +# CONFIG_IP6_NF_IPTABLES is not set # # DCCP Configuration (EXPERIMENTAL) @@ -306,6 +355,7 @@ CONFIG_IP_NF_QUEUE=m # QoS and/or fair queueing # # CONFIG_NET_SCHED is not set +CONFIG_NET_CLS_ROUTE=y # # Network testing @@ -358,7 +408,7 @@ CONFIG_FW_LOADER=y # CONFIG_BLK_DEV_COW_COMMON is not set CONFIG_BLK_DEV_LOOP=y # CONFIG_BLK_DEV_CRYPTOLOOP is not set -# CONFIG_BLK_DEV_NBD is not set +CONFIG_BLK_DEV_NBD=y # CONFIG_BLK_DEV_SX8 is not set CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_COUNT=16 @@ -434,23 +484,7 @@ CONFIG_IDEDMA_AUTO=y # # Multi-device support (RAID and LVM) # -CONFIG_MD=y -CONFIG_BLK_DEV_MD=m -CONFIG_MD_LINEAR=m -CONFIG_MD_RAID0=m -CONFIG_MD_RAID1=m -# CONFIG_MD_RAID10 is not set -# CONFIG_MD_RAID5 is not set -# CONFIG_MD_RAID6 is not set -# CONFIG_MD_MULTIPATH is not set -# CONFIG_MD_FAULTY is not set -CONFIG_BLK_DEV_DM=m -CONFIG_DM_CRYPT=m -CONFIG_DM_SNAPSHOT=m -CONFIG_DM_MIRROR=m -CONFIG_DM_ZERO=m -CONFIG_DM_MULTIPATH=m -# CONFIG_DM_MULTIPATH_EMC is not set +# CONFIG_MD is not set # # Fusion MPT device support @@ -514,7 +548,7 @@ CONFIG_MII=y # CONFIG_ACENIC is not set # CONFIG_DL2K is not set CONFIG_E1000=m -CONFIG_E1000_NAPI=y +# CONFIG_E1000_NAPI is not set # CONFIG_E1000_DISABLE_PACKET_SPLIT is not set # CONFIG_NS83820 is not set # CONFIG_HAMACHI is not set @@ -526,7 +560,7 @@ CONFIG_SKGE=m # CONFIG_SK98LIN is not set # CONFIG_TIGON3 is not set # CONFIG_BNX2 is not set -CONFIG_SPIDER_NET=m +CONFIG_SPIDER_NET=y # CONFIG_MV643XX_ETH is not set # @@ -644,8 +678,6 @@ CONFIG_SERIAL_CORE_CONSOLE=y # CONFIG_SERIAL_JSM is not set CONFIG_UNIX98_PTYS=y # CONFIG_LEGACY_PTYS is not set -CONFIG_HVC_DRIVER=y -CONFIG_HVC_RTAS=y # # IPMI @@ -662,13 +694,14 @@ CONFIG_WATCHDOG=y # Watchdog Device Drivers # # CONFIG_SOFT_WATCHDOG is not set -CONFIG_WATCHDOG_RTAS=y +# CONFIG_WATCHDOG_RTAS is not set # # PCI-based Watchdog Cards # # CONFIG_PCIPCWATCHDOG is not set # CONFIG_WDTPCI is not set +# CONFIG_RTC is not set CONFIG_GEN_RTC=y # CONFIG_GEN_RTC_X is not set # CONFIG_DTLK is not set @@ -800,7 +833,6 @@ CONFIG_DUMMY_CONSOLE=y # CONFIG_USB_ARCH_HAS_HCD=y CONFIG_USB_ARCH_HAS_OHCI=y -CONFIG_USB_ARCH_HAS_EHCI=y # CONFIG_USB is not set # @@ -820,14 +852,7 @@ CONFIG_USB_ARCH_HAS_EHCI=y # # InfiniBand support # -CONFIG_INFINIBAND=y -CONFIG_INFINIBAND_USER_MAD=m -CONFIG_INFINIBAND_USER_ACCESS=m -CONFIG_INFINIBAND_MTHCA=m -CONFIG_INFINIBAND_MTHCA_DEBUG=y -CONFIG_INFINIBAND_IPOIB=m -CONFIG_INFINIBAND_IPOIB_DEBUG=y -CONFIG_INFINIBAND_IPOIB_DEBUG_DATA=y +# CONFIG_INFINIBAND is not set # # EDAC - error detection and reporting (RAS) (EXPERIMENTAL) @@ -1012,6 +1037,10 @@ CONFIG_CRC32=y # CONFIG_LIBCRC32C is not set CONFIG_ZLIB_INFLATE=m CONFIG_ZLIB_DEFLATE=m +CONFIG_TEXTSEARCH=y +CONFIG_TEXTSEARCH_KMP=m +CONFIG_TEXTSEARCH_BM=m +CONFIG_TEXTSEARCH_FSM=m # # Instrumentation Support @@ -1029,7 +1058,7 @@ CONFIG_LOG_BUF_SHIFT=15 CONFIG_DETECT_SOFTLOCKUP=y # CONFIG_SCHEDSTATS is not set # CONFIG_DEBUG_SLAB is not set -CONFIG_DEBUG_MUTEXES=y +# CONFIG_DEBUG_MUTEXES is not set # CONFIG_DEBUG_SPINLOCK is not set CONFIG_DEBUG_SPINLOCK_SLEEP=y # CONFIG_DEBUG_KOBJECT is not set diff --git a/trunk/arch/powerpc/configs/mpc8540_ads_defconfig b/trunk/arch/powerpc/configs/mpc8540_ads_defconfig index 7f0780f1aa39..2a8290ee15c6 100644 --- a/trunk/arch/powerpc/configs/mpc8540_ads_defconfig +++ b/trunk/arch/powerpc/configs/mpc8540_ads_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.16 -# Mon Mar 27 23:37:36 2006 +# Linux kernel version: +# Sat Jan 14 15:57:54 2006 # # CONFIG_PPC64 is not set CONFIG_PPC32=y @@ -9,7 +9,6 @@ CONFIG_PPC_MERGE=y CONFIG_MMU=y CONFIG_GENERIC_HARDIRQS=y CONFIG_RWSEM_XCHGADD_ALGORITHM=y -CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_CALIBRATE_DELAY=y CONFIG_PPC=y CONFIG_EARLY_PRINTK=y @@ -19,7 +18,6 @@ CONFIG_ARCH_MAY_HAVE_PC_FDC=y CONFIG_PPC_OF=y CONFIG_PPC_UDBG_16550=y # CONFIG_GENERIC_TBSYNC is not set -CONFIG_DEFAULT_UIMAGE=y # # Processor support @@ -44,6 +42,7 @@ CONFIG_SPE=y # Code maturity level options # CONFIG_EXPERIMENTAL=y +CONFIG_CLEAN_COMPILE=y CONFIG_BROKEN_ON_SMP=y CONFIG_INIT_ENV_ARG_LIMIT=32 @@ -59,7 +58,6 @@ CONFIG_SYSVIPC=y CONFIG_SYSCTL=y # CONFIG_AUDIT is not set # CONFIG_IKCONFIG is not set -# CONFIG_RELAY is not set CONFIG_INITRAMFS_SOURCE="" # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set CONFIG_EMBEDDED=y @@ -74,6 +72,10 @@ CONFIG_BASE_FULL=y CONFIG_FUTEX=y CONFIG_EPOLL=y CONFIG_SHMEM=y +CONFIG_CC_ALIGN_FUNCTIONS=0 +CONFIG_CC_ALIGN_LABELS=0 +CONFIG_CC_ALIGN_LOOPS=0 +CONFIG_CC_ALIGN_JUMPS=0 CONFIG_SLAB=y # CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=0 @@ -88,8 +90,6 @@ CONFIG_BASE_SMALL=0 # Block layer # # CONFIG_LBD is not set -# CONFIG_BLK_DEV_IO_TRACE is not set -# CONFIG_LSF is not set # # IO Schedulers @@ -183,7 +183,6 @@ CONFIG_NET=y # # Networking options # -# CONFIG_NETDEBUG is not set CONFIG_PACKET=y # CONFIG_PACKET_MMAP is not set CONFIG_UNIX=y @@ -221,11 +220,6 @@ CONFIG_TCP_CONG_BIC=y # SCTP Configuration (EXPERIMENTAL) # # CONFIG_IP_SCTP is not set - -# -# TIPC Configuration (EXPERIMENTAL) -# -# CONFIG_TIPC is not set # CONFIG_ATM is not set # CONFIG_BRIDGE is not set # CONFIG_VLAN_8021Q is not set @@ -235,6 +229,11 @@ CONFIG_TCP_CONG_BIC=y # CONFIG_ATALK is not set # CONFIG_X25 is not set # CONFIG_LAPB is not set + +# +# TIPC Configuration (EXPERIMENTAL) +# +# CONFIG_TIPC is not set # CONFIG_NET_DIVERT is not set # CONFIG_ECONET is not set # CONFIG_WAN_ROUTER is not set @@ -487,12 +486,6 @@ CONFIG_GEN_RTC=y # # CONFIG_I2C is not set -# -# SPI support -# -# CONFIG_SPI is not set -# CONFIG_SPI_MASTER is not set - # # Dallas's 1-wire bus # @@ -503,13 +496,16 @@ CONFIG_GEN_RTC=y # CONFIG_HWMON=y # CONFIG_HWMON_VID is not set -# CONFIG_SENSORS_F71805F is not set # CONFIG_HWMON_DEBUG_CHIP is not set # # Misc devices # +# +# Multimedia Capabilities Port drivers +# + # # Multimedia devices # @@ -535,7 +531,6 @@ CONFIG_HWMON=y # # CONFIG_USB_ARCH_HAS_HCD is not set # CONFIG_USB_ARCH_HAS_OHCI is not set -# CONFIG_USB_ARCH_HAS_EHCI is not set # # NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' @@ -556,7 +551,7 @@ CONFIG_HWMON=y # # -# EDAC - error detection and reporting (RAS) (EXPERIMENTAL) +# SN Devices # # @@ -608,6 +603,7 @@ CONFIG_SYSFS=y CONFIG_TMPFS=y # CONFIG_HUGETLB_PAGE is not set CONFIG_RAMFS=y +# CONFIG_RELAYFS_FS is not set # CONFIG_CONFIGFS_FS is not set # @@ -662,7 +658,6 @@ CONFIG_PARTITION_ADVANCED=y # CONFIG_SGI_PARTITION is not set # CONFIG_ULTRIX_PARTITION is not set # CONFIG_SUN_PARTITION is not set -# CONFIG_KARMA_PARTITION is not set # CONFIG_EFI_PARTITION is not set # @@ -700,8 +695,6 @@ CONFIG_DEBUG_MUTEXES=y # CONFIG_DEBUG_INFO is not set # CONFIG_DEBUG_FS is not set # CONFIG_DEBUG_VM is not set -# CONFIG_UNWIND_INFO is not set -CONFIG_FORCED_INLINING=y # CONFIG_RCU_TORTURE_TEST is not set # CONFIG_DEBUGGER is not set # CONFIG_BDI_SWITCH is not set diff --git a/trunk/arch/powerpc/kernel/Makefile b/trunk/arch/powerpc/kernel/Makefile index 0cc0995b81b0..80e9fe2632b8 100644 --- a/trunk/arch/powerpc/kernel/Makefile +++ b/trunk/arch/powerpc/kernel/Makefile @@ -12,12 +12,12 @@ endif obj-y := semaphore.o cputable.o ptrace.o syscalls.o \ irq.o align.o signal_32.o pmc.o vdso.o \ - init_task.o process.o systbl.o idle.o + init_task.o process.o systbl.o obj-y += vdso32/ obj-$(CONFIG_PPC64) += setup_64.o binfmt_elf32.o sys_ppc32.o \ signal_64.o ptrace32.o \ paca.o cpu_setup_power4.o \ - firmware.o sysfs.o + firmware.o sysfs.o idle_64.o obj-$(CONFIG_PPC64) += vdso64/ obj-$(CONFIG_ALTIVEC) += vecemu.o vector.o obj-$(CONFIG_POWER4) += idle_power4.o @@ -34,11 +34,6 @@ obj-$(CONFIG_IBMEBUS) += ibmebus.o obj-$(CONFIG_GENERIC_TBSYNC) += smp-tbsync.o obj64-$(CONFIG_PPC_MULTIPLATFORM) += nvram_64.o obj-$(CONFIG_CRASH_DUMP) += crash_dump.o -obj-$(CONFIG_6xx) += idle_6xx.o l2cr_6xx.o cpu_setup_6xx.o -obj-$(CONFIG_TAU) += tau_6xx.o -obj32-$(CONFIG_SOFTWARE_SUSPEND) += swsusp_32.o -obj32-$(CONFIG_MODULES) += module_32.o -obj-$(CONFIG_E500) += perfmon_fsl_booke.o ifeq ($(CONFIG_PPC_MERGE),y) @@ -56,6 +51,7 @@ obj-$(CONFIG_PPC64) += misc_64.o dma_64.o iommu.o obj-$(CONFIG_PPC_MULTIPLATFORM) += prom_init.o obj-$(CONFIG_MODULES) += ppc_ksyms.o obj-$(CONFIG_BOOTX_TEXT) += btext.o +obj-$(CONFIG_6xx) += idle_6xx.o obj-$(CONFIG_SMP) += smp.o obj-$(CONFIG_KPROBES) += kprobes.o obj-$(CONFIG_PPC_UDBG_16550) += legacy_serial.o udbg_16550.o @@ -81,7 +77,6 @@ smpobj-$(CONFIG_SMP) += smp.o endif -obj-$(CONFIG_PPC32) += $(obj32-y) obj-$(CONFIG_PPC64) += $(obj64-y) extra-$(CONFIG_PPC_FPU) += fpu.o diff --git a/trunk/arch/powerpc/kernel/asm-offsets.c b/trunk/arch/powerpc/kernel/asm-offsets.c index 54b48f330051..882889b15926 100644 --- a/trunk/arch/powerpc/kernel/asm-offsets.c +++ b/trunk/arch/powerpc/kernel/asm-offsets.c @@ -105,6 +105,8 @@ int main(void) DEFINE(ICACHEL1LINESIZE, offsetof(struct ppc64_caches, iline_size)); DEFINE(ICACHEL1LOGLINESIZE, offsetof(struct ppc64_caches, log_iline_size)); DEFINE(ICACHEL1LINESPERPAGE, offsetof(struct ppc64_caches, ilines_per_page)); + DEFINE(PLATFORM_LPAR, PLATFORM_LPAR); + /* paca */ DEFINE(PACA_SIZE, sizeof(struct paca_struct)); DEFINE(PACAPACAINDEX, offsetof(struct paca_struct, paca_index)); diff --git a/trunk/arch/powerpc/kernel/crash_dump.c b/trunk/arch/powerpc/kernel/crash_dump.c index 764d07329716..211d72653ea6 100644 --- a/trunk/arch/powerpc/kernel/crash_dump.c +++ b/trunk/arch/powerpc/kernel/crash_dump.c @@ -61,7 +61,7 @@ static int __init parse_elfcorehdr(char *p) if (p) elfcorehdr_addr = memparse(p, &p); - return 1; + return 0; } __setup("elfcorehdr=", parse_elfcorehdr); #endif @@ -71,7 +71,7 @@ static int __init parse_savemaxmem(char *p) if (p) saved_max_pfn = (memparse(p, &p) >> PAGE_SHIFT) - 1; - return 1; + return 0; } __setup("savemaxmem=", parse_savemaxmem); diff --git a/trunk/arch/powerpc/kernel/entry_32.S b/trunk/arch/powerpc/kernel/entry_32.S index b3a979467225..4827ca1ec89b 100644 --- a/trunk/arch/powerpc/kernel/entry_32.S +++ b/trunk/arch/powerpc/kernel/entry_32.S @@ -135,10 +135,10 @@ transfer_to_handler: mfspr r11,SPRN_HID0 mtcr r11 BEGIN_FTR_SECTION - bt- 8,4f /* Check DOZE */ + bt- 8,power_save_6xx_restore /* Check DOZE */ END_FTR_SECTION_IFSET(CPU_FTR_CAN_DOZE) BEGIN_FTR_SECTION - bt- 9,4f /* Check NAP */ + bt- 9,power_save_6xx_restore /* Check NAP */ END_FTR_SECTION_IFSET(CPU_FTR_CAN_NAP) #endif /* CONFIG_6xx */ .globl transfer_to_handler_cont @@ -157,10 +157,6 @@ transfer_to_handler_cont: SYNC RFI /* jump to handler, enable MMU */ -#ifdef CONFIG_6xx -4: b power_save_6xx_restore -#endif - /* * On kernel stack overflow, load up an initial stack pointer * and call StackOverflow(regs), which should not return. diff --git a/trunk/arch/powerpc/kernel/entry_64.S b/trunk/arch/powerpc/kernel/entry_64.S index 19ad5c6b1818..1060155d84c3 100644 --- a/trunk/arch/powerpc/kernel/entry_64.S +++ b/trunk/arch/powerpc/kernel/entry_64.S @@ -617,12 +617,6 @@ _GLOBAL(enter_rtas) mfsrr1 r10 std r10,_SRR1(r1) - /* Temporary workaround to clear CR until RTAS can be modified to - * ignore all bits. - */ - li r0,0 - mtcr r0 - /* There is no way it is acceptable to get here with interrupts enabled, * check it with the asm equivalent of WARN_ON */ diff --git a/trunk/arch/powerpc/kernel/firmware.c b/trunk/arch/powerpc/kernel/firmware.c index 0bfe9061720a..4d37a3cb80f6 100644 --- a/trunk/arch/powerpc/kernel/firmware.c +++ b/trunk/arch/powerpc/kernel/firmware.c @@ -14,9 +14,7 @@ */ #include -#include #include -unsigned long powerpc_firmware_features; -EXPORT_SYMBOL_GPL(powerpc_firmware_features); +unsigned long ppc64_firmware_features; diff --git a/trunk/arch/powerpc/kernel/head_64.S b/trunk/arch/powerpc/kernel/head_64.S index a5ae04a57c78..35084f3a841b 100644 --- a/trunk/arch/powerpc/kernel/head_64.S +++ b/trunk/arch/powerpc/kernel/head_64.S @@ -1544,11 +1544,7 @@ _STATIC(__boot_from_prom) mr r28,r6 mr r27,r7 - /* - * Align the stack to 16-byte boundary - * Depending on the size and layout of the ELF sections in the initial - * boot binary, the stack pointer will be unalignet on PowerMac - */ + /* Align the stack to 16-byte boundary for broken yaboot */ rldicr r1,r1,0,59 /* Make sure we are running in 64 bits mode */ @@ -1851,6 +1847,21 @@ _STATIC(start_here_multiplatform) bl .__save_cpu_setup sync + /* Setup a valid physical PACA pointer in SPRG3 for early_setup + * note that boot_cpuid can always be 0 nowadays since there is + * nowhere it can be initialized differently before we reach this + * code + */ + LOAD_REG_IMMEDIATE(r27, boot_cpuid) + add r27,r27,r26 + lwz r27,0(r27) + + LOAD_REG_IMMEDIATE(r24, paca) /* Get base vaddr of paca array */ + mulli r13,r27,PACA_SIZE /* Calculate vaddr of right paca */ + add r13,r13,r24 /* for this processor. */ + add r13,r13,r26 /* convert to physical addr */ + mtspr SPRN_SPRG3,r13 + /* Do very early kernel initializations, including initial hash table, * stab and slb setup before we turn on relocation. */ @@ -1919,17 +1930,6 @@ _STATIC(start_here_common) /* Not reached */ BUG_OPCODE -/* Put the paca pointer into r13 and SPRG3 */ -_GLOBAL(setup_boot_paca) - LOAD_REG_IMMEDIATE(r3, boot_cpuid) - lwz r3,0(r3) - LOAD_REG_IMMEDIATE(r4, paca) /* Get base vaddr of paca array */ - mulli r3,r3,PACA_SIZE /* Calculate vaddr of right paca */ - add r13,r3,r4 /* for this processor. */ - mtspr SPRN_SPRG3,r13 - - blr - /* * We put a few things here that have to be page-aligned. * This stuff goes at the beginning of the bss, which is page-aligned. diff --git a/trunk/arch/powerpc/kernel/idle.c b/trunk/arch/powerpc/kernel/idle_64.c similarity index 65% rename from trunk/arch/powerpc/kernel/idle.c rename to trunk/arch/powerpc/kernel/idle_64.c index e9f321d74d85..b879d3057ef8 100644 --- a/trunk/arch/powerpc/kernel/idle.c +++ b/trunk/arch/powerpc/kernel/idle_64.c @@ -2,17 +2,13 @@ * Idle daemon for PowerPC. Idle daemon will handle any action * that needs to be taken when the system becomes idle. * - * Originally written by Cort Dougan (cort@cs.nmt.edu). - * Subsequent 32-bit hacking by Tom Rini, Armin Kuster, - * Paul Mackerras and others. + * Originally Written by Cort Dougan (cort@cs.nmt.edu) * * iSeries supported added by Mike Corrigan * * Additional shared processor, SMT, and firmware support * Copyright (c) 2003 Dave Engebretsen * - * 32-bit and 64-bit versions merged by Paul Mackerras - * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version @@ -33,43 +29,18 @@ #include #include -#ifdef CONFIG_HOTPLUG_CPU -#define cpu_should_die() (cpu_is_offline(smp_processor_id()) && \ - system_state == SYSTEM_RUNNING) -#else -#define cpu_should_die() 0 -#endif +extern void power4_idle(void); -/* - * The body of the idle task. - */ -void cpu_idle(void) +void default_idle(void) { - if (ppc_md.idle_loop) - ppc_md.idle_loop(); /* doesn't return */ - + unsigned int cpu = smp_processor_id(); set_thread_flag(TIF_POLLING_NRFLAG); - while (1) { - ppc64_runlatch_off(); - while (!need_resched() && !cpu_should_die()) { - if (ppc_md.power_save) { - clear_thread_flag(TIF_POLLING_NRFLAG); - /* - * smp_mb is so clearing of TIF_POLLING_NRFLAG - * is ordered w.r.t. need_resched() test. - */ - smp_mb(); - local_irq_disable(); - - /* check again after disabling irqs */ - if (!need_resched() && !cpu_should_die()) - ppc_md.power_save(); - - local_irq_enable(); - set_thread_flag(TIF_POLLING_NRFLAG); + while (1) { + if (!need_resched()) { + while (!need_resched() && !cpu_is_offline(cpu)) { + ppc64_runlatch_off(); - } else { /* * Go into low thread priority and possibly * low power mode. @@ -77,18 +48,46 @@ void cpu_idle(void) HMT_low(); HMT_very_low(); } + + HMT_medium(); } - HMT_medium(); ppc64_runlatch_on(); - if (cpu_should_die()) - cpu_die(); preempt_enable_no_resched(); schedule(); preempt_disable(); + if (cpu_is_offline(cpu) && system_state == SYSTEM_RUNNING) + cpu_die(); } } +void native_idle(void) +{ + while (1) { + ppc64_runlatch_off(); + + if (!need_resched()) + power4_idle(); + + if (need_resched()) { + ppc64_runlatch_on(); + preempt_enable_no_resched(); + schedule(); + preempt_disable(); + } + + if (cpu_is_offline(smp_processor_id()) && + system_state == SYSTEM_RUNNING) + cpu_die(); + } +} + +void cpu_idle(void) +{ + BUG_ON(NULL == ppc_md.idle_loop); + ppc_md.idle_loop(); +} + int powersave_nap; #ifdef CONFIG_SYSCTL diff --git a/trunk/arch/powerpc/kernel/idle_6xx.S b/trunk/arch/powerpc/kernel/idle_6xx.S index 12a4efbaa08f..444fdcc769f1 100644 --- a/trunk/arch/powerpc/kernel/idle_6xx.S +++ b/trunk/arch/powerpc/kernel/idle_6xx.S @@ -87,6 +87,19 @@ END_FTR_SECTION_IFSET(CPU_FTR_CAN_NAP) cmpwi 0,r3,0 beqlr + /* Clear MSR:EE */ + mfmsr r7 + rlwinm r0,r7,0,17,15 + mtmsr r0 + + /* Check current_thread_info()->flags */ + rlwinm r4,r1,0,0,18 + lwz r4,TI_FLAGS(r4) + andi. r0,r4,_TIF_NEED_RESCHED + beq 1f + mtmsr r7 /* out of line this ? */ + blr +1: /* Some pre-nap cleanups needed on some CPUs */ andis. r0,r3,HID0_NAP@h beq 2f @@ -144,8 +157,7 @@ BEGIN_FTR_SECTION DSSALL sync END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) - mfmsr r7 - ori r7,r7,MSR_EE + ori r7,r7,MSR_EE /* Could be ommited (already set) */ oris r7,r7,MSR_POW@h sync isync @@ -208,6 +220,8 @@ _GLOBAL(nap_save_msscr0) _GLOBAL(nap_save_hid1) .space 4*NR_CPUS +_GLOBAL(powersave_nap) + .long 0 _GLOBAL(powersave_lowspeed) .long 0 diff --git a/trunk/arch/powerpc/kernel/idle_power4.S b/trunk/arch/powerpc/kernel/idle_power4.S index 6dad1c02496e..c16b4afab582 100644 --- a/trunk/arch/powerpc/kernel/idle_power4.S +++ b/trunk/arch/powerpc/kernel/idle_power4.S @@ -1,5 +1,11 @@ /* - * This file contains the power_save function for 970-family CPUs. + * This file contains the power_save function for 6xx & 7xxx CPUs + * rewritten in assembler + * + * Warning ! This code assumes that if your machine has a 750fx + * it will have PLL 1 set to low speed mode (used during NAP/DOZE). + * if this is not the case some additional changes will have to + * be done to check a runtime var (a bit like powersave-nap) * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -20,23 +26,49 @@ .text +/* + * Here is the power_save_6xx function. This could eventually be + * split into several functions & changing the function pointer + * depending on the various features. + */ _GLOBAL(power4_idle) BEGIN_FTR_SECTION blr END_FTR_SECTION_IFCLR(CPU_FTR_CAN_NAP) + /* We must dynamically check for the NAP feature as it + * can be cleared by CPU init after the fixups are done + */ + LOAD_REG_ADDRBASE(r3,cur_cpu_spec) + ld r4,ADDROFF(cur_cpu_spec)(r3) + ld r4,CPU_SPEC_FEATURES(r4) + andi. r0,r4,CPU_FTR_CAN_NAP + beqlr /* Now check if user or arch enabled NAP mode */ LOAD_REG_ADDRBASE(r3,powersave_nap) lwz r4,ADDROFF(powersave_nap)(r3) cmpwi 0,r4,0 beqlr + /* Clear MSR:EE */ + mfmsr r7 + li r4,0 + ori r4,r4,MSR_EE + andc r0,r7,r4 + mtmsrd r0 + + /* Check current_thread_info()->flags */ + clrrdi r4,r1,THREAD_SHIFT + ld r4,TI_FLAGS(r4) + andi. r0,r4,_TIF_NEED_RESCHED + beq 1f + mtmsrd r7 /* out of line this ? */ + blr +1: /* Go to NAP now */ BEGIN_FTR_SECTION DSSALL sync END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) - mfmsr r7 - ori r7,r7,MSR_EE oris r7,r7,MSR_POW@h sync isync diff --git a/trunk/arch/powerpc/kernel/irq.c b/trunk/arch/powerpc/kernel/irq.c index bb5c9501234c..771a59cbd213 100644 --- a/trunk/arch/powerpc/kernel/irq.c +++ b/trunk/arch/powerpc/kernel/irq.c @@ -379,7 +379,7 @@ void irq_ctx_init(void) struct thread_info *tp; int i; - for_each_possible_cpu(i) { + for_each_cpu(i) { memset((void *)softirq_ctx[i], 0, THREAD_SIZE); tp = softirq_ctx[i]; tp->cpu = i; diff --git a/trunk/arch/powerpc/kernel/legacy_serial.c b/trunk/arch/powerpc/kernel/legacy_serial.c index 6e67b5b49ba1..c7a799a09516 100644 --- a/trunk/arch/powerpc/kernel/legacy_serial.c +++ b/trunk/arch/powerpc/kernel/legacy_serial.c @@ -37,7 +37,7 @@ static int legacy_serial_console = -1; static int __init add_legacy_port(struct device_node *np, int want_index, int iotype, phys_addr_t base, phys_addr_t taddr, unsigned long irq, - upf_t flags) + unsigned int flags) { u32 *clk, *spd, clock = BASE_BAUD * 16; int index; @@ -113,7 +113,7 @@ static int __init add_legacy_soc_port(struct device_node *np, { phys_addr_t addr; u32 *addrp; - upf_t flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_SHARE_IRQ; + unsigned int flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_SHARE_IRQ; /* We only support ports that have a clock frequency properly * encoded in the device-tree. @@ -236,23 +236,6 @@ static int __init add_legacy_pci_port(struct device_node *np, } #endif -static void __init setup_legacy_serial_console(int console) -{ - struct legacy_serial_info *info = - &legacy_serial_infos[console]; - void __iomem *addr; - - if (info->taddr == 0) - return; - addr = ioremap(info->taddr, 0x1000); - if (addr == NULL) - return; - if (info->speed == 0) - info->speed = udbg_probe_uart_speed(addr, info->clock); - DBG("default console speed = %d\n", info->speed); - udbg_init_uart(addr, info->speed, info->clock); -} - /* * This is called very early, as part of setup_system() or eventually * setup_arch(), basically before anything else in this file. This function @@ -335,8 +318,25 @@ void __init find_legacy_serial_ports(void) #endif DBG("legacy_serial_console = %d\n", legacy_serial_console); - if (legacy_serial_console >= 0) - setup_legacy_serial_console(legacy_serial_console); + + /* udbg is 64 bits only for now, that will change soon though ... */ + while (legacy_serial_console >= 0) { + struct legacy_serial_info *info = + &legacy_serial_infos[legacy_serial_console]; + void __iomem *addr; + + if (info->taddr == 0) + break; + addr = ioremap(info->taddr, 0x1000); + if (addr == NULL) + break; + if (info->speed == 0) + info->speed = udbg_probe_uart_speed(addr, info->clock); + DBG("default console speed = %d\n", info->speed); + udbg_init_uart(addr, info->speed, info->clock); + break; + } + DBG(" <- find_legacy_serial_port()\n"); } diff --git a/trunk/arch/powerpc/kernel/lparcfg.c b/trunk/arch/powerpc/kernel/lparcfg.c index 1b73508ecb2b..e789fef4eb8a 100644 --- a/trunk/arch/powerpc/kernel/lparcfg.c +++ b/trunk/arch/powerpc/kernel/lparcfg.c @@ -56,7 +56,7 @@ static unsigned long get_purr(void) unsigned long sum_purr = 0; int cpu; - for_each_possible_cpu(cpu) { + for_each_cpu(cpu) { sum_purr += lppaca[cpu].emulated_time_base; #ifdef PURR_DEBUG @@ -222,7 +222,7 @@ static unsigned long get_purr(void) int cpu; struct cpu_usage *cu; - for_each_possible_cpu(cpu) { + for_each_cpu(cpu) { cu = &per_cpu(cpu_usage_array, cpu); sum_purr += cu->current_tb; } diff --git a/trunk/arch/powerpc/kernel/nvram_64.c b/trunk/arch/powerpc/kernel/nvram_64.c index ada50aa5b600..fd7db8d542db 100644 --- a/trunk/arch/powerpc/kernel/nvram_64.c +++ b/trunk/arch/powerpc/kernel/nvram_64.c @@ -160,7 +160,7 @@ static int dev_nvram_ioctl(struct inode *inode, struct file *file, case IOC_NVRAM_GET_OFFSET: { int part, offset; - if (!machine_is(powermac)) + if (_machine != PLATFORM_POWERMAC) return -EINVAL; if (copy_from_user(&part, (void __user*)arg, sizeof(part)) != 0) return -EFAULT; @@ -174,9 +174,8 @@ static int dev_nvram_ioctl(struct inode *inode, struct file *file, return 0; } #endif /* CONFIG_PPC_PMAC */ - default: - return -EINVAL; } + return -EINVAL; } struct file_operations nvram_fops = { @@ -444,7 +443,7 @@ static int nvram_setup_partition(void) * in our nvram, as Apple defined partitions use pretty much * all of the space */ - if (machine_is(powermac)) + if (_machine == PLATFORM_POWERMAC) return -ENOSPC; /* see if we have an OS partition that meets our needs. diff --git a/trunk/arch/powerpc/kernel/paca.c b/trunk/arch/powerpc/kernel/paca.c index f505a8827e3e..5d1b708086bd 100644 --- a/trunk/arch/powerpc/kernel/paca.c +++ b/trunk/arch/powerpc/kernel/paca.c @@ -56,11 +56,14 @@ struct lppaca lppaca[] = { * processors. The processor VPD array needs one entry per physical * processor (not thread). */ -#define PACA_INIT_COMMON(number) \ +#define PACA_INIT_COMMON(number, start, asrr, asrv) \ .lppaca_ptr = &lppaca[number], \ .lock_token = 0x8000, \ .paca_index = (number), /* Paca Index */ \ .kernel_toc = (unsigned long)(&__toc_start) + 0x8000UL, \ + .stab_real = (asrr), /* Real pointer to segment table */ \ + .stab_addr = (asrv), /* Virt pointer to segment table */ \ + .cpu_start = (start), /* Processor start */ \ .hw_cpu_id = 0xffff, #ifdef CONFIG_PPC_ISERIES @@ -69,20 +72,30 @@ struct lppaca lppaca[] = { #define PACA_INIT(number) \ { \ - PACA_INIT_COMMON(number) \ + PACA_INIT_COMMON(number, 0, 0, 0) \ + PACA_INIT_ISERIES(number) \ +} + +#define BOOTCPU_PACA_INIT(number) \ +{ \ + PACA_INIT_COMMON(number, 1, 0, (u64)&initial_stab) \ PACA_INIT_ISERIES(number) \ } #else #define PACA_INIT(number) \ { \ - PACA_INIT_COMMON(number) \ + PACA_INIT_COMMON(number, 0, 0, 0) \ } +#define BOOTCPU_PACA_INIT(number) \ +{ \ + PACA_INIT_COMMON(number, 1, STAB0_PHYS_ADDR, (u64)&initial_stab) \ +} #endif struct paca_struct paca[] = { - PACA_INIT(0), + BOOTCPU_PACA_INIT(0), #if NR_CPUS > 1 PACA_INIT( 1), PACA_INIT( 2), PACA_INIT( 3), #if NR_CPUS > 4 diff --git a/trunk/arch/powerpc/kernel/pci_32.c b/trunk/arch/powerpc/kernel/pci_32.c index b129d2e4b759..704c846b2b0f 100644 --- a/trunk/arch/powerpc/kernel/pci_32.c +++ b/trunk/arch/powerpc/kernel/pci_32.c @@ -787,7 +787,7 @@ pci_busdev_to_OF_node(struct pci_bus *bus, int devfn) * fix has to be done by making the remapping per-host and always * filling the pci_to_OF map. --BenH */ - if (machine_is(powermac) && busnr >= 0xf0) + if (_machine == _MACH_Pmac && busnr >= 0xf0) busnr -= 0xf0; else #endif @@ -1728,7 +1728,7 @@ long sys_pciconfig_iobase(long which, unsigned long bus, unsigned long devfn) * (bus 0 is HT root), we return the AGP one instead. */ #ifdef CONFIG_PPC_PMAC - if (machine_is(powermac) && machine_is_compatible("MacRISC4")) + if (_machine == _MACH_Pmac && machine_is_compatible("MacRISC4")) if (bus == 0) bus = 0xf0; #endif /* CONFIG_PPC_PMAC */ diff --git a/trunk/arch/powerpc/kernel/pci_64.c b/trunk/arch/powerpc/kernel/pci_64.c index 4c4449be81ce..ba92bab7cc2c 100644 --- a/trunk/arch/powerpc/kernel/pci_64.c +++ b/trunk/arch/powerpc/kernel/pci_64.c @@ -78,7 +78,6 @@ int global_phb_number; /* Global phb counter */ /* Cached ISA bridge dev. */ struct pci_dev *ppc64_isabridge_dev = NULL; -EXPORT_SYMBOL_GPL(ppc64_isabridge_dev); static void fixup_broken_pcnet32(struct pci_dev* dev) { diff --git a/trunk/arch/powerpc/kernel/proc_ppc64.c b/trunk/arch/powerpc/kernel/proc_ppc64.c index 3c2cf661f6d9..7ba42a405f41 100644 --- a/trunk/arch/powerpc/kernel/proc_ppc64.c +++ b/trunk/arch/powerpc/kernel/proc_ppc64.c @@ -23,7 +23,6 @@ #include #include -#include #include #include #include @@ -52,7 +51,7 @@ static int __init proc_ppc64_create(void) if (!root) return 1; - if (!machine_is(pseries) && !machine_is(cell)) + if (!(platform_is_pseries() || _machine == PLATFORM_CELL)) return 0; if (!proc_mkdir("rtas", root)) diff --git a/trunk/arch/powerpc/kernel/process.c b/trunk/arch/powerpc/kernel/process.c index 2dd47d2dd998..f698aa77127e 100644 --- a/trunk/arch/powerpc/kernel/process.c +++ b/trunk/arch/powerpc/kernel/process.c @@ -45,7 +45,6 @@ #include #include #include -#include #ifdef CONFIG_PPC64 #include #endif @@ -363,11 +362,7 @@ static void show_instructions(struct pt_regs *regs) if (!(i % 8)) printk("\n"); - /* We use __get_user here *only* to avoid an OOPS on a - * bad address because the pc *should* only be a - * kernel address. - */ - if (BAD_PC(pc) || __get_user(instr, (unsigned int __user *)pc)) { + if (BAD_PC(pc) || __get_user(instr, (unsigned int *)pc)) { printk("XXXXXXXX "); } else { if (regs->nip == pc) @@ -770,7 +765,7 @@ int sys_execve(unsigned long a0, unsigned long a1, unsigned long a2, return error; } -int validate_sp(unsigned long sp, struct task_struct *p, +static int validate_sp(unsigned long sp, struct task_struct *p, unsigned long nbytes) { unsigned long stack_page = (unsigned long)task_stack_page(p); @@ -808,8 +803,6 @@ int validate_sp(unsigned long sp, struct task_struct *p, #define FRAME_MARKER 2 #endif -EXPORT_SYMBOL(validate_sp); - unsigned long get_wchan(struct task_struct *p) { unsigned long ip, sp; @@ -834,6 +827,7 @@ unsigned long get_wchan(struct task_struct *p) } while (count++ < 16); return 0; } +EXPORT_SYMBOL(get_wchan); static int kstack_depth_to_print = 64; diff --git a/trunk/arch/powerpc/kernel/prom.c b/trunk/arch/powerpc/kernel/prom.c index 4336390bcf34..d63cd562d9d5 100644 --- a/trunk/arch/powerpc/kernel/prom.c +++ b/trunk/arch/powerpc/kernel/prom.c @@ -383,14 +383,14 @@ static int __devinit finish_node_interrupts(struct device_node *np, /* Apple uses bits in there in a different way, let's * only keep the real sense bit on macs */ - if (machine_is(powermac)) + if (_machine == PLATFORM_POWERMAC) sense &= 0x1; np->intrs[intrcount].sense = map_mpic_senses[sense]; } #ifdef CONFIG_PPC64 /* We offset irq numbers for the u3 MPIC by 128 in PowerMac */ - if (machine_is(powermac) && ic && ic->parent) { + if (_machine == PLATFORM_POWERMAC && ic && ic->parent) { char *name = get_property(ic->parent, "name", NULL); if (name && !strcmp(name, "u3")) np->intrs[intrcount].line += 128; @@ -570,18 +570,6 @@ int __init of_scan_flat_dt(int (*it)(unsigned long node, return rc; } -unsigned long __init of_get_flat_dt_root(void) -{ - unsigned long p = ((unsigned long)initial_boot_params) + - initial_boot_params->off_dt_struct; - - while(*((u32 *)p) == OF_DT_NOP) - p += 4; - BUG_ON (*((u32 *)p) != OF_DT_BEGIN_NODE); - p += 4; - return _ALIGN(p + strlen((char *)p) + 1, 4); -} - /** * This function can be used within scan_flattened_dt callback to get * access to properties @@ -624,25 +612,6 @@ void* __init of_get_flat_dt_prop(unsigned long node, const char *name, } while(1); } -int __init of_flat_dt_is_compatible(unsigned long node, const char *compat) -{ - const char* cp; - unsigned long cplen, l; - - cp = of_get_flat_dt_prop(node, "compatible", &cplen); - if (cp == NULL) - return 0; - while (cplen > 0) { - if (strncasecmp(cp, compat, strlen(compat)) == 0) - return 1; - l = strlen(cp) + 1; - cp += l; - cplen -= l; - } - - return 0; -} - static void *__init unflatten_dt_alloc(unsigned long *mem, unsigned long size, unsigned long align) { @@ -717,7 +686,7 @@ static unsigned long __init unflatten_dt_node(unsigned long mem, #ifdef DEBUG if ((strlen(p) + l + 1) != allocl) { DBG("%s: p: %d, l: %d, a: %d\n", - pathp, (int)strlen(p), l, allocl); + pathp, strlen(p), l, allocl); } #endif p += strlen(p); @@ -885,73 +854,35 @@ void __init unflatten_device_tree(void) DBG(" <- unflatten_device_tree()\n"); } + static int __init early_init_dt_scan_cpus(unsigned long node, - const char *uname, int depth, - void *data) + const char *uname, int depth, void *data) { - static int logical_cpuid = 0; - char *type = of_get_flat_dt_prop(node, "device_type", NULL); -#ifdef CONFIG_ALTIVEC u32 *prop; -#endif - u32 *intserv; - int i, nthreads; - unsigned long len; - int found = 0; + unsigned long size; + char *type = of_get_flat_dt_prop(node, "device_type", &size); /* We are scanning "cpu" nodes only */ if (type == NULL || strcmp(type, "cpu") != 0) return 0; - /* Get physical cpuid */ - intserv = of_get_flat_dt_prop(node, "ibm,ppc-interrupt-server#s", &len); - if (intserv) { - nthreads = len / sizeof(int); - } else { - intserv = of_get_flat_dt_prop(node, "reg", NULL); - nthreads = 1; - } - - /* - * Now see if any of these threads match our boot cpu. - * NOTE: This must match the parsing done in smp_setup_cpu_maps. - */ - for (i = 0; i < nthreads; i++) { - /* - * version 2 of the kexec param format adds the phys cpuid of - * booted proc. + boot_cpuid = 0; + boot_cpuid_phys = 0; + if (initial_boot_params && initial_boot_params->version >= 2) { + /* version 2 of the kexec param format adds the phys cpuid + * of booted proc. */ - if (initial_boot_params && initial_boot_params->version >= 2) { - if (intserv[i] == - initial_boot_params->boot_cpuid_phys) { - found = 1; - break; - } - } else { - /* - * Check if it's the boot-cpu, set it's hw index now, - * unfortunately this format did not support booting - * off secondary threads. - */ - if (of_get_flat_dt_prop(node, + boot_cpuid_phys = initial_boot_params->boot_cpuid_phys; + } else { + /* Check if it's the boot-cpu, set it's hw index now */ + if (of_get_flat_dt_prop(node, "linux,boot-cpu", NULL) != NULL) { - found = 1; - break; - } + prop = of_get_flat_dt_prop(node, "reg", NULL); + if (prop != NULL) + boot_cpuid_phys = *prop; } - -#ifdef CONFIG_SMP - /* logical cpu id is always 0 on UP kernels */ - logical_cpuid++; -#endif - } - - if (found) { - DBG("boot cpu: logical %d physical %d\n", logical_cpuid, - intserv[i]); - boot_cpuid = logical_cpuid; - set_hard_smp_processor_id(boot_cpuid, intserv[i]); } + set_hard_smp_processor_id(0, boot_cpuid_phys); #ifdef CONFIG_ALTIVEC /* Check if we have a VMX and eventually update CPU features */ @@ -970,10 +901,16 @@ static int __init early_init_dt_scan_cpus(unsigned long node, #endif /* CONFIG_ALTIVEC */ #ifdef CONFIG_PPC_PSERIES - if (nthreads > 1) + /* + * Check for an SMT capable CPU and set the CPU feature. We do + * this by looking at the size of the ibm,ppc-interrupt-server#s + * property + */ + prop = (u32 *)of_get_flat_dt_prop(node, "ibm,ppc-interrupt-server#s", + &size); + cur_cpu_spec->cpu_features &= ~CPU_FTR_SMT; + if (prop && ((size / sizeof(u32)) > 1)) cur_cpu_spec->cpu_features |= CPU_FTR_SMT; - else - cur_cpu_spec->cpu_features &= ~CPU_FTR_SMT; #endif return 0; @@ -982,6 +919,7 @@ static int __init early_init_dt_scan_cpus(unsigned long node, static int __init early_init_dt_scan_chosen(unsigned long node, const char *uname, int depth, void *data) { + u32 *prop; unsigned long *lprop; unsigned long l; char *p; @@ -992,6 +930,14 @@ static int __init early_init_dt_scan_chosen(unsigned long node, (strcmp(uname, "chosen") != 0 && strcmp(uname, "chosen@0") != 0)) return 0; + /* get platform type */ + prop = (u32 *)of_get_flat_dt_prop(node, "linux,platform", NULL); + if (prop == NULL) + return 0; +#ifdef CONFIG_PPC_MULTIPLATFORM + _machine = *prop; +#endif + #ifdef CONFIG_PPC64 /* check if iommu is forced on or off */ if (of_get_flat_dt_prop(node, "linux,iommu-off", NULL) != NULL) @@ -1018,15 +964,15 @@ static int __init early_init_dt_scan_chosen(unsigned long node, * set of RTAS infos now if available */ { - u64 *basep, *entryp, *sizep; + u64 *basep, *entryp; basep = of_get_flat_dt_prop(node, "linux,rtas-base", NULL); entryp = of_get_flat_dt_prop(node, "linux,rtas-entry", NULL); - sizep = of_get_flat_dt_prop(node, "linux,rtas-size", NULL); - if (basep && entryp && sizep) { + prop = of_get_flat_dt_prop(node, "linux,rtas-size", NULL); + if (basep && entryp && prop) { rtas.base = *basep; rtas.entry = *entryp; - rtas.size = *sizep; + rtas.size = *prop; } } #endif /* CONFIG_PPC_RTAS */ @@ -1055,13 +1001,25 @@ static int __init early_init_dt_scan_chosen(unsigned long node, if (strstr(cmd_line, "mem=")) { char *p, *q; + unsigned long maxmem = 0; for (q = cmd_line; (p = strstr(q, "mem=")) != 0; ) { q = p + 4; if (p > cmd_line && p[-1] != ' ') continue; - memory_limit = memparse(q, &q); + maxmem = simple_strtoul(q, &q, 0); + if (*q == 'k' || *q == 'K') { + maxmem <<= 10; + ++q; + } else if (*q == 'm' || *q == 'M') { + maxmem <<= 20; + ++q; + } else if (*q == 'g' || *q == 'G') { + maxmem <<= 30; + ++q; + } } + memory_limit = maxmem; } /* break now */ @@ -1797,7 +1755,7 @@ static int of_finish_dynamic_node(struct device_node *node) /* We don't support that function on PowerMac, at least * not yet */ - if (machine_is(powermac)) + if (_machine == PLATFORM_POWERMAC) return -ENODEV; /* fix up new node's linux_phandle field */ diff --git a/trunk/arch/powerpc/kernel/prom_init.c b/trunk/arch/powerpc/kernel/prom_init.c index d66c5e77fcff..813c2cd194c2 100644 --- a/trunk/arch/powerpc/kernel/prom_init.c +++ b/trunk/arch/powerpc/kernel/prom_init.c @@ -180,16 +180,6 @@ static unsigned long __initdata prom_tce_alloc_start; static unsigned long __initdata prom_tce_alloc_end; #endif -/* Platforms codes are now obsolete in the kernel. Now only used within this - * file and ultimately gone too. Feel free to change them if you need, they - * are not shared with anything outside of this file anymore - */ -#define PLATFORM_PSERIES 0x0100 -#define PLATFORM_PSERIES_LPAR 0x0101 -#define PLATFORM_LPAR 0x0001 -#define PLATFORM_POWERMAC 0x0400 -#define PLATFORM_GENERIC 0x0500 - static int __initdata of_platform; static char __initdata prom_cmd_line[COMMAND_LINE_SIZE]; @@ -407,11 +397,6 @@ static void __init __attribute__((noreturn)) prom_panic(const char *reason) reason = PTRRELOC(reason); #endif prom_print(reason); - /* Do not call exit because it clears the screen on pmac - * it also causes some sort of double-fault on early pmacs */ - if (RELOC(of_platform) == PLATFORM_POWERMAC) - asm("trap\n"); - /* ToDo: should put up an SRC here on p/iSeries */ call_prom("exit", 0, 0); @@ -1502,10 +1487,7 @@ static int __init prom_find_machine_type(void) int len, i = 0; #ifdef CONFIG_PPC64 phandle rtas; - int x; #endif - - /* Look for a PowerMac */ len = prom_getprop(_prom->root, "compatible", compat, sizeof(compat)-1); if (len > 0) { @@ -1518,36 +1500,28 @@ static int __init prom_find_machine_type(void) if (strstr(p, RELOC("Power Macintosh")) || strstr(p, RELOC("MacRISC"))) return PLATFORM_POWERMAC; +#ifdef CONFIG_PPC64 + if (strstr(p, RELOC("Momentum,Maple"))) + return PLATFORM_MAPLE; + if (strstr(p, RELOC("IBM,CPB"))) + return PLATFORM_CELL; +#endif i += sl + 1; } } #ifdef CONFIG_PPC64 - /* If not a mac, try to figure out if it's an IBM pSeries or any other - * PAPR compliant platform. We assume it is if : - * - /device_type is "chrp" (please, do NOT use that for future - * non-IBM designs ! - * - it has /rtas - */ - len = prom_getprop(_prom->root, "model", - compat, sizeof(compat)-1); - if (len <= 0) - return PLATFORM_GENERIC; - compat[len] = 0; - if (strcmp(compat, "chrp")) - return PLATFORM_GENERIC; - /* Default to pSeries. We need to know if we are running LPAR */ rtas = call_prom("finddevice", 1, 1, ADDR("/rtas")); - if (!PHANDLE_VALID(rtas)) - return PLATFORM_GENERIC; - x = prom_getproplen(rtas, "ibm,hypertas-functions"); - if (x != PROM_ERROR) { - prom_printf("Hypertas detected, assuming LPAR !\n"); - return PLATFORM_PSERIES_LPAR; + if (PHANDLE_VALID(rtas)) { + int x = prom_getproplen(rtas, "ibm,hypertas-functions"); + if (x != PROM_ERROR) { + prom_printf("Hypertas detected, assuming LPAR !\n"); + return PLATFORM_PSERIES_LPAR; + } } return PLATFORM_PSERIES; #else - return PLATFORM_GENERIC; + return PLATFORM_CHRP; #endif } @@ -2055,6 +2029,7 @@ unsigned long __init prom_init(unsigned long r3, unsigned long r4, { struct prom_t *_prom; unsigned long hdr; + u32 getprop_rval; unsigned long offset = reloc_offset(); #ifdef CONFIG_PPC32 @@ -2085,12 +2060,6 @@ unsigned long __init prom_init(unsigned long r3, unsigned long r4, */ prom_init_stdout(); - /* - * Get default machine type. At this point, we do not differentiate - * between pSeries SMP and pSeries LPAR - */ - RELOC(of_platform) = prom_find_machine_type(); - /* Bail if this is a kdump kernel. */ if (PHYSICAL_START > 0) prom_panic("Error: You can't boot a kdump kernel from OF!\n"); @@ -2100,6 +2069,15 @@ unsigned long __init prom_init(unsigned long r3, unsigned long r4, */ prom_check_initrd(r3, r4); + /* + * Get default machine type. At this point, we do not differentiate + * between pSeries SMP and pSeries LPAR + */ + RELOC(of_platform) = prom_find_machine_type(); + getprop_rval = RELOC(of_platform); + prom_setprop(_prom->chosen, "/chosen", "linux,platform", + &getprop_rval, sizeof(getprop_rval)); + #ifdef CONFIG_PPC_PSERIES /* * On pSeries, inform the firmware about our capabilities diff --git a/trunk/arch/powerpc/kernel/rtas-proc.c b/trunk/arch/powerpc/kernel/rtas-proc.c index 456286cf1d14..1f03fb28cc0a 100644 --- a/trunk/arch/powerpc/kernel/rtas-proc.c +++ b/trunk/arch/powerpc/kernel/rtas-proc.c @@ -257,7 +257,7 @@ static int __init proc_rtas_init(void) { struct proc_dir_entry *entry; - if (!machine_is(pseries)) + if (_machine != PLATFORM_PSERIES && _machine != PLATFORM_PSERIES_LPAR) return 1; rtas_node = of_find_node_by_name(NULL, "rtas"); diff --git a/trunk/arch/powerpc/kernel/rtas.c b/trunk/arch/powerpc/kernel/rtas.c index 06636c927a7e..b5b2add7ad1e 100644 --- a/trunk/arch/powerpc/kernel/rtas.c +++ b/trunk/arch/powerpc/kernel/rtas.c @@ -25,7 +25,6 @@ #include #include #include -#include #include #include #include @@ -33,7 +32,6 @@ #include #include #include -#include struct rtas_t rtas = { .lock = SPIN_LOCK_UNLOCKED @@ -593,7 +591,7 @@ static void rtas_percpu_suspend_me(void *info) data->waiting = 0; data->args->args[data->args->nargs] = rtas_call(ibm_suspend_me_token, 0, 1, NULL); - for_each_possible_cpu(i) + for_each_cpu(i) plpar_hcall_norets(H_PROD,i); } else { data->waiting = -EBUSY; @@ -626,7 +624,7 @@ static int rtas_ibm_suspend_me(struct rtas_args *args) /* Prod each CPU. This won't hurt, and will wake * anyone we successfully put to sleep with H_Join */ - for_each_possible_cpu(i) + for_each_cpu(i) plpar_hcall_norets(H_PROD, i); return data.waiting; @@ -769,7 +767,7 @@ void __init rtas_initialize(void) * the stop-self token if any */ #ifdef CONFIG_PPC64 - if (machine_is(pseries) && firmware_has_feature(FW_FEATURE_LPAR)) { + if (_machine == PLATFORM_PSERIES_LPAR) { rtas_region = min(lmb.rmo_size, RTAS_INSTANTIATE_MAX); ibm_suspend_me_token = rtas_token("ibm,suspend-me"); } diff --git a/trunk/arch/powerpc/kernel/setup-common.c b/trunk/arch/powerpc/kernel/setup-common.c index c607f3b9ca17..c1d62bf11f29 100644 --- a/trunk/arch/powerpc/kernel/setup-common.c +++ b/trunk/arch/powerpc/kernel/setup-common.c @@ -9,9 +9,6 @@ * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. */ - -#undef DEBUG - #include #include #include @@ -44,7 +41,6 @@ #include #include #include -#include #include #include #include @@ -60,6 +56,8 @@ #include "setup.h" +#undef DEBUG + #ifdef DEBUG #include #define DBG(fmt...) udbg_printf(fmt) @@ -67,12 +65,10 @@ #define DBG(fmt...) #endif -/* The main machine-dep calls structure - */ -struct machdep_calls ppc_md; -EXPORT_SYMBOL(ppc_md); -struct machdep_calls *machine_id; -EXPORT_SYMBOL(machine_id); +#ifdef CONFIG_PPC_MULTIPLATFORM +int _machine = 0; +EXPORT_SYMBOL(_machine); +#endif unsigned long klimit = (unsigned long) _end; @@ -172,8 +168,7 @@ static int show_cpuinfo(struct seq_file *m, void *v) bogosum/(500000/HZ), bogosum/(5000/HZ) % 100); #endif /* CONFIG_SMP && CONFIG_PPC32 */ seq_printf(m, "timebase\t: %lu\n", ppc_tb_freq); - if (ppc_md.name) - seq_printf(m, "platform\t: %s\n", ppc_md.name); + if (ppc_md.show_cpuinfo != NULL) ppc_md.show_cpuinfo(m); @@ -357,13 +352,12 @@ void __init check_for_initrd(void) * must be called before using this. * * While we're here, we may as well set the "physical" cpu ids in the paca. - * - * NOTE: This must match the parsing done in early_init_dt_scan_cpus. */ void __init smp_setup_cpu_maps(void) { struct device_node *dn = NULL; int cpu = 0; + int swap_cpuid = 0; while ((dn = of_find_node_by_type(dn, "cpu")) && cpu < NR_CPUS) { int *intserv; @@ -382,17 +376,30 @@ void __init smp_setup_cpu_maps(void) for (j = 0; j < nthreads && cpu < NR_CPUS; j++) { cpu_set(cpu, cpu_present_map); set_hard_smp_processor_id(cpu, intserv[j]); + + if (intserv[j] == boot_cpuid_phys) + swap_cpuid = cpu; cpu_set(cpu, cpu_possible_map); cpu++; } } + /* Swap CPU id 0 with boot_cpuid_phys, so we can always assume that + * boot cpu is logical 0. + */ + if (boot_cpuid_phys != get_hard_smp_processor_id(0)) { + u32 tmp; + tmp = get_hard_smp_processor_id(0); + set_hard_smp_processor_id(0, boot_cpuid_phys); + set_hard_smp_processor_id(swap_cpuid, tmp); + } + #ifdef CONFIG_PPC64 /* * On pSeries LPAR, we need to know how many cpus * could possibly be added to this partition. */ - if (machine_is(pseries) && firmware_has_feature(FW_FEATURE_LPAR) && + if (_machine == PLATFORM_PSERIES_LPAR && (dn = of_find_node_by_path("/rtas"))) { int num_addr_cell, num_size_cell, maxcpus; unsigned int *ireg; @@ -431,7 +438,7 @@ void __init smp_setup_cpu_maps(void) /* * Do the sibling map; assume only two threads per processor. */ - for_each_possible_cpu(cpu) { + for_each_cpu(cpu) { cpu_set(cpu, cpu_sibling_map[cpu]); if (cpu_has_feature(CPU_FTR_SMT)) cpu_set(cpu ^ 0x1, cpu_sibling_map[cpu]); @@ -461,34 +468,3 @@ static int __init early_xmon(char *p) } early_param("xmon", early_xmon); #endif - -void probe_machine(void) -{ - extern struct machdep_calls __machine_desc_start; - extern struct machdep_calls __machine_desc_end; - - /* - * Iterate all ppc_md structures until we find the proper - * one for the current machine type - */ - DBG("Probing machine type ...\n"); - - for (machine_id = &__machine_desc_start; - machine_id < &__machine_desc_end; - machine_id++) { - DBG(" %s ...", machine_id->name); - memcpy(&ppc_md, machine_id, sizeof(struct machdep_calls)); - if (ppc_md.probe()) { - DBG(" match !\n"); - break; - } - DBG("\n"); - } - /* What can we do if we didn't find ? */ - if (machine_id >= &__machine_desc_end) { - DBG("No suitable machine found !\n"); - for (;;); - } - - printk(KERN_INFO "Using %s machine description\n", ppc_md.name); -} diff --git a/trunk/arch/powerpc/kernel/setup_32.c b/trunk/arch/powerpc/kernel/setup_32.c index a72bf5dceeee..dc2770df25b3 100644 --- a/trunk/arch/powerpc/kernel/setup_32.c +++ b/trunk/arch/powerpc/kernel/setup_32.c @@ -53,6 +53,9 @@ extern void platform_init(void); extern void bootx_init(unsigned long r4, unsigned long phys); +extern void ppc6xx_idle(void); +extern void power4_idle(void); + boot_infos_t *boot_infos; struct ide_machdep_calls ppc_ide_md; @@ -67,6 +70,10 @@ unsigned int DMA_MODE_WRITE; int have_of = 1; #ifdef CONFIG_PPC_MULTIPLATFORM +extern void prep_init(void); +extern void pmac_init(void); +extern void chrp_init(void); + dev_t boot_dev; #endif /* CONFIG_PPC_MULTIPLATFORM */ @@ -78,6 +85,9 @@ unsigned long SYSRQ_KEY = 0x54; unsigned long vgacon_remap_base; #endif +struct machdep_calls ppc_md; +EXPORT_SYMBOL(ppc_md); + /* * These are used in binfmt_elf.c to put aux entries on the stack * for each elf executable being started. @@ -101,7 +111,7 @@ unsigned long __init early_init(unsigned long dt_ptr) /* First zero the BSS -- use memset_io, some platforms don't have * caches on yet */ - memset_io((void __iomem *)PTRRELOC(&__bss_start), 0, _end - __bss_start); + memset_io(PTRRELOC(&__bss_start), 0, _end - __bss_start); /* * Identify the CPU type and fix up code sections @@ -113,6 +123,48 @@ unsigned long __init early_init(unsigned long dt_ptr) return KERNELBASE + offset; } +#ifdef CONFIG_PPC_MULTIPLATFORM +/* + * The PPC_MULTIPLATFORM version of platform_init... + */ +void __init platform_init(void) +{ + /* if we didn't get any bootinfo telling us what we are... */ + if (_machine == 0) { + /* prep boot loader tells us if we're prep or not */ + if ( *(unsigned long *)(KERNELBASE) == (0xdeadc0de) ) + _machine = _MACH_prep; + } + +#ifdef CONFIG_PPC_PREP + /* not much more to do here, if prep */ + if (_machine == _MACH_prep) { + prep_init(); + return; + } +#endif + +#ifdef CONFIG_ADB + if (strstr(cmd_line, "adb_sync")) { + extern int __adb_probe_sync; + __adb_probe_sync = 1; + } +#endif /* CONFIG_ADB */ + + switch (_machine) { +#ifdef CONFIG_PPC_PMAC + case _MACH_Pmac: + pmac_init(); + break; +#endif +#ifdef CONFIG_PPC_CHRP + case _MACH_chrp: + chrp_init(); + break; +#endif + } +} +#endif /* * Find out what kind of machine we're on and save any data we need @@ -138,17 +190,11 @@ void __init machine_init(unsigned long dt_ptr, unsigned long phys) strlcpy(cmd_line, CONFIG_CMDLINE, sizeof(cmd_line)); #endif /* CONFIG_CMDLINE */ -#ifdef CONFIG_PPC_MULTIPLATFORM - probe_machine(); -#else - /* Base init based on machine type. Obsoloete, please kill ! */ + /* Base init based on machine type */ platform_init(); -#endif #ifdef CONFIG_6xx - if (cpu_has_feature(CPU_FTR_CAN_DOZE) || - cpu_has_feature(CPU_FTR_CAN_NAP)) - ppc_md.power_save = ppc6xx_idle; + ppc_md.power_save = ppc6xx_idle; #endif if (ppc_md.progress) @@ -226,7 +272,7 @@ int __init ppc_init(void) if ( ppc_md.progress ) ppc_md.progress(" ", 0xffff); /* register CPU devices */ - for_each_possible_cpu(i) + for_each_cpu(i) register_cpu(&cpu_devices[i], i, NULL); /* call platform init */ @@ -306,6 +352,12 @@ void __init setup_arch(char **cmdline_p) do_init_bootmem(); if ( ppc_md.progress ) ppc_md.progress("setup_arch: bootmem", 0x3eab); +#ifdef CONFIG_PPC_OCP + /* Initialize OCP device list */ + ocp_early_init(); + if ( ppc_md.progress ) ppc_md.progress("ocp: exit", 0x3eab); +#endif + #ifdef CONFIG_DUMMY_CONSOLE conswitchp = &dummy_con; #endif @@ -314,4 +366,7 @@ void __init setup_arch(char **cmdline_p) if ( ppc_md.progress ) ppc_md.progress("arch: exit", 0x3eab); paging_init(); + + /* this is for modules since _machine can be a define -- Cort */ + ppc_md.ppc_machine = _machine; } diff --git a/trunk/arch/powerpc/kernel/setup_64.c b/trunk/arch/powerpc/kernel/setup_64.c index 59aa92cd6fa4..e20c1fae3423 100644 --- a/trunk/arch/powerpc/kernel/setup_64.c +++ b/trunk/arch/powerpc/kernel/setup_64.c @@ -73,6 +73,7 @@ int have_of = 1; int boot_cpuid = 0; +int boot_cpuid_phys = 0; dev_t boot_dev; u64 ppc64_pft_size; @@ -95,6 +96,11 @@ int dcache_bsize; int icache_bsize; int ucache_bsize; +/* The main machine-dep calls structure + */ +struct machdep_calls ppc_md; +EXPORT_SYMBOL(ppc_md); + #ifdef CONFIG_MAGIC_SYSRQ unsigned long SYSRQ_KEY; #endif /* CONFIG_MAGIC_SYSRQ */ @@ -155,6 +161,32 @@ early_param("smt-enabled", early_smt_enabled); #define check_smt_enabled() #endif /* CONFIG_SMP */ +extern struct machdep_calls pSeries_md; +extern struct machdep_calls pmac_md; +extern struct machdep_calls maple_md; +extern struct machdep_calls cell_md; +extern struct machdep_calls iseries_md; + +/* Ultimately, stuff them in an elf section like initcalls... */ +static struct machdep_calls __initdata *machines[] = { +#ifdef CONFIG_PPC_PSERIES + &pSeries_md, +#endif /* CONFIG_PPC_PSERIES */ +#ifdef CONFIG_PPC_PMAC + &pmac_md, +#endif /* CONFIG_PPC_PMAC */ +#ifdef CONFIG_PPC_MAPLE + &maple_md, +#endif /* CONFIG_PPC_MAPLE */ +#ifdef CONFIG_PPC_CELL + &cell_md, +#endif +#ifdef CONFIG_PPC_ISERIES + &iseries_md, +#endif + NULL +}; + /* * Early initialization entry point. This is called by head.S * with MMU translation disabled. We rely on the "feature" of @@ -176,10 +208,13 @@ early_param("smt-enabled", early_smt_enabled); void __init early_setup(unsigned long dt_ptr) { + struct paca_struct *lpaca = get_paca(); + static struct machdep_calls **mach; + /* Enable early debugging if any specified (see udbg.h) */ udbg_early_init(); - DBG(" -> early_setup(), dt_ptr: 0x%lx\n", dt_ptr); + DBG(" -> early_setup()\n"); /* * Do early initializations using the flattened device @@ -188,16 +223,22 @@ void __init early_setup(unsigned long dt_ptr) */ early_init_devtree(__va(dt_ptr)); - /* Now we know the logical id of our boot cpu, setup the paca. */ - setup_boot_paca(); - - /* Fix up paca fields required for the boot cpu */ - get_paca()->cpu_start = 1; - get_paca()->stab_real = __pa((u64)&initial_stab); - get_paca()->stab_addr = (u64)&initial_stab; + /* + * Iterate all ppc_md structures until we find the proper + * one for the current machine type + */ + DBG("Probing machine type for platform %x...\n", _machine); - /* Probe the machine type */ - probe_machine(); + for (mach = machines; *mach; mach++) { + if ((*mach)->probe(_machine)) + break; + } + /* What can we do if we didn't find ? */ + if (*mach == NULL) { + DBG("No suitable machine found !\n"); + for (;;); + } + ppc_md = **mach; #ifdef CONFIG_CRASH_DUMP kdump_setup(); @@ -219,7 +260,7 @@ void __init early_setup(unsigned long dt_ptr) if (cpu_has_feature(CPU_FTR_SLB)) slb_initialize(); else - stab_initialize(get_paca()->stab_real); + stab_initialize(lpaca->stab_real); } DBG(" <- early_setup()\n"); @@ -299,7 +340,7 @@ static void __init initialize_cache_info(void) const char *dc, *ic; /* Then read cache informations */ - if (machine_is(powermac)) { + if (_machine == PLATFORM_POWERMAC) { dc = "d-cache-block-size"; ic = "i-cache-block-size"; } else { @@ -443,6 +484,7 @@ void __init setup_system(void) printk("ppc64_pft_size = 0x%lx\n", ppc64_pft_size); printk("ppc64_interrupt_controller = 0x%ld\n", ppc64_interrupt_controller); + printk("platform = 0x%x\n", _machine); printk("physicalMemorySize = 0x%lx\n", lmb_phys_mem_size()); printk("ppc64_caches.dcache_line_size = 0x%x\n", ppc64_caches.dline_size); @@ -474,7 +516,7 @@ static void __init irqstack_early_init(void) * interrupt stacks must be under 256MB, we cannot afford to take * SLB misses on them. */ - for_each_possible_cpu(i) { + for_each_cpu(i) { softirq_ctx[i] = (struct thread_info *) __va(lmb_alloc_base(THREAD_SIZE, THREAD_SIZE, 0x10000000)); @@ -507,7 +549,7 @@ static void __init emergency_stack_init(void) */ limit = min(0x10000000UL, lmb.rmo_size); - for_each_possible_cpu(i) + for_each_cpu(i) paca[i].emergency_sp = __va(lmb_alloc_base(HW_PAGE_SIZE, 128, limit)) + HW_PAGE_SIZE; } @@ -560,6 +602,12 @@ void __init setup_arch(char **cmdline_p) ppc_md.setup_arch(); + /* Use the default idle loop if the platform hasn't provided one. */ + if (NULL == ppc_md.idle_loop) { + ppc_md.idle_loop = default_idle; + printk(KERN_INFO "Using default idle loop\n"); + } + paging_init(); ppc64_boot_msg(0x15, "Setup Done"); } @@ -624,7 +672,7 @@ void __init setup_per_cpu_areas(void) size = PERCPU_ENOUGH_ROOM; #endif - for_each_possible_cpu(i) { + for_each_cpu(i) { ptr = alloc_bootmem_node(NODE_DATA(cpu_to_node(i)), size); if (!ptr) panic("Cannot allocate cpu data for CPU %d\n", i); diff --git a/trunk/arch/powerpc/kernel/signal_32.c b/trunk/arch/powerpc/kernel/signal_32.c index 01e3c08cb550..d7a4e814974d 100644 --- a/trunk/arch/powerpc/kernel/signal_32.c +++ b/trunk/arch/powerpc/kernel/signal_32.c @@ -42,7 +42,6 @@ #include #include -#include #include #include #ifdef CONFIG_PPC64 diff --git a/trunk/arch/powerpc/kernel/signal_64.c b/trunk/arch/powerpc/kernel/signal_64.c index 27f65b95184d..47f910380a6a 100644 --- a/trunk/arch/powerpc/kernel/signal_64.c +++ b/trunk/arch/powerpc/kernel/signal_64.c @@ -33,7 +33,6 @@ #include #include #include -#include #include #define DEBUG_SIG 0 @@ -212,7 +211,7 @@ static inline void __user * get_sigframe(struct k_sigaction *ka, struct pt_regs /* Default to using normal stack */ newsp = regs->gpr[1]; - if ((ka->sa.sa_flags & SA_ONSTACK) && current->sas_ss_size) { + if (ka->sa.sa_flags & SA_ONSTACK) { if (! on_sig_stack(regs->gpr[1])) newsp = (current->sas_ss_sp + current->sas_ss_size); } diff --git a/trunk/arch/powerpc/kernel/smp.c b/trunk/arch/powerpc/kernel/smp.c index 530f7dba0bd2..805eaedbc308 100644 --- a/trunk/arch/powerpc/kernel/smp.c +++ b/trunk/arch/powerpc/kernel/smp.c @@ -362,7 +362,7 @@ void __init smp_prepare_cpus(unsigned int max_cpus) smp_space_timers(max_cpus); - for_each_possible_cpu(cpu) + for_each_cpu(cpu) if (cpu != boot_cpuid) smp_create_idle(cpu); } diff --git a/trunk/arch/powerpc/kernel/syscalls.c b/trunk/arch/powerpc/kernel/syscalls.c index 9b69d99a9103..ad895c99813b 100644 --- a/trunk/arch/powerpc/kernel/syscalls.c +++ b/trunk/arch/powerpc/kernel/syscalls.c @@ -40,7 +40,6 @@ #include #include #include -#include #include #include diff --git a/trunk/arch/powerpc/kernel/sysfs.c b/trunk/arch/powerpc/kernel/sysfs.c index 73560ef6f802..0f0c3a9ae2e5 100644 --- a/trunk/arch/powerpc/kernel/sysfs.c +++ b/trunk/arch/powerpc/kernel/sysfs.c @@ -65,20 +65,20 @@ static int __init smt_setup(void) unsigned int cpu; if (!cpu_has_feature(CPU_FTR_SMT)) - return -ENODEV; + return 1; options = find_path_device("/options"); if (!options) - return -ENODEV; + return 1; val = (unsigned int *)get_property(options, "ibm,smt-snooze-delay", NULL); if (!smt_snooze_cmdline && val) { - for_each_possible_cpu(cpu) + for_each_cpu(cpu) per_cpu(smt_snooze_delay, cpu) = *val; } - return 0; + return 1; } __initcall(smt_setup); @@ -93,7 +93,7 @@ static int __init setup_smt_snooze_delay(char *str) smt_snooze_cmdline = 1; if (get_option(&str, &snooze)) { - for_each_possible_cpu(cpu) + for_each_cpu(cpu) per_cpu(smt_snooze_delay, cpu) = snooze; } @@ -347,7 +347,7 @@ static int __init topology_init(void) register_cpu_notifier(&sysfs_cpu_nb); - for_each_possible_cpu(cpu) { + for_each_cpu(cpu) { struct cpu *c = &per_cpu(cpu_devices, cpu); #ifdef CONFIG_NUMA diff --git a/trunk/arch/powerpc/kernel/time.c b/trunk/arch/powerpc/kernel/time.c index 24e3ad756de0..4a27218a086c 100644 --- a/trunk/arch/powerpc/kernel/time.c +++ b/trunk/arch/powerpc/kernel/time.c @@ -261,7 +261,7 @@ void snapshot_timebases(void) if (!cpu_has_feature(CPU_FTR_PURR)) return; - for_each_possible_cpu(cpu) + for_each_cpu(cpu) spin_lock_init(&per_cpu(cpu_purr_data, cpu).lock); on_each_cpu(snapshot_tb_and_purr, NULL, 0, 1); } @@ -751,7 +751,7 @@ void __init smp_space_timers(unsigned int max_cpus) * systems works better if the two threads' timebase interrupts * are staggered by half a jiffy with respect to each other. */ - for_each_possible_cpu(i) { + for_each_cpu(i) { if (i == boot_cpuid) continue; if (i == (boot_cpuid ^ 1)) diff --git a/trunk/arch/powerpc/kernel/traps.c b/trunk/arch/powerpc/kernel/traps.c index 4cbde211eb69..9763faab6739 100644 --- a/trunk/arch/powerpc/kernel/traps.c +++ b/trunk/arch/powerpc/kernel/traps.c @@ -97,6 +97,7 @@ static DEFINE_SPINLOCK(die_lock); int die(const char *str, struct pt_regs *regs, long err) { static int die_counter, crash_dump_start = 0; + int nl = 0; if (debugger(regs)) return 1; @@ -105,7 +106,7 @@ int die(const char *str, struct pt_regs *regs, long err) spin_lock_irq(&die_lock); bust_spinlocks(1); #ifdef CONFIG_PMAC_BACKLIGHT - if (machine_is(powermac)) { + if (_machine == _MACH_Pmac) { set_backlight_enable(1); set_backlight_level(BACKLIGHT_MAX); } @@ -113,18 +114,46 @@ int die(const char *str, struct pt_regs *regs, long err) printk("Oops: %s, sig: %ld [#%d]\n", str, err, ++die_counter); #ifdef CONFIG_PREEMPT printk("PREEMPT "); + nl = 1; #endif #ifdef CONFIG_SMP printk("SMP NR_CPUS=%d ", NR_CPUS); + nl = 1; #endif #ifdef CONFIG_DEBUG_PAGEALLOC printk("DEBUG_PAGEALLOC "); + nl = 1; #endif #ifdef CONFIG_NUMA printk("NUMA "); + nl = 1; #endif - printk("%s\n", ppc_md.name ? "" : ppc_md.name); - +#ifdef CONFIG_PPC64 + switch (_machine) { + case PLATFORM_PSERIES: + printk("PSERIES "); + nl = 1; + break; + case PLATFORM_PSERIES_LPAR: + printk("PSERIES LPAR "); + nl = 1; + break; + case PLATFORM_ISERIES_LPAR: + printk("ISERIES LPAR "); + nl = 1; + break; + case PLATFORM_POWERMAC: + printk("POWERMAC "); + nl = 1; + break; + case PLATFORM_CELL: + printk("CELL "); + nl = 1; + break; + } +#endif + if (nl) + printk("\n"); print_modules(); show_regs(regs); bust_spinlocks(0); diff --git a/trunk/arch/powerpc/kernel/vdso.c b/trunk/arch/powerpc/kernel/vdso.c index 573afb68d69e..ec8370368423 100644 --- a/trunk/arch/powerpc/kernel/vdso.c +++ b/trunk/arch/powerpc/kernel/vdso.c @@ -33,7 +33,6 @@ #include #include #include -#include #include #include @@ -668,13 +667,7 @@ void __init vdso_init(void) vdso_data->version.major = SYSTEMCFG_MAJOR; vdso_data->version.minor = SYSTEMCFG_MINOR; vdso_data->processor = mfspr(SPRN_PVR); - /* - * Fake the old platform number for pSeries and iSeries and add - * in LPAR bit if necessary - */ - vdso_data->platform = machine_is(iseries) ? 0x200 : 0x100; - if (firmware_has_feature(FW_FEATURE_LPAR)) - vdso_data->platform |= 1; + vdso_data->platform = _machine; vdso_data->physicalMemorySize = lmb_phys_mem_size(); vdso_data->dcache_size = ppc64_caches.dsize; vdso_data->dcache_line_size = ppc64_caches.dline_size; diff --git a/trunk/arch/powerpc/kernel/vdso32/sigtramp.S b/trunk/arch/powerpc/kernel/vdso32/sigtramp.S index 0c6a37b29dde..e04642781917 100644 --- a/trunk/arch/powerpc/kernel/vdso32/sigtramp.S +++ b/trunk/arch/powerpc/kernel/vdso32/sigtramp.S @@ -261,7 +261,7 @@ V_FUNCTION_END(__kernel_sigtramp_rt32) .Lcie_start: .long 0 /* CIE ID */ .byte 1 /* Version number */ - .string "zRS" /* NUL-terminated augmentation string */ + .string "zR" /* NUL-terminated augmentation string */ .uleb128 4 /* Code alignment factor */ .sleb128 -4 /* Data alignment factor */ .byte 67 /* Return address register column, ap */ diff --git a/trunk/arch/powerpc/kernel/vdso64/sigtramp.S b/trunk/arch/powerpc/kernel/vdso64/sigtramp.S index 7479edb101b8..31b604ab56de 100644 --- a/trunk/arch/powerpc/kernel/vdso64/sigtramp.S +++ b/trunk/arch/powerpc/kernel/vdso64/sigtramp.S @@ -263,7 +263,7 @@ V_FUNCTION_END(__kernel_sigtramp_rt64) .Lcie_start: .long 0 /* CIE ID */ .byte 1 /* Version number */ - .string "zRS" /* NUL-terminated augmentation string */ + .string "zR" /* NUL-terminated augmentation string */ .uleb128 4 /* Code alignment factor */ .sleb128 -8 /* Data alignment factor */ .byte 67 /* Return address register column, ap */ diff --git a/trunk/arch/powerpc/kernel/vmlinux.lds.S b/trunk/arch/powerpc/kernel/vmlinux.lds.S index fe79c2584cb0..7fa7b15fd8e6 100644 --- a/trunk/arch/powerpc/kernel/vmlinux.lds.S +++ b/trunk/arch/powerpc/kernel/vmlinux.lds.S @@ -1,11 +1,9 @@ #include #ifdef CONFIG_PPC64 #include -#define PROVIDE32(x) PROVIDE(__unused__##x) #else #define PAGE_SIZE 4096 #define KERNELBASE CONFIG_KERNEL_START -#define PROVIDE32(x) PROVIDE(x) #endif #include @@ -20,42 +18,43 @@ jiffies = jiffies_64 + 4; #endif SECTIONS { - /* Sections to be discarded. */ - /DISCARD/ : { - *(.exitcall.exit) - *(.exit.data) - } - - . = KERNELBASE; - -/* - * Text, read only data and other permanent read-only sections - */ - - /* Text and gots */ - .text : { - *(.text .text.*) - SCHED_TEXT - LOCK_TEXT - KPROBES_TEXT - *(.fixup) - + /* Sections to be discarded. */ + /DISCARD/ : { + *(.exitcall.exit) + *(.exit.data) + } + + . = KERNELBASE; + + /* Read-only sections, merged into text segment: */ + .text : { + *(.text .text.*) + SCHED_TEXT + LOCK_TEXT + KPROBES_TEXT + *(.fixup) #ifdef CONFIG_PPC32 - *(.got1) - __got2_start = .; - *(.got2) - __got2_end = .; -#endif /* CONFIG_PPC32 */ - - . = ALIGN(PAGE_SIZE); - _etext = .; - PROVIDE32 (etext = .); - } + *(.got1) + __got2_start = .; + *(.got2) + __got2_end = .; +#else + . = ALIGN(PAGE_SIZE); + _etext = .; +#endif + } +#ifdef CONFIG_PPC32 + _etext = .; + PROVIDE (etext = .); - /* Read-only data */ - RODATA + RODATA + .fini : { *(.fini) } =0 + .ctors : { *(.ctors) } + .dtors : { *(.dtors) } + + .fixup : { *(.fixup) } +#endif - /* Exception & bug tables */ __ex_table : { __start___ex_table = .; *(__ex_table) @@ -68,172 +67,192 @@ SECTIONS __stop___bug_table = .; } -/* - * Init sections discarded at runtime - */ - . = ALIGN(PAGE_SIZE); - __init_begin = .; - - .init.text : { - _sinittext = .; - *(.init.text) - _einittext = .; - } - - /* .exit.text is discarded at runtime, not link time, - * to deal with references from __bug_table - */ - .exit.text : { *(.exit.text) } - - .init.data : { - *(.init.data); - __vtop_table_begin = .; - *(.vtop_fixup); - __vtop_table_end = .; - __ptov_table_begin = .; - *(.ptov_fixup); - __ptov_table_end = .; - } - - . = ALIGN(16); - .init.setup : { - __setup_start = .; - *(.init.setup) - __setup_end = .; - } - - .initcall.init : { - __initcall_start = .; - *(.initcall1.init) - *(.initcall2.init) - *(.initcall3.init) - *(.initcall4.init) - *(.initcall5.init) - *(.initcall6.init) - *(.initcall7.init) - __initcall_end = .; - } - - .con_initcall.init : { - __con_initcall_start = .; - *(.con_initcall.init) - __con_initcall_end = .; - } - - SECURITY_INIT - - . = ALIGN(8); +#ifdef CONFIG_PPC64 __ftr_fixup : { __start___ftr_fixup = .; *(__ftr_fixup) __stop___ftr_fixup = .; } - . = ALIGN(PAGE_SIZE); - .init.ramfs : { - __initramfs_start = .; - *(.init.ramfs) - __initramfs_end = .; - } + RODATA +#endif #ifdef CONFIG_PPC32 - . = ALIGN(32); -#else - . = ALIGN(128); + /* Read-write section, merged into data segment: */ + . = ALIGN(PAGE_SIZE); + _sdata = .; + .data : + { + *(.data) + *(.data1) + *(.sdata) + *(.sdata2) + *(.got.plt) *(.got) + *(.dynamic) + CONSTRUCTORS + } + + . = ALIGN(PAGE_SIZE); + __nosave_begin = .; + .data_nosave : { *(.data.nosave) } + . = ALIGN(PAGE_SIZE); + __nosave_end = .; + + . = ALIGN(32); + .data.cacheline_aligned : { *(.data.cacheline_aligned) } + + _edata = .; + PROVIDE (edata = .); + + . = ALIGN(8192); + .data.init_task : { *(.data.init_task) } #endif - .data.percpu : { - __per_cpu_start = .; - *(.data.percpu) - __per_cpu_end = .; - } - . = ALIGN(8); - .machine.desc : { - __machine_desc_start = . ; - *(.machine.desc) - __machine_desc_end = . ; - } - - /* freed after init ends here */ - . = ALIGN(PAGE_SIZE); - __init_end = .; - -/* - * And now the various read/write data - */ - - . = ALIGN(PAGE_SIZE); - _sdata = .; + /* will be freed after init */ + . = ALIGN(PAGE_SIZE); + __init_begin = .; + .init.text : { + _sinittext = .; + *(.init.text) + _einittext = .; + } +#ifdef CONFIG_PPC32 + /* .exit.text is discarded at runtime, not link time, + to deal with references from __bug_table */ + .exit.text : { *(.exit.text) } +#endif + .init.data : { + *(.init.data); + __vtop_table_begin = .; + *(.vtop_fixup); + __vtop_table_end = .; + __ptov_table_begin = .; + *(.ptov_fixup); + __ptov_table_end = .; + } + + . = ALIGN(16); + .init.setup : { + __setup_start = .; + *(.init.setup) + __setup_end = .; + } + + .initcall.init : { + __initcall_start = .; + *(.initcall1.init) + *(.initcall2.init) + *(.initcall3.init) + *(.initcall4.init) + *(.initcall5.init) + *(.initcall6.init) + *(.initcall7.init) + __initcall_end = .; + } + + .con_initcall.init : { + __con_initcall_start = .; + *(.con_initcall.init) + __con_initcall_end = .; + } + + SECURITY_INIT #ifdef CONFIG_PPC32 - .data : - { - *(.data) - *(.sdata) - *(.got.plt) *(.got) - } + __start___ftr_fixup = .; + __ftr_fixup : { *(__ftr_fixup) } + __stop___ftr_fixup = .; #else - .data : { - *(.data .data.rel* .toc1) - *(.branch_lt) - } - - .opd : { - *(.opd) - } - - .got : { - __toc_start = .; - *(.got) - *(.toc) - } + . = ALIGN(PAGE_SIZE); + .init.ramfs : { + __initramfs_start = .; + *(.init.ramfs) + __initramfs_end = .; + } #endif - . = ALIGN(PAGE_SIZE); - _edata = .; - PROVIDE32 (edata = .); - - /* The initial task and kernel stack */ #ifdef CONFIG_PPC32 - . = ALIGN(8192); -#else - . = ALIGN(16384); + . = ALIGN(32); #endif - .data.init_task : { - *(.data.init_task) - } + .data.percpu : { + __per_cpu_start = .; + *(.data.percpu) + __per_cpu_end = .; + } - . = ALIGN(PAGE_SIZE); - .data.page_aligned : { - *(.data.page_aligned) - } + . = ALIGN(PAGE_SIZE); +#ifdef CONFIG_PPC64 + . = ALIGN(16384); + __init_end = .; + /* freed after init ends here */ + + /* Read/write sections */ + . = ALIGN(PAGE_SIZE); + . = ALIGN(16384); + _sdata = .; + /* The initial task and kernel stack */ + .data.init_task : { + *(.data.init_task) + } + + . = ALIGN(PAGE_SIZE); + .data.page_aligned : { + *(.data.page_aligned) + } + + .data.cacheline_aligned : { + *(.data.cacheline_aligned) + } + + .data : { + *(.data .data.rel* .toc1) + *(.branch_lt) + } + + .opd : { + *(.opd) + } + + .got : { + __toc_start = .; + *(.got) + *(.toc) + . = ALIGN(PAGE_SIZE); + _edata = .; + } + + . = ALIGN(PAGE_SIZE); +#else + __initramfs_start = .; + .init.ramfs : { + *(.init.ramfs) + } + __initramfs_end = .; - .data.cacheline_aligned : { - *(.data.cacheline_aligned) - } + . = ALIGN(4096); + __init_end = .; - . = ALIGN(PAGE_SIZE); - __data_nosave : { - __nosave_begin = .; - *(.data.nosave) - . = ALIGN(PAGE_SIZE); - __nosave_end = .; - } + . = ALIGN(4096); + _sextratext = .; + _eextratext = .; -/* - * And finally the bss - */ - - .bss : { - __bss_start = .; - *(.sbss) *(.scommon) - *(.dynbss) - *(.bss) - *(COMMON) - __bss_stop = .; - } + __bss_start = .; +#endif + + .bss : { + __bss_start = .; + *(.sbss) *(.scommon) + *(.dynbss) + *(.bss) + *(COMMON) + __bss_stop = .; + } - . = ALIGN(PAGE_SIZE); - _end = . ; - PROVIDE32 (end = .); +#ifdef CONFIG_PPC64 + . = ALIGN(PAGE_SIZE); +#endif + _end = . ; +#ifdef CONFIG_PPC32 + PROVIDE (end = .); +#endif } diff --git a/trunk/arch/powerpc/lib/sstep.c b/trunk/arch/powerpc/lib/sstep.c index c251d9936612..666c2aa55016 100644 --- a/trunk/arch/powerpc/lib/sstep.c +++ b/trunk/arch/powerpc/lib/sstep.c @@ -18,7 +18,7 @@ extern char system_call_common[]; #ifdef CONFIG_PPC64 /* Bits in SRR1 that are copied from MSR */ -#define MSR_MASK 0xffffffff87c0ffffUL +#define MSR_MASK 0xffffffff87c0ffff #else #define MSR_MASK 0x87c0ffff #endif diff --git a/trunk/arch/powerpc/mm/fault.c b/trunk/arch/powerpc/mm/fault.c index 5aea0909a5ec..ec4adcb4bc28 100644 --- a/trunk/arch/powerpc/mm/fault.c +++ b/trunk/arch/powerpc/mm/fault.c @@ -267,29 +267,25 @@ int __kprobes do_page_fault(struct pt_regs *regs, unsigned long address, #endif #if defined(CONFIG_4xx) || defined(CONFIG_BOOKE) pte_t *ptep; - pmd_t *pmdp; /* Since 4xx/Book-E supports per-page execute permission, * we lazily flush dcache to icache. */ ptep = NULL; - if (get_pteptr(mm, address, &ptep, &pmdp)) { - spinlock_t *ptl = pte_lockptr(mm, pmdp); - spin_lock(ptl); - if (pte_present(*ptep)) { - struct page *page = pte_page(*ptep); - - if (!test_bit(PG_arch_1, &page->flags)) { - flush_dcache_icache_page(page); - set_bit(PG_arch_1, &page->flags); - } - pte_update(ptep, 0, _PAGE_HWEXEC); - _tlbie(address); - pte_unmap_unlock(ptep, ptl); - up_read(&mm->mmap_sem); - return 0; + if (get_pteptr(mm, address, &ptep) && pte_present(*ptep)) { + struct page *page = pte_page(*ptep); + + if (! test_bit(PG_arch_1, &page->flags)) { + flush_dcache_icache_page(page); + set_bit(PG_arch_1, &page->flags); } - pte_unmap_unlock(ptep, ptl); + pte_update(ptep, 0, _PAGE_HWEXEC); + _tlbie(address); + pte_unmap(ptep); + up_read(&mm->mmap_sem); + return 0; } + if (ptep != NULL) + pte_unmap(ptep); #endif /* a write */ } else if (is_write) { diff --git a/trunk/arch/powerpc/mm/hash_utils_64.c b/trunk/arch/powerpc/mm/hash_utils_64.c index c006d9039633..89b35c181314 100644 --- a/trunk/arch/powerpc/mm/hash_utils_64.c +++ b/trunk/arch/powerpc/mm/hash_utils_64.c @@ -167,7 +167,7 @@ int htab_bolt_mapping(unsigned long vstart, unsigned long vend, * normal insert callback here. */ #ifdef CONFIG_PPC_ISERIES - if (machine_is(iseries)) + if (_machine == PLATFORM_ISERIES_LPAR) ret = iSeries_hpte_insert(hpteg, va, paddr, tmp_mode, @@ -176,7 +176,7 @@ int htab_bolt_mapping(unsigned long vstart, unsigned long vend, else #endif #ifdef CONFIG_PPC_PSERIES - if (machine_is(pseries) && firmware_has_feature(FW_FEATURE_LPAR)) + if (_machine & PLATFORM_LPAR) ret = pSeries_lpar_hpte_insert(hpteg, va, paddr, tmp_mode, @@ -295,7 +295,8 @@ static void __init htab_init_page_sizes(void) * Not in the device-tree, let's fallback on known size * list for 16M capable GP & GR */ - if (cpu_has_feature(CPU_FTR_16M_PAGE) && !machine_is(iseries)) + if ((_machine != PLATFORM_ISERIES_LPAR) && + cpu_has_feature(CPU_FTR_16M_PAGE)) memcpy(mmu_psize_defs, mmu_psize_defaults_gp, sizeof(mmu_psize_defaults_gp)); found: diff --git a/trunk/arch/powerpc/mm/mem.c b/trunk/arch/powerpc/mm/mem.c index 741dd8802d49..5e435a9c3431 100644 --- a/trunk/arch/powerpc/mm/mem.c +++ b/trunk/arch/powerpc/mm/mem.c @@ -342,7 +342,7 @@ void __init mem_init(void) #ifdef CONFIG_NEED_MULTIPLE_NODES for_each_online_node(nid) { if (NODE_DATA(nid)->node_spanned_pages != 0) { - printk("freeing bootmem node %d\n", nid); + printk("freeing bootmem node %x\n", nid); totalram_pages += free_all_bootmem_node(NODE_DATA(nid)); } diff --git a/trunk/arch/powerpc/mm/numa.c b/trunk/arch/powerpc/mm/numa.c index 0a335f34974c..e89b22aa539e 100644 --- a/trunk/arch/powerpc/mm/numa.c +++ b/trunk/arch/powerpc/mm/numa.c @@ -756,7 +756,6 @@ int hot_add_scn_to_nid(unsigned long scn_addr) struct device_node *memory = NULL; nodemask_t nodes; int default_nid = any_online_node(NODE_MASK_ALL); - int nid; if (!numa_enabled || (min_common_depth < 0)) return default_nid; @@ -791,7 +790,6 @@ int hot_add_scn_to_nid(unsigned long scn_addr) goto ha_new_range; } BUG(); /* section address should be found above */ - return 0; /* Temporary code to ensure that returned node is not empty */ got_nid: diff --git a/trunk/arch/powerpc/mm/pgtable_32.c b/trunk/arch/powerpc/mm/pgtable_32.c index 90628601fac7..d296eb6b4545 100644 --- a/trunk/arch/powerpc/mm/pgtable_32.c +++ b/trunk/arch/powerpc/mm/pgtable_32.c @@ -372,7 +372,7 @@ void __init io_block_mapping(unsigned long virt, phys_addr_t phys, * the PTE pointer is unmodified if PTE is not found. */ int -get_pteptr(struct mm_struct *mm, unsigned long addr, pte_t **ptep, pmd_t **pmdp) +get_pteptr(struct mm_struct *mm, unsigned long addr, pte_t **ptep) { pgd_t *pgd; pmd_t *pmd; @@ -387,8 +387,6 @@ get_pteptr(struct mm_struct *mm, unsigned long addr, pte_t **ptep, pmd_t **pmdp) if (pte) { retval = 1; *ptep = pte; - if (pmdp) - *pmdp = pmd; /* XXX caller needs to do pte_unmap, yuck */ } } @@ -426,7 +424,7 @@ unsigned long iopa(unsigned long addr) mm = &init_mm; pa = 0; - if (get_pteptr(mm, addr, &pte, NULL)) { + if (get_pteptr(mm, addr, &pte)) { pa = (pte_val(*pte) & PAGE_MASK) | (addr & ~PAGE_MASK); pte_unmap(pte); } diff --git a/trunk/arch/powerpc/mm/stab.c b/trunk/arch/powerpc/mm/stab.c index 4a9291d9fef8..91d25fb27f89 100644 --- a/trunk/arch/powerpc/mm/stab.c +++ b/trunk/arch/powerpc/mm/stab.c @@ -239,7 +239,7 @@ void stabs_alloc(void) if (cpu_has_feature(CPU_FTR_SLB)) return; - for_each_possible_cpu(cpu) { + for_each_cpu(cpu) { unsigned long newstab; if (cpu == 0) diff --git a/trunk/arch/powerpc/oprofile/Makefile b/trunk/arch/powerpc/oprofile/Makefile index f5f9859a8338..554cd7c75321 100644 --- a/trunk/arch/powerpc/oprofile/Makefile +++ b/trunk/arch/powerpc/oprofile/Makefile @@ -6,7 +6,7 @@ DRIVER_OBJS := $(addprefix ../../../drivers/oprofile/, \ oprofilefs.o oprofile_stats.o \ timer_int.o ) -oprofile-y := $(DRIVER_OBJS) common.o backtrace.o +oprofile-y := $(DRIVER_OBJS) common.o oprofile-$(CONFIG_PPC64) += op_model_rs64.o op_model_power4.o oprofile-$(CONFIG_FSL_BOOKE) += op_model_fsl_booke.o oprofile-$(CONFIG_PPC32) += op_model_7450.o diff --git a/trunk/arch/powerpc/oprofile/backtrace.c b/trunk/arch/powerpc/oprofile/backtrace.c deleted file mode 100644 index 75f57bc96b40..000000000000 --- a/trunk/arch/powerpc/oprofile/backtrace.c +++ /dev/null @@ -1,126 +0,0 @@ -/** - * Copyright (C) 2005 Brian Rogan , IBM - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. -**/ - -#include -#include -#include -#include - -#define STACK_SP(STACK) *(STACK) - -#define STACK_LR64(STACK) *((unsigned long *)(STACK) + 2) -#define STACK_LR32(STACK) *((unsigned int *)(STACK) + 1) - -#ifdef CONFIG_PPC64 -#define STACK_LR(STACK) STACK_LR64(STACK) -#else -#define STACK_LR(STACK) STACK_LR32(STACK) -#endif - -static unsigned int user_getsp32(unsigned int sp, int is_first) -{ - unsigned int stack_frame[2]; - - if (!access_ok(VERIFY_READ, sp, sizeof(stack_frame))) - return 0; - - /* - * The most likely reason for this is that we returned -EFAULT, - * which means that we've done all that we can do from - * interrupt context. - */ - if (__copy_from_user_inatomic(stack_frame, (void *)(long)sp, - sizeof(stack_frame))) - return 0; - - if (!is_first) - oprofile_add_trace(STACK_LR32(stack_frame)); - - /* - * We do not enforce increasing stack addresses here because - * we may transition to a different stack, eg a signal handler. - */ - return STACK_SP(stack_frame); -} - -#ifdef CONFIG_PPC64 -static unsigned long user_getsp64(unsigned long sp, int is_first) -{ - unsigned long stack_frame[3]; - - if (!access_ok(VERIFY_READ, sp, sizeof(stack_frame))) - return 0; - - if (__copy_from_user_inatomic(stack_frame, (void *)sp, - sizeof(stack_frame))) - return 0; - - if (!is_first) - oprofile_add_trace(STACK_LR64(stack_frame)); - - return STACK_SP(stack_frame); -} -#endif - -static unsigned long kernel_getsp(unsigned long sp, int is_first) -{ - unsigned long *stack_frame = (unsigned long *)sp; - - if (!validate_sp(sp, current, STACK_FRAME_OVERHEAD)) - return 0; - - if (!is_first) - oprofile_add_trace(STACK_LR(stack_frame)); - - /* - * We do not enforce increasing stack addresses here because - * we might be transitioning from an interrupt stack to a kernel - * stack. validate_sp() is designed to understand this, so just - * use it. - */ - return STACK_SP(stack_frame); -} - -void op_powerpc_backtrace(struct pt_regs * const regs, unsigned int depth) -{ - unsigned long sp = regs->gpr[1]; - int first_frame = 1; - - /* We ditch the top stackframe so need to loop through an extra time */ - depth += 1; - - if (!user_mode(regs)) { - while (depth--) { - sp = kernel_getsp(sp, first_frame); - if (!sp) - break; - first_frame = 0; - } - } else { -#ifdef CONFIG_PPC64 - if (!test_thread_flag(TIF_32BIT)) { - while (depth--) { - sp = user_getsp64(sp, first_frame); - if (!sp) - break; - first_frame = 0; - } - - return; - } -#endif - - while (depth--) { - sp = user_getsp32(sp, first_frame); - if (!sp) - break; - first_frame = 0; - } - } -} diff --git a/trunk/arch/powerpc/oprofile/common.c b/trunk/arch/powerpc/oprofile/common.c index 5b1de7e8041e..cc2535be3a73 100644 --- a/trunk/arch/powerpc/oprofile/common.c +++ b/trunk/arch/powerpc/oprofile/common.c @@ -117,10 +117,18 @@ static int op_powerpc_create_files(struct super_block *sb, struct dentry *root) oprofilefs_create_ulong(sb, root, "enable_kernel", &sys.enable_kernel); oprofilefs_create_ulong(sb, root, "enable_user", &sys.enable_user); +#ifdef CONFIG_PPC64 + oprofilefs_create_ulong(sb, root, "backtrace_spinlocks", + &sys.backtrace_spinlocks); +#endif /* Default to tracing both kernel and user */ sys.enable_kernel = 1; sys.enable_user = 1; +#ifdef CONFIG_PPC64 + /* Turn on backtracing through spinlocks by default */ + sys.backtrace_spinlocks = 1; +#endif return 0; } @@ -160,7 +168,6 @@ int __init oprofile_arch_init(struct oprofile_operations *ops) ops->shutdown = op_powerpc_shutdown; ops->start = op_powerpc_start; ops->stop = op_powerpc_stop; - ops->backtrace = op_powerpc_backtrace; printk(KERN_INFO "oprofile: using %s performance monitoring.\n", ops->cpu_type); diff --git a/trunk/arch/powerpc/oprofile/op_model_7450.c b/trunk/arch/powerpc/oprofile/op_model_7450.c index e0491c3c71f1..32abfdbb0eb1 100644 --- a/trunk/arch/powerpc/oprofile/op_model_7450.c +++ b/trunk/arch/powerpc/oprofile/op_model_7450.c @@ -176,13 +176,13 @@ static void fsl7450_handle_interrupt(struct pt_regs *regs, mtmsr(mfmsr() | MSR_PMM); pc = mfspr(SPRN_SIAR); - is_kernel = is_kernel_addr(pc); + is_kernel = (pc >= KERNELBASE); for (i = 0; i < NUM_CTRS; ++i) { val = ctr_read(i); if (val < 0) { if (oprofile_running && ctr[i].enabled) { - oprofile_add_ext_sample(pc, regs, i, is_kernel); + oprofile_add_pc(pc, is_kernel, i); ctr_write(i, reset_value[i]); } else { ctr_write(i, 0); diff --git a/trunk/arch/powerpc/oprofile/op_model_fsl_booke.c b/trunk/arch/powerpc/oprofile/op_model_fsl_booke.c index 93d63e62662f..26539cda6023 100644 --- a/trunk/arch/powerpc/oprofile/op_model_fsl_booke.c +++ b/trunk/arch/powerpc/oprofile/op_model_fsl_booke.c @@ -154,13 +154,13 @@ static void fsl_booke_handle_interrupt(struct pt_regs *regs, mtmsr(mfmsr() | MSR_PMM); pc = regs->nip; - is_kernel = is_kernel_addr(pc); + is_kernel = (pc >= KERNELBASE); for (i = 0; i < num_counters; ++i) { val = ctr_read(i); if (val < 0) { if (oprofile_running && ctr[i].enabled) { - oprofile_add_ext_sample(pc, regs, i, is_kernel); + oprofile_add_pc(pc, is_kernel, i); ctr_write(i, reset_value[i]); } else { ctr_write(i, 0); diff --git a/trunk/arch/powerpc/oprofile/op_model_power4.c b/trunk/arch/powerpc/oprofile/op_model_power4.c index 4c2beab1fdc1..4b06e53eb9b4 100644 --- a/trunk/arch/powerpc/oprofile/op_model_power4.c +++ b/trunk/arch/powerpc/oprofile/op_model_power4.c @@ -25,14 +25,18 @@ static unsigned long reset_value[OP_MAX_COUNTER]; static int oprofile_running; static int mmcra_has_sihv; -/* Unfortunately these bits vary between CPUs */ -static unsigned long mmcra_sihv = MMCRA_SIHV; -static unsigned long mmcra_sipr = MMCRA_SIPR; /* mmcr values are set in power4_reg_setup, used in power4_cpu_setup */ static u32 mmcr0_val; static u64 mmcr1_val; -static u64 mmcra_val; +static u32 mmcra_val; + +/* + * Since we do not have an NMI, backtracing through spinlocks is + * only a best guess. In light of this, allow it to be disabled at + * runtime. + */ +static int backtrace_spinlocks; static void power4_reg_setup(struct op_counter_config *ctr, struct op_system_config *sys, @@ -59,6 +63,8 @@ static void power4_reg_setup(struct op_counter_config *ctr, mmcr1_val = sys->mmcr1; mmcra_val = sys->mmcra; + backtrace_spinlocks = sys->backtrace_spinlocks; + for (i = 0; i < cur_cpu_spec->num_pmcs; ++i) reset_value[i] = 0x80000000UL - ctr[i].count; @@ -191,6 +197,25 @@ static void __attribute_used__ kernel_unknown_bucket(void) { } +static unsigned long check_spinlock_pc(struct pt_regs *regs, + unsigned long profile_pc) +{ + unsigned long pc = instruction_pointer(regs); + + /* + * If both the SIAR (sampled instruction) and the perfmon exception + * occurred in a spinlock region then we account the sample to the + * calling function. This isnt 100% correct, we really need soft + * IRQ disable so we always get the perfmon exception at the + * point at which the SIAR is set. + */ + if (backtrace_spinlocks && in_lock_functions(pc) && + in_lock_functions(profile_pc)) + return regs->link; + else + return profile_pc; +} + /* * On GQ and newer the MMCRA stores the HV and PR bits at the time * the SIAR was sampled. We use that to work out if the SIAR was sampled in @@ -203,17 +228,17 @@ static unsigned long get_pc(struct pt_regs *regs) /* Cant do much about it */ if (!mmcra_has_sihv) - return pc; + return check_spinlock_pc(regs, pc); mmcra = mfspr(SPRN_MMCRA); /* Were we in the hypervisor? */ - if (firmware_has_feature(FW_FEATURE_LPAR) && (mmcra & mmcra_sihv)) + if (firmware_has_feature(FW_FEATURE_LPAR) && (mmcra & MMCRA_SIHV)) /* function descriptor madness */ return *((unsigned long *)hypervisor_bucket); /* We were in userspace, nothing to do */ - if (mmcra & mmcra_sipr) + if (mmcra & MMCRA_SIPR) return pc; #ifdef CONFIG_PPC_RTAS @@ -232,7 +257,7 @@ static unsigned long get_pc(struct pt_regs *regs) /* function descriptor madness */ return *((unsigned long *)kernel_unknown_bucket); - return pc; + return check_spinlock_pc(regs, pc); } static int get_kernel(unsigned long pc) @@ -243,7 +268,7 @@ static int get_kernel(unsigned long pc) is_kernel = is_kernel_addr(pc); } else { unsigned long mmcra = mfspr(SPRN_MMCRA); - is_kernel = ((mmcra & mmcra_sipr) == 0); + is_kernel = ((mmcra & MMCRA_SIPR) == 0); } return is_kernel; @@ -268,7 +293,7 @@ static void power4_handle_interrupt(struct pt_regs *regs, val = ctr_read(i); if (val < 0) { if (oprofile_running && ctr[i].enabled) { - oprofile_add_ext_sample(pc, regs, i, is_kernel); + oprofile_add_pc(pc, is_kernel, i); ctr_write(i, reset_value[i]); } else { ctr_write(i, 0); diff --git a/trunk/arch/powerpc/oprofile/op_model_rs64.c b/trunk/arch/powerpc/oprofile/op_model_rs64.c index 042f8f4867ad..5c909ee609fe 100644 --- a/trunk/arch/powerpc/oprofile/op_model_rs64.c +++ b/trunk/arch/powerpc/oprofile/op_model_rs64.c @@ -175,13 +175,10 @@ static void rs64_handle_interrupt(struct pt_regs *regs, struct op_counter_config *ctr) { unsigned int mmcr0; - int is_kernel; int val; int i; unsigned long pc = mfspr(SPRN_SIAR); - is_kernel = is_kernel_addr(pc); - /* set the PMM bit (see comment below) */ mtmsrd(mfmsr() | MSR_PMM); @@ -189,7 +186,7 @@ static void rs64_handle_interrupt(struct pt_regs *regs, val = ctr_read(i); if (val < 0) { if (ctr[i].enabled) { - oprofile_add_ext_sample(pc, regs, i, is_kernel); + oprofile_add_pc(pc, is_kernel_addr(pc), i); ctr_write(i, reset_value[i]); } else { ctr_write(i, 0); diff --git a/trunk/arch/powerpc/platforms/85xx/Kconfig b/trunk/arch/powerpc/platforms/85xx/Kconfig index 06e371282f57..d3d0ff745e84 100644 --- a/trunk/arch/powerpc/platforms/85xx/Kconfig +++ b/trunk/arch/powerpc/platforms/85xx/Kconfig @@ -7,7 +7,6 @@ choice config MPC8540_ADS bool "Freescale MPC8540 ADS" - select DEFAULT_UIMAGE help This option enables support for the MPC 8540 ADS board diff --git a/trunk/arch/powerpc/platforms/cell/Kconfig b/trunk/arch/powerpc/platforms/cell/Kconfig index c2a3db8edb0c..3157071e241c 100644 --- a/trunk/arch/powerpc/platforms/cell/Kconfig +++ b/trunk/arch/powerpc/platforms/cell/Kconfig @@ -10,9 +10,4 @@ config SPU_FS Units on machines implementing the Broadband Processor Architecture. -config SPUFS_MMAP - bool - depends on SPU_FS && SPARSEMEM && !PPC_64K_PAGES - default y - endmenu diff --git a/trunk/arch/powerpc/platforms/cell/Makefile b/trunk/arch/powerpc/platforms/cell/Makefile index e570bad06394..3b998a393e3f 100644 --- a/trunk/arch/powerpc/platforms/cell/Makefile +++ b/trunk/arch/powerpc/platforms/cell/Makefile @@ -6,11 +6,5 @@ obj-$(CONFIG_SPU_FS) += spu-base.o spufs/ spu-base-y += spu_base.o spu_priv1.o -# needed only when building loadable spufs.ko -spufs-modular-$(CONFIG_SPU_FS) += spu_syscalls.o -obj-y += $(spufs-modular-m) - -# always needed in kernel -spufs-builtin-$(CONFIG_SPU_FS) += spu_callbacks.o -obj-y += $(spufs-builtin-y) $(spufs-builtin-m) - +builtin-spufs-$(CONFIG_SPU_FS) += spu_syscalls.o +obj-y += $(builtin-spufs-m) diff --git a/trunk/arch/powerpc/platforms/cell/interrupt.c b/trunk/arch/powerpc/platforms/cell/interrupt.c index 978be1c30c1b..63aa52acf441 100644 --- a/trunk/arch/powerpc/platforms/cell/interrupt.c +++ b/trunk/arch/powerpc/platforms/cell/interrupt.c @@ -63,24 +63,7 @@ static DEFINE_PER_CPU(struct iic, iic); void iic_local_enable(void) { - struct iic *iic = &__get_cpu_var(iic); - u64 tmp; - - /* - * There seems to be a bug that is present in DD2.x CPUs - * and still only partially fixed in DD3.1. - * This bug causes a value written to the priority register - * not to make it there, resulting in a system hang unless we - * write it again. - * Masking with 0xf0 is done because the Cell BE does not - * implement the lower four bits of the interrupt priority, - * they always read back as zeroes, although future CPUs - * might implement different bits. - */ - do { - out_be64(&iic->regs->prio, 0xff); - tmp = in_be64(&iic->regs->prio); - } while ((tmp & 0xf0) != 0xf0); + out_be64(&__get_cpu_var(iic).regs->prio, 0xff); } void iic_local_disable(void) @@ -140,7 +123,7 @@ static int iic_external_get_irq(struct iic_pending_bits pending) pending.class != 2) break; irq = IIC_EXT_OFFSET - + spider_get_irq(node) + + spider_get_irq(pending.prio + node * IIC_NODE_STRIDE) + node * IIC_NODE_STRIDE; break; case 0x01 ... 0x04: @@ -191,98 +174,38 @@ int iic_get_irq(struct pt_regs *regs) return irq; } -/* hardcoded part to be compatible with older firmware */ - -static int setup_iic_hardcoded(void) +static int setup_iic(int cpu, struct iic *iic) { struct device_node *np; - int nodeid, cpu; + int nodeid = cpu / 2; unsigned long regs; - struct iic *iic; - for_each_cpu(cpu) { - iic = &per_cpu(iic, cpu); - nodeid = cpu/2; - - for (np = of_find_node_by_type(NULL, "cpu"); - np; - np = of_find_node_by_type(np, "cpu")) { - if (nodeid == *(int *)get_property(np, "node-id", NULL)) - break; - } - - if (!np) { - printk(KERN_WARNING "IIC: CPU %d not found\n", cpu); - iic->regs = NULL; - iic->target_id = 0xff; - return -ENODEV; - } - - regs = *(long *)get_property(np, "iic", NULL); - - /* hack until we have decided on the devtree info */ - regs += 0x400; - if (cpu & 1) - regs += 0x20; - - printk(KERN_INFO "IIC for CPU %d at %lx\n", cpu, regs); - iic->regs = ioremap(regs, sizeof(struct iic_regs)); - iic->target_id = (nodeid << 4) + ((cpu & 1) ? 0xf : 0xe); + for (np = of_find_node_by_type(NULL, "cpu"); + np; + np = of_find_node_by_type(np, "cpu")) { + if (nodeid == *(int *)get_property(np, "node-id", NULL)) + break; } - return 0; -} - -static int setup_iic(void) -{ - struct device_node *dn; - unsigned long *regs; - char *compatible; - unsigned *np, found = 0; - struct iic *iic = NULL; - - for (dn = NULL; (dn = of_find_node_by_name(dn, "interrupt-controller"));) { - compatible = (char *)get_property(dn, "compatible", NULL); - - if (!compatible) { - printk(KERN_WARNING "no compatible property found !\n"); - continue; - } - - if (strstr(compatible, "IBM,CBEA-Internal-Interrupt-Controller")) - regs = (unsigned long *)get_property(dn,"reg", NULL); - else - continue; - - if (!regs) - printk(KERN_WARNING "IIC: no reg property\n"); - - np = (unsigned int *)get_property(dn, "ibm,interrupt-server-ranges", NULL); - - if (!np) { - printk(KERN_WARNING "IIC: CPU association not found\n"); - iic->regs = NULL; - iic->target_id = 0xff; - return -ENODEV; - } - - iic = &per_cpu(iic, np[0]); - iic->regs = ioremap(regs[0], sizeof(struct iic_regs)); - iic->target_id = ((np[0] & 2) << 3) + ((np[0] & 1) ? 0xf : 0xe); - printk("IIC for CPU %d at %lx mapped to %p\n", np[0], regs[0], iic->regs); + if (!np) { + printk(KERN_WARNING "IIC: CPU %d not found\n", cpu); + iic->regs = NULL; + iic->target_id = 0xff; + return -ENODEV; + } - iic = &per_cpu(iic, np[1]); - iic->regs = ioremap(regs[2], sizeof(struct iic_regs)); - iic->target_id = ((np[1] & 2) << 3) + ((np[1] & 1) ? 0xf : 0xe); - printk("IIC for CPU %d at %lx mapped to %p\n", np[1], regs[2], iic->regs); + regs = *(long *)get_property(np, "iic", NULL); - found++; - } + /* hack until we have decided on the devtree info */ + regs += 0x400; + if (cpu & 1) + regs += 0x20; - if (found) - return 0; - else - return -ENODEV; + printk(KERN_DEBUG "IIC for CPU %d at %lx\n", cpu, regs); + iic->regs = __ioremap(regs, sizeof(struct iic_regs), + _PAGE_NO_CACHE); + iic->target_id = (nodeid << 4) + ((cpu & 1) ? 0xf : 0xe); + return 0; } #ifdef CONFIG_SMP @@ -360,12 +283,10 @@ void iic_init_IRQ(void) int cpu, irq_offset; struct iic *iic; - if (setup_iic() < 0) - setup_iic_hardcoded(); - irq_offset = 0; - for_each_possible_cpu(cpu) { + for_each_cpu(cpu) { iic = &per_cpu(iic, cpu); + setup_iic(cpu, iic); if (iic->regs) out_be64(&iic->regs->prio, 0xff); } diff --git a/trunk/arch/powerpc/platforms/cell/interrupt.h b/trunk/arch/powerpc/platforms/cell/interrupt.h index 799f77d98f96..a14bd38791c0 100644 --- a/trunk/arch/powerpc/platforms/cell/interrupt.h +++ b/trunk/arch/powerpc/platforms/cell/interrupt.h @@ -57,7 +57,7 @@ extern void iic_local_disable(void); extern u8 iic_get_target_id(int cpu); extern void spider_init_IRQ(void); -extern int spider_get_irq(int node); +extern int spider_get_irq(unsigned long int_pending); #endif #endif /* ASM_CELL_PIC_H */ diff --git a/trunk/arch/powerpc/platforms/cell/iommu.c b/trunk/arch/powerpc/platforms/cell/iommu.c index a49ceb799a8e..46e7cb9c3e64 100644 --- a/trunk/arch/powerpc/platforms/cell/iommu.c +++ b/trunk/arch/powerpc/platforms/cell/iommu.c @@ -289,7 +289,7 @@ static void cell_do_map_iommu(struct cell_iommu *iommu, ioc_base = iommu->mapped_base; ioc_mmio_base = iommu->mapped_mmio_base; - for (real_address = 0, io_address = map_start; + for (real_address = 0, io_address = 0; io_address <= map_start + map_size; real_address += io_page_size, io_address += io_page_size) { 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, set_iopt_cache(ioc_mmio_base, get_ioc_hash_1way(ioste, io_address), get_ioc_tag(ioste, io_address), - get_iopt_entry(real_address, ioid, IOPT_PROT_RW)); + get_iopt_entry(real_address-map_start, ioid, IOPT_PROT_RW)); } } @@ -344,8 +344,8 @@ static int cell_map_iommu_hardcoded(int num_nodes) /* node 0 */ iommu = &cell_iommus[0]; - iommu->mapped_base = ioremap(0x20000511000, 0x1000); - iommu->mapped_mmio_base = ioremap(0x20000510000, 0x1000); + iommu->mapped_base = __ioremap(0x20000511000, 0x1000, _PAGE_NO_CACHE); + iommu->mapped_mmio_base = __ioremap(0x20000510000, 0x1000, _PAGE_NO_CACHE); enable_mapping(iommu->mapped_base, iommu->mapped_mmio_base); @@ -357,8 +357,8 @@ static int cell_map_iommu_hardcoded(int num_nodes) /* node 1 */ iommu = &cell_iommus[1]; - iommu->mapped_base = ioremap(0x30000511000, 0x1000); - iommu->mapped_mmio_base = ioremap(0x30000510000, 0x1000); + iommu->mapped_base = __ioremap(0x30000511000, 0x1000, _PAGE_NO_CACHE); + iommu->mapped_mmio_base = __ioremap(0x30000510000, 0x1000, _PAGE_NO_CACHE); enable_mapping(iommu->mapped_base, iommu->mapped_mmio_base); @@ -407,8 +407,8 @@ static int cell_map_iommu(void) iommu->base = *base; iommu->mmio_base = *mmio_base; - iommu->mapped_base = ioremap(*base, 0x1000); - iommu->mapped_mmio_base = ioremap(*mmio_base, 0x1000); + iommu->mapped_base = __ioremap(*base, 0x1000, _PAGE_NO_CACHE); + iommu->mapped_mmio_base = __ioremap(*mmio_base, 0x1000, _PAGE_NO_CACHE); enable_mapping(iommu->mapped_base, iommu->mapped_mmio_base); diff --git a/trunk/arch/powerpc/platforms/cell/pervasive.c b/trunk/arch/powerpc/platforms/cell/pervasive.c index 7eed8c624517..e0e051c675dd 100644 --- a/trunk/arch/powerpc/platforms/cell/pervasive.c +++ b/trunk/arch/powerpc/platforms/cell/pervasive.c @@ -203,7 +203,7 @@ static int __init cbe_find_pmd_mmio(int cpu, struct cbe_pervasive *p) pr_debug("pervasive area for CPU %d at %lx, size %x\n", cpu, real_address, size); - p->regs = ioremap(real_address, size); + p->regs = __ioremap(real_address, size, _PAGE_NO_CACHE); p->thread = thread; return 0; } @@ -217,7 +217,7 @@ void __init cell_pervasive_init(void) if (!cpu_has_feature(CPU_FTR_PAUSE_ZERO)) return; - for_each_possible_cpu(cpu) { + for_each_cpu(cpu) { p = &cbe_pervasive[cpu]; ret = cbe_find_pmd_mmio(cpu, p); if (ret) diff --git a/trunk/arch/powerpc/platforms/cell/setup.c b/trunk/arch/powerpc/platforms/cell/setup.c index dac5d0365fde..fec8e65b36ea 100644 --- a/trunk/arch/powerpc/platforms/cell/setup.c +++ b/trunk/arch/powerpc/platforms/cell/setup.c @@ -195,13 +195,9 @@ static void __init cell_init_early(void) } -static int __init cell_probe(void) +static int __init cell_probe(int platform) { - /* XXX This is temporary, the Cell maintainer will come up with - * more appropriate detection logic - */ - unsigned long root = of_get_flat_dt_root(); - if (!of_flat_dt_is_compatible(root, "IBM,CPBW-1.0")) + if (platform != PLATFORM_CELL) return 0; return 1; @@ -216,8 +212,7 @@ static int cell_check_legacy_ioport(unsigned int baseport) return -ENODEV; } -define_machine(cell) { - .name = "Cell", +struct machdep_calls __initdata cell_md = { .probe = cell_probe, .setup_arch = cell_setup_arch, .init_early = cell_init_early, diff --git a/trunk/arch/powerpc/platforms/cell/spider-pic.c b/trunk/arch/powerpc/platforms/cell/spider-pic.c index 55cbdd77a62d..e74132188bdf 100644 --- a/trunk/arch/powerpc/platforms/cell/spider-pic.c +++ b/trunk/arch/powerpc/platforms/cell/spider-pic.c @@ -84,11 +84,10 @@ static void __iomem *spider_get_irq_config(int irq) static void spider_enable_irq(unsigned int irq) { - int nodeid = (irq / IIC_NODE_STRIDE) * 0x10; void __iomem *cfg = spider_get_irq_config(irq); irq = spider_get_nr(irq); - out_be32(cfg, (in_be32(cfg) & ~0xf0)| 0x3107000eu | nodeid); + out_be32(cfg, in_be32(cfg) | 0x3107000eu); out_be32(cfg + 4, in_be32(cfg + 4) | 0x00020000u | irq); } @@ -132,108 +131,61 @@ static struct hw_interrupt_type spider_pic = { .end = spider_end_irq, }; -int spider_get_irq(int node) + +int spider_get_irq(unsigned long int_pending) { + void __iomem *regs = spider_get_pic(int_pending); unsigned long cs; - void __iomem *regs = spider_pics[node]; - - cs = in_be32(regs + TIR_CS) >> 24; + int irq; - if (cs == 63) - return -1; - else - return cs; -} + cs = in_be32(regs + TIR_CS); -/* hardcoded part to be compatible with older firmware */ + irq = cs >> 24; + if (irq != 63) + return irq; -void spider_init_IRQ_hardcoded(void) + return -1; +} + +void spider_init_IRQ(void) { int node; + struct device_node *dn; + unsigned int *property; long spiderpic; - long pics[] = { 0x24000008000, 0x34000008000 }; int n; - pr_debug("%s(%d): Using hardcoded defaults\n", __FUNCTION__, __LINE__); +/* FIXME: detect multiple PICs as soon as the device tree has them */ + for (node = 0; node < 1; node++) { + dn = of_find_node_by_path("/"); + n = prom_n_addr_cells(dn); + property = (unsigned int *) get_property(dn, + "platform-spider-pic", NULL); - for (node = 0; node < num_present_cpus()/2; node++) { - spiderpic = pics[node]; + if (!property) + continue; + for (spiderpic = 0; n > 0; --n) + spiderpic = (spiderpic << 32) + *property++; printk(KERN_DEBUG "SPIDER addr: %lx\n", spiderpic); - spider_pics[node] = ioremap(spiderpic, 0x800); + spider_pics[node] = __ioremap(spiderpic, 0x800, _PAGE_NO_CACHE); for (n = 0; n < IIC_NUM_EXT; n++) { int irq = n + IIC_EXT_OFFSET + node * IIC_NODE_STRIDE; get_irq_desc(irq)->handler = &spider_pic; - } /* do not mask any interrupts because of level */ out_be32(spider_pics[node] + TIR_MSK, 0x0); - + /* disable edge detection clear */ /* out_be32(spider_pics[node] + TIR_EDC, 0x0); */ - + /* enable interrupt packets to be output */ out_be32(spider_pics[node] + TIR_PIEN, in_be32(spider_pics[node] + TIR_PIEN) | 0x1); - + /* Enable the interrupt detection enable bit. Do this last! */ out_be32(spider_pics[node] + TIR_DEN, - in_be32(spider_pics[node] + TIR_DEN) | 0x1); - } -} - -void spider_init_IRQ(void) -{ - long spider_reg; - struct device_node *dn; - char *compatible; - int n, node = 0; - - for (dn = NULL; (dn = of_find_node_by_name(dn, "interrupt-controller"));) { - compatible = (char *)get_property(dn, "compatible", NULL); + in_be32(spider_pics[node] +TIR_DEN) | 0x1); - if (!compatible) - continue; - - if (strstr(compatible, "CBEA,platform-spider-pic")) - spider_reg = *(long *)get_property(dn,"reg", NULL); - else if (strstr(compatible, "sti,platform-spider-pic")) { - spider_init_IRQ_hardcoded(); - return; - } else - continue; - - if (!spider_reg) - printk("interrupt controller does not have reg property !\n"); - - n = prom_n_addr_cells(dn); - - if ( n != 2) - printk("reg property with invalid number of elements \n"); - - spider_pics[node] = ioremap(spider_reg, 0x800); - - printk("SPIDER addr: %lx with %i addr_cells mapped to %p\n", - spider_reg, n, spider_pics[node]); - - for (n = 0; n < IIC_NUM_EXT; n++) { - int irq = n + IIC_EXT_OFFSET + node * IIC_NODE_STRIDE; - get_irq_desc(irq)->handler = &spider_pic; } - - /* do not mask any interrupts because of level */ - out_be32(spider_pics[node] + TIR_MSK, 0x0); - - /* disable edge detection clear */ - /* out_be32(spider_pics[node] + TIR_EDC, 0x0); */ - - /* enable interrupt packets to be output */ - out_be32(spider_pics[node] + TIR_PIEN, - in_be32(spider_pics[node] + TIR_PIEN) | 0x1); - - /* Enable the interrupt detection enable bit. Do this last! */ - out_be32(spider_pics[node] + TIR_DEN, - in_be32(spider_pics[node] + TIR_DEN) | 0x1); - - node++; } } diff --git a/trunk/arch/powerpc/platforms/cell/spu_base.c b/trunk/arch/powerpc/platforms/cell/spu_base.c index 269dda4fd0b4..a8fa1eeeb174 100644 --- a/trunk/arch/powerpc/platforms/cell/spu_base.c +++ b/trunk/arch/powerpc/platforms/cell/spu_base.c @@ -111,7 +111,7 @@ static int __spu_trap_data_seg(struct spu *spu, unsigned long ea) extern int hash_page(unsigned long ea, unsigned long access, unsigned long trap); //XXX static int __spu_trap_data_map(struct spu *spu, unsigned long ea, u64 dsisr) { - pr_debug("%s, %lx, %lx\n", __FUNCTION__, dsisr, ea); + pr_debug("%s\n", __FUNCTION__); /* Handle kernel space hash faults immediately. User hash faults need to be deferred to process context. */ @@ -168,7 +168,7 @@ static int __spu_trap_halt(struct spu *spu) static int __spu_trap_tag_group(struct spu *spu) { pr_debug("%s\n", __FUNCTION__); - spu->mfc_callback(spu); + /* wake_up(&spu->dma_wq); */ return 0; } @@ -242,8 +242,6 @@ spu_irq_class_1(int irq, void *data, struct pt_regs *regs) spu_mfc_dsisr_set(spu, 0ul); spu_int_stat_clear(spu, 1, stat); spin_unlock(&spu->register_lock); - pr_debug("%s: %lx %lx %lx %lx\n", __FUNCTION__, mask, stat, - dar, dsisr); if (stat & 1) /* segment fault */ __spu_trap_data_seg(spu, dar); @@ -486,13 +484,14 @@ int spu_irq_class_1_bottom(struct spu *spu) ea = spu->dar; dsisr = spu->dsisr; - if (dsisr & (MFC_DSISR_PTE_NOT_FOUND | MFC_DSISR_ACCESS_DENIED)) { + if (dsisr & MFC_DSISR_PTE_NOT_FOUND) { access = (_PAGE_PRESENT | _PAGE_USER); access |= (dsisr & MFC_DSISR_ACCESS_PUT) ? _PAGE_RW : 0UL; if (hash_page(ea, access, 0x300) != 0) error |= CLASS1_ENABLE_STORAGE_FAULT_INTR; } - if (error & CLASS1_ENABLE_STORAGE_FAULT_INTR) { + if ((error & CLASS1_ENABLE_STORAGE_FAULT_INTR) || + (dsisr & MFC_DSISR_ACCESS_DENIED)) { if ((ret = spu_handle_mm_fault(spu)) != 0) error |= CLASS1_ENABLE_STORAGE_FAULT_INTR; else @@ -569,11 +568,6 @@ static int __init spu_map_device(struct spu *spu, struct device_node *spe) if (!spu->local_store) goto out; - prop = get_property(spe, "problem", NULL); - if (!prop) - goto out_unmap; - spu->problem_phys = *(unsigned long *)prop; - spu->problem= map_spe_prop(spe, "problem"); if (!spu->problem) goto out_unmap; @@ -638,7 +632,6 @@ static int __init create_spu(struct device_node *spe) spu->ibox_callback = NULL; spu->wbox_callback = NULL; spu->stop_callback = NULL; - spu->mfc_callback = NULL; mutex_lock(&spu_mutex); spu->number = number++; diff --git a/trunk/arch/powerpc/platforms/cell/spu_callbacks.c b/trunk/arch/powerpc/platforms/cell/spu_callbacks.c deleted file mode 100644 index 3a4245c926ad..000000000000 --- a/trunk/arch/powerpc/platforms/cell/spu_callbacks.c +++ /dev/null @@ -1,345 +0,0 @@ -/* - * System call callback functions for SPUs - */ - -#define DEBUG - -#include -#include -#include - -#include -#include -#include - -/* - * This table defines the system calls that an SPU can call. - * It is currently a subset of the 64 bit powerpc system calls, - * with the exact semantics. - * - * The reasons for disabling some of the system calls are: - * 1. They interact with the way SPU syscalls are handled - * and we can't let them execute ever: - * restart_syscall, exit, for, execve, ptrace, ... - * 2. They are deprecated and replaced by other means: - * uselib, pciconfig_*, sysfs, ... - * 3. They are somewhat interacting with the system in a way - * we don't want an SPU to: - * reboot, init_module, mount, kexec_load - * 4. They are optional and we can't rely on them being - * linked into the kernel. Unfortunately, the cond_syscall - * helper does not work here as it does not add the necessary - * opd symbols: - * mbind, mq_open, ipc, ... - */ - -void *spu_syscall_table[] = { - [__NR_restart_syscall] sys_ni_syscall, /* sys_restart_syscall */ - [__NR_exit] sys_ni_syscall, /* sys_exit */ - [__NR_fork] sys_ni_syscall, /* ppc_fork */ - [__NR_read] sys_read, - [__NR_write] sys_write, - [__NR_open] sys_open, - [__NR_close] sys_close, - [__NR_waitpid] sys_waitpid, - [__NR_creat] sys_creat, - [__NR_link] sys_link, - [__NR_unlink] sys_unlink, - [__NR_execve] sys_ni_syscall, /* sys_execve */ - [__NR_chdir] sys_chdir, - [__NR_time] sys_time, - [__NR_mknod] sys_mknod, - [__NR_chmod] sys_chmod, - [__NR_lchown] sys_lchown, - [__NR_break] sys_ni_syscall, - [__NR_oldstat] sys_ni_syscall, - [__NR_lseek] sys_lseek, - [__NR_getpid] sys_getpid, - [__NR_mount] sys_ni_syscall, /* sys_mount */ - [__NR_umount] sys_ni_syscall, - [__NR_setuid] sys_setuid, - [__NR_getuid] sys_getuid, - [__NR_stime] sys_stime, - [__NR_ptrace] sys_ni_syscall, /* sys_ptrace */ - [__NR_alarm] sys_alarm, - [__NR_oldfstat] sys_ni_syscall, - [__NR_pause] sys_ni_syscall, /* sys_pause */ - [__NR_utime] sys_ni_syscall, /* sys_utime */ - [__NR_stty] sys_ni_syscall, - [__NR_gtty] sys_ni_syscall, - [__NR_access] sys_access, - [__NR_nice] sys_nice, - [__NR_ftime] sys_ni_syscall, - [__NR_sync] sys_sync, - [__NR_kill] sys_kill, - [__NR_rename] sys_rename, - [__NR_mkdir] sys_mkdir, - [__NR_rmdir] sys_rmdir, - [__NR_dup] sys_dup, - [__NR_pipe] sys_pipe, - [__NR_times] sys_times, - [__NR_prof] sys_ni_syscall, - [__NR_brk] sys_brk, - [__NR_setgid] sys_setgid, - [__NR_getgid] sys_getgid, - [__NR_signal] sys_ni_syscall, /* sys_signal */ - [__NR_geteuid] sys_geteuid, - [__NR_getegid] sys_getegid, - [__NR_acct] sys_ni_syscall, /* sys_acct */ - [__NR_umount2] sys_ni_syscall, /* sys_umount */ - [__NR_lock] sys_ni_syscall, - [__NR_ioctl] sys_ioctl, - [__NR_fcntl] sys_fcntl, - [__NR_mpx] sys_ni_syscall, - [__NR_setpgid] sys_setpgid, - [__NR_ulimit] sys_ni_syscall, - [__NR_oldolduname] sys_ni_syscall, - [__NR_umask] sys_umask, - [__NR_chroot] sys_chroot, - [__NR_ustat] sys_ni_syscall, /* sys_ustat */ - [__NR_dup2] sys_dup2, - [__NR_getppid] sys_getppid, - [__NR_getpgrp] sys_getpgrp, - [__NR_setsid] sys_setsid, - [__NR_sigaction] sys_ni_syscall, - [__NR_sgetmask] sys_sgetmask, - [__NR_ssetmask] sys_ssetmask, - [__NR_setreuid] sys_setreuid, - [__NR_setregid] sys_setregid, - [__NR_sigsuspend] sys_ni_syscall, - [__NR_sigpending] sys_ni_syscall, - [__NR_sethostname] sys_sethostname, - [__NR_setrlimit] sys_setrlimit, - [__NR_getrlimit] sys_ni_syscall, - [__NR_getrusage] sys_getrusage, - [__NR_gettimeofday] sys_gettimeofday, - [__NR_settimeofday] sys_settimeofday, - [__NR_getgroups] sys_getgroups, - [__NR_setgroups] sys_setgroups, - [__NR_select] sys_ni_syscall, - [__NR_symlink] sys_symlink, - [__NR_oldlstat] sys_ni_syscall, - [__NR_readlink] sys_readlink, - [__NR_uselib] sys_ni_syscall, /* sys_uselib */ - [__NR_swapon] sys_ni_syscall, /* sys_swapon */ - [__NR_reboot] sys_ni_syscall, /* sys_reboot */ - [__NR_readdir] sys_ni_syscall, - [__NR_mmap] sys_mmap, - [__NR_munmap] sys_munmap, - [__NR_truncate] sys_truncate, - [__NR_ftruncate] sys_ftruncate, - [__NR_fchmod] sys_fchmod, - [__NR_fchown] sys_fchown, - [__NR_getpriority] sys_getpriority, - [__NR_setpriority] sys_setpriority, - [__NR_profil] sys_ni_syscall, - [__NR_statfs] sys_ni_syscall, /* sys_statfs */ - [__NR_fstatfs] sys_ni_syscall, /* sys_fstatfs */ - [__NR_ioperm] sys_ni_syscall, - [__NR_socketcall] sys_socketcall, - [__NR_syslog] sys_syslog, - [__NR_setitimer] sys_setitimer, - [__NR_getitimer] sys_getitimer, - [__NR_stat] sys_newstat, - [__NR_lstat] sys_newlstat, - [__NR_fstat] sys_newfstat, - [__NR_olduname] sys_ni_syscall, - [__NR_iopl] sys_ni_syscall, - [__NR_vhangup] sys_vhangup, - [__NR_idle] sys_ni_syscall, - [__NR_vm86] sys_ni_syscall, - [__NR_wait4] sys_wait4, - [__NR_swapoff] sys_ni_syscall, /* sys_swapoff */ - [__NR_sysinfo] sys_sysinfo, - [__NR_ipc] sys_ni_syscall, /* sys_ipc */ - [__NR_fsync] sys_fsync, - [__NR_sigreturn] sys_ni_syscall, - [__NR_clone] sys_ni_syscall, /* ppc_clone */ - [__NR_setdomainname] sys_setdomainname, - [__NR_uname] ppc_newuname, - [__NR_modify_ldt] sys_ni_syscall, - [__NR_adjtimex] sys_adjtimex, - [__NR_mprotect] sys_mprotect, - [__NR_sigprocmask] sys_ni_syscall, - [__NR_create_module] sys_ni_syscall, - [__NR_init_module] sys_ni_syscall, /* sys_init_module */ - [__NR_delete_module] sys_ni_syscall, /* sys_delete_module */ - [__NR_get_kernel_syms] sys_ni_syscall, - [__NR_quotactl] sys_ni_syscall, /* sys_quotactl */ - [__NR_getpgid] sys_getpgid, - [__NR_fchdir] sys_fchdir, - [__NR_bdflush] sys_bdflush, - [__NR_sysfs] sys_ni_syscall, /* sys_sysfs */ - [__NR_personality] ppc64_personality, - [__NR_afs_syscall] sys_ni_syscall, - [__NR_setfsuid] sys_setfsuid, - [__NR_setfsgid] sys_setfsgid, - [__NR__llseek] sys_llseek, - [__NR_getdents] sys_getdents, - [__NR__newselect] sys_select, - [__NR_flock] sys_flock, - [__NR_msync] sys_msync, - [__NR_readv] sys_readv, - [__NR_writev] sys_writev, - [__NR_getsid] sys_getsid, - [__NR_fdatasync] sys_fdatasync, - [__NR__sysctl] sys_ni_syscall, /* sys_sysctl */ - [__NR_mlock] sys_mlock, - [__NR_munlock] sys_munlock, - [__NR_mlockall] sys_mlockall, - [__NR_munlockall] sys_munlockall, - [__NR_sched_setparam] sys_sched_setparam, - [__NR_sched_getparam] sys_sched_getparam, - [__NR_sched_setscheduler] sys_sched_setscheduler, - [__NR_sched_getscheduler] sys_sched_getscheduler, - [__NR_sched_yield] sys_sched_yield, - [__NR_sched_get_priority_max] sys_sched_get_priority_max, - [__NR_sched_get_priority_min] sys_sched_get_priority_min, - [__NR_sched_rr_get_interval] sys_sched_rr_get_interval, - [__NR_nanosleep] sys_nanosleep, - [__NR_mremap] sys_mremap, - [__NR_setresuid] sys_setresuid, - [__NR_getresuid] sys_getresuid, - [__NR_query_module] sys_ni_syscall, - [__NR_poll] sys_poll, - [__NR_nfsservctl] sys_ni_syscall, /* sys_nfsservctl */ - [__NR_setresgid] sys_setresgid, - [__NR_getresgid] sys_getresgid, - [__NR_prctl] sys_prctl, - [__NR_rt_sigreturn] sys_ni_syscall, /* ppc64_rt_sigreturn */ - [__NR_rt_sigaction] sys_ni_syscall, /* sys_rt_sigaction */ - [__NR_rt_sigprocmask] sys_ni_syscall, /* sys_rt_sigprocmask */ - [__NR_rt_sigpending] sys_ni_syscall, /* sys_rt_sigpending */ - [__NR_rt_sigtimedwait] sys_ni_syscall, /* sys_rt_sigtimedwait */ - [__NR_rt_sigqueueinfo] sys_ni_syscall, /* sys_rt_sigqueueinfo */ - [__NR_rt_sigsuspend] sys_ni_syscall, /* sys_rt_sigsuspend */ - [__NR_pread64] sys_pread64, - [__NR_pwrite64] sys_pwrite64, - [__NR_chown] sys_chown, - [__NR_getcwd] sys_getcwd, - [__NR_capget] sys_capget, - [__NR_capset] sys_capset, - [__NR_sigaltstack] sys_ni_syscall, /* sys_sigaltstack */ - [__NR_sendfile] sys_sendfile64, - [__NR_getpmsg] sys_ni_syscall, - [__NR_putpmsg] sys_ni_syscall, - [__NR_vfork] sys_ni_syscall, /* ppc_vfork */ - [__NR_ugetrlimit] sys_getrlimit, - [__NR_readahead] sys_readahead, - [192] sys_ni_syscall, - [193] sys_ni_syscall, - [194] sys_ni_syscall, - [195] sys_ni_syscall, - [196] sys_ni_syscall, - [197] sys_ni_syscall, - [__NR_pciconfig_read] sys_ni_syscall, /* sys_pciconfig_read */ - [__NR_pciconfig_write] sys_ni_syscall, /* sys_pciconfig_write */ - [__NR_pciconfig_iobase] sys_ni_syscall, /* sys_pciconfig_iobase */ - [__NR_multiplexer] sys_ni_syscall, - [__NR_getdents64] sys_getdents64, - [__NR_pivot_root] sys_pivot_root, - [204] sys_ni_syscall, - [__NR_madvise] sys_madvise, - [__NR_mincore] sys_mincore, - [__NR_gettid] sys_gettid, - [__NR_tkill] sys_tkill, - [__NR_setxattr] sys_setxattr, - [__NR_lsetxattr] sys_lsetxattr, - [__NR_fsetxattr] sys_fsetxattr, - [__NR_getxattr] sys_getxattr, - [__NR_lgetxattr] sys_lgetxattr, - [__NR_fgetxattr] sys_fgetxattr, - [__NR_listxattr] sys_listxattr, - [__NR_llistxattr] sys_llistxattr, - [__NR_flistxattr] sys_flistxattr, - [__NR_removexattr] sys_removexattr, - [__NR_lremovexattr] sys_lremovexattr, - [__NR_fremovexattr] sys_fremovexattr, - [__NR_futex] sys_futex, - [__NR_sched_setaffinity] sys_sched_setaffinity, - [__NR_sched_getaffinity] sys_sched_getaffinity, - [__NR_tuxcall] sys_ni_syscall, - [226] sys_ni_syscall, - [__NR_io_setup] sys_io_setup, - [__NR_io_destroy] sys_io_destroy, - [__NR_io_getevents] sys_io_getevents, - [__NR_io_submit] sys_io_submit, - [__NR_io_cancel] sys_io_cancel, - [__NR_set_tid_address] sys_ni_syscall, /* sys_set_tid_address */ - [__NR_fadvise64] sys_fadvise64, - [__NR_exit_group] sys_ni_syscall, /* sys_exit_group */ - [__NR_lookup_dcookie] sys_ni_syscall, /* sys_lookup_dcookie */ - [__NR_epoll_create] sys_epoll_create, - [__NR_epoll_ctl] sys_epoll_ctl, - [__NR_epoll_wait] sys_epoll_wait, - [__NR_remap_file_pages] sys_remap_file_pages, - [__NR_timer_create] sys_timer_create, - [__NR_timer_settime] sys_timer_settime, - [__NR_timer_gettime] sys_timer_gettime, - [__NR_timer_getoverrun] sys_timer_getoverrun, - [__NR_timer_delete] sys_timer_delete, - [__NR_clock_settime] sys_clock_settime, - [__NR_clock_gettime] sys_clock_gettime, - [__NR_clock_getres] sys_clock_getres, - [__NR_clock_nanosleep] sys_clock_nanosleep, - [__NR_swapcontext] sys_ni_syscall, /* ppc64_swapcontext */ - [__NR_tgkill] sys_tgkill, - [__NR_utimes] sys_utimes, - [__NR_statfs64] sys_statfs64, - [__NR_fstatfs64] sys_fstatfs64, - [254] sys_ni_syscall, - [__NR_rtas] ppc_rtas, - [256] sys_ni_syscall, - [257] sys_ni_syscall, - [258] sys_ni_syscall, - [__NR_mbind] sys_ni_syscall, /* sys_mbind */ - [__NR_get_mempolicy] sys_ni_syscall, /* sys_get_mempolicy */ - [__NR_set_mempolicy] sys_ni_syscall, /* sys_set_mempolicy */ - [__NR_mq_open] sys_ni_syscall, /* sys_mq_open */ - [__NR_mq_unlink] sys_ni_syscall, /* sys_mq_unlink */ - [__NR_mq_timedsend] sys_ni_syscall, /* sys_mq_timedsend */ - [__NR_mq_timedreceive] sys_ni_syscall, /* sys_mq_timedreceive */ - [__NR_mq_notify] sys_ni_syscall, /* sys_mq_notify */ - [__NR_mq_getsetattr] sys_ni_syscall, /* sys_mq_getsetattr */ - [__NR_kexec_load] sys_ni_syscall, /* sys_kexec_load */ - [__NR_add_key] sys_ni_syscall, /* sys_add_key */ - [__NR_request_key] sys_ni_syscall, /* sys_request_key */ - [__NR_keyctl] sys_ni_syscall, /* sys_keyctl */ - [__NR_waitid] sys_ni_syscall, /* sys_waitid */ - [__NR_ioprio_set] sys_ni_syscall, /* sys_ioprio_set */ - [__NR_ioprio_get] sys_ni_syscall, /* sys_ioprio_get */ - [__NR_inotify_init] sys_ni_syscall, /* sys_inotify_init */ - [__NR_inotify_add_watch] sys_ni_syscall, /* sys_inotify_add_watch */ - [__NR_inotify_rm_watch] sys_ni_syscall, /* sys_inotify_rm_watch */ - [__NR_spu_run] sys_ni_syscall, /* sys_spu_run */ - [__NR_spu_create] sys_ni_syscall, /* sys_spu_create */ - [__NR_pselect6] sys_ni_syscall, /* sys_pselect */ - [__NR_ppoll] sys_ni_syscall, /* sys_ppoll */ - [__NR_unshare] sys_unshare, -}; - -long spu_sys_callback(struct spu_syscall_block *s) -{ - long (*syscall)(u64 a1, u64 a2, u64 a3, u64 a4, u64 a5, u64 a6); - - BUILD_BUG_ON(ARRAY_SIZE(spu_syscall_table) != __NR_syscalls); - - syscall = spu_syscall_table[s->nr_ret]; - - if (s->nr_ret >= __NR_syscalls) { - pr_debug("%s: invalid syscall #%ld", __FUNCTION__, s->nr_ret); - return -ENOSYS; - } - -#ifdef DEBUG - print_symbol(KERN_DEBUG "SPU-syscall %s:", (unsigned long)syscall); - printk("syscall%ld(%lx, %lx, %lx, %lx, %lx, %lx)\n", - s->nr_ret, - s->parm[0], s->parm[1], s->parm[2], - s->parm[3], s->parm[4], s->parm[5]); -#endif - - return syscall(s->parm[0], s->parm[1], s->parm[2], - s->parm[3], s->parm[4], s->parm[5]); -} -EXPORT_SYMBOL_GPL(spu_sys_callback); diff --git a/trunk/arch/powerpc/platforms/cell/spufs/backing_ops.c b/trunk/arch/powerpc/platforms/cell/spufs/backing_ops.c index f1d35ddc9df3..a5c489a53c61 100644 --- a/trunk/arch/powerpc/platforms/cell/spufs/backing_ops.c +++ b/trunk/arch/powerpc/platforms/cell/spufs/backing_ops.c @@ -285,49 +285,6 @@ static void spu_backing_runcntl_stop(struct spu_context *ctx) spu_backing_runcntl_write(ctx, SPU_RUNCNTL_STOP); } -static int spu_backing_set_mfc_query(struct spu_context * ctx, u32 mask, - u32 mode) -{ - struct spu_problem_collapsed *prob = &ctx->csa.prob; - int ret; - - spin_lock(&ctx->csa.register_lock); - ret = -EAGAIN; - if (prob->dma_querytype_RW) - goto out; - ret = 0; - /* FIXME: what are the side-effects of this? */ - prob->dma_querymask_RW = mask; - prob->dma_querytype_RW = mode; -out: - spin_unlock(&ctx->csa.register_lock); - - return ret; -} - -static u32 spu_backing_read_mfc_tagstatus(struct spu_context * ctx) -{ - return ctx->csa.prob.dma_tagstatus_R; -} - -static u32 spu_backing_get_mfc_free_elements(struct spu_context *ctx) -{ - return ctx->csa.prob.dma_qstatus_R; -} - -static int spu_backing_send_mfc_command(struct spu_context *ctx, - struct mfc_dma_command *cmd) -{ - int ret; - - spin_lock(&ctx->csa.register_lock); - ret = -EAGAIN; - /* FIXME: set up priv2->puq */ - spin_unlock(&ctx->csa.register_lock); - - return ret; -} - struct spu_context_ops spu_backing_ops = { .mbox_read = spu_backing_mbox_read, .mbox_stat_read = spu_backing_mbox_stat_read, @@ -348,8 +305,4 @@ struct spu_context_ops spu_backing_ops = { .get_ls = spu_backing_get_ls, .runcntl_write = spu_backing_runcntl_write, .runcntl_stop = spu_backing_runcntl_stop, - .set_mfc_query = spu_backing_set_mfc_query, - .read_mfc_tagstatus = spu_backing_read_mfc_tagstatus, - .get_mfc_free_elements = spu_backing_get_mfc_free_elements, - .send_mfc_command = spu_backing_send_mfc_command, }; diff --git a/trunk/arch/powerpc/platforms/cell/spufs/context.c b/trunk/arch/powerpc/platforms/cell/spufs/context.c index 8bb33abfad17..336f238102fd 100644 --- a/trunk/arch/powerpc/platforms/cell/spufs/context.c +++ b/trunk/arch/powerpc/platforms/cell/spufs/context.c @@ -27,7 +27,7 @@ #include #include "spufs.h" -struct spu_context *alloc_spu_context(void) +struct spu_context *alloc_spu_context(struct address_space *local_store) { struct spu_context *ctx; ctx = kmalloc(sizeof *ctx, GFP_KERNEL); @@ -47,17 +47,10 @@ struct spu_context *alloc_spu_context(void) init_waitqueue_head(&ctx->ibox_wq); init_waitqueue_head(&ctx->wbox_wq); init_waitqueue_head(&ctx->stop_wq); - init_waitqueue_head(&ctx->mfc_wq); ctx->ibox_fasync = NULL; ctx->wbox_fasync = NULL; - ctx->mfc_fasync = NULL; - ctx->mfc = NULL; - ctx->tagwait = 0; ctx->state = SPU_STATE_SAVED; - ctx->local_store = NULL; - ctx->cntl = NULL; - ctx->signal1 = NULL; - ctx->signal2 = NULL; + ctx->local_store = local_store; ctx->spu = NULL; ctx->ops = &spu_backing_ops; ctx->owner = get_task_mm(current); @@ -75,6 +68,8 @@ void destroy_spu_context(struct kref *kref) ctx = container_of(kref, struct spu_context, kref); down_write(&ctx->state_sema); spu_deactivate(ctx); + ctx->ibox_fasync = NULL; + ctx->wbox_fasync = NULL; up_write(&ctx->state_sema); spu_fini_csa(&ctx->csa); kfree(ctx); @@ -114,16 +109,7 @@ void spu_release(struct spu_context *ctx) void spu_unmap_mappings(struct spu_context *ctx) { - if (ctx->local_store) - unmap_mapping_range(ctx->local_store, 0, LS_SIZE, 1); - if (ctx->mfc) - unmap_mapping_range(ctx->mfc, 0, 0x4000, 1); - if (ctx->cntl) - unmap_mapping_range(ctx->cntl, 0, 0x4000, 1); - if (ctx->signal1) - unmap_mapping_range(ctx->signal1, 0, 0x4000, 1); - if (ctx->signal2) - unmap_mapping_range(ctx->signal2, 0, 0x4000, 1); + unmap_mapping_range(ctx->local_store, 0, LS_SIZE, 1); } int spu_acquire_runnable(struct spu_context *ctx) diff --git a/trunk/arch/powerpc/platforms/cell/spufs/file.c b/trunk/arch/powerpc/platforms/cell/spufs/file.c index 366185e92667..dfa649c9b956 100644 --- a/trunk/arch/powerpc/platforms/cell/spufs/file.c +++ b/trunk/arch/powerpc/platforms/cell/spufs/file.c @@ -20,8 +20,6 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#undef DEBUG - #include #include #include @@ -41,10 +39,8 @@ static int spufs_mem_open(struct inode *inode, struct file *file) { struct spufs_inode_info *i = SPUFS_I(inode); - struct spu_context *ctx = i->i_ctx; - file->private_data = ctx; - file->f_mapping = inode->i_mapping; - ctx->local_store = inode->i_mapping; + file->private_data = i->i_ctx; + file->f_mapping = i->i_ctx->local_store; return 0; } @@ -88,7 +84,7 @@ spufs_mem_write(struct file *file, const char __user *buffer, return ret; } -#ifdef CONFIG_SPUFS_MMAP +#ifdef CONFIG_SPARSEMEM static struct page * spufs_mem_mmap_nopage(struct vm_area_struct *vma, unsigned long address, int *type) @@ -140,113 +136,11 @@ static struct file_operations spufs_mem_fops = { .read = spufs_mem_read, .write = spufs_mem_write, .llseek = generic_file_llseek, -#ifdef CONFIG_SPUFS_MMAP +#ifdef CONFIG_SPARSEMEM .mmap = spufs_mem_mmap, #endif }; -#ifdef CONFIG_SPUFS_MMAP -static struct page *spufs_ps_nopage(struct vm_area_struct *vma, - unsigned long address, - int *type, unsigned long ps_offs) -{ - struct page *page = NOPAGE_SIGBUS; - int fault_type = VM_FAULT_SIGBUS; - struct spu_context *ctx = vma->vm_file->private_data; - unsigned long offset = address - vma->vm_start; - unsigned long area; - int ret; - - offset += vma->vm_pgoff << PAGE_SHIFT; - if (offset >= 0x4000) - goto out; - - ret = spu_acquire_runnable(ctx); - if (ret) - goto out; - - area = ctx->spu->problem_phys + ps_offs; - page = pfn_to_page((area + offset) >> PAGE_SHIFT); - fault_type = VM_FAULT_MINOR; - page_cache_get(page); - - spu_release(ctx); - - out: - if (type) - *type = fault_type; - - return page; -} - -static struct page *spufs_cntl_mmap_nopage(struct vm_area_struct *vma, - unsigned long address, int *type) -{ - return spufs_ps_nopage(vma, address, type, 0x4000); -} - -static struct vm_operations_struct spufs_cntl_mmap_vmops = { - .nopage = spufs_cntl_mmap_nopage, -}; - -/* - * mmap support for problem state control area [0x4000 - 0x4fff]. - * Mapping this area requires that the application have CAP_SYS_RAWIO, - * as these registers require special care when read/writing. - */ -static int spufs_cntl_mmap(struct file *file, struct vm_area_struct *vma) -{ - if (!(vma->vm_flags & VM_SHARED)) - return -EINVAL; - - if (!capable(CAP_SYS_RAWIO)) - return -EPERM; - - vma->vm_flags |= VM_RESERVED; - vma->vm_page_prot = __pgprot(pgprot_val(vma->vm_page_prot) - | _PAGE_NO_CACHE); - - vma->vm_ops = &spufs_cntl_mmap_vmops; - return 0; -} -#endif - -static int spufs_cntl_open(struct inode *inode, struct file *file) -{ - struct spufs_inode_info *i = SPUFS_I(inode); - struct spu_context *ctx = i->i_ctx; - - file->private_data = ctx; - file->f_mapping = inode->i_mapping; - ctx->cntl = inode->i_mapping; - return 0; -} - -static ssize_t -spufs_cntl_read(struct file *file, char __user *buffer, - size_t size, loff_t *pos) -{ - /* FIXME: read from spu status */ - return -EINVAL; -} - -static ssize_t -spufs_cntl_write(struct file *file, const char __user *buffer, - size_t size, loff_t *pos) -{ - /* FIXME: write to runctl bit */ - return -EINVAL; -} - -static struct file_operations spufs_cntl_fops = { - .open = spufs_cntl_open, - .read = spufs_cntl_read, - .write = spufs_cntl_write, -#ifdef CONFIG_SPUFS_MMAP - .mmap = spufs_cntl_mmap, -#endif -}; - static int spufs_regs_open(struct inode *inode, struct file *file) { @@ -607,16 +501,6 @@ static struct file_operations spufs_wbox_stat_fops = { .read = spufs_wbox_stat_read, }; -static int spufs_signal1_open(struct inode *inode, struct file *file) -{ - struct spufs_inode_info *i = SPUFS_I(inode); - struct spu_context *ctx = i->i_ctx; - file->private_data = ctx; - file->f_mapping = inode->i_mapping; - ctx->signal1 = inode->i_mapping; - return nonseekable_open(inode, file); -} - static ssize_t spufs_signal1_read(struct file *file, char __user *buf, size_t len, loff_t *pos) { @@ -657,50 +541,12 @@ static ssize_t spufs_signal1_write(struct file *file, const char __user *buf, return 4; } -#ifdef CONFIG_SPUFS_MMAP -static struct page *spufs_signal1_mmap_nopage(struct vm_area_struct *vma, - unsigned long address, int *type) -{ - return spufs_ps_nopage(vma, address, type, 0x14000); -} - -static struct vm_operations_struct spufs_signal1_mmap_vmops = { - .nopage = spufs_signal1_mmap_nopage, -}; - -static int spufs_signal1_mmap(struct file *file, struct vm_area_struct *vma) -{ - if (!(vma->vm_flags & VM_SHARED)) - return -EINVAL; - - vma->vm_flags |= VM_RESERVED; - vma->vm_page_prot = __pgprot(pgprot_val(vma->vm_page_prot) - | _PAGE_NO_CACHE); - - vma->vm_ops = &spufs_signal1_mmap_vmops; - return 0; -} -#endif - static struct file_operations spufs_signal1_fops = { - .open = spufs_signal1_open, + .open = spufs_pipe_open, .read = spufs_signal1_read, .write = spufs_signal1_write, -#ifdef CONFIG_SPUFS_MMAP - .mmap = spufs_signal1_mmap, -#endif }; -static int spufs_signal2_open(struct inode *inode, struct file *file) -{ - struct spufs_inode_info *i = SPUFS_I(inode); - struct spu_context *ctx = i->i_ctx; - file->private_data = ctx; - file->f_mapping = inode->i_mapping; - ctx->signal2 = inode->i_mapping; - return nonseekable_open(inode, file); -} - static ssize_t spufs_signal2_read(struct file *file, char __user *buf, size_t len, loff_t *pos) { @@ -743,39 +589,10 @@ static ssize_t spufs_signal2_write(struct file *file, const char __user *buf, return 4; } -#ifdef CONFIG_SPUFS_MMAP -static struct page *spufs_signal2_mmap_nopage(struct vm_area_struct *vma, - unsigned long address, int *type) -{ - return spufs_ps_nopage(vma, address, type, 0x1c000); -} - -static struct vm_operations_struct spufs_signal2_mmap_vmops = { - .nopage = spufs_signal2_mmap_nopage, -}; - -static int spufs_signal2_mmap(struct file *file, struct vm_area_struct *vma) -{ - if (!(vma->vm_flags & VM_SHARED)) - return -EINVAL; - - /* FIXME: */ - vma->vm_flags |= VM_RESERVED; - vma->vm_page_prot = __pgprot(pgprot_val(vma->vm_page_prot) - | _PAGE_NO_CACHE); - - vma->vm_ops = &spufs_signal2_mmap_vmops; - return 0; -} -#endif - static struct file_operations spufs_signal2_fops = { - .open = spufs_signal2_open, + .open = spufs_pipe_open, .read = spufs_signal2_read, .write = spufs_signal2_write, -#ifdef CONFIG_SPUFS_MMAP - .mmap = spufs_signal2_mmap, -#endif }; static void spufs_signal1_type_set(void *data, u64 val) @@ -824,332 +641,6 @@ static u64 spufs_signal2_type_get(void *data) DEFINE_SIMPLE_ATTRIBUTE(spufs_signal2_type, spufs_signal2_type_get, spufs_signal2_type_set, "%llu"); -#ifdef CONFIG_SPUFS_MMAP -static struct page *spufs_mfc_mmap_nopage(struct vm_area_struct *vma, - unsigned long address, int *type) -{ - return spufs_ps_nopage(vma, address, type, 0x3000); -} - -static struct vm_operations_struct spufs_mfc_mmap_vmops = { - .nopage = spufs_mfc_mmap_nopage, -}; - -/* - * mmap support for problem state MFC DMA area [0x0000 - 0x0fff]. - * Mapping this area requires that the application have CAP_SYS_RAWIO, - * as these registers require special care when read/writing. - */ -static int spufs_mfc_mmap(struct file *file, struct vm_area_struct *vma) -{ - if (!(vma->vm_flags & VM_SHARED)) - return -EINVAL; - - if (!capable(CAP_SYS_RAWIO)) - return -EPERM; - - vma->vm_flags |= VM_RESERVED; - vma->vm_page_prot = __pgprot(pgprot_val(vma->vm_page_prot) - | _PAGE_NO_CACHE); - - vma->vm_ops = &spufs_mfc_mmap_vmops; - return 0; -} -#endif - -static int spufs_mfc_open(struct inode *inode, struct file *file) -{ - struct spufs_inode_info *i = SPUFS_I(inode); - struct spu_context *ctx = i->i_ctx; - - /* we don't want to deal with DMA into other processes */ - if (ctx->owner != current->mm) - return -EINVAL; - - if (atomic_read(&inode->i_count) != 1) - return -EBUSY; - - file->private_data = ctx; - return nonseekable_open(inode, file); -} - -/* interrupt-level mfc callback function. */ -void spufs_mfc_callback(struct spu *spu) -{ - struct spu_context *ctx = spu->ctx; - - wake_up_all(&ctx->mfc_wq); - - pr_debug("%s %s\n", __FUNCTION__, spu->name); - if (ctx->mfc_fasync) { - u32 free_elements, tagstatus; - unsigned int mask; - - /* no need for spu_acquire in interrupt context */ - free_elements = ctx->ops->get_mfc_free_elements(ctx); - tagstatus = ctx->ops->read_mfc_tagstatus(ctx); - - mask = 0; - if (free_elements & 0xffff) - mask |= POLLOUT; - if (tagstatus & ctx->tagwait) - mask |= POLLIN; - - kill_fasync(&ctx->mfc_fasync, SIGIO, mask); - } -} - -static int spufs_read_mfc_tagstatus(struct spu_context *ctx, u32 *status) -{ - /* See if there is one tag group is complete */ - /* FIXME we need locking around tagwait */ - *status = ctx->ops->read_mfc_tagstatus(ctx) & ctx->tagwait; - ctx->tagwait &= ~*status; - if (*status) - return 1; - - /* enable interrupt waiting for any tag group, - may silently fail if interrupts are already enabled */ - ctx->ops->set_mfc_query(ctx, ctx->tagwait, 1); - return 0; -} - -static ssize_t spufs_mfc_read(struct file *file, char __user *buffer, - size_t size, loff_t *pos) -{ - struct spu_context *ctx = file->private_data; - int ret = -EINVAL; - u32 status; - - if (size != 4) - goto out; - - spu_acquire(ctx); - if (file->f_flags & O_NONBLOCK) { - status = ctx->ops->read_mfc_tagstatus(ctx); - if (!(status & ctx->tagwait)) - ret = -EAGAIN; - else - ctx->tagwait &= ~status; - } else { - ret = spufs_wait(ctx->mfc_wq, - spufs_read_mfc_tagstatus(ctx, &status)); - } - spu_release(ctx); - - if (ret) - goto out; - - ret = 4; - if (copy_to_user(buffer, &status, 4)) - ret = -EFAULT; - -out: - return ret; -} - -static int spufs_check_valid_dma(struct mfc_dma_command *cmd) -{ - pr_debug("queueing DMA %x %lx %x %x %x\n", cmd->lsa, - cmd->ea, cmd->size, cmd->tag, cmd->cmd); - - switch (cmd->cmd) { - case MFC_PUT_CMD: - case MFC_PUTF_CMD: - case MFC_PUTB_CMD: - case MFC_GET_CMD: - case MFC_GETF_CMD: - case MFC_GETB_CMD: - break; - default: - pr_debug("invalid DMA opcode %x\n", cmd->cmd); - return -EIO; - } - - if ((cmd->lsa & 0xf) != (cmd->ea &0xf)) { - pr_debug("invalid DMA alignment, ea %lx lsa %x\n", - cmd->ea, cmd->lsa); - return -EIO; - } - - switch (cmd->size & 0xf) { - case 1: - break; - case 2: - if (cmd->lsa & 1) - goto error; - break; - case 4: - if (cmd->lsa & 3) - goto error; - break; - case 8: - if (cmd->lsa & 7) - goto error; - break; - case 0: - if (cmd->lsa & 15) - goto error; - break; - error: - default: - pr_debug("invalid DMA alignment %x for size %x\n", - cmd->lsa & 0xf, cmd->size); - return -EIO; - } - - if (cmd->size > 16 * 1024) { - pr_debug("invalid DMA size %x\n", cmd->size); - return -EIO; - } - - if (cmd->tag & 0xfff0) { - /* we reserve the higher tag numbers for kernel use */ - pr_debug("invalid DMA tag\n"); - return -EIO; - } - - if (cmd->class) { - /* not supported in this version */ - pr_debug("invalid DMA class\n"); - return -EIO; - } - - return 0; -} - -static int spu_send_mfc_command(struct spu_context *ctx, - struct mfc_dma_command cmd, - int *error) -{ - *error = ctx->ops->send_mfc_command(ctx, &cmd); - if (*error == -EAGAIN) { - /* wait for any tag group to complete - so we have space for the new command */ - ctx->ops->set_mfc_query(ctx, ctx->tagwait, 1); - /* try again, because the queue might be - empty again */ - *error = ctx->ops->send_mfc_command(ctx, &cmd); - if (*error == -EAGAIN) - return 0; - } - return 1; -} - -static ssize_t spufs_mfc_write(struct file *file, const char __user *buffer, - size_t size, loff_t *pos) -{ - struct spu_context *ctx = file->private_data; - struct mfc_dma_command cmd; - int ret = -EINVAL; - - if (size != sizeof cmd) - goto out; - - ret = -EFAULT; - if (copy_from_user(&cmd, buffer, sizeof cmd)) - goto out; - - ret = spufs_check_valid_dma(&cmd); - if (ret) - goto out; - - spu_acquire_runnable(ctx); - if (file->f_flags & O_NONBLOCK) { - ret = ctx->ops->send_mfc_command(ctx, &cmd); - } else { - int status; - ret = spufs_wait(ctx->mfc_wq, - spu_send_mfc_command(ctx, cmd, &status)); - if (status) - ret = status; - } - spu_release(ctx); - - if (ret) - goto out; - - ctx->tagwait |= 1 << cmd.tag; - -out: - return ret; -} - -static unsigned int spufs_mfc_poll(struct file *file,poll_table *wait) -{ - struct spu_context *ctx = file->private_data; - u32 free_elements, tagstatus; - unsigned int mask; - - spu_acquire(ctx); - ctx->ops->set_mfc_query(ctx, ctx->tagwait, 2); - free_elements = ctx->ops->get_mfc_free_elements(ctx); - tagstatus = ctx->ops->read_mfc_tagstatus(ctx); - spu_release(ctx); - - poll_wait(file, &ctx->mfc_wq, wait); - - mask = 0; - if (free_elements & 0xffff) - mask |= POLLOUT | POLLWRNORM; - if (tagstatus & ctx->tagwait) - mask |= POLLIN | POLLRDNORM; - - pr_debug("%s: free %d tagstatus %d tagwait %d\n", __FUNCTION__, - free_elements, tagstatus, ctx->tagwait); - - return mask; -} - -static int spufs_mfc_flush(struct file *file) -{ - struct spu_context *ctx = file->private_data; - int ret; - - spu_acquire(ctx); -#if 0 -/* this currently hangs */ - ret = spufs_wait(ctx->mfc_wq, - ctx->ops->set_mfc_query(ctx, ctx->tagwait, 2)); - if (ret) - goto out; - ret = spufs_wait(ctx->mfc_wq, - ctx->ops->read_mfc_tagstatus(ctx) == ctx->tagwait); -out: -#else - ret = 0; -#endif - spu_release(ctx); - - return ret; -} - -static int spufs_mfc_fsync(struct file *file, struct dentry *dentry, - int datasync) -{ - return spufs_mfc_flush(file); -} - -static int spufs_mfc_fasync(int fd, struct file *file, int on) -{ - struct spu_context *ctx = file->private_data; - - return fasync_helper(fd, file, on, &ctx->mfc_fasync); -} - -static struct file_operations spufs_mfc_fops = { - .open = spufs_mfc_open, - .read = spufs_mfc_read, - .write = spufs_mfc_write, - .poll = spufs_mfc_poll, - .flush = spufs_mfc_flush, - .fsync = spufs_mfc_fsync, - .fasync = spufs_mfc_fasync, -#ifdef CONFIG_SPUFS_MMAP - .mmap = spufs_mfc_mmap, -#endif -}; - static void spufs_npc_set(void *data, u64 val) { struct spu_context *ctx = data; @@ -1292,8 +783,6 @@ struct tree_descr spufs_dir_contents[] = { { "signal2", &spufs_signal2_fops, 0666, }, { "signal1_type", &spufs_signal1_type, 0666, }, { "signal2_type", &spufs_signal2_type, 0666, }, - { "mfc", &spufs_mfc_fops, 0666, }, - { "cntl", &spufs_cntl_fops, 0666, }, { "npc", &spufs_npc_ops, 0666, }, { "fpcr", &spufs_fpcr_fops, 0666, }, { "decr", &spufs_decr_ops, 0666, }, diff --git a/trunk/arch/powerpc/platforms/cell/spufs/hw_ops.c b/trunk/arch/powerpc/platforms/cell/spufs/hw_ops.c index a13a8b5a014d..5445719bff79 100644 --- a/trunk/arch/powerpc/platforms/cell/spufs/hw_ops.c +++ b/trunk/arch/powerpc/platforms/cell/spufs/hw_ops.c @@ -232,59 +232,6 @@ static void spu_hw_runcntl_stop(struct spu_context *ctx) spin_unlock_irq(&ctx->spu->register_lock); } -static int spu_hw_set_mfc_query(struct spu_context * ctx, u32 mask, u32 mode) -{ - struct spu_problem *prob = ctx->spu->problem; - int ret; - - spin_lock_irq(&ctx->spu->register_lock); - ret = -EAGAIN; - if (in_be32(&prob->dma_querytype_RW)) - goto out; - ret = 0; - out_be32(&prob->dma_querymask_RW, mask); - out_be32(&prob->dma_querytype_RW, mode); -out: - spin_unlock_irq(&ctx->spu->register_lock); - return ret; -} - -static u32 spu_hw_read_mfc_tagstatus(struct spu_context * ctx) -{ - return in_be32(&ctx->spu->problem->dma_tagstatus_R); -} - -static u32 spu_hw_get_mfc_free_elements(struct spu_context *ctx) -{ - return in_be32(&ctx->spu->problem->dma_qstatus_R); -} - -static int spu_hw_send_mfc_command(struct spu_context *ctx, - struct mfc_dma_command *cmd) -{ - u32 status; - struct spu_problem *prob = ctx->spu->problem; - - spin_lock_irq(&ctx->spu->register_lock); - out_be32(&prob->mfc_lsa_W, cmd->lsa); - out_be64(&prob->mfc_ea_W, cmd->ea); - out_be32(&prob->mfc_union_W.by32.mfc_size_tag32, - cmd->size << 16 | cmd->tag); - out_be32(&prob->mfc_union_W.by32.mfc_class_cmd32, - cmd->class << 16 | cmd->cmd); - status = in_be32(&prob->mfc_union_W.by32.mfc_class_cmd32); - spin_unlock_irq(&ctx->spu->register_lock); - - switch (status & 0xffff) { - case 0: - return 0; - case 2: - return -EAGAIN; - default: - return -EINVAL; - } -} - struct spu_context_ops spu_hw_ops = { .mbox_read = spu_hw_mbox_read, .mbox_stat_read = spu_hw_mbox_stat_read, @@ -305,8 +252,4 @@ struct spu_context_ops spu_hw_ops = { .get_ls = spu_hw_get_ls, .runcntl_write = spu_hw_runcntl_write, .runcntl_stop = spu_hw_runcntl_stop, - .set_mfc_query = spu_hw_set_mfc_query, - .read_mfc_tagstatus = spu_hw_read_mfc_tagstatus, - .get_mfc_free_elements = spu_hw_get_mfc_free_elements, - .send_mfc_command = spu_hw_send_mfc_command, }; diff --git a/trunk/arch/powerpc/platforms/cell/spufs/inode.c b/trunk/arch/powerpc/platforms/cell/spufs/inode.c index d9554199afa7..5be40aa483fd 100644 --- a/trunk/arch/powerpc/platforms/cell/spufs/inode.c +++ b/trunk/arch/powerpc/platforms/cell/spufs/inode.c @@ -241,7 +241,7 @@ spufs_mkdir(struct inode *dir, struct dentry *dentry, int mode) inode->i_gid = dir->i_gid; inode->i_mode &= S_ISGID; } - ctx = alloc_spu_context(); + ctx = alloc_spu_context(inode->i_mapping); SPUFS_I(inode)->i_ctx = ctx; if (!ctx) goto out_iput; @@ -442,7 +442,7 @@ static struct file_system_type spufs_type = { .kill_sb = kill_litter_super, }; -static int __init spufs_init(void) +static int spufs_init(void) { int ret; ret = -ENOMEM; @@ -472,7 +472,7 @@ static int __init spufs_init(void) } module_init(spufs_init); -static void __exit spufs_exit(void) +static void spufs_exit(void) { spu_sched_exit(); unregister_spu_syscalls(&spufs_calls); diff --git a/trunk/arch/powerpc/platforms/cell/spufs/run.c b/trunk/arch/powerpc/platforms/cell/spufs/run.c index c04e078c0fe5..18ea8866c61a 100644 --- a/trunk/arch/powerpc/platforms/cell/spufs/run.c +++ b/trunk/arch/powerpc/platforms/cell/spufs/run.c @@ -76,90 +76,6 @@ static inline int spu_reacquire_runnable(struct spu_context *ctx, u32 *npc, return 0; } -/* - * SPU syscall restarting is tricky because we violate the basic - * assumption that the signal handler is running on the interrupted - * thread. Here instead, the handler runs on PowerPC user space code, - * while the syscall was called from the SPU. - * This means we can only do a very rough approximation of POSIX - * signal semantics. - */ -int spu_handle_restartsys(struct spu_context *ctx, long *spu_ret, - unsigned int *npc) -{ - int ret; - - switch (*spu_ret) { - case -ERESTARTSYS: - case -ERESTARTNOINTR: - /* - * Enter the regular syscall restarting for - * sys_spu_run, then restart the SPU syscall - * callback. - */ - *npc -= 8; - ret = -ERESTARTSYS; - break; - case -ERESTARTNOHAND: - case -ERESTART_RESTARTBLOCK: - /* - * Restart block is too hard for now, just return -EINTR - * to the SPU. - * ERESTARTNOHAND comes from sys_pause, we also return - * -EINTR from there. - * Assume that we need to be restarted ourselves though. - */ - *spu_ret = -EINTR; - ret = -ERESTARTSYS; - break; - default: - printk(KERN_WARNING "%s: unexpected return code %ld\n", - __FUNCTION__, *spu_ret); - ret = 0; - } - return ret; -} - -int spu_process_callback(struct spu_context *ctx) -{ - struct spu_syscall_block s; - u32 ls_pointer, npc; - char *ls; - long spu_ret; - int ret; - - /* get syscall block from local store */ - npc = ctx->ops->npc_read(ctx); - ls = ctx->ops->get_ls(ctx); - ls_pointer = *(u32*)(ls + npc); - if (ls_pointer > (LS_SIZE - sizeof(s))) - return -EFAULT; - memcpy(&s, ls + ls_pointer, sizeof (s)); - - /* do actual syscall without pinning the spu */ - ret = 0; - spu_ret = -ENOSYS; - npc += 4; - - if (s.nr_ret < __NR_syscalls) { - spu_release(ctx); - /* do actual system call from here */ - spu_ret = spu_sys_callback(&s); - if (spu_ret <= -ERESTARTSYS) { - ret = spu_handle_restartsys(ctx, &spu_ret, &npc); - } - spu_acquire(ctx); - if (ret == -ERESTARTSYS) - return ret; - } - - /* write result, jump over indirect pointer */ - memcpy(ls + ls_pointer, &spu_ret, sizeof (spu_ret)); - ctx->ops->npc_write(ctx, npc); - ctx->ops->runcntl_write(ctx, SPU_RUNCNTL_RUNNABLE); - return ret; -} - static inline int spu_process_events(struct spu_context *ctx) { struct spu *spu = ctx->spu; @@ -191,13 +107,6 @@ long spufs_run_spu(struct file *file, struct spu_context *ctx, ret = spufs_wait(ctx->stop_wq, spu_stopped(ctx, status)); if (unlikely(ret)) break; - if ((*status & SPU_STATUS_STOPPED_BY_STOP) && - (*status >> SPU_STOP_STATUS_SHIFT == 0x2104)) { - ret = spu_process_callback(ctx); - if (ret) - break; - *status &= ~SPU_STATUS_STOPPED_BY_STOP; - } if (unlikely(ctx->state != SPU_STATE_RUNNABLE)) { ret = spu_reacquire_runnable(ctx, npc, status); if (ret) diff --git a/trunk/arch/powerpc/platforms/cell/spufs/sched.c b/trunk/arch/powerpc/platforms/cell/spufs/sched.c index bf652cd77000..963182fbd1aa 100644 --- a/trunk/arch/powerpc/platforms/cell/spufs/sched.c +++ b/trunk/arch/powerpc/platforms/cell/spufs/sched.c @@ -180,7 +180,6 @@ static inline void bind_context(struct spu *spu, struct spu_context *ctx) spu->ibox_callback = spufs_ibox_callback; spu->wbox_callback = spufs_wbox_callback; spu->stop_callback = spufs_stop_callback; - spu->mfc_callback = spufs_mfc_callback; mb(); spu_unmap_mappings(ctx); spu_restore(&ctx->csa, spu); @@ -198,7 +197,6 @@ static inline void unbind_context(struct spu *spu, struct spu_context *ctx) spu->ibox_callback = NULL; spu->wbox_callback = NULL; spu->stop_callback = NULL; - spu->mfc_callback = NULL; spu->mm = NULL; spu->pid = 0; spu->prio = MAX_PRIO; diff --git a/trunk/arch/powerpc/platforms/cell/spufs/spufs.h b/trunk/arch/powerpc/platforms/cell/spufs/spufs.h index 4485738e2102..db2601f0abd5 100644 --- a/trunk/arch/powerpc/platforms/cell/spufs/spufs.h +++ b/trunk/arch/powerpc/platforms/cell/spufs/spufs.h @@ -43,11 +43,7 @@ struct spu_context { struct spu *spu; /* pointer to a physical SPU */ struct spu_state csa; /* SPU context save area. */ spinlock_t mmio_lock; /* protects mmio access */ - struct address_space *local_store; /* local store mapping. */ - struct address_space *mfc; /* 'mfc' area mappings. */ - struct address_space *cntl; /* 'control' area mappings. */ - struct address_space *signal1; /* 'signal1' area mappings. */ - struct address_space *signal2; /* 'signal2' area mappings. */ + struct address_space *local_store;/* local store backing store */ enum { SPU_STATE_RUNNABLE, SPU_STATE_SAVED } state; struct rw_semaphore state_sema; @@ -59,27 +55,13 @@ struct spu_context { wait_queue_head_t ibox_wq; wait_queue_head_t wbox_wq; wait_queue_head_t stop_wq; - wait_queue_head_t mfc_wq; struct fasync_struct *ibox_fasync; struct fasync_struct *wbox_fasync; - struct fasync_struct *mfc_fasync; - u32 tagwait; struct spu_context_ops *ops; struct work_struct reap_work; u64 flags; }; -struct mfc_dma_command { - int32_t pad; /* reserved */ - uint32_t lsa; /* local storage address */ - uint64_t ea; /* effective address */ - uint16_t size; /* transfer size */ - uint16_t tag; /* command tag */ - uint16_t class; /* class ID */ - uint16_t cmd; /* command opcode */ -}; - - /* SPU context query/set operations. */ struct spu_context_ops { int (*mbox_read) (struct spu_context * ctx, u32 * data); @@ -102,11 +84,6 @@ struct spu_context_ops { char*(*get_ls) (struct spu_context * ctx); void (*runcntl_write) (struct spu_context * ctx, u32 data); void (*runcntl_stop) (struct spu_context * ctx); - int (*set_mfc_query)(struct spu_context * ctx, u32 mask, u32 mode); - u32 (*read_mfc_tagstatus)(struct spu_context * ctx); - u32 (*get_mfc_free_elements)(struct spu_context *ctx); - int (*send_mfc_command)(struct spu_context *ctx, - struct mfc_dma_command *cmd); }; extern struct spu_context_ops spu_hw_ops; @@ -129,7 +106,7 @@ long spufs_create_thread(struct nameidata *nd, extern struct file_operations spufs_context_fops; /* context management */ -struct spu_context * alloc_spu_context(void); +struct spu_context * alloc_spu_context(struct address_space *local_store); void destroy_spu_context(struct kref *kref); struct spu_context * get_spu_context(struct spu_context *ctx); int put_spu_context(struct spu_context *ctx); @@ -182,6 +159,5 @@ size_t spu_ibox_read(struct spu_context *ctx, u32 *data); void spufs_ibox_callback(struct spu *spu); void spufs_wbox_callback(struct spu *spu); void spufs_stop_callback(struct spu *spu); -void spufs_mfc_callback(struct spu *spu); #endif diff --git a/trunk/arch/powerpc/platforms/cell/spufs/switch.c b/trunk/arch/powerpc/platforms/cell/spufs/switch.c index 97898d5d34e5..212db28531fa 100644 --- a/trunk/arch/powerpc/platforms/cell/spufs/switch.c +++ b/trunk/arch/powerpc/platforms/cell/spufs/switch.c @@ -2145,8 +2145,7 @@ static void init_priv1(struct spu_state *csa) csa->priv1.int_mask_class1_RW = CLASS1_ENABLE_SEGMENT_FAULT_INTR | CLASS1_ENABLE_STORAGE_FAULT_INTR; csa->priv1.int_mask_class2_RW = CLASS2_ENABLE_SPU_STOP_INTR | - CLASS2_ENABLE_SPU_HALT_INTR | - CLASS2_ENABLE_SPU_DMA_TAG_GROUP_COMPLETE_INTR; + CLASS2_ENABLE_SPU_HALT_INTR; } static void init_priv2(struct spu_state *csa) diff --git a/trunk/arch/powerpc/platforms/chrp/chrp.h b/trunk/arch/powerpc/platforms/chrp/chrp.h index 63f0aee4c158..814f54742e0f 100644 --- a/trunk/arch/powerpc/platforms/chrp/chrp.h +++ b/trunk/arch/powerpc/platforms/chrp/chrp.h @@ -8,4 +8,4 @@ extern int chrp_set_rtc_time(struct rtc_time *); extern long chrp_time_init(void); extern void chrp_find_bridges(void); -extern void chrp_event_scan(unsigned long); +extern void chrp_event_scan(void); diff --git a/trunk/arch/powerpc/platforms/chrp/setup.c b/trunk/arch/powerpc/platforms/chrp/setup.c index 23a201718704..8bf4307e323d 100644 --- a/trunk/arch/powerpc/platforms/chrp/setup.c +++ b/trunk/arch/powerpc/platforms/chrp/setup.c @@ -35,7 +35,6 @@ #include #include #include -#include #include #include @@ -62,10 +61,6 @@ EXPORT_SYMBOL(_chrp_type); struct mpic *chrp_mpic; -/* Used for doing CHRP event-scans */ -DEFINE_PER_CPU(struct timer_list, heartbeat_timer); -unsigned long event_scan_interval; - /* * XXX this should be in xmon.h, but putting it there means xmon.h * has to include (to get irqreturn_t), which @@ -234,6 +229,8 @@ void __init chrp_setup_arch(void) { struct device_node *root = find_path_device ("/"); char *machine = NULL; + struct device_node *device; + unsigned int *p = NULL; /* init to some ~sane value until calibrate_delay() runs */ loops_per_jiffy = 50000000/HZ; @@ -290,11 +287,22 @@ void __init chrp_setup_arch(void) */ sio_init(); - pci_create_OF_bus_map(); + /* Get the event scan rate for the rtas so we know how + * often it expects a heartbeat. -- Cort + */ + device = find_devices("rtas"); + if (device) + p = (unsigned int *) get_property + (device, "rtas-event-scan-rate", NULL); + if (p && *p) { + ppc_md.heartbeat = chrp_event_scan; + ppc_md.heartbeat_reset = HZ / (*p * 30) - 1; + ppc_md.heartbeat_count = 1; + printk("RTAS Event Scan Rate: %u (%lu jiffies)\n", + *p, ppc_md.heartbeat_reset); + } -#ifdef CONFIG_SMP - smp_ops = &chrp_smp_ops; -#endif /* CONFIG_SMP */ + pci_create_OF_bus_map(); /* * Print the banner, then scroll down so boot progress @@ -304,7 +312,7 @@ void __init chrp_setup_arch(void) } void -chrp_event_scan(unsigned long unused) +chrp_event_scan(void) { unsigned char log[1024]; int ret = 0; @@ -312,8 +320,7 @@ chrp_event_scan(unsigned long unused) /* XXX: we should loop until the hardware says no more error logs -- Cort */ rtas_call(rtas_token("event-scan"), 4, 1, &ret, 0xffffffff, 0, __pa(log), 1024); - mod_timer(&__get_cpu_var(heartbeat_timer), - jiffies + event_scan_interval); + ppc_md.heartbeat_count = ppc_md.heartbeat_reset; } /* @@ -458,9 +465,6 @@ void __init chrp_init_IRQ(void) void __init chrp_init2(void) { - struct device_node *device; - unsigned int *p = NULL; - #ifdef CONFIG_NVRAM chrp_nvram_init(); #endif @@ -472,53 +476,12 @@ chrp_init2(void) request_region(0x80,0x10,"dma page reg"); request_region(0xc0,0x20,"dma2"); - /* Get the event scan rate for the rtas so we know how - * often it expects a heartbeat. -- Cort - */ - device = find_devices("rtas"); - if (device) - p = (unsigned int *) get_property - (device, "rtas-event-scan-rate", NULL); - if (p && *p) { - /* - * Arrange to call chrp_event_scan at least *p times - * per minute. We use 59 rather than 60 here so that - * the rate will be slightly higher than the minimum. - * This all assumes we don't do hotplug CPU on any - * machine that needs the event scans done. - */ - unsigned long interval, offset; - int cpu, ncpus; - struct timer_list *timer; - - interval = HZ * 59 / *p; - offset = HZ; - ncpus = num_online_cpus(); - event_scan_interval = ncpus * interval; - for (cpu = 0; cpu < ncpus; ++cpu) { - timer = &per_cpu(heartbeat_timer, cpu); - setup_timer(timer, chrp_event_scan, 0); - timer->expires = jiffies + offset; - add_timer_on(timer, cpu); - offset += interval; - } - printk("RTAS Event Scan Rate: %u (%lu jiffies)\n", - *p, interval); - } - if (ppc_md.progress) ppc_md.progress(" Have fun! ", 0x7777); } -static int __init chrp_probe(void) +void __init chrp_init(void) { - char *dtype = of_get_flat_dt_prop(of_get_flat_dt_root(), - "device_type", NULL); - if (dtype == NULL) - return 0; - if (strcmp(dtype, "chrp")) - return 0; - ISA_DMA_THRESHOLD = ~0L; DMA_MODE_READ = 0x44; DMA_MODE_WRITE = 0x48; diff --git a/trunk/arch/powerpc/platforms/iseries/setup.c b/trunk/arch/powerpc/platforms/iseries/setup.c index 6ce8a404ba6b..fa4550611c11 100644 --- a/trunk/arch/powerpc/platforms/iseries/setup.c +++ b/trunk/arch/powerpc/platforms/iseries/setup.c @@ -675,20 +675,18 @@ static void iseries_dedicated_idle(void) void __init iSeries_init_IRQ(void) { } #endif -static int __init iseries_probe(void) +static int __init iseries_probe(int platform) { - unsigned long root = of_get_flat_dt_root(); - if (!of_flat_dt_is_compatible(root, "IBM,iSeries")) + if (PLATFORM_ISERIES_LPAR != platform) return 0; - powerpc_firmware_features |= FW_FEATURE_ISERIES; - powerpc_firmware_features |= FW_FEATURE_LPAR; + ppc64_firmware_features |= FW_FEATURE_ISERIES; + ppc64_firmware_features |= FW_FEATURE_LPAR; return 1; } -define_machine(iseries) { - .name = "iSeries", +struct machdep_calls __initdata iseries_md = { .setup_arch = iSeries_setup_arch, .show_cpuinfo = iSeries_show_cpuinfo, .init_IRQ = iSeries_init_IRQ, @@ -932,6 +930,7 @@ void build_flat_dt(struct iseries_flat_dt *dt, unsigned long phys_mem_size) /* /chosen */ dt_start_node(dt, "chosen"); + dt_prop_u32(dt, "linux,platform", PLATFORM_ISERIES_LPAR); dt_prop_str(dt, "bootargs", cmd_line); if (cmd_mem_limit) dt_prop_u64(dt, "linux,memory-limit", cmd_mem_limit); diff --git a/trunk/arch/powerpc/platforms/maple/setup.c b/trunk/arch/powerpc/platforms/maple/setup.c index 24c0aef4ea39..ec5c1e10c407 100644 --- a/trunk/arch/powerpc/platforms/maple/setup.c +++ b/trunk/arch/powerpc/platforms/maple/setup.c @@ -259,10 +259,9 @@ static void __init maple_progress(char *s, unsigned short hex) /* * Called very early, MMU is off, device-tree isn't unflattened */ -static int __init maple_probe(void) +static int __init maple_probe(int platform) { - unsigned long root = of_get_flat_dt_root(); - if (!of_flat_dt_is_compatible(root, "Momentum,Maple")) + if (platform != PLATFORM_MAPLE) return 0; /* * On U3, the DART (iommu) must be allocated now since it @@ -275,8 +274,7 @@ static int __init maple_probe(void) return 1; } -define_machine(maple_md) { - .name = "Maple", +struct machdep_calls __initdata maple_md = { .probe = maple_probe, .setup_arch = maple_setup_arch, .init_early = maple_init_early, @@ -292,7 +290,7 @@ define_machine(maple_md) { .get_rtc_time = maple_get_rtc_time, .calibrate_decr = generic_calibrate_decr, .progress = maple_progress, - .power_save = power4_idle, + .idle_loop = native_idle, #ifdef CONFIG_KEXEC .machine_kexec = default_machine_kexec, .machine_kexec_prepare = default_machine_kexec_prepare, diff --git a/trunk/arch/powerpc/platforms/powermac/bootx_init.c b/trunk/arch/powerpc/platforms/powermac/bootx_init.c index eacbfd9beabc..fa8b4d7b5ded 100644 --- a/trunk/arch/powerpc/platforms/powermac/bootx_init.c +++ b/trunk/arch/powerpc/platforms/powermac/bootx_init.c @@ -161,7 +161,9 @@ static void __init bootx_dt_add_prop(char *name, void *data, int size, static void __init bootx_add_chosen_props(unsigned long base, unsigned long *mem_end) { - u32 val; + u32 val = _MACH_Pmac; + + bootx_dt_add_prop("linux,platform", &val, 4, mem_end); if (bootx_info->kernelParamsOffset) { char *args = (char *)((unsigned long)bootx_info) + @@ -491,7 +493,7 @@ void __init bootx_init(unsigned long r3, unsigned long r4) && (strcmp(model, "iMac,1") == 0 || strcmp(model, "PowerMac1,1") == 0)) { bootx_printf("iMac,1 detected, shutting down USB \n"); - out_le32((unsigned __iomem *)0x80880008, 1); /* XXX */ + out_le32((unsigned *)0x80880008, 1); /* XXX */ } } diff --git a/trunk/arch/powerpc/platforms/powermac/feature.c b/trunk/arch/powerpc/platforms/powermac/feature.c index a5063cd675c5..e49eddd5042d 100644 --- a/trunk/arch/powerpc/platforms/powermac/feature.c +++ b/trunk/arch/powerpc/platforms/powermac/feature.c @@ -2951,7 +2951,7 @@ static void *pmac_early_vresume_data; void pmac_set_early_video_resume(void (*proc)(void *data), void *data) { - if (!machine_is(powermac)) + if (_machine != _MACH_Pmac) return; preempt_disable(); pmac_early_vresume_proc = proc; diff --git a/trunk/arch/powerpc/platforms/powermac/low_i2c.c b/trunk/arch/powerpc/platforms/powermac/low_i2c.c index e14f9ac55cf4..87eb6bb7f0e7 100644 --- a/trunk/arch/powerpc/platforms/powermac/low_i2c.c +++ b/trunk/arch/powerpc/platforms/powermac/low_i2c.c @@ -1457,9 +1457,6 @@ int __init pmac_i2c_init(void) return 0; i2c_inited = 1; - if (!machine_is(powermac)) - return 0; - /* Probe keywest-i2c busses */ kw_i2c_probe(); diff --git a/trunk/arch/powerpc/platforms/powermac/nvram.c b/trunk/arch/powerpc/platforms/powermac/nvram.c index 262f967b880a..5fd28995c74c 100644 --- a/trunk/arch/powerpc/platforms/powermac/nvram.c +++ b/trunk/arch/powerpc/platforms/powermac/nvram.c @@ -74,7 +74,7 @@ struct core99_header { * Read and write the non-volatile RAM on PowerMacs and CHRP machines. */ static int nvram_naddrs; -static volatile unsigned char __iomem *nvram_data; +static volatile unsigned char *nvram_data; static int is_core_99; static int core99_bank = 0; static int nvram_partitions[3]; @@ -148,7 +148,7 @@ static ssize_t core99_nvram_size(void) } #ifdef CONFIG_PPC32 -static volatile unsigned char __iomem *nvram_addr; +static volatile unsigned char *nvram_addr; static int nvram_mult; static unsigned char direct_nvram_read_byte(int addr) @@ -285,7 +285,7 @@ static int sm_erase_bank(int bank) int stat, i; unsigned long timeout; - u8 __iomem *base = (u8 __iomem *)nvram_data + core99_bank*NVRAM_SIZE; + u8* base = (u8 *)nvram_data + core99_bank*NVRAM_SIZE; DBG("nvram: Sharp/Micron Erasing bank %d...\n", bank); @@ -317,7 +317,7 @@ static int sm_write_bank(int bank, u8* datas) int i, stat = 0; unsigned long timeout; - u8 __iomem *base = (u8 __iomem *)nvram_data + core99_bank*NVRAM_SIZE; + u8* base = (u8 *)nvram_data + core99_bank*NVRAM_SIZE; DBG("nvram: Sharp/Micron Writing bank %d...\n", bank); @@ -352,7 +352,7 @@ static int amd_erase_bank(int bank) int i, stat = 0; unsigned long timeout; - u8 __iomem *base = (u8 __iomem *)nvram_data + core99_bank*NVRAM_SIZE; + u8* base = (u8 *)nvram_data + core99_bank*NVRAM_SIZE; DBG("nvram: AMD Erasing bank %d...\n", bank); @@ -399,7 +399,7 @@ static int amd_write_bank(int bank, u8* datas) int i, stat = 0; unsigned long timeout; - u8 __iomem *base = (u8 __iomem *)nvram_data + core99_bank*NVRAM_SIZE; + u8* base = (u8 *)nvram_data + core99_bank*NVRAM_SIZE; DBG("nvram: AMD Writing bank %d...\n", bank); @@ -597,7 +597,7 @@ int __init pmac_nvram_init(void) } #ifdef CONFIG_PPC32 - if (machine_is(chrp) && nvram_naddrs == 1) { + if (_machine == _MACH_chrp && nvram_naddrs == 1) { nvram_data = ioremap(r1.start, s1); nvram_mult = 1; ppc_md.nvram_read_val = direct_nvram_read_byte; diff --git a/trunk/arch/powerpc/platforms/powermac/pci.c b/trunk/arch/powerpc/platforms/powermac/pci.c index f5d8d15d74fa..de3f30e6b333 100644 --- a/trunk/arch/powerpc/platforms/powermac/pci.c +++ b/trunk/arch/powerpc/platforms/powermac/pci.c @@ -1201,7 +1201,7 @@ void __init pmac_pcibios_after_init(void) #ifdef CONFIG_PPC32 void pmac_pci_fixup_cardbus(struct pci_dev* dev) { - if (!machine_is(powermac)) + if (_machine != _MACH_Pmac) return; /* * Fix the interrupt routing on the various cardbus bridges @@ -1244,9 +1244,8 @@ void pmac_pci_fixup_pciata(struct pci_dev* dev) * On PowerMacs, we try to switch any PCI ATA controller to * fully native mode */ - if (!machine_is(powermac)) + if (_machine != _MACH_Pmac) return; - /* Some controllers don't have the class IDE */ if (dev->vendor == PCI_VENDOR_ID_PROMISE) switch(dev->device) { diff --git a/trunk/arch/powerpc/platforms/powermac/pfunc_base.c b/trunk/arch/powerpc/platforms/powermac/pfunc_base.c index a3bd3e728fa3..9b7150f10414 100644 --- a/trunk/arch/powerpc/platforms/powermac/pfunc_base.c +++ b/trunk/arch/powerpc/platforms/powermac/pfunc_base.c @@ -336,8 +336,6 @@ int __init pmac_pfunc_base_install(void) return 0; pfbase_inited = 1; - if (!machine_is(powermac)) - return 0; DBG("Installing base platform functions...\n"); diff --git a/trunk/arch/powerpc/platforms/powermac/setup.c b/trunk/arch/powerpc/platforms/powermac/setup.c index 4d15e396655c..385aab90c4d2 100644 --- a/trunk/arch/powerpc/platforms/powermac/setup.c +++ b/trunk/arch/powerpc/platforms/powermac/setup.c @@ -350,13 +350,6 @@ static void __init pmac_setup_arch(void) smp_ops = &psurge_smp_ops; #endif #endif /* CONFIG_SMP */ - -#ifdef CONFIG_ADB - if (strstr(cmd_line, "adb_sync")) { - extern int __adb_probe_sync; - __adb_probe_sync = 1; - } -#endif /* CONFIG_ADB */ } char *bootpath; @@ -583,6 +576,30 @@ pmac_halt(void) pmac_power_off(); } +#ifdef CONFIG_PPC32 +void __init pmac_init(void) +{ + /* isa_io_base gets set in pmac_pci_init */ + isa_mem_base = PMAC_ISA_MEM_BASE; + pci_dram_offset = PMAC_PCI_DRAM_OFFSET; + ISA_DMA_THRESHOLD = ~0L; + DMA_MODE_READ = 1; + DMA_MODE_WRITE = 2; + + ppc_md = pmac_md; + +#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE) +#ifdef CONFIG_BLK_DEV_IDE_PMAC + ppc_ide_md.ide_init_hwif = pmac_ide_init_hwif_ports; + ppc_ide_md.default_io_base = pmac_ide_get_base; +#endif /* CONFIG_BLK_DEV_IDE_PMAC */ +#endif /* defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE) */ + + if (ppc_md.progress) ppc_md.progress("pmac_init(): exit", 0); + +} +#endif + /* * Early initialization. */ @@ -629,12 +646,6 @@ static int __init pmac_declare_of_platform_devices(void) { struct device_node *np; - if (machine_is(chrp)) - return -1; - - if (!machine_is(powermac)) - return 0; - np = of_find_node_by_name(NULL, "valkyrie"); if (np) of_platform_device_create(np, "valkyrie", NULL); @@ -655,15 +666,12 @@ device_initcall(pmac_declare_of_platform_devices); /* * Called very early, MMU is off, device-tree isn't unflattened */ -static int __init pmac_probe(void) +static int __init pmac_probe(int platform) { - unsigned long root = of_get_flat_dt_root(); - - if (!of_flat_dt_is_compatible(root, "Power Macintosh") && - !of_flat_dt_is_compatible(root, "MacRISC")) +#ifdef CONFIG_PPC64 + if (platform != PLATFORM_POWERMAC) return 0; -#ifdef CONFIG_PPC64 /* * On U3, the DART (iommu) must be allocated now since it * has an impact on htab_initialize (due to the large page it @@ -673,23 +681,6 @@ static int __init pmac_probe(void) alloc_dart_table(); #endif -#ifdef CONFIG_PPC32 - /* isa_io_base gets set in pmac_pci_init */ - isa_mem_base = PMAC_ISA_MEM_BASE; - pci_dram_offset = PMAC_PCI_DRAM_OFFSET; - ISA_DMA_THRESHOLD = ~0L; - DMA_MODE_READ = 1; - DMA_MODE_WRITE = 2; - -#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE) -#ifdef CONFIG_BLK_DEV_IDE_PMAC - ppc_ide_md.ide_init_hwif = pmac_ide_init_hwif_ports; - ppc_ide_md.default_io_base = pmac_ide_get_base; -#endif /* CONFIG_BLK_DEV_IDE_PMAC */ -#endif /* defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE) */ - -#endif /* CONFIG_PPC32 */ - #ifdef CONFIG_PMAC_SMU /* * SMU based G5s need some memory below 2Gb, at least the current @@ -718,8 +709,10 @@ static int pmac_pci_probe_mode(struct pci_bus *bus) } #endif -define_machine(powermac) { - .name = "PowerMac", +struct machdep_calls __initdata pmac_md = { +#if defined(CONFIG_HOTPLUG_CPU) && defined(CONFIG_PPC64) + .cpu_die = generic_mach_cpu_die, +#endif .probe = pmac_probe, .setup_arch = pmac_setup_arch, .init_early = pmac_init_early, @@ -740,7 +733,7 @@ define_machine(powermac) { .progress = udbg_progress, #ifdef CONFIG_PPC64 .pci_probe_mode = pmac_pci_probe_mode, - .power_save = power4_idle, + .idle_loop = native_idle, .enable_pmcs = power4_enable_pmcs, #ifdef CONFIG_KEXEC .machine_kexec = default_machine_kexec, @@ -753,7 +746,4 @@ define_machine(powermac) { .pcibios_after_init = pmac_pcibios_after_init, .phys_mem_access_prot = pci_phys_mem_access_prot, #endif -#if defined(CONFIG_HOTPLUG_CPU) && defined(CONFIG_PPC64) - .cpu_die = generic_mach_cpu_die, -#endif }; diff --git a/trunk/arch/powerpc/platforms/powermac/time.c b/trunk/arch/powerpc/platforms/powermac/time.c index 890758aa9667..5d9afa1fa02d 100644 --- a/trunk/arch/powerpc/platforms/powermac/time.c +++ b/trunk/arch/powerpc/platforms/powermac/time.c @@ -336,10 +336,10 @@ static struct pmu_sleep_notifier time_sleep_notifier = { */ void __init pmac_calibrate_decr(void) { -#if defined(CONFIG_PM) && defined(CONFIG_ADB_PMU) +#ifdef CONFIG_PM /* XXX why here? */ pmu_register_sleep_notifier(&time_sleep_notifier); -#endif +#endif /* CONFIG_PM */ generic_calibrate_decr(); diff --git a/trunk/arch/powerpc/platforms/powermac/udbg_scc.c b/trunk/arch/powerpc/platforms/powermac/udbg_scc.c index b4fa9f03b461..c4352a8db644 100644 --- a/trunk/arch/powerpc/platforms/powermac/udbg_scc.c +++ b/trunk/arch/powerpc/platforms/powermac/udbg_scc.c @@ -116,7 +116,7 @@ void udbg_scc_init(int force_scc) /* Setup for 57600 8N1 */ if (ch == ch_a) addr += 0x20; - sccc = ioremap(addr & PAGE_MASK, PAGE_SIZE) ; + sccc = (volatile u8 * __iomem) ioremap(addr & PAGE_MASK, PAGE_SIZE) ; sccc += addr & ~PAGE_MASK; sccd = sccc + 0x10; diff --git a/trunk/arch/powerpc/platforms/pseries/eeh.c b/trunk/arch/powerpc/platforms/pseries/eeh.c index 9b2b1cb117b3..2ab9dcdfb415 100644 --- a/trunk/arch/powerpc/platforms/pseries/eeh.c +++ b/trunk/arch/powerpc/platforms/pseries/eeh.c @@ -1018,7 +1018,7 @@ static int __init eeh_init_proc(void) { struct proc_dir_entry *e; - if (machine_is(pseries)) { + if (platform_is_pseries()) { e = create_proc_entry("ppc64/eeh", 0, NULL); if (e) e->proc_fops = &proc_eeh_operations; diff --git a/trunk/arch/powerpc/platforms/pseries/eeh_driver.c b/trunk/arch/powerpc/platforms/pseries/eeh_driver.c index cc2495a0cdd5..b811d5ff92fe 100644 --- a/trunk/arch/powerpc/platforms/pseries/eeh_driver.c +++ b/trunk/arch/powerpc/platforms/pseries/eeh_driver.c @@ -257,7 +257,6 @@ void handle_eeh_events (struct eeh_event *event) struct pci_bus *frozen_bus; int rc = 0; enum pci_ers_result result = PCI_ERS_RESULT_NONE; - const char *pci_str, *drv_str; frozen_dn = find_device_pe(event->dn); frozen_bus = pcibios_find_pci_bus(frozen_dn); @@ -292,13 +291,6 @@ void handle_eeh_events (struct eeh_event *event) frozen_pdn = PCI_DN(frozen_dn); frozen_pdn->eeh_freeze_count++; - - pci_str = pci_name (frozen_pdn->pcidev); - drv_str = pcid_name (frozen_pdn->pcidev); - if (!pci_str) { - pci_str = pci_name (event->dev); - drv_str = pcid_name (event->dev); - } if (frozen_pdn->eeh_freeze_count > EEH_MAX_ALLOWED_FREEZES) goto hard_fail; @@ -314,7 +306,9 @@ void handle_eeh_events (struct eeh_event *event) eeh_slot_error_detail(frozen_pdn, 1 /* Temporary Error */); printk(KERN_WARNING "EEH: This PCI device has failed %d times since last reboot: %s - %s\n", - frozen_pdn->eeh_freeze_count, drv_str, pci_str); + frozen_pdn->eeh_freeze_count, + pci_name (frozen_pdn->pcidev), + pcid_name(frozen_pdn->pcidev)); /* Walk the various device drivers attached to this slot through * a reset sequence, giving each an opportunity to do what it needs @@ -366,7 +360,9 @@ void handle_eeh_events (struct eeh_event *event) "EEH: PCI device %s - %s has failed %d times \n" "and has been permanently disabled. Please try reseating\n" "this device or replacing it.\n", - drv_str, pci_str, frozen_pdn->eeh_freeze_count); + pci_name (frozen_pdn->pcidev), + pcid_name(frozen_pdn->pcidev), + frozen_pdn->eeh_freeze_count); eeh_slot_error_detail(frozen_pdn, 2 /* Permanent Error */); diff --git a/trunk/arch/powerpc/platforms/pseries/firmware.c b/trunk/arch/powerpc/platforms/pseries/firmware.c index c01d8f0cbe6d..989f4bc136cb 100644 --- a/trunk/arch/powerpc/platforms/pseries/firmware.c +++ b/trunk/arch/powerpc/platforms/pseries/firmware.c @@ -91,7 +91,7 @@ void __init fw_feature_init(void) continue; /* we have a match */ - powerpc_firmware_features |= + ppc64_firmware_features |= firmware_features_table[i].val; break; } diff --git a/trunk/arch/powerpc/platforms/pseries/hvconsole.c b/trunk/arch/powerpc/platforms/pseries/hvconsole.c index ba6befd96636..138e128a3886 100644 --- a/trunk/arch/powerpc/platforms/pseries/hvconsole.c +++ b/trunk/arch/powerpc/platforms/pseries/hvconsole.c @@ -62,11 +62,6 @@ int hvc_put_chars(uint32_t vtermno, const char *buf, int count) unsigned long *lbuf = (unsigned long *) buf; long ret; - - /* hcall will ret H_PARAMETER if 'count' exceeds firmware max.*/ - if (count > MAX_VIO_PUT_CHARS) - count = MAX_VIO_PUT_CHARS; - ret = plpar_hcall_norets(H_PUT_TERM_CHAR, vtermno, count, lbuf[0], lbuf[1]); if (ret == H_Success) diff --git a/trunk/arch/powerpc/platforms/pseries/pci.c b/trunk/arch/powerpc/platforms/pseries/pci.c index e97e67f5e079..946ad59e3352 100644 --- a/trunk/arch/powerpc/platforms/pseries/pci.c +++ b/trunk/arch/powerpc/platforms/pseries/pci.c @@ -120,7 +120,7 @@ static void fixup_winbond_82c105(struct pci_dev* dev) int i; unsigned int reg; - if (!machine_is(pseries)) + if (!platform_is_pseries()) return; printk("Using INTC for W82c105 IDE controller.\n"); diff --git a/trunk/arch/powerpc/platforms/pseries/pci_dlpar.c b/trunk/arch/powerpc/platforms/pseries/pci_dlpar.c index 6bfacc217085..44abdeb9ca03 100644 --- a/trunk/arch/powerpc/platforms/pseries/pci_dlpar.c +++ b/trunk/arch/powerpc/platforms/pseries/pci_dlpar.c @@ -28,7 +28,6 @@ #include #include #include -#include static struct pci_bus * find_bus_among_children(struct pci_bus *bus, @@ -153,24 +152,20 @@ pcibios_pci_config_bridge(struct pci_dev *dev) void pcibios_add_pci_devices(struct pci_bus * bus) { - int slotno, num, mode; + int slotno, num; struct pci_dev *dev; struct device_node *dn = pci_bus_to_OF_node(bus); eeh_add_device_tree_early(dn); - mode = PCI_PROBE_NORMAL; - if (ppc_md.pci_probe_mode) - mode = ppc_md.pci_probe_mode(bus); - - if (mode == PCI_PROBE_DEVTREE) { + if (_machine == PLATFORM_PSERIES_LPAR) { /* use ofdt-based probe */ of_scan_bus(dn, bus); if (!list_empty(&bus->devices)) { pcibios_fixup_new_pci_devices(bus, 0); pci_bus_add_devices(bus); } - } else if (mode == PCI_PROBE_NORMAL) { + } else { /* use legacy probe */ slotno = PCI_SLOT(PCI_DN(dn->child)->devfn); num = pci_scan_slot(bus, PCI_DEVFN(slotno, 0)); diff --git a/trunk/arch/powerpc/platforms/pseries/ras.c b/trunk/arch/powerpc/platforms/pseries/ras.c index 9639c66b453d..b046bcf7443d 100644 --- a/trunk/arch/powerpc/platforms/pseries/ras.c +++ b/trunk/arch/powerpc/platforms/pseries/ras.c @@ -132,7 +132,7 @@ static int __init init_ras_IRQ(void) of_node_put(np); } - return 0; + return 1; } __initcall(init_ras_IRQ); diff --git a/trunk/arch/powerpc/platforms/pseries/reconfig.c b/trunk/arch/powerpc/platforms/pseries/reconfig.c index 1773103354be..5ad90676567a 100644 --- a/trunk/arch/powerpc/platforms/pseries/reconfig.c +++ b/trunk/arch/powerpc/platforms/pseries/reconfig.c @@ -17,9 +17,8 @@ #include #include -#include -#include #include +#include @@ -509,7 +508,7 @@ static int proc_ppc64_create_ofdt(void) { struct proc_dir_entry *ent; - if (!machine_is(pseries)) + if (!platform_is_pseries()) return 0; ent = create_proc_entry("ppc64/ofdt", S_IWUSR, NULL); diff --git a/trunk/arch/powerpc/platforms/pseries/rtasd.c b/trunk/arch/powerpc/platforms/pseries/rtasd.c index fcc4d561a236..a6f628d4c9dc 100644 --- a/trunk/arch/powerpc/platforms/pseries/rtasd.c +++ b/trunk/arch/powerpc/platforms/pseries/rtasd.c @@ -27,7 +27,6 @@ #include #include #include -#include #if 0 #define DEBUG(A...) printk(KERN_ERR A) @@ -482,7 +481,7 @@ static int __init rtas_init(void) { struct proc_dir_entry *entry; - if (!machine_is(pseries)) + if (!platform_is_pseries()) return 0; /* No RTAS */ diff --git a/trunk/arch/powerpc/platforms/pseries/setup.c b/trunk/arch/powerpc/platforms/pseries/setup.c index b2fbf8ba8fbb..44d5c7fdcd97 100644 --- a/trunk/arch/powerpc/platforms/pseries/setup.c +++ b/trunk/arch/powerpc/platforms/pseries/setup.c @@ -81,8 +81,8 @@ extern void find_udbg_vterm(void); int fwnmi_active; /* TRUE if an FWNMI handler is present */ -static void pseries_shared_idle_sleep(void); -static void pseries_dedicated_idle_sleep(void); +static void pseries_shared_idle(void); +static void pseries_dedicated_idle(void); struct mpic *pSeries_mpic; @@ -236,13 +236,14 @@ static void __init pSeries_setup_arch(void) vpa_init(boot_cpuid); if (get_lppaca()->shared_proc) { printk(KERN_INFO "Using shared processor idle loop\n"); - ppc_md.power_save = pseries_shared_idle_sleep; + ppc_md.idle_loop = pseries_shared_idle; } else { printk(KERN_INFO "Using dedicated idle loop\n"); - ppc_md.power_save = pseries_dedicated_idle_sleep; + ppc_md.idle_loop = pseries_dedicated_idle; } } else { printk(KERN_INFO "Using default idle loop\n"); + ppc_md.idle_loop = default_idle; } if (firmware_has_feature(FW_FEATURE_LPAR)) @@ -372,123 +373,156 @@ static int pSeries_check_legacy_ioport(unsigned int baseport) /* * Called very early, MMU is off, device-tree isn't unflattened */ +extern struct machdep_calls pSeries_md; -static int __init pSeries_probe_hypertas(unsigned long node, - const char *uname, int depth, - void *data) +static int __init pSeries_probe(int platform) { - if (depth != 1 || - (strcmp(uname, "rtas") != 0 && strcmp(uname, "rtas@0") != 0)) - return 0; - - if (of_get_flat_dt_prop(node, "ibm,hypertas-functions", NULL) != NULL) - powerpc_firmware_features |= FW_FEATURE_LPAR; - - return 1; -} - -static int __init pSeries_probe(void) -{ - char *dtype = of_get_flat_dt_prop(of_get_flat_dt_root(), - "device_type", NULL); - if (dtype == NULL) - return 0; - if (strcmp(dtype, "chrp")) + if (platform != PLATFORM_PSERIES && + platform != PLATFORM_PSERIES_LPAR) return 0; - DBG("pSeries detected, looking for LPAR capability...\n"); - - /* Now try to figure out if we are running on LPAR */ - of_scan_flat_dt(pSeries_probe_hypertas, NULL); + /* if we have some ppc_md fixups for LPAR to do, do + * it here ... + */ - DBG("Machine is%s LPAR !\n", - (powerpc_firmware_features & FW_FEATURE_LPAR) ? "" : " not"); + if (platform == PLATFORM_PSERIES_LPAR) + ppc64_firmware_features |= FW_FEATURE_LPAR; return 1; } - DECLARE_PER_CPU(unsigned long, smt_snooze_delay); -static void pseries_dedicated_idle_sleep(void) -{ - unsigned int cpu = smp_processor_id(); - unsigned long start_snooze; - unsigned long *smt_snooze_delay = &__get_cpu_var(smt_snooze_delay); +static inline void dedicated_idle_sleep(unsigned int cpu) +{ + struct lppaca *plppaca = &lppaca[cpu ^ 1]; - /* - * Indicate to the HV that we are idle. Now would be - * a good time to find other work to dispatch. - */ - get_lppaca()->idle = 1; + /* Only sleep if the other thread is not idle */ + if (!(plppaca->idle)) { + local_irq_disable(); - /* - * We come in with interrupts disabled, and need_resched() - * has been checked recently. If we should poll for a little - * while, do so. - */ - if (*smt_snooze_delay) { - start_snooze = get_tb() + - *smt_snooze_delay * tb_ticks_per_usec; - local_irq_enable(); + /* + * We are about to sleep the thread and so wont be polling any + * more. + */ + clear_thread_flag(TIF_POLLING_NRFLAG); + smp_mb__after_clear_bit(); + + /* + * SMT dynamic mode. Cede will result in this thread going + * dormant, if the partner thread is still doing work. Thread + * wakes up if partner goes idle, an interrupt is presented, or + * a prod occurs. Returning from the cede enables external + * interrupts. + */ + if (!need_resched()) + cede_processor(); + else + local_irq_enable(); set_thread_flag(TIF_POLLING_NRFLAG); + } else { + /* + * Give the HV an opportunity at the processor, since we are + * not doing any work. + */ + poll_pending(); + } +} - while (get_tb() < start_snooze) { - if (need_resched() || cpu_is_offline(cpu)) - goto out; - ppc64_runlatch_off(); - HMT_low(); - HMT_very_low(); +static void pseries_dedicated_idle(void) +{ + unsigned int cpu = smp_processor_id(); + unsigned long start_snooze; + unsigned long *smt_snooze_delay = &__get_cpu_var(smt_snooze_delay); + set_thread_flag(TIF_POLLING_NRFLAG); + + while (1) { + /* + * Indicate to the HV that we are idle. Now would be + * a good time to find other work to dispatch. + */ + get_lppaca()->idle = 1; + + if (!need_resched()) { + start_snooze = get_tb() + + *smt_snooze_delay * tb_ticks_per_usec; + + while (!need_resched() && !cpu_is_offline(cpu)) { + ppc64_runlatch_off(); + + /* + * Go into low thread priority and possibly + * low power mode. + */ + HMT_low(); + HMT_very_low(); + + if (*smt_snooze_delay != 0 && + get_tb() > start_snooze) { + HMT_medium(); + dedicated_idle_sleep(cpu); + } + + } + + HMT_medium(); } - HMT_medium(); - clear_thread_flag(TIF_POLLING_NRFLAG); - smp_mb(); - local_irq_disable(); - if (need_resched() || cpu_is_offline(cpu)) - goto out; - } + get_lppaca()->idle = 0; + ppc64_runlatch_on(); - /* - * Cede if the other thread is not idle, so that it can - * go single-threaded. If the other thread is idle, - * we ask the hypervisor if it has pending work it - * wants to do and cede if it does. Otherwise we keep - * polling in order to reduce interrupt latency. - * - * Doing the cede when the other thread is active will - * result in this thread going dormant, meaning the other - * thread gets to run in single-threaded (ST) mode, which - * is slightly faster than SMT mode with this thread at - * very low priority. The cede enables interrupts, which - * doesn't matter here. - */ - if (!lppaca[cpu ^ 1].idle || poll_pending() == H_Pending) - cede_processor(); + preempt_enable_no_resched(); + schedule(); + preempt_disable(); -out: - HMT_medium(); - get_lppaca()->idle = 0; + if (cpu_is_offline(cpu) && system_state == SYSTEM_RUNNING) + cpu_die(); + } } -static void pseries_shared_idle_sleep(void) +static void pseries_shared_idle(void) { - /* - * Indicate to the HV that we are idle. Now would be - * a good time to find other work to dispatch. - */ - get_lppaca()->idle = 1; + unsigned int cpu = smp_processor_id(); - /* - * Yield the processor to the hypervisor. We return if - * an external interrupt occurs (which are driven prior - * to returning here) or if a prod occurs from another - * processor. When returning here, external interrupts - * are enabled. - */ - cede_processor(); + while (1) { + /* + * Indicate to the HV that we are idle. Now would be + * a good time to find other work to dispatch. + */ + get_lppaca()->idle = 1; + + while (!need_resched() && !cpu_is_offline(cpu)) { + local_irq_disable(); + ppc64_runlatch_off(); - get_lppaca()->idle = 0; + /* + * Yield the processor to the hypervisor. We return if + * an external interrupt occurs (which are driven prior + * to returning here) or if a prod occurs from another + * processor. When returning here, external interrupts + * are enabled. + * + * Check need_resched() again with interrupts disabled + * to avoid a race. + */ + if (!need_resched()) + cede_processor(); + else + local_irq_enable(); + + HMT_medium(); + } + + get_lppaca()->idle = 0; + ppc64_runlatch_on(); + + preempt_enable_no_resched(); + schedule(); + preempt_disable(); + + if (cpu_is_offline(cpu) && system_state == SYSTEM_RUNNING) + cpu_die(); + } } static int pSeries_pci_probe_mode(struct pci_bus *bus) @@ -519,8 +553,7 @@ static void pseries_kexec_cpu_down(int crash_shutdown, int secondary) } #endif -define_machine(pseries) { - .name = "pSeries", +struct machdep_calls __initdata pSeries_md = { .probe = pSeries_probe, .setup_arch = pSeries_setup_arch, .init_early = pSeries_init_early, diff --git a/trunk/arch/powerpc/platforms/pseries/xics.c b/trunk/arch/powerpc/platforms/pseries/xics.c index 4864cb32be25..eb86cdb9b802 100644 --- a/trunk/arch/powerpc/platforms/pseries/xics.c +++ b/trunk/arch/powerpc/platforms/pseries/xics.c @@ -500,7 +500,7 @@ void xics_init_IRQ(void) np; np = of_find_node_by_type(np, "cpu")) { ireg = (uint *)get_property(np, "reg", &ilen); - if (ireg && ireg[0] == get_hard_smp_processor_id(boot_cpuid)) { + if (ireg && ireg[0] == boot_cpuid_phys) { ireg = (uint *)get_property(np, "ibm,ppc-interrupt-gserver#s", &ilen); i = ilen / sizeof(int); @@ -541,7 +541,7 @@ void xics_init_IRQ(void) ops = &pSeriesLP_ops; else { #ifdef CONFIG_SMP - for_each_possible_cpu(i) { + for_each_cpu(i) { int hard_id; /* FIXME: Do this dynamically! --RR */ diff --git a/trunk/arch/ppc/Kconfig b/trunk/arch/ppc/Kconfig index e9a8f5d1dfcd..3a3e302b4ea2 100644 --- a/trunk/arch/ppc/Kconfig +++ b/trunk/arch/ppc/Kconfig @@ -61,15 +61,15 @@ config 6xx select PPC_FPU help There are four types of PowerPC chips supported. The more common - types (601, 603, 604, 740, 750, 7400), the older Freescale - (formerly Motorola) embedded versions (821, 823, 850, 855, 860, - 52xx, 82xx, 83xx), the IBM embedded versions (403 and 405) and - the Book E embedded processors from IBM (44x) and Freescale (85xx). - For support for 64-bit processors, set ARCH=powerpc. + types (601, 603, 604, 740, 750, 7400), the Motorola embedded + versions (821, 823, 850, 855, 860, 52xx, 82xx, 83xx), the IBM + embedded versions (403 and 405) and the POWER3 processor. + (For support for more recent 64-bit processors, set ARCH=powerpc.) Unless you are building a kernel for one of the embedded processor - systems, choose 6xx. - Also note that because the 52xx, 82xx, & 83xx family have a 603e - core, specific support for that chipset is asked later on. + systems or a POWER3-based IBM RS/6000, choose 6xx. + Note that the kernel runs in 32-bit mode even on 64-bit chips. + Also note that because the 52xx, 82xx, & 83xx family has a 603e core, + specific support for that chipset is asked later on. config 40x bool "40x" @@ -77,6 +77,10 @@ config 40x config 44x bool "44x" +config POWER3 + select PPC_FPU + bool "POWER3" + config 8xx bool "8xx" @@ -248,9 +252,14 @@ config PPC601_SYNC_FIX source arch/ppc/platforms/4xx/Kconfig source arch/ppc/platforms/85xx/Kconfig +config PPC64BRIDGE + bool + depends on POWER3 + default y + config PPC_STD_MMU bool - depends on 6xx + depends on 6xx || POWER3 default y config NOT_COHERENT_CACHE @@ -525,8 +534,8 @@ endmenu choice prompt "Machine Type" - depends on 6xx - default PPC_PREP + depends on 6xx || POWER3 + default PPC_MULTIPLATFORM ---help--- Linux currently supports several different kinds of PowerPC-based machines: Apple Power Macintoshes and clones (such as the Motorola @@ -536,14 +545,15 @@ choice Platform) machines (including all of the recent IBM RS/6000 and pSeries machines), and several embedded PowerPC systems containing 4xx, 6xx, 7xx, 8xx, 74xx, and 82xx processors. Currently, the - default option is to build a kernel which works on PReP. + default option is to build a kernel which works on PReP and CHRP. - Note that support for Apple and CHRP machines is now only available - with ARCH=powerpc, and has been removed from this menu. If you - wish to build a kernel for an Apple or CHRP machine, exit this - configuration process and re-run it with ARCH=powerpc. + Note that support for Apple machines is now only available with + ARCH=powerpc, and has been removed from this menu. If you wish + to build a kernel for an Apple machine, exit this configuration + process and re-run it with ARCH=powerpc. - Select PReP if configuring for a PReP machine. + Select CHRP/PReP if configuring for an IBM RS/6000 or + pSeries machine, or a PReP machine. Select Gemini if configuring for a Synergy Microsystems' Gemini series Single Board Computer. More information is available at: @@ -552,8 +562,8 @@ choice Select APUS if configuring for a PowerUP Amiga. More information is available at: . -config PPC_PREP - bool "PReP" +config PPC_MULTIPLATFORM + bool "CHRP/PReP" config APUS bool "Amiga-APUS" @@ -705,13 +715,6 @@ config LITE5200 much but it's only been tested on this board version. I think this board is also known as IceCube. -config LITE5200B - bool "Freescale LITE5200B" - depends LITE5200 - help - Support for the LITE5200B dev board for the MPC5200 from Freescale. - This is the new board with 2 PCI slots. - config MPC834x_SYS bool "Freescale MPC834x SYS" help @@ -797,6 +800,25 @@ config CPM2 you wish to build a kernel for a machine with a CPM2 coprocessor on it (826x, 827x, 8560). +config PPC_CHRP + bool "Support for CHRP (Common Hardware Reference Platform) machines" + depends on PPC_MULTIPLATFORM + select PPC_I8259 + select PPC_INDIRECT_PCI + default y + +config PPC_PREP + bool "Support for PReP (PowerPC Reference Platform) machines" + depends on PPC_MULTIPLATFORM + select PPC_I8259 + select PPC_INDIRECT_PCI + default y + +config PPC_OF + bool + depends on PPC_CHRP + default y + config PPC_GEN550 bool depends on SANDPOINT || SPRUCE || PPLUS || \ @@ -955,6 +977,14 @@ source "mm/Kconfig" source "fs/Kconfig.binfmt" +config PROC_DEVICETREE + bool "Support for Open Firmware device tree in /proc" + depends on PPC_OF && PROC_FS + help + This option adds a device-tree directory under /proc which contains + an image of the device tree that the kernel copies from Open + Firmware. If unsure, say Y here. + config PREP_RESIDUAL bool "Support for PReP Residual Data" depends on PPC_PREP @@ -1147,7 +1177,8 @@ menu "Bus options" config ISA bool "Support for ISA-bus hardware" - depends on PPC_PREP + depends on PPC_PREP || PPC_CHRP + select PPC_I8259 help Find out whether you have ISA slots on your motherboard. ISA is the name of a bus system, i.e. the way the CPU talks to the other stuff @@ -1157,18 +1188,18 @@ config ISA config GENERIC_ISA_DMA bool - depends on 6xx && !CPM2 + depends on POWER3 || 6xx && !CPM2 default y config PPC_I8259 bool - default y if 85xx || PPC_PREP + default y if 85xx default n config PPC_INDIRECT_PCI bool depends on PCI - default y if 40x || 44x || 85xx || 83xx || PPC_PREP + default y if 40x || 44x || 85xx || 83xx default n config EISA @@ -1359,7 +1390,7 @@ config CONSISTENT_SIZE config BOOT_LOAD_BOOL bool "Set the boot link/load address" - depends on ADVANCED_OPTIONS && !PPC_PREP + depends on ADVANCED_OPTIONS && !PPC_MULTIPLATFORM help This option allows you to set the initial load address of the zImage or zImage.initrd file. This can be useful if you are on a board diff --git a/trunk/arch/ppc/Kconfig.debug b/trunk/arch/ppc/Kconfig.debug index f94b87740973..8cc75abf3d83 100644 --- a/trunk/arch/ppc/Kconfig.debug +++ b/trunk/arch/ppc/Kconfig.debug @@ -53,6 +53,13 @@ config BDI_SWITCH Unless you are intending to debug the kernel with one of these machines, say N here. +config BOOTX_TEXT + bool "Support for early boot text console (BootX or OpenFirmware only)" + depends PPC_OF + help + Say Y here to see progress messages from the boot firmware in text + mode. Requires either BootX or Open Firmware. + config SERIAL_TEXT_DEBUG bool "Support for early boot texts over serial port" depends on 4xx || LOPEC || MV64X60 || PPLUS || PRPMC800 || \ diff --git a/trunk/arch/ppc/Makefile b/trunk/arch/ppc/Makefile index 0db66dcf0723..9fbdf54ba2be 100644 --- a/trunk/arch/ppc/Makefile +++ b/trunk/arch/ppc/Makefile @@ -40,8 +40,10 @@ ifndef CONFIG_FSL_BOOKE CFLAGS += -mstring endif +cpu-as-$(CONFIG_PPC64BRIDGE) += -Wa,-mppc64bridge cpu-as-$(CONFIG_4xx) += -Wa,-m405 cpu-as-$(CONFIG_6xx) += -Wa,-maltivec +cpu-as-$(CONFIG_POWER4) += -Wa,-maltivec cpu-as-$(CONFIG_E500) += -Wa,-me500 cpu-as-$(CONFIG_E200) += -Wa,-me200 @@ -57,6 +59,8 @@ head-$(CONFIG_4xx) := arch/ppc/kernel/head_4xx.o head-$(CONFIG_44x) := arch/ppc/kernel/head_44x.o head-$(CONFIG_FSL_BOOKE) := arch/ppc/kernel/head_fsl_booke.o +head-$(CONFIG_6xx) += arch/ppc/kernel/idle_6xx.o +head-$(CONFIG_POWER4) += arch/ppc/kernel/idle_power4.o head-$(CONFIG_PPC_FPU) += arch/powerpc/kernel/fpu.o core-y += arch/ppc/kernel/ arch/powerpc/kernel/ \ @@ -67,7 +71,7 @@ core-y += arch/ppc/kernel/ arch/powerpc/kernel/ \ core-$(CONFIG_4xx) += arch/ppc/platforms/4xx/ core-$(CONFIG_83xx) += arch/ppc/platforms/83xx/ core-$(CONFIG_85xx) += arch/ppc/platforms/85xx/ -core-$(CONFIG_MATH_EMULATION) += arch/powerpc/math-emu/ +core-$(CONFIG_MATH_EMULATION) += arch/ppc/math-emu/ core-$(CONFIG_XMON) += arch/ppc/xmon/ core-$(CONFIG_APUS) += arch/ppc/amiga/ drivers-$(CONFIG_8xx) += arch/ppc/8xx_io/ diff --git a/trunk/arch/ppc/boot/Makefile b/trunk/arch/ppc/boot/Makefile index b739e25d4728..84eec0bef93c 100644 --- a/trunk/arch/ppc/boot/Makefile +++ b/trunk/arch/ppc/boot/Makefile @@ -19,13 +19,14 @@ HOSTCFLAGS += -Iarch/$(ARCH)/boot/include BOOT_TARGETS = zImage zImage.initrd znetboot znetboot.initrd bootdir-y := simple +bootdir-$(CONFIG_PPC_OF) += openfirmware subdir-y := lib common images -subdir-$(CONFIG_PPC_PREP) += of1275 +subdir-$(CONFIG_PPC_MULTIPLATFORM) += of1275 # for cleaning -subdir- += simple +subdir- += simple openfirmware -hostprogs-y := $(addprefix utils/, mkprep mkbugboot mktree) +hostprogs-y := $(addprefix utils/, addnote mknote hack-coff mkprep mkbugboot mktree) PHONY += $(BOOT_TARGETS) $(bootdir-y) diff --git a/trunk/arch/ppc/boot/openfirmware/Makefile b/trunk/arch/ppc/boot/openfirmware/Makefile new file mode 100644 index 000000000000..66b739743759 --- /dev/null +++ b/trunk/arch/ppc/boot/openfirmware/Makefile @@ -0,0 +1,109 @@ +# Makefile for making bootable images on various OpenFirmware machines. +# +# This file is included by the global makefile so that you can add your own +# architecture-specific flags and dependencies. +# +# Paul Mackerras January 1997 +# XCOFF bootable images for PowerMacs +# Geert Uytterhoeven September 1997 +# ELF bootable iamges for CHRP machines. +# Tom Rini January 2001 +# Cleaned up, moved into arch/ppc/boot/pmac +# Tom Rini July/August 2002 +# Merged 'chrp' and 'pmac' into 'openfirmware', and cleaned up the +# rules. + +zImage.initrd znetboot.initrd: del-ramdisk-sec := -R .ramdisk +zImage.initrd znetboot.initrd: initrd := .initrd + + +boot := arch/ppc/boot +common := $(boot)/common +utils := $(boot)/utils +bootlib := $(boot)/lib +of1275 := $(boot)/of1275 +images := $(boot)/images + +CHRP_LD_ARGS := -T $(srctree)/$(boot)/ld.script -e _start -Ttext 0x00800000 + +COMMONOBJS := start.o misc.o common.o +CHRPOBJS := crt0.o $(COMMONOBJS) chrpmain.o + +targets := $(CHRPOBJS) dummy.o +CHRPOBJS := $(addprefix $(obj)/, $(CHRPOBJS)) + +LIBS := lib/lib.a $(bootlib)/lib.a $(of1275)/lib.a $(common)/lib.a + +ifdef CONFIG_SMP +END := .smp +endif +ifdef CONFIG_PPC64BRIDGE +END += .64 +endif + + +$(images)/ramdisk.image.gz: + @echo ' MISSING $@' + @echo ' RAM disk image must be provided separately' + @/bin/false + +quiet_cmd_genimage = GEN $@ + cmd_genimage = $(OBJCOPY) -R .comment \ + --add-section=.image=$(images)/vmlinux.gz \ + --set-section-flags=.image=contents,alloc,load,readonly,data $< $@ + +targets += image.o +$(obj)/image.o: $(obj)/dummy.o $(images)/vmlinux.gz FORCE + $(call if_changed,genimage) + +# Place the ramdisk in the initrd image. +quiet_cmd_genimage-initrd = GEN $@ + cmd_genimage-initrd = $(OBJCOPY) $< $@ \ + --add-section=.ramdisk=$(images)/ramdisk.image.gz \ + --set-section-flags=.ramdisk=contents,alloc,load,readonly,data +targets += image.initrd.o +$(obj)/image.initrd.o: $(obj)/image.o $(images)/ramdisk.image.gz FORCE + $(call if_changed,genimage-initrd) + + +targets += crt0.o +$(obj)/crt0.o: $(common)/crt0.S FORCE + $(call if_changed_dep,as_o_S) + +quiet_cmd_gen-chrp = CHRP $@ + cmd_gen-chrp = $(LD) $(CHRP_LD_ARGS) -o $@ $(CHRPOBJS) $< $(LIBS) && \ + $(OBJCOPY) $@ $@ -R .comment $(del-ramdisk-sec) + +$(images)/zImage.chrp: $(obj)/image.o $(CHRPOBJS) $(LIBS) \ + $(srctree)/$(boot)/ld.script + $(call cmd,gen-chrp) +$(images)/zImage.initrd.chrp: $(obj)/image.initrd.o $(CHRPOBJS) $(LIBS) \ + $(srctree)/$(boot)/ld.script + $(call cmd,gen-chrp) + +quiet_cmd_addnote = ADDNOTE $@ + cmd_addnote = cat $< > $@ && $(utils)/addnote $@ +$(images)/zImage.chrp-rs6k $(images)/zImage.initrd.chrp-rs6k: \ + %-rs6k: % + $(call cmd,addnote) + +# The targets used on the make command-line + +PHONY += zImage zImage.initrd +zImage: $(images)/zImage.chrp \ + $(images)/zImage.chrp-rs6k + @echo ' kernel: $@ is ready ($<)' +zImage.initrd: $(images)/zImage.initrd.chrp \ + $(images)/zImage.initrd.chrp-rs6k + @echo ' kernel: $@ is ready ($<)' + +TFTPIMAGE := /tftpboot/zImage + +PHONY += znetboot znetboot.initrd +znetboot: $(images)/zImage.chrp + cp $(images)/zImage.chrp $(TFTPIMAGE).chrp$(END) + @echo ' kernel: $@ is ready ($<)' +znetboot.initrd:$(images)/zImage.initrd.chrp + cp $(images)/zImage.initrd.chrp $(TFTPIMAGE).chrp$(END) + @echo ' kernel: $@ is ready ($<)' + diff --git a/trunk/arch/ppc/boot/openfirmware/chrpmain.c b/trunk/arch/ppc/boot/openfirmware/chrpmain.c new file mode 100644 index 000000000000..245dbd9fc120 --- /dev/null +++ b/trunk/arch/ppc/boot/openfirmware/chrpmain.c @@ -0,0 +1,101 @@ +/* + * Copyright (C) Paul Mackerras 1997. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ +#include +#include "nonstdio.h" +#include "of1275.h" +#include +#include + +/* Passed from the linker */ +extern char __image_begin, __image_end; +extern char __ramdisk_begin, __ramdisk_end; +extern char _start, _end; + +extern unsigned int heap_max; +extern void flush_cache(void *, unsigned long); +extern void gunzip(void *, int, unsigned char *, int *); +extern void make_bi_recs(unsigned long addr, char *name, unsigned int mach, + unsigned int progend); + +char *avail_ram; +char *begin_avail, *end_avail; +char *avail_high; + +#define RAM_START 0x00000000 +#define RAM_END (64<<20) + +#define BOOT_START ((unsigned long)_start) +#define BOOT_END ((unsigned long)(_end + 0xFFF) & ~0xFFF) + +#define RAM_FREE ((unsigned long)(_end+0x1000)&~0xFFF) +#define PROG_START 0x00010000 +#define PROG_SIZE 0x007f0000 /* 8MB */ + +#define SCRATCH_SIZE (128 << 10) + +static char scratch[SCRATCH_SIZE]; /* 128k of scratch space for gunzip */ + +typedef void (*kernel_start_t)(int, int, void *, unsigned int, unsigned int); + +void +boot(int a1, int a2, void *prom) +{ + unsigned sa, len; + void *dst; + unsigned char *im; + unsigned int initrd_size, initrd_start; + + printf("chrpboot starting: loaded at 0x%p\n\r", &_start); + + initrd_size = &__ramdisk_end - &__ramdisk_begin; + if (initrd_size) { + initrd_start = (RAM_END - initrd_size) & ~0xFFF; + a1 = initrd_start; + a2 = initrd_size; + claim(initrd_start, RAM_END - initrd_start, 0); + printf("initial ramdisk moving 0x%x <- 0x%p (%x bytes)\n\r", + initrd_start, &__ramdisk_begin, initrd_size); + memcpy((char *)initrd_start, &__ramdisk_begin, initrd_size); + } else { + initrd_start = 0; + initrd_size = 0; + a2 = 0xdeadbeef; + } + + im = &__image_begin; + len = &__image_end - &__image_begin; + /* claim 4MB starting at PROG_START */ + claim(PROG_START, PROG_SIZE - PROG_START, 0); + dst = (void *) PROG_START; + if (im[0] == 0x1f && im[1] == 0x8b) { + avail_ram = scratch; + begin_avail = avail_high = avail_ram; + end_avail = scratch + sizeof(scratch); + printf("gunzipping (0x%p <- 0x%p:0x%p)...", dst, im, im+len); + gunzip(dst, PROG_SIZE - PROG_START, im, &len); + printf("done %u bytes\n\r", len); + printf("%u bytes of heap consumed, max in use %u\n\r", + avail_high - begin_avail, heap_max); + } else { + memmove(dst, im, len); + } + + flush_cache(dst, len); + make_bi_recs(((unsigned long) dst + len), "chrpboot", _MACH_chrp, + (PROG_START + PROG_SIZE)); + + sa = PROG_START; + printf("start address = 0x%x\n\r", sa); + + (*(kernel_start_t)sa)(a1, a2, prom, initrd_start, initrd_size); + + printf("returned?\n\r"); + + pause(); +} diff --git a/trunk/arch/ppc/boot/openfirmware/common.c b/trunk/arch/ppc/boot/openfirmware/common.c new file mode 100644 index 000000000000..0f46756a903e --- /dev/null +++ b/trunk/arch/ppc/boot/openfirmware/common.c @@ -0,0 +1,146 @@ +/* + * Copyright (C) Paul Mackerras 1997. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#include "nonstdio.h" +#include "of1275.h" +#include +#include +#include +#include + +/* Information from the linker */ + +extern int strcmp(const char *s1, const char *s2); +extern char *avail_ram, *avail_high; +extern char *end_avail; + +unsigned int heap_use, heap_max; + +struct memchunk { + unsigned int size; + struct memchunk *next; +}; + +static struct memchunk *freechunks; + +static void *zalloc(unsigned size) +{ + void *p; + struct memchunk **mpp, *mp; + + size = (size + 7) & -8; + heap_use += size; + if (heap_use > heap_max) + heap_max = heap_use; + for (mpp = &freechunks; (mp = *mpp) != 0; mpp = &mp->next) { + if (mp->size == size) { + *mpp = mp->next; + return mp; + } + } + p = avail_ram; + avail_ram += size; + if (avail_ram > avail_high) + avail_high = avail_ram; + if (avail_ram > end_avail) { + printf("oops... out of memory\n\r"); + pause(); + } + return p; +} + +#define HEAD_CRC 2 +#define EXTRA_FIELD 4 +#define ORIG_NAME 8 +#define COMMENT 0x10 +#define RESERVED 0xe0 + +void gunzip(void *dst, int dstlen, unsigned char *src, int *lenp) +{ + z_stream s; + int r, i, flags; + + /* skip header */ + i = 10; + flags = src[3]; + if (src[2] != Z_DEFLATED || (flags & RESERVED) != 0) { + printf("bad gzipped data\n\r"); + exit(); + } + if ((flags & EXTRA_FIELD) != 0) + i = 12 + src[10] + (src[11] << 8); + if ((flags & ORIG_NAME) != 0) + while (src[i++] != 0) + ; + if ((flags & COMMENT) != 0) + while (src[i++] != 0) + ; + if ((flags & HEAD_CRC) != 0) + i += 2; + if (i >= *lenp) { + printf("gunzip: ran out of data in header\n\r"); + exit(); + } + + /* Initialize ourself. */ + s.workspace = zalloc(zlib_inflate_workspacesize()); + r = zlib_inflateInit2(&s, -MAX_WBITS); + if (r != Z_OK) { + printf("zlib_inflateInit2 returned %d\n\r", r); + exit(); + } + s.next_in = src + i; + s.avail_in = *lenp - i; + s.next_out = dst; + s.avail_out = dstlen; + r = zlib_inflate(&s, Z_FINISH); + if (r != Z_OK && r != Z_STREAM_END) { + printf("inflate returned %d msg: %s\n\r", r, s.msg); + exit(); + } + *lenp = s.next_out - (unsigned char *) dst; + zlib_inflateEnd(&s); +} + +/* Make a bi_rec in OF. We need to be passed a name for BI_BOOTLOADER_ID, + * a machine type for BI_MACHTYPE, and the location where the end of the + * bootloader is (PROG_START + PROG_SIZE) + */ +void make_bi_recs(unsigned long addr, char *name, unsigned int mach, + unsigned long progend) +{ + struct bi_record *rec; + + + /* leave a 1MB gap then align to the next 1MB boundary */ + addr = _ALIGN(addr+ (1<<20) - 1, (1<<20)); + /* oldworld machine seem very unhappy about this. -- Tom */ + if (addr >= progend) + claim(addr, 0x1000, 0); + + rec = (struct bi_record *)addr; + rec->tag = BI_FIRST; + rec->size = sizeof(struct bi_record); + rec = (struct bi_record *)((unsigned long)rec + rec->size); + + rec->tag = BI_BOOTLOADER_ID; + sprintf( (char *)rec->data, name); + rec->size = sizeof(struct bi_record) + strlen(name) + 1; + rec = (struct bi_record *)((unsigned long)rec + rec->size); + + rec->tag = BI_MACHTYPE; + rec->data[0] = mach; + rec->data[1] = 1; + rec->size = sizeof(struct bi_record) + 2 * sizeof(unsigned long); + rec = (struct bi_record *)((unsigned long)rec + rec->size); + + rec->tag = BI_LAST; + rec->size = sizeof(struct bi_record); + rec = (struct bi_record *)((unsigned long)rec + rec->size); +} diff --git a/trunk/arch/ppc/boot/openfirmware/dummy.c b/trunk/arch/ppc/boot/openfirmware/dummy.c new file mode 100644 index 000000000000..31dbf45bf99c --- /dev/null +++ b/trunk/arch/ppc/boot/openfirmware/dummy.c @@ -0,0 +1,4 @@ +int main(void) +{ + return 0; +} diff --git a/trunk/arch/ppc/boot/openfirmware/misc.S b/trunk/arch/ppc/boot/openfirmware/misc.S new file mode 100644 index 000000000000..ab9e897cadd0 --- /dev/null +++ b/trunk/arch/ppc/boot/openfirmware/misc.S @@ -0,0 +1,67 @@ +/* + * Copyright (C) Paul Mackerras 1997. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + .text + +/* + * Use the BAT2 & 3 registers to map the 1st 16MB of RAM to + * the address given as the 1st argument. + */ + .globl setup_bats +setup_bats: + mfpvr 5 + rlwinm 5,5,16,16,31 /* r3 = 1 for 601, 4 for 604 */ + cmpwi 0,5,1 + li 0,0 + bne 4f + mtibatl 3,0 /* invalidate BAT first */ + ori 3,3,4 /* set up BAT registers for 601 */ + li 4,0x7f + mtibatu 2,3 + mtibatl 2,4 + oris 3,3,0x80 + oris 4,4,0x80 + mtibatu 3,3 + mtibatl 3,4 + b 5f +4: mtdbatu 3,0 /* invalidate BATs first */ + mtibatu 3,0 + ori 3,3,0xff /* set up BAT registers for 604 */ + li 4,2 + mtdbatl 2,4 + mtdbatu 2,3 + mtibatl 2,4 + mtibatu 2,3 + oris 3,3,0x80 + oris 4,4,0x80 + mtdbatl 3,4 + mtdbatu 3,3 + mtibatl 3,4 + mtibatu 3,3 +5: sync + isync + blr + +/* + * Flush the dcache and invalidate the icache for a range of addresses. + * + * flush_cache(addr, len) + */ + .global flush_cache +flush_cache: + addi 4,4,0x1f /* len = (len + 0x1f) / 0x20 */ + rlwinm. 4,4,27,5,31 + mtctr 4 + beqlr +1: dcbf 0,3 + icbi 0,3 + addi 3,3,0x20 + bdnz 1b + sync + isync + blr diff --git a/trunk/arch/ppc/boot/openfirmware/start.c b/trunk/arch/ppc/boot/openfirmware/start.c new file mode 100644 index 000000000000..1617a26956bf --- /dev/null +++ b/trunk/arch/ppc/boot/openfirmware/start.c @@ -0,0 +1,172 @@ +/* + * Copyright (C) Paul Mackerras 1997. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ +#include +#include "of1275.h" + +extern int strlen(const char *s); +extern void boot(int a1, int a2, void *prom); + +phandle stdin; +phandle stdout; +phandle stderr; + +void printk(char *fmt, ...); + +void +start(int a1, int a2, void *promptr) +{ + ofinit(promptr); + if (ofstdio(&stdin, &stdout, &stderr)) + exit(); + + boot(a1, a2, promptr); + for (;;) + exit(); +} + +int writestring(void *f, char *ptr, int nb) +{ + int w = 0, i; + char *ret = "\r"; + + for (i = 0; i < nb; ++i) { + if (ptr[i] == '\n') { + if (i > w) { + write(f, ptr + w, i - w); + w = i; + } + write(f, ret, 1); + } + } + if (w < nb) + write(f, ptr + w, nb - w); + return nb; +} + +int +putc(int c, void *f) +{ + char ch = c; + + return writestring(f, &ch, 1) == 1? c: -1; +} + +int +putchar(int c) +{ + return putc(c, stdout); +} + +int +fputs(char *str, void *f) +{ + int n = strlen(str); + + return writestring(f, str, n) == n? 0: -1; +} + +int +readchar(void) +{ + char ch; + + for (;;) { + switch (read(stdin, &ch, 1)) { + case 1: + return ch; + case -1: + printk("read(stdin) returned -1\n"); + return -1; + } + } +} + +static char line[256]; +static char *lineptr; +static int lineleft; + +int +getchar(void) +{ + int c; + + if (lineleft == 0) { + lineptr = line; + for (;;) { + c = readchar(); + if (c == -1 || c == 4) + break; + if (c == '\r' || c == '\n') { + *lineptr++ = '\n'; + putchar('\n'); + break; + } + switch (c) { + case 0177: + case '\b': + if (lineptr > line) { + putchar('\b'); + putchar(' '); + putchar('\b'); + --lineptr; + } + break; + case 'U' & 0x1F: + while (lineptr > line) { + putchar('\b'); + putchar(' '); + putchar('\b'); + --lineptr; + } + break; + default: + if (lineptr >= &line[sizeof(line) - 1]) + putchar('\a'); + else { + putchar(c); + *lineptr++ = c; + } + } + } + lineleft = lineptr - line; + lineptr = line; + } + if (lineleft == 0) + return -1; + --lineleft; + return *lineptr++; +} + +extern int vsprintf(char *buf, const char *fmt, va_list args); +static char sprint_buf[1024]; + +void +printk(char *fmt, ...) +{ + va_list args; + int n; + + va_start(args, fmt); + n = vsprintf(sprint_buf, fmt, args); + va_end(args); + writestring(stdout, sprint_buf, n); +} + +int +printf(char *fmt, ...) +{ + va_list args; + int n; + + va_start(args, fmt); + n = vsprintf(sprint_buf, fmt, args); + va_end(args); + writestring(stdout, sprint_buf, n); + return n; +} diff --git a/trunk/arch/ppc/boot/simple/mpc10x_memory.c b/trunk/arch/ppc/boot/simple/mpc10x_memory.c index 8da8f576031d..c24290823f7f 100644 --- a/trunk/arch/ppc/boot/simple/mpc10x_memory.c +++ b/trunk/arch/ppc/boot/simple/mpc10x_memory.c @@ -50,10 +50,10 @@ MPC10X_PCI_OP(read, dword, u32 *, in_le32, 0) * the system. This assumes that the firmware has correctly set up the memory * controller registers. On CONFIG_PPC_PREP, we know we are being called * under a PReP memory map. On all other machines, we assume we are under - * a CHRP memory map. Further, on CONFIG_PPC_PREP we must rename + * a CHRP memory map. Further, on CONFIG_PPC_MULTIPLATFORM we must rename * this function. */ -#ifdef CONFIG_PPC_PREP +#ifdef CONFIG_PPC_MULTIPLATFORM #define get_mem_size mpc10x_get_mem_size #endif unsigned long diff --git a/trunk/arch/ppc/boot/simple/relocate.S b/trunk/arch/ppc/boot/simple/relocate.S index 2533113c1cc5..7efddc507564 100644 --- a/trunk/arch/ppc/boot/simple/relocate.S +++ b/trunk/arch/ppc/boot/simple/relocate.S @@ -194,7 +194,7 @@ start_ldr: /* * Start at the begining. */ -#ifdef CONFIG_PPC_PREP +#ifdef CONFIG_PPC_MULTIPLATFORM li r9,0xc mtlr r9 /* tell kernel we're prep, by putting 0xdeadc0de at KERNELLOAD, diff --git a/trunk/arch/ppc/boot/utils/addnote.c b/trunk/arch/ppc/boot/utils/addnote.c new file mode 100644 index 000000000000..6c52b18f2d04 --- /dev/null +++ b/trunk/arch/ppc/boot/utils/addnote.c @@ -0,0 +1,175 @@ +/* + * Program to hack in a PT_NOTE program header entry in an ELF file. + * This is needed for OF on RS/6000s to load an image correctly. + * Note that OF needs a program header entry for the note, not an + * ELF section. + * + * Copyright 2000 Paul Mackerras. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + * + * Usage: addnote zImage + */ +#include +#include +#include +#include +#include + +char arch[] = "PowerPC"; + +#define N_DESCR 6 +unsigned int descr[N_DESCR] = { +#if 1 + /* values for IBM RS/6000 machines */ + 0xffffffff, /* real-mode = true */ + 0x00c00000, /* real-base, i.e. where we expect OF to be */ + 0xffffffff, /* real-size */ + 0xffffffff, /* virt-base */ + 0xffffffff, /* virt-size */ + 0x4000, /* load-base */ +#else + /* values for longtrail CHRP */ + 0, /* real-mode = false */ + 0xffffffff, /* real-base */ + 0xffffffff, /* real-size */ + 0xffffffff, /* virt-base */ + 0xffffffff, /* virt-size */ + 0x00600000, /* load-base */ +#endif +}; + +unsigned char buf[512]; + +#define GET_16BE(off) ((buf[off] << 8) + (buf[(off)+1])) +#define GET_32BE(off) ((GET_16BE(off) << 16) + GET_16BE((off)+2)) + +#define PUT_16BE(off, v) (buf[off] = ((v) >> 8) & 0xff, \ + buf[(off) + 1] = (v) & 0xff) +#define PUT_32BE(off, v) (PUT_16BE((off), (v) >> 16), \ + PUT_16BE((off) + 2, (v))) + +/* Structure of an ELF file */ +#define E_IDENT 0 /* ELF header */ +#define E_PHOFF 28 +#define E_PHENTSIZE 42 +#define E_PHNUM 44 +#define E_HSIZE 52 /* size of ELF header */ + +#define EI_MAGIC 0 /* offsets in E_IDENT area */ +#define EI_CLASS 4 +#define EI_DATA 5 + +#define PH_TYPE 0 /* ELF program header */ +#define PH_OFFSET 4 +#define PH_FILESZ 16 +#define PH_HSIZE 32 /* size of program header */ + +#define PT_NOTE 4 /* Program header type = note */ + +#define ELFCLASS32 1 +#define ELFDATA2MSB 2 + +unsigned char elf_magic[4] = { 0x7f, 'E', 'L', 'F' }; + +int main(int ac, char **av) +{ + int fd, n, i; + int ph, ps, np; + int nnote, ns; + + if (ac != 2) { + fprintf(stderr, "Usage: %s elf-file\n", av[0]); + exit(1); + } + fd = open(av[1], O_RDWR); + if (fd < 0) { + perror(av[1]); + exit(1); + } + + nnote = strlen(arch) + 1 + (N_DESCR + 3) * 4; + + n = read(fd, buf, sizeof(buf)); + if (n < 0) { + perror("read"); + exit(1); + } + + if (n < E_HSIZE || memcmp(&buf[E_IDENT+EI_MAGIC], elf_magic, 4) != 0) + goto notelf; + + if (buf[E_IDENT+EI_CLASS] != ELFCLASS32 + || buf[E_IDENT+EI_DATA] != ELFDATA2MSB) { + fprintf(stderr, "%s is not a big-endian 32-bit ELF image\n", + av[1]); + exit(1); + } + + ph = GET_32BE(E_PHOFF); + ps = GET_16BE(E_PHENTSIZE); + np = GET_16BE(E_PHNUM); + if (ph < E_HSIZE || ps < PH_HSIZE || np < 1) + goto notelf; + if (ph + (np + 1) * ps + nnote > n) + goto nospace; + + for (i = 0; i < np; ++i) { + if (GET_32BE(ph + PH_TYPE) == PT_NOTE) { + fprintf(stderr, "%s already has a note entry\n", + av[1]); + exit(0); + } + ph += ps; + } + + /* XXX check that the area we want to use is all zeroes */ + for (i = 0; i < ps + nnote; ++i) + if (buf[ph + i] != 0) + goto nospace; + + /* fill in the program header entry */ + ns = ph + ps; + PUT_32BE(ph + PH_TYPE, PT_NOTE); + PUT_32BE(ph + PH_OFFSET, ns); + PUT_32BE(ph + PH_FILESZ, nnote); + + /* fill in the note area we point to */ + /* XXX we should probably make this a proper section */ + PUT_32BE(ns, strlen(arch) + 1); + PUT_32BE(ns + 4, N_DESCR * 4); + PUT_32BE(ns + 8, 0x1275); + strcpy(&buf[ns + 12], arch); + ns += 12 + strlen(arch) + 1; + for (i = 0; i < N_DESCR; ++i) + PUT_32BE(ns + i * 4, descr[i]); + + /* Update the number of program headers */ + PUT_16BE(E_PHNUM, np + 1); + + /* write back */ + lseek(fd, (long) 0, SEEK_SET); + i = write(fd, buf, n); + if (i < 0) { + perror("write"); + exit(1); + } + if (i < n) { + fprintf(stderr, "%s: write truncated\n", av[1]); + exit(1); + } + + exit(0); + + notelf: + fprintf(stderr, "%s does not appear to be an ELF file\n", av[0]); + exit(1); + + nospace: + fprintf(stderr, "sorry, I can't find space in %s to put the note\n", + av[0]); + exit(1); +} diff --git a/trunk/arch/ppc/boot/utils/hack-coff.c b/trunk/arch/ppc/boot/utils/hack-coff.c new file mode 100644 index 000000000000..5e5a6573a1ef --- /dev/null +++ b/trunk/arch/ppc/boot/utils/hack-coff.c @@ -0,0 +1,84 @@ +/* + * hack-coff.c - hack the header of an xcoff file to fill in + * a few fields needed by the Open Firmware xcoff loader on + * Power Macs but not initialized by objcopy. + * + * Copyright (C) Paul Mackerras 1997. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ +#include +#include +#include +#include +#include +#include "rs6000.h" + +#define AOUT_MAGIC 0x010b + +#define get_16be(x) ((((unsigned char *)(x))[0] << 8) \ + + ((unsigned char *)(x))[1]) +#define put_16be(x, v) (((unsigned char *)(x))[0] = (v) >> 8, \ + ((unsigned char *)(x))[1] = (v) & 0xff) +#define get_32be(x) ((((unsigned char *)(x))[0] << 24) \ + + (((unsigned char *)(x))[1] << 16) \ + + (((unsigned char *)(x))[2] << 8) \ + + ((unsigned char *)(x))[3]) + +int +main(int ac, char **av) +{ + int fd; + int i, nsect; + int aoutsz; + struct external_filehdr fhdr; + AOUTHDR aout; + struct external_scnhdr shdr; + + if (ac != 2) { + fprintf(stderr, "Usage: hack-coff coff-file\n"); + exit(1); + } + if ((fd = open(av[1], 2)) == -1) { + perror(av[2]); + exit(1); + } + if (read(fd, &fhdr, sizeof(fhdr)) != sizeof(fhdr)) + goto readerr; + i = get_16be(fhdr.f_magic); + if (i != U802TOCMAGIC && i != U802WRMAGIC && i != U802ROMAGIC) { + fprintf(stderr, "%s: not an xcoff file\n", av[1]); + exit(1); + } + aoutsz = get_16be(fhdr.f_opthdr); + if (read(fd, &aout, aoutsz) != aoutsz) + goto readerr; + nsect = get_16be(fhdr.f_nscns); + for (i = 0; i < nsect; ++i) { + if (read(fd, &shdr, sizeof(shdr)) != sizeof(shdr)) + goto readerr; + if (strcmp(shdr.s_name, ".text") == 0) { + put_16be(aout.o_snentry, i+1); + put_16be(aout.o_sntext, i+1); + } else if (strcmp(shdr.s_name, ".data") == 0) { + put_16be(aout.o_sndata, i+1); + } else if (strcmp(shdr.s_name, ".bss") == 0) { + put_16be(aout.o_snbss, i+1); + } + } + put_16be(aout.magic, AOUT_MAGIC); + if (lseek(fd, (long) sizeof(struct external_filehdr), 0) == -1 + || write(fd, &aout, aoutsz) != aoutsz) { + fprintf(stderr, "%s: write error\n", av[1]); + exit(1); + } + close(fd); + exit(0); + +readerr: + fprintf(stderr, "%s: read error or file too short\n", av[1]); + exit(1); +} diff --git a/trunk/arch/ppc/boot/utils/mknote.c b/trunk/arch/ppc/boot/utils/mknote.c new file mode 100644 index 000000000000..b9fbb2cbfc8f --- /dev/null +++ b/trunk/arch/ppc/boot/utils/mknote.c @@ -0,0 +1,44 @@ +/* + * Copyright (C) Cort Dougan 1999. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + * + * Generate a note section as per the CHRP specification. + * + */ + +#include +#include + +#define PL(x) printf("%c%c%c%c", ((x)>>24)&0xff, ((x)>>16)&0xff, ((x)>>8)&0xff, (x)&0xff ); + +int main(void) +{ +/* header */ + /* namesz */ + PL(strlen("PowerPC")+1); + /* descrsz */ + PL(6*4); + /* type */ + PL(0x1275); + /* name */ + printf("PowerPC"); printf("%c", 0); + +/* descriptor */ + /* real-mode */ + PL(0xffffffff); + /* real-base */ + PL(0x00c00000); + /* real-size */ + PL(0xffffffff); + /* virt-base */ + PL(0xffffffff); + /* virt-size */ + PL(0xffffffff); + /* load-base */ + PL(0x4000); + return 0; +} diff --git a/trunk/arch/ppc/configs/prep_defconfig b/trunk/arch/ppc/configs/common_defconfig similarity index 100% rename from trunk/arch/ppc/configs/prep_defconfig rename to trunk/arch/ppc/configs/common_defconfig diff --git a/trunk/arch/ppc/configs/ibmchrp_defconfig b/trunk/arch/ppc/configs/ibmchrp_defconfig new file mode 100644 index 000000000000..27f3e69c1f96 --- /dev/null +++ b/trunk/arch/ppc/configs/ibmchrp_defconfig @@ -0,0 +1,875 @@ +# +# Automatically generated make config: don't edit +# +CONFIG_MMU=y +CONFIG_RWSEM_XCHGADD_ALGORITHM=y +CONFIG_HAVE_DEC_LOCK=y +CONFIG_PPC=y +CONFIG_PPC32=y +CONFIG_GENERIC_NVRAM=y + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +CONFIG_CLEAN_COMPILE=y +# CONFIG_STANDALONE is not set +CONFIG_BROKEN_ON_SMP=y + +# +# General setup +# +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +CONFIG_POSIX_MQUEUE=y +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +# CONFIG_AUDIT is not set +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_HOTPLUG is not set +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +# CONFIG_EMBEDDED is not set +CONFIG_KALLSYMS=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set + +# +# Loadable module support +# +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +CONFIG_MODULE_FORCE_UNLOAD=y +CONFIG_OBSOLETE_MODPARM=y +# CONFIG_MODVERSIONS is not set +CONFIG_KMOD=y + +# +# Processor +# +CONFIG_6xx=y +# CONFIG_40x is not set +# CONFIG_44x is not set +# CONFIG_POWER3 is not set +# CONFIG_POWER4 is not set +# CONFIG_8xx is not set +# CONFIG_ALTIVEC is not set +# CONFIG_TAU is not set +# CONFIG_CPU_FREQ is not set +# CONFIG_PPC601_SYNC_FIX is not set +CONFIG_PPC_STD_MMU=y + +# +# Platform options +# +CONFIG_PPC_MULTIPLATFORM=y +# CONFIG_APUS is not set +# CONFIG_WILLOW is not set +# CONFIG_PCORE is not set +# CONFIG_POWERPMC250 is not set +# CONFIG_EV64260 is not set +# CONFIG_SPRUCE is not set +# CONFIG_LOPEC is not set +# CONFIG_MCPN765 is not set +# CONFIG_MVME5100 is not set +# CONFIG_PPLUS is not set +# CONFIG_PRPMC750 is not set +# CONFIG_PRPMC800 is not set +# CONFIG_SANDPOINT is not set +# CONFIG_ADIR is not set +# CONFIG_K2 is not set +# CONFIG_PAL4 is not set +# CONFIG_GEMINI is not set +# CONFIG_EST8260 is not set +# CONFIG_SBS8260 is not set +# CONFIG_RPX6 is not set +# CONFIG_TQM8260 is not set +CONFIG_PPC_CHRP=y +CONFIG_PPC_PMAC=y +CONFIG_PPC_PREP=y +CONFIG_PPC_OF=y +CONFIG_PPCBUG_NVRAM=y +# CONFIG_SMP is not set +# CONFIG_PREEMPT is not set +CONFIG_HIGHMEM=y +CONFIG_KERNEL_ELF=y +CONFIG_BINFMT_ELF=y +CONFIG_BINFMT_MISC=y +CONFIG_PROC_DEVICETREE=y +CONFIG_PPC_RTAS=y +# CONFIG_PREP_RESIDUAL is not set +# CONFIG_CMDLINE_BOOL is not set + +# +# Bus options +# +CONFIG_ISA=y +CONFIG_GENERIC_ISA_DMA=y +CONFIG_PCI=y +CONFIG_PCI_DOMAINS=y +CONFIG_PCI_LEGACY_PROC=y +CONFIG_PCI_NAMES=y + +# +# Advanced setup +# +# CONFIG_ADVANCED_OPTIONS is not set + +# +# Default settings for advanced configuration options are used +# +CONFIG_HIGHMEM_START=0xfe000000 +CONFIG_LOWMEM_SIZE=0x30000000 +CONFIG_KERNEL_START=0xc0000000 +CONFIG_TASK_SIZE=0x80000000 +CONFIG_BOOT_LOAD=0x00800000 + +# +# Device Drivers +# + +# +# Generic Driver Options +# + +# +# Memory Technology Devices (MTD) +# +# CONFIG_MTD is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Plug and Play support +# +# CONFIG_PNP is not set + +# +# Block devices +# +CONFIG_BLK_DEV_FD=y +# CONFIG_BLK_DEV_XD is not set +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_UMEM is not set +CONFIG_BLK_DEV_LOOP=y +# CONFIG_BLK_DEV_CRYPTOLOOP is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_CARMEL is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_SIZE=4096 +CONFIG_BLK_DEV_INITRD=y +CONFIG_LBD=y + +# +# ATA/ATAPI/MFM/RLL support +# +# CONFIG_IDE is not set + +# +# SCSI device support +# +CONFIG_SCSI=y +CONFIG_SCSI_PROC_FS=y + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=y +CONFIG_CHR_DEV_ST=y +# CONFIG_CHR_DEV_OSST is not set +CONFIG_BLK_DEV_SR=y +CONFIG_BLK_DEV_SR_VENDOR=y +CONFIG_CHR_DEV_SG=y + +# +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs +# +# CONFIG_SCSI_MULTI_LUN is not set +# CONFIG_SCSI_REPORT_LUNS is not set +CONFIG_SCSI_CONSTANTS=y +# CONFIG_SCSI_LOGGING is not set + +# +# SCSI Transport Attributes +# +CONFIG_SCSI_SPI_ATTRS=y +# CONFIG_SCSI_FC_ATTRS is not set + +# +# SCSI low-level drivers +# +# CONFIG_BLK_DEV_3W_XXXX_RAID is not set +# CONFIG_SCSI_7000FASST is not set +# CONFIG_SCSI_ACARD is not set +# CONFIG_SCSI_AHA152X is not set +# CONFIG_SCSI_AHA1542 is not set +# CONFIG_SCSI_AACRAID is not set +# CONFIG_SCSI_AIC7XXX is not set +# CONFIG_SCSI_AIC7XXX_OLD is not set +# CONFIG_SCSI_AIC79XX is not set +# CONFIG_SCSI_ADVANSYS is not set +# CONFIG_SCSI_IN2000 is not set +# CONFIG_SCSI_MEGARAID is not set +# CONFIG_SCSI_SATA is not set +# CONFIG_SCSI_BUSLOGIC is not set +# CONFIG_SCSI_CPQFCTS is not set +# CONFIG_SCSI_DMX3191D is not set +# CONFIG_SCSI_DTC3280 is not set +# CONFIG_SCSI_EATA is not set +# CONFIG_SCSI_EATA_PIO is not set +# CONFIG_SCSI_FUTURE_DOMAIN is not set +# CONFIG_SCSI_GDTH is not set +# CONFIG_SCSI_GENERIC_NCR5380 is not set +# CONFIG_SCSI_GENERIC_NCR5380_MMIO is not set +# CONFIG_SCSI_IPS is not set +# CONFIG_SCSI_INIA100 is not set +# CONFIG_SCSI_NCR53C406A is not set +CONFIG_SCSI_SYM53C8XX_2=y +CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=0 +CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16 +CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64 +# CONFIG_SCSI_SYM53C8XX_IOMAPPED is not set +# CONFIG_SCSI_IPR is not set +# CONFIG_SCSI_PAS16 is not set +# CONFIG_SCSI_PSI240I is not set +# CONFIG_SCSI_QLOGIC_FAS is not set +# CONFIG_SCSI_QLOGIC_ISP is not set +# CONFIG_SCSI_QLOGIC_FC is not set +# CONFIG_SCSI_QLOGIC_1280 is not set +CONFIG_SCSI_QLA2XXX=y +# CONFIG_SCSI_QLA21XX is not set +# CONFIG_SCSI_QLA22XX is not set +# CONFIG_SCSI_QLA2300 is not set +# CONFIG_SCSI_QLA2322 is not set +# CONFIG_SCSI_QLA6312 is not set +# CONFIG_SCSI_QLA6322 is not set +# CONFIG_SCSI_SYM53C416 is not set +# CONFIG_SCSI_DC395x is not set +# CONFIG_SCSI_DC390T is not set +# CONFIG_SCSI_T128 is not set +# CONFIG_SCSI_U14_34F is not set +# CONFIG_SCSI_NSP32 is not set +# CONFIG_SCSI_DEBUG is not set +# CONFIG_SCSI_MESH is not set +# CONFIG_SCSI_MAC53C94 is not set + +# +# Old CD-ROM drivers (not SCSI, not IDE) +# +# CONFIG_CD_NO_IDESCSI is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set + +# +# Fusion MPT device support +# +# CONFIG_FUSION is not set + +# +# IEEE 1394 (FireWire) support +# +# CONFIG_IEEE1394 is not set + +# +# I2O device support +# +# CONFIG_I2O is not set + +# +# Macintosh device drivers +# +# CONFIG_ADB is not set +# CONFIG_ADB_CUDA is not set +# CONFIG_ADB_PMU is not set +# CONFIG_MAC_FLOPPY is not set +# CONFIG_MAC_SERIAL is not set + +# +# Networking support +# +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +# CONFIG_NETLINK_DEV is not set +CONFIG_UNIX=y +# CONFIG_NET_KEY is not set +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +# CONFIG_IP_ADVANCED_ROUTER is not set +# CONFIG_IP_PNP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_IP_MROUTE is not set +# CONFIG_ARPD is not set +CONFIG_SYN_COOKIES=y +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set + +# +# IP: Virtual Server Configuration +# +# CONFIG_IP_VS is not set +# CONFIG_IPV6 is not set +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_DEBUG is not set + +# +# IP: Netfilter Configuration +# +CONFIG_IP_NF_CONNTRACK=m +CONFIG_IP_NF_FTP=m +CONFIG_IP_NF_IRC=m +CONFIG_IP_NF_TFTP=m +CONFIG_IP_NF_AMANDA=m +# CONFIG_IP_NF_QUEUE is not set +CONFIG_IP_NF_IPTABLES=m +CONFIG_IP_NF_MATCH_LIMIT=m +CONFIG_IP_NF_MATCH_IPRANGE=m +CONFIG_IP_NF_MATCH_MAC=m +# CONFIG_IP_NF_MATCH_PKTTYPE is not set +CONFIG_IP_NF_MATCH_MARK=m +CONFIG_IP_NF_MATCH_MULTIPORT=m +CONFIG_IP_NF_MATCH_TOS=m +CONFIG_IP_NF_MATCH_RECENT=m +CONFIG_IP_NF_MATCH_ECN=m +CONFIG_IP_NF_MATCH_DSCP=m +CONFIG_IP_NF_MATCH_AH_ESP=m +CONFIG_IP_NF_MATCH_LENGTH=m +CONFIG_IP_NF_MATCH_TTL=m +CONFIG_IP_NF_MATCH_TCPMSS=m +CONFIG_IP_NF_MATCH_HELPER=m +CONFIG_IP_NF_MATCH_STATE=m +CONFIG_IP_NF_MATCH_CONNTRACK=m +CONFIG_IP_NF_MATCH_OWNER=m +CONFIG_IP_NF_FILTER=m +CONFIG_IP_NF_TARGET_REJECT=m +CONFIG_IP_NF_NAT=m +CONFIG_IP_NF_NAT_NEEDED=y +CONFIG_IP_NF_TARGET_MASQUERADE=m +CONFIG_IP_NF_TARGET_REDIRECT=m +CONFIG_IP_NF_TARGET_NETMAP=m +CONFIG_IP_NF_TARGET_SAME=m +CONFIG_IP_NF_NAT_SNMP_BASIC=m +CONFIG_IP_NF_NAT_IRC=m +CONFIG_IP_NF_NAT_FTP=m +CONFIG_IP_NF_NAT_TFTP=m +CONFIG_IP_NF_NAT_AMANDA=m +# CONFIG_IP_NF_MANGLE is not set +# CONFIG_IP_NF_TARGET_LOG is not set +CONFIG_IP_NF_TARGET_ULOG=m +CONFIG_IP_NF_TARGET_TCPMSS=m +CONFIG_IP_NF_ARPTABLES=m +CONFIG_IP_NF_ARPFILTER=m +CONFIG_IP_NF_ARP_MANGLE=m +CONFIG_IP_NF_COMPAT_IPCHAINS=m +# CONFIG_IP_NF_COMPAT_IPFWADM is not set +CONFIG_IP_NF_TARGET_NOTRACK=m +CONFIG_IP_NF_RAW=m + +# +# SCTP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_SCTP is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_HW_FLOWCONTROL is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +CONFIG_MII=y +# CONFIG_MACE is not set +# CONFIG_BMAC is not set +# CONFIG_OAKNET is not set +# CONFIG_HAPPYMEAL is not set +# CONFIG_SUNGEM is not set +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_LANCE is not set +# CONFIG_NET_VENDOR_SMC is not set +# CONFIG_NET_VENDOR_RACAL is not set + +# +# Tulip family network device support +# +# CONFIG_NET_TULIP is not set +# CONFIG_AT1700 is not set +# CONFIG_DEPCA is not set +# CONFIG_HP100 is not set +# CONFIG_NET_ISA is not set +CONFIG_NET_PCI=y +CONFIG_PCNET32=y +# CONFIG_AMD8111_ETH is not set +# CONFIG_ADAPTEC_STARFIRE is not set +# CONFIG_AC3200 is not set +# CONFIG_APRICOT is not set +# CONFIG_B44 is not set +# CONFIG_FORCEDETH is not set +# CONFIG_CS89x0 is not set +# CONFIG_DGRS is not set +# CONFIG_EEPRO100 is not set +# CONFIG_E100 is not set +# CONFIG_FEALNX is not set +# CONFIG_NATSEMI is not set +# CONFIG_NE2K_PCI is not set +# CONFIG_8139CP is not set +# CONFIG_8139TOO is not set +# CONFIG_SIS900 is not set +# CONFIG_EPIC100 is not set +# CONFIG_SUNDANCE is not set +# CONFIG_TLAN is not set +# CONFIG_VIA_RHINE is not set +# CONFIG_NET_POCKET is not set + +# +# Ethernet (1000 Mbit) +# +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +# CONFIG_E1000 is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set +# CONFIG_SK98LIN is not set +# CONFIG_TIGON3 is not set + +# +# Ethernet (10000 Mbit) +# +# CONFIG_IXGB is not set +# CONFIG_S2IO is not set + +# +# Token Ring devices +# +# CONFIG_TR is not set + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_NET_FC is not set +# CONFIG_RCPCI is not set +# CONFIG_SHAPER is not set +# CONFIG_NETCONSOLE is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Telephony Support +# +# CONFIG_PHONE is not set + +# +# Input device support +# +CONFIG_INPUT=y + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=y +CONFIG_INPUT_MOUSEDEV_PSAUX=y +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set +CONFIG_INPUT_EVDEV=y +# CONFIG_INPUT_EVBUG is not set + +# +# Input I/O drivers +# +# CONFIG_GAMEPORT is not set +CONFIG_SOUND_GAMEPORT=y +CONFIG_SERIO=y +CONFIG_SERIO_I8042=y +CONFIG_SERIO_SERPORT=y +# CONFIG_SERIO_CT82C710 is not set +# CONFIG_SERIO_PCIPS2 is not set + +# +# Input Device Drivers +# +CONFIG_INPUT_KEYBOARD=y +CONFIG_KEYBOARD_ATKBD=y +# CONFIG_KEYBOARD_SUNKBD is not set +# CONFIG_KEYBOARD_LKKBD is not set +# CONFIG_KEYBOARD_XTKBD is not set +# CONFIG_KEYBOARD_NEWTON is not set +CONFIG_INPUT_MOUSE=y +CONFIG_MOUSE_PS2=y +# CONFIG_MOUSE_SERIAL is not set +# CONFIG_MOUSE_INPORT is not set +# CONFIG_MOUSE_LOGIBM is not set +# CONFIG_MOUSE_PC110PAD is not set +# CONFIG_MOUSE_VSXXXAA is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +CONFIG_INPUT_MISC=y +CONFIG_INPUT_UINPUT=y + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +CONFIG_SERIAL_8250=y +# CONFIG_SERIAL_8250_CONSOLE is not set +CONFIG_SERIAL_8250_NR_UARTS=4 +# CONFIG_SERIAL_8250_EXTENDED is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_CORE=y +# CONFIG_SERIAL_PMACZILOG is not set +CONFIG_UNIX98_PTYS=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 +# CONFIG_QIC02_TAPE is not set + +# +# IPMI +# +# CONFIG_IPMI_HANDLER is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +CONFIG_NVRAM=y +CONFIG_GEN_RTC=y +# CONFIG_GEN_RTC_X is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_FTAPE is not set +# CONFIG_AGP is not set +# CONFIG_DRM is not set +# CONFIG_RAW_DRIVER is not set + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# Misc devices +# + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set + +# +# Graphics support +# +CONFIG_FB=y +# CONFIG_FB_PM2 is not set +# CONFIG_FB_CYBER2000 is not set +CONFIG_FB_OF=y +# CONFIG_FB_CONTROL is not set +# CONFIG_FB_PLATINUM is not set +# CONFIG_FB_VALKYRIE is not set +# CONFIG_FB_CT65550 is not set +# CONFIG_FB_IMSTT is not set +# CONFIG_FB_S3TRIO is not set +# CONFIG_FB_VGA16 is not set +# CONFIG_FB_RIVA is not set +CONFIG_FB_MATROX=y +CONFIG_FB_MATROX_MILLENIUM=y +CONFIG_FB_MATROX_MYSTIQUE=y +# CONFIG_FB_MATROX_G450 is not set +CONFIG_FB_MATROX_G100A=y +CONFIG_FB_MATROX_G100=y +# CONFIG_FB_MATROX_MULTIHEAD is not set +# CONFIG_FB_RADEON_OLD is not set +# CONFIG_FB_RADEON is not set +# CONFIG_FB_ATY128 is not set +# CONFIG_FB_ATY is not set +# CONFIG_FB_SIS is not set +# CONFIG_FB_NEOMAGIC is not set +# CONFIG_FB_KYRO is not set +CONFIG_FB_3DFX=y +# CONFIG_FB_VOODOO1 is not set +# CONFIG_FB_TRIDENT is not set +# CONFIG_FB_VIRTUAL is not set + +# +# Console display driver support +# +CONFIG_VGA_CONSOLE=y +# CONFIG_MDA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE=y +CONFIG_PCI_CONSOLE=y +# CONFIG_FONTS is not set +CONFIG_FONT_8x8=y +CONFIG_FONT_8x16=y + +# +# Logo configuration +# +CONFIG_LOGO=y +CONFIG_LOGO_LINUX_MONO=y +CONFIG_LOGO_LINUX_VGA16=y +CONFIG_LOGO_LINUX_CLUT224=y + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +# CONFIG_USB is not set + +# +# USB Gadget Support +# +# CONFIG_USB_GADGET is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT3_FS is not set +# CONFIG_JBD is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +# CONFIG_XFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_QUOTA is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set + +# +# CD-ROM/DVD Filesystems +# +CONFIG_ISO9660_FS=y +# CONFIG_JOLIET is not set +# CONFIG_ZISOFS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=m +CONFIG_MSDOS_FS=m +CONFIG_VFAT_FS=m +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_KCORE=y +CONFIG_SYSFS=y +CONFIG_DEVFS_FS=y +# CONFIG_DEVFS_MOUNT is not set +# CONFIG_DEVFS_DEBUG is not set +# CONFIG_DEVPTS_FS_XATTR is not set +CONFIG_TMPFS=y +# CONFIG_HUGETLB_PAGE is not set +CONFIG_RAMFS=y + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_CRAMFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +# CONFIG_NFS_FS is not set +# CONFIG_NFSD is not set +# CONFIG_EXPORTFS is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +CONFIG_MAC_PARTITION=y +CONFIG_MSDOS_PARTITION=y +# CONFIG_BSD_DISKLABEL is not set +# CONFIG_MINIX_SUBPARTITION is not set +# CONFIG_SOLARIS_X86_PARTITION is not set +# CONFIG_UNIXWARE_DISKLABEL is not set +# CONFIG_LDM_PARTITION is not set +# CONFIG_NEC98_PARTITION is not set +# CONFIG_SGI_PARTITION is not set +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_EFI_PARTITION is not set + +# +# Native Language Support +# +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="iso8859-1" +# CONFIG_NLS_CODEPAGE_437 is not set +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +# CONFIG_NLS_CODEPAGE_850 is not set +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +CONFIG_NLS_ISO8859_1=m +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_15 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +# CONFIG_NLS_UTF8 is not set + +# +# Library routines +# +CONFIG_CRC32=y +# CONFIG_LIBCRC32C is not set + +# +# Kernel hacking +# +# CONFIG_DEBUG_KERNEL is not set +# CONFIG_BOOTX_TEXT is not set + +# +# Security options +# +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set diff --git a/trunk/arch/ppc/configs/pmac_defconfig b/trunk/arch/ppc/configs/pmac_defconfig new file mode 100644 index 000000000000..a2db8b541c9b --- /dev/null +++ b/trunk/arch/ppc/configs/pmac_defconfig @@ -0,0 +1,1591 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.13-rc3 +# Wed Jul 13 14:13:13 2005 +# +CONFIG_MMU=y +CONFIG_GENERIC_HARDIRQS=y +CONFIG_RWSEM_XCHGADD_ALGORITHM=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_HAVE_DEC_LOCK=y +CONFIG_PPC=y +CONFIG_PPC32=y +CONFIG_GENERIC_NVRAM=y +CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +CONFIG_CLEAN_COMPILE=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_INIT_ENV_ARG_LIMIT=32 + +# +# General setup +# +CONFIG_LOCALVERSION="" +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +CONFIG_POSIX_MQUEUE=y +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +# CONFIG_AUDIT is not set +CONFIG_HOTPLUG=y +CONFIG_KOBJECT_UEVENT=y +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +# CONFIG_EMBEDDED is not set +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_ALL is not set +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_SHMEM=y +CONFIG_CC_ALIGN_FUNCTIONS=0 +CONFIG_CC_ALIGN_LABELS=0 +CONFIG_CC_ALIGN_LOOPS=0 +CONFIG_CC_ALIGN_JUMPS=0 +# CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 + +# +# Loadable module support +# +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +CONFIG_OBSOLETE_MODPARM=y +CONFIG_MODVERSIONS=y +CONFIG_MODULE_SRCVERSION_ALL=y +CONFIG_KMOD=y + +# +# Processor +# +CONFIG_6xx=y +# CONFIG_40x is not set +# CONFIG_44x is not set +# CONFIG_POWER3 is not set +# CONFIG_POWER4 is not set +# CONFIG_8xx is not set +# CONFIG_E200 is not set +# CONFIG_E500 is not set +CONFIG_PPC_FPU=y +CONFIG_ALTIVEC=y +CONFIG_TAU=y +# CONFIG_TAU_INT is not set +# CONFIG_TAU_AVERAGE is not set +# CONFIG_KEXEC is not set +CONFIG_CPU_FREQ=y +CONFIG_CPU_FREQ_TABLE=y +# CONFIG_CPU_FREQ_DEBUG is not set +CONFIG_CPU_FREQ_STAT=m +CONFIG_CPU_FREQ_STAT_DETAILS=y +CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y +# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set +CONFIG_CPU_FREQ_GOV_PERFORMANCE=y +CONFIG_CPU_FREQ_GOV_POWERSAVE=m +CONFIG_CPU_FREQ_GOV_USERSPACE=m +CONFIG_CPU_FREQ_GOV_ONDEMAND=m +CONFIG_CPU_FREQ_GOV_CONSERVATIVE=m +CONFIG_CPU_FREQ_PMAC=y +CONFIG_PPC601_SYNC_FIX=y +CONFIG_PM=y +CONFIG_PPC_STD_MMU=y + +# +# Platform options +# +CONFIG_PPC_MULTIPLATFORM=y +# CONFIG_APUS is not set +# CONFIG_KATANA is not set +# CONFIG_WILLOW is not set +# CONFIG_CPCI690 is not set +# CONFIG_PCORE is not set +# CONFIG_POWERPMC250 is not set +# CONFIG_CHESTNUT is not set +# CONFIG_SPRUCE is not set +# CONFIG_HDPU is not set +# CONFIG_EV64260 is not set +# CONFIG_LOPEC is not set +# CONFIG_MCPN765 is not set +# CONFIG_MVME5100 is not set +# CONFIG_PPLUS is not set +# CONFIG_PRPMC750 is not set +# CONFIG_PRPMC800 is not set +# CONFIG_SANDPOINT is not set +# CONFIG_RADSTONE_PPC7D is not set +# CONFIG_ADIR is not set +# CONFIG_K2 is not set +# CONFIG_PAL4 is not set +# CONFIG_GEMINI is not set +# CONFIG_EST8260 is not set +# CONFIG_SBC82xx is not set +# CONFIG_SBS8260 is not set +# CONFIG_RPX8260 is not set +# CONFIG_TQM8260 is not set +# CONFIG_ADS8272 is not set +# CONFIG_PQ2FADS is not set +# CONFIG_LITE5200 is not set +# CONFIG_MPC834x_SYS is not set +CONFIG_PPC_CHRP=y +CONFIG_PPC_PMAC=y +CONFIG_PPC_PREP=y +CONFIG_PPC_OF=y +CONFIG_PPCBUG_NVRAM=y +# CONFIG_SMP is not set +# CONFIG_HIGHMEM is not set +# CONFIG_HZ_100 is not set +CONFIG_HZ_250=y +# CONFIG_HZ_1000 is not set +CONFIG_HZ=250 +CONFIG_PREEMPT_NONE=y +# CONFIG_PREEMPT_VOLUNTARY is not set +# CONFIG_PREEMPT is not set +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_FLATMEM_MANUAL=y +# CONFIG_DISCONTIGMEM_MANUAL is not set +# CONFIG_SPARSEMEM_MANUAL is not set +CONFIG_FLATMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y +CONFIG_BINFMT_ELF=y +CONFIG_BINFMT_MISC=m +CONFIG_PROC_DEVICETREE=y +# CONFIG_PREP_RESIDUAL is not set +# CONFIG_CMDLINE_BOOL is not set +# CONFIG_PM_DEBUG is not set +CONFIG_SOFTWARE_SUSPEND=y +CONFIG_PM_STD_PARTITION="" +# CONFIG_SECCOMP is not set +CONFIG_ISA_DMA_API=y + +# +# Bus options +# +# CONFIG_ISA is not set +CONFIG_GENERIC_ISA_DMA=y +CONFIG_PCI=y +CONFIG_PCI_DOMAINS=y +CONFIG_PCI_LEGACY_PROC=y +CONFIG_PCI_NAMES=y +# CONFIG_PCI_DEBUG is not set + +# +# PCCARD (PCMCIA/CardBus) support +# +CONFIG_PCCARD=m +# CONFIG_PCMCIA_DEBUG is not set +CONFIG_PCMCIA=m +# CONFIG_PCMCIA_LOAD_CIS is not set +# CONFIG_PCMCIA_IOCTL is not set +CONFIG_CARDBUS=y + +# +# PC-card bridges +# +CONFIG_YENTA=m +# CONFIG_PD6729 is not set +# CONFIG_I82092 is not set +# CONFIG_TCIC is not set +CONFIG_PCCARD_NONSTATIC=m + +# +# Advanced setup +# +CONFIG_ADVANCED_OPTIONS=y +CONFIG_HIGHMEM_START=0xfe000000 +# CONFIG_LOWMEM_SIZE_BOOL is not set +CONFIG_LOWMEM_SIZE=0x30000000 +# CONFIG_KERNEL_START_BOOL is not set +CONFIG_KERNEL_START=0xc0000000 +CONFIG_TASK_SIZE_BOOL=y +CONFIG_TASK_SIZE=0xc0000000 +CONFIG_BOOT_LOAD=0x00800000 + +# +# Networking +# +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +CONFIG_UNIX=y +# CONFIG_NET_KEY is not set +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_FIB_HASH=y +# CONFIG_IP_PNP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_IP_MROUTE is not set +# CONFIG_ARPD is not set +CONFIG_SYN_COOKIES=y +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_TUNNEL is not set +CONFIG_IP_TCPDIAG=y +# CONFIG_IP_TCPDIAG_IPV6 is not set +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_BIC=y + +# +# IP: Virtual Server Configuration +# +# CONFIG_IP_VS is not set +# CONFIG_IPV6 is not set +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_DEBUG is not set + +# +# IP: Netfilter Configuration +# +CONFIG_IP_NF_CONNTRACK=m +CONFIG_IP_NF_CT_ACCT=y +CONFIG_IP_NF_CONNTRACK_MARK=y +CONFIG_IP_NF_CT_PROTO_SCTP=m +CONFIG_IP_NF_FTP=m +CONFIG_IP_NF_IRC=m +CONFIG_IP_NF_TFTP=m +CONFIG_IP_NF_AMANDA=m +CONFIG_IP_NF_QUEUE=m +CONFIG_IP_NF_IPTABLES=m +CONFIG_IP_NF_MATCH_LIMIT=m +CONFIG_IP_NF_MATCH_IPRANGE=m +CONFIG_IP_NF_MATCH_MAC=m +CONFIG_IP_NF_MATCH_PKTTYPE=m +CONFIG_IP_NF_MATCH_MARK=m +CONFIG_IP_NF_MATCH_MULTIPORT=m +CONFIG_IP_NF_MATCH_TOS=m +CONFIG_IP_NF_MATCH_RECENT=m +CONFIG_IP_NF_MATCH_ECN=m +CONFIG_IP_NF_MATCH_DSCP=m +CONFIG_IP_NF_MATCH_AH_ESP=m +CONFIG_IP_NF_MATCH_LENGTH=m +CONFIG_IP_NF_MATCH_TTL=m +CONFIG_IP_NF_MATCH_TCPMSS=m +CONFIG_IP_NF_MATCH_HELPER=m +CONFIG_IP_NF_MATCH_STATE=m +CONFIG_IP_NF_MATCH_CONNTRACK=m +CONFIG_IP_NF_MATCH_OWNER=m +CONFIG_IP_NF_MATCH_ADDRTYPE=m +CONFIG_IP_NF_MATCH_REALM=m +CONFIG_IP_NF_MATCH_SCTP=m +CONFIG_IP_NF_MATCH_COMMENT=m +CONFIG_IP_NF_MATCH_CONNMARK=m +CONFIG_IP_NF_MATCH_HASHLIMIT=m +CONFIG_IP_NF_FILTER=m +CONFIG_IP_NF_TARGET_REJECT=m +CONFIG_IP_NF_TARGET_LOG=m +CONFIG_IP_NF_TARGET_ULOG=m +CONFIG_IP_NF_TARGET_TCPMSS=m +CONFIG_IP_NF_NAT=m +CONFIG_IP_NF_NAT_NEEDED=y +CONFIG_IP_NF_TARGET_MASQUERADE=m +CONFIG_IP_NF_TARGET_REDIRECT=m +CONFIG_IP_NF_TARGET_NETMAP=m +CONFIG_IP_NF_TARGET_SAME=m +CONFIG_IP_NF_NAT_SNMP_BASIC=m +CONFIG_IP_NF_NAT_IRC=m +CONFIG_IP_NF_NAT_FTP=m +CONFIG_IP_NF_NAT_TFTP=m +CONFIG_IP_NF_NAT_AMANDA=m +CONFIG_IP_NF_MANGLE=m +CONFIG_IP_NF_TARGET_TOS=m +CONFIG_IP_NF_TARGET_ECN=m +CONFIG_IP_NF_TARGET_DSCP=m +CONFIG_IP_NF_TARGET_MARK=m +CONFIG_IP_NF_TARGET_CLASSIFY=m +CONFIG_IP_NF_TARGET_CONNMARK=m +CONFIG_IP_NF_TARGET_CLUSTERIP=m +CONFIG_IP_NF_RAW=m +CONFIG_IP_NF_TARGET_NOTRACK=m +CONFIG_IP_NF_ARPTABLES=m +CONFIG_IP_NF_ARPFILTER=m +CONFIG_IP_NF_ARP_MANGLE=m + +# +# SCTP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_SCTP is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_SCHED is not set +CONFIG_NET_CLS_ROUTE=y + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +CONFIG_NETPOLL=y +# CONFIG_NETPOLL_RX is not set +# CONFIG_NETPOLL_TRAP is not set +CONFIG_NET_POLL_CONTROLLER=y +# CONFIG_HAMRADIO is not set +CONFIG_IRDA=m + +# +# IrDA protocols +# +CONFIG_IRLAN=m +CONFIG_IRNET=m +CONFIG_IRCOMM=m +# CONFIG_IRDA_ULTRA is not set + +# +# IrDA options +# +CONFIG_IRDA_CACHE_LAST_LSAP=y +CONFIG_IRDA_FAST_RR=y +# CONFIG_IRDA_DEBUG is not set + +# +# Infrared-port device drivers +# + +# +# SIR device drivers +# +CONFIG_IRTTY_SIR=m + +# +# Dongle support +# +# CONFIG_DONGLE is not set + +# +# Old SIR device drivers +# +# CONFIG_IRPORT_SIR is not set + +# +# Old Serial dongle support +# + +# +# FIR device drivers +# +# CONFIG_USB_IRDA is not set +# CONFIG_SIGMATEL_FIR is not set +# CONFIG_NSC_FIR is not set +# CONFIG_WINBOND_FIR is not set +# CONFIG_TOSHIBA_FIR is not set +# CONFIG_SMC_IRCC_FIR is not set +# CONFIG_ALI_FIR is not set +# CONFIG_VLSI_FIR is not set +# CONFIG_VIA_FIR is not set +# CONFIG_BT is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +# CONFIG_STANDALONE is not set +CONFIG_PREVENT_FIRMWARE_BUILD=y +CONFIG_FW_LOADER=m +# CONFIG_DEBUG_DRIVER is not set + +# +# Memory Technology Devices (MTD) +# +# CONFIG_MTD is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Plug and Play support +# + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +CONFIG_MAC_FLOPPY=m +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_UMEM is not set +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_LOOP=y +# CONFIG_BLK_DEV_CRYPTOLOOP is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_SX8 is not set +# CONFIG_BLK_DEV_UB is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=4096 +CONFIG_BLK_DEV_INITRD=y +CONFIG_INITRAMFS_SOURCE="" +CONFIG_LBD=y +CONFIG_CDROM_PKTCDVD=m +CONFIG_CDROM_PKTCDVD_BUFFERS=8 +# CONFIG_CDROM_PKTCDVD_WCACHE is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +# CONFIG_ATA_OVER_ETH is not set + +# +# ATA/ATAPI/MFM/RLL support +# +CONFIG_IDE=y +CONFIG_BLK_DEV_IDE=y + +# +# Please see Documentation/ide.txt for help/info on IDE drives +# +# CONFIG_BLK_DEV_IDE_SATA is not set +CONFIG_BLK_DEV_IDEDISK=y +# CONFIG_IDEDISK_MULTI_MODE is not set +# CONFIG_BLK_DEV_IDECS is not set +CONFIG_BLK_DEV_IDECD=y +# CONFIG_BLK_DEV_IDETAPE is not set +CONFIG_BLK_DEV_IDEFLOPPY=y +CONFIG_BLK_DEV_IDESCSI=y +# CONFIG_IDE_TASK_IOCTL is not set + +# +# IDE chipset support/bugfixes +# +# CONFIG_IDE_GENERIC is not set +CONFIG_BLK_DEV_IDEPCI=y +CONFIG_IDEPCI_SHARE_IRQ=y +# CONFIG_BLK_DEV_OFFBOARD is not set +CONFIG_BLK_DEV_GENERIC=y +# CONFIG_BLK_DEV_OPTI621 is not set +# CONFIG_BLK_DEV_SL82C105 is not set +CONFIG_BLK_DEV_IDEDMA_PCI=y +# CONFIG_BLK_DEV_IDEDMA_FORCED is not set +CONFIG_IDEDMA_PCI_AUTO=y +# CONFIG_IDEDMA_ONLYDISK is not set +# CONFIG_BLK_DEV_AEC62XX is not set +# CONFIG_BLK_DEV_ALI15X3 is not set +# CONFIG_BLK_DEV_AMD74XX is not set +CONFIG_BLK_DEV_CMD64X=y +# CONFIG_BLK_DEV_TRIFLEX is not set +# CONFIG_BLK_DEV_CY82C693 is not set +# CONFIG_BLK_DEV_CS5520 is not set +# CONFIG_BLK_DEV_CS5530 is not set +# CONFIG_BLK_DEV_HPT34X is not set +# CONFIG_BLK_DEV_HPT366 is not set +# CONFIG_BLK_DEV_SC1200 is not set +# CONFIG_BLK_DEV_PIIX is not set +# CONFIG_BLK_DEV_IT821X is not set +# CONFIG_BLK_DEV_NS87415 is not set +# CONFIG_BLK_DEV_PDC202XX_OLD is not set +CONFIG_BLK_DEV_PDC202XX_NEW=y +# CONFIG_PDC202XX_FORCE is not set +# CONFIG_BLK_DEV_SVWKS is not set +# CONFIG_BLK_DEV_SIIMAGE is not set +# CONFIG_BLK_DEV_SLC90E66 is not set +# CONFIG_BLK_DEV_TRM290 is not set +# CONFIG_BLK_DEV_VIA82CXXX is not set +CONFIG_BLK_DEV_IDE_PMAC=y +CONFIG_BLK_DEV_IDE_PMAC_ATA100FIRST=y +CONFIG_BLK_DEV_IDEDMA_PMAC=y +CONFIG_BLK_DEV_IDE_PMAC_BLINK=y +# CONFIG_IDE_ARM is not set +CONFIG_BLK_DEV_IDEDMA=y +# CONFIG_IDEDMA_IVB is not set +CONFIG_IDEDMA_AUTO=y +# CONFIG_BLK_DEV_HD is not set + +# +# SCSI device support +# +CONFIG_SCSI=y +CONFIG_SCSI_PROC_FS=y + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=y +CONFIG_CHR_DEV_ST=y +# CONFIG_CHR_DEV_OSST is not set +CONFIG_BLK_DEV_SR=y +CONFIG_BLK_DEV_SR_VENDOR=y +CONFIG_CHR_DEV_SG=y +# CONFIG_CHR_DEV_SCH is not set + +# +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs +# +# CONFIG_SCSI_MULTI_LUN is not set +CONFIG_SCSI_CONSTANTS=y +# CONFIG_SCSI_LOGGING is not set + +# +# SCSI Transport Attributes +# +CONFIG_SCSI_SPI_ATTRS=y +# CONFIG_SCSI_FC_ATTRS is not set +# CONFIG_SCSI_ISCSI_ATTRS is not set + +# +# SCSI low-level drivers +# +# CONFIG_BLK_DEV_3W_XXXX_RAID is not set +# CONFIG_SCSI_3W_9XXX is not set +# CONFIG_SCSI_ACARD is not set +# CONFIG_SCSI_AACRAID is not set +CONFIG_SCSI_AIC7XXX=m +CONFIG_AIC7XXX_CMDS_PER_DEVICE=253 +CONFIG_AIC7XXX_RESET_DELAY_MS=15000 +CONFIG_AIC7XXX_DEBUG_ENABLE=y +CONFIG_AIC7XXX_DEBUG_MASK=0 +CONFIG_AIC7XXX_REG_PRETTY_PRINT=y +CONFIG_SCSI_AIC7XXX_OLD=m +# CONFIG_SCSI_AIC79XX is not set +# CONFIG_SCSI_DPT_I2O is not set +# CONFIG_MEGARAID_NEWGEN is not set +# CONFIG_MEGARAID_LEGACY is not set +# CONFIG_SCSI_SATA is not set +# CONFIG_SCSI_BUSLOGIC is not set +# CONFIG_SCSI_DMX3191D is not set +# CONFIG_SCSI_EATA is not set +# CONFIG_SCSI_FUTURE_DOMAIN is not set +# CONFIG_SCSI_GDTH is not set +# CONFIG_SCSI_IPS is not set +# CONFIG_SCSI_INITIO is not set +# CONFIG_SCSI_INIA100 is not set +CONFIG_SCSI_SYM53C8XX_2=y +CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=0 +CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16 +CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64 +# CONFIG_SCSI_SYM53C8XX_IOMAPPED is not set +# CONFIG_SCSI_IPR is not set +# CONFIG_SCSI_QLOGIC_FC is not set +# CONFIG_SCSI_QLOGIC_1280 is not set +CONFIG_SCSI_QLA2XXX=y +# CONFIG_SCSI_QLA21XX is not set +# CONFIG_SCSI_QLA22XX is not set +# CONFIG_SCSI_QLA2300 is not set +# CONFIG_SCSI_QLA2322 is not set +# CONFIG_SCSI_QLA6312 is not set +# CONFIG_SCSI_LPFC is not set +# CONFIG_SCSI_DC395x is not set +# CONFIG_SCSI_DC390T is not set +# CONFIG_SCSI_NSP32 is not set +# CONFIG_SCSI_DEBUG is not set +CONFIG_SCSI_MESH=y +CONFIG_SCSI_MESH_SYNC_RATE=5 +CONFIG_SCSI_MESH_RESET_DELAY_MS=1000 +CONFIG_SCSI_MAC53C94=y + +# +# PCMCIA SCSI adapter support +# +# CONFIG_PCMCIA_AHA152X is not set +# CONFIG_PCMCIA_FDOMAIN is not set +# CONFIG_PCMCIA_NINJA_SCSI is not set +# CONFIG_PCMCIA_QLOGIC is not set +# CONFIG_PCMCIA_SYM53C500 is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set + +# +# Fusion MPT device support +# +# CONFIG_FUSION is not set +# CONFIG_FUSION_SPI is not set +# CONFIG_FUSION_FC is not set + +# +# IEEE 1394 (FireWire) support +# +CONFIG_IEEE1394=m + +# +# Subsystem Options +# +# CONFIG_IEEE1394_VERBOSEDEBUG is not set +# CONFIG_IEEE1394_OUI_DB is not set +CONFIG_IEEE1394_EXTRA_CONFIG_ROMS=y +CONFIG_IEEE1394_CONFIG_ROM_IP1394=y +# CONFIG_IEEE1394_EXPORT_FULL_API is not set + +# +# Device Drivers +# +# CONFIG_IEEE1394_PCILYNX is not set +CONFIG_IEEE1394_OHCI1394=m + +# +# Protocol Drivers +# +CONFIG_IEEE1394_VIDEO1394=m +CONFIG_IEEE1394_SBP2=m +# CONFIG_IEEE1394_SBP2_PHYS_DMA is not set +CONFIG_IEEE1394_ETH1394=m +CONFIG_IEEE1394_DV1394=m +CONFIG_IEEE1394_RAWIO=m +CONFIG_IEEE1394_CMP=m +CONFIG_IEEE1394_AMDTP=m + +# +# I2O device support +# +# CONFIG_I2O is not set + +# +# Macintosh device drivers +# +CONFIG_ADB=y +CONFIG_ADB_CUDA=y +CONFIG_ADB_PMU=y +CONFIG_PMAC_APM_EMU=y +CONFIG_PMAC_MEDIABAY=y +CONFIG_PMAC_BACKLIGHT=y +CONFIG_ADB_MACIO=y +CONFIG_INPUT_ADBHID=y +CONFIG_MAC_EMUMOUSEBTN=y +CONFIG_THERM_WINDTUNNEL=m +CONFIG_THERM_ADT746X=m +# CONFIG_ANSLCD is not set + +# +# Network device support +# +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +CONFIG_TUN=m + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +CONFIG_MII=y +CONFIG_MACE=y +# CONFIG_MACE_AAUI_PORT is not set +CONFIG_BMAC=y +# CONFIG_HAPPYMEAL is not set +CONFIG_SUNGEM=y +# CONFIG_NET_VENDOR_3COM is not set + +# +# Tulip family network device support +# +# CONFIG_NET_TULIP is not set +# CONFIG_HP100 is not set +CONFIG_NET_PCI=y +CONFIG_PCNET32=y +# CONFIG_AMD8111_ETH is not set +# CONFIG_ADAPTEC_STARFIRE is not set +# CONFIG_B44 is not set +# CONFIG_FORCEDETH is not set +# CONFIG_DGRS is not set +# CONFIG_EEPRO100 is not set +# CONFIG_E100 is not set +# CONFIG_FEALNX is not set +# CONFIG_NATSEMI is not set +# CONFIG_NE2K_PCI is not set +# CONFIG_8139CP is not set +# CONFIG_8139TOO is not set +# CONFIG_SIS900 is not set +# CONFIG_EPIC100 is not set +# CONFIG_SUNDANCE is not set +# CONFIG_TLAN is not set +# CONFIG_VIA_RHINE is not set + +# +# Ethernet (1000 Mbit) +# +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +# CONFIG_E1000 is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set +# CONFIG_SKGE is not set +# CONFIG_SK98LIN is not set +# CONFIG_VIA_VELOCITY is not set +# CONFIG_TIGON3 is not set +# CONFIG_BNX2 is not set +# CONFIG_MV643XX_ETH is not set + +# +# Ethernet (10000 Mbit) +# +# CONFIG_IXGB is not set +# CONFIG_S2IO is not set + +# +# Token Ring devices +# +# CONFIG_TR is not set + +# +# Wireless LAN (non-hamradio) +# +CONFIG_NET_RADIO=y + +# +# Obsolete Wireless cards support (pre-802.11) +# +# CONFIG_STRIP is not set +# CONFIG_PCMCIA_WAVELAN is not set +# CONFIG_PCMCIA_NETWAVE is not set + +# +# Wireless 802.11 Frequency Hopping cards support +# +# CONFIG_PCMCIA_RAYCS is not set + +# +# Wireless 802.11b ISA/PCI cards support +# +CONFIG_HERMES=m +CONFIG_APPLE_AIRPORT=m +# CONFIG_PLX_HERMES is not set +# CONFIG_TMD_HERMES is not set +# CONFIG_PCI_HERMES is not set +# CONFIG_ATMEL is not set + +# +# Wireless 802.11b Pcmcia/Cardbus cards support +# +CONFIG_PCMCIA_HERMES=m +# CONFIG_AIRO_CS is not set +# CONFIG_PCMCIA_WL3501 is not set + +# +# Prism GT/Duette 802.11(a/b/g) PCI/Cardbus support +# +# CONFIG_PRISM54 is not set +CONFIG_NET_WIRELESS=y + +# +# PCMCIA network device support +# +# CONFIG_NET_PCMCIA is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +CONFIG_PPP=y +CONFIG_PPP_MULTILINK=y +# CONFIG_PPP_FILTER is not set +CONFIG_PPP_ASYNC=y +CONFIG_PPP_SYNC_TTY=m +CONFIG_PPP_DEFLATE=y +CONFIG_PPP_BSDCOMP=m +CONFIG_PPPOE=m +# CONFIG_SLIP is not set +# CONFIG_NET_FC is not set +# CONFIG_SHAPER is not set +CONFIG_NETCONSOLE=m + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Telephony Support +# +# CONFIG_PHONE is not set + +# +# Input device support +# +CONFIG_INPUT=y + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=y +# CONFIG_INPUT_MOUSEDEV_PSAUX is not set +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set +CONFIG_INPUT_EVDEV=y +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +CONFIG_INPUT_KEYBOARD=y +# CONFIG_KEYBOARD_ATKBD is not set +# CONFIG_KEYBOARD_SUNKBD is not set +# CONFIG_KEYBOARD_LKKBD is not set +# CONFIG_KEYBOARD_XTKBD is not set +# CONFIG_KEYBOARD_NEWTON is not set +CONFIG_INPUT_MOUSE=y +# CONFIG_MOUSE_PS2 is not set +# CONFIG_MOUSE_SERIAL is not set +# CONFIG_MOUSE_VSXXXAA is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set + +# +# Hardware I/O ports +# +# CONFIG_SERIO is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +CONFIG_SERIAL_8250=m +CONFIG_SERIAL_8250_CS=m +CONFIG_SERIAL_8250_NR_UARTS=4 +# CONFIG_SERIAL_8250_EXTENDED is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_SERIAL_PMACZILOG=y +CONFIG_SERIAL_PMACZILOG_CONSOLE=y +# CONFIG_SERIAL_JSM is not set +CONFIG_UNIX98_PTYS=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 + +# +# IPMI +# +# CONFIG_IPMI_HANDLER is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +CONFIG_NVRAM=y +CONFIG_GEN_RTC=y +# CONFIG_GEN_RTC_X is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set + +# +# Ftape, the floppy tape device driver +# +CONFIG_AGP=m +CONFIG_AGP_UNINORTH=m +CONFIG_DRM=m +# CONFIG_DRM_TDFX is not set +CONFIG_DRM_R128=m +CONFIG_DRM_RADEON=m +# CONFIG_DRM_MGA is not set +# CONFIG_DRM_SIS is not set +# CONFIG_DRM_VIA is not set + +# +# PCMCIA character devices +# +# CONFIG_SYNCLINK_CS is not set +# CONFIG_RAW_DRIVER is not set + +# +# TPM devices +# +# CONFIG_TCG_TPM is not set + +# +# I2C support +# +CONFIG_I2C=y +CONFIG_I2C_CHARDEV=m + +# +# I2C Algorithms +# +CONFIG_I2C_ALGOBIT=y +# CONFIG_I2C_ALGOPCF is not set +# CONFIG_I2C_ALGOPCA is not set + +# +# I2C Hardware Bus support +# +# CONFIG_I2C_ALI1535 is not set +# CONFIG_I2C_ALI1563 is not set +# CONFIG_I2C_ALI15X3 is not set +# CONFIG_I2C_AMD756 is not set +# CONFIG_I2C_AMD8111 is not set +# CONFIG_I2C_HYDRA is not set +# CONFIG_I2C_I801 is not set +# CONFIG_I2C_I810 is not set +# CONFIG_I2C_PIIX4 is not set +# CONFIG_I2C_ISA is not set +CONFIG_I2C_KEYWEST=m +# CONFIG_I2C_MPC is not set +# CONFIG_I2C_NFORCE2 is not set +# CONFIG_I2C_PARPORT_LIGHT is not set +# CONFIG_I2C_PROSAVAGE is not set +# CONFIG_I2C_SAVAGE4 is not set +# CONFIG_SCx200_ACB is not set +# CONFIG_I2C_SIS5595 is not set +# CONFIG_I2C_SIS630 is not set +# CONFIG_I2C_SIS96X is not set +# CONFIG_I2C_STUB is not set +# CONFIG_I2C_VIA is not set +# CONFIG_I2C_VIAPRO is not set +# CONFIG_I2C_VOODOO3 is not set +# CONFIG_I2C_PCA_ISA is not set +# CONFIG_I2C_SENSOR is not set + +# +# Miscellaneous I2C Chip support +# +# CONFIG_SENSORS_DS1337 is not set +# CONFIG_SENSORS_DS1374 is not set +# CONFIG_SENSORS_EEPROM is not set +# CONFIG_SENSORS_PCF8574 is not set +# CONFIG_SENSORS_PCA9539 is not set +# CONFIG_SENSORS_PCF8591 is not set +# CONFIG_SENSORS_RTC8564 is not set +# CONFIG_SENSORS_M41T00 is not set +# CONFIG_SENSORS_MAX6875 is not set +# CONFIG_I2C_DEBUG_CORE is not set +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set +# CONFIG_I2C_DEBUG_CHIP is not set + +# +# Dallas's 1-wire bus +# +# CONFIG_W1 is not set + +# +# Hardware Monitoring support +# +# CONFIG_HWMON is not set + +# +# Misc devices +# + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set + +# +# Graphics support +# +CONFIG_FB=y +CONFIG_FB_CFB_FILLRECT=y +CONFIG_FB_CFB_COPYAREA=y +CONFIG_FB_CFB_IMAGEBLIT=y +CONFIG_FB_SOFT_CURSOR=y +CONFIG_FB_MACMODES=y +CONFIG_FB_MODE_HELPERS=y +CONFIG_FB_TILEBLITTING=y +# CONFIG_FB_CIRRUS is not set +# CONFIG_FB_PM2 is not set +# CONFIG_FB_CYBER2000 is not set +CONFIG_FB_OF=y +CONFIG_FB_CONTROL=y +CONFIG_FB_PLATINUM=y +CONFIG_FB_VALKYRIE=y +CONFIG_FB_CT65550=y +# CONFIG_FB_ASILIANT is not set +CONFIG_FB_IMSTT=y +# CONFIG_FB_VGA16 is not set +# CONFIG_FB_NVIDIA is not set +# CONFIG_FB_RIVA is not set +CONFIG_FB_MATROX=y +CONFIG_FB_MATROX_MILLENIUM=y +CONFIG_FB_MATROX_MYSTIQUE=y +CONFIG_FB_MATROX_G=y +# CONFIG_FB_MATROX_I2C is not set +# CONFIG_FB_MATROX_MULTIHEAD is not set +# CONFIG_FB_RADEON_OLD is not set +CONFIG_FB_RADEON=y +CONFIG_FB_RADEON_I2C=y +# CONFIG_FB_RADEON_DEBUG is not set +CONFIG_FB_ATY128=y +CONFIG_FB_ATY=y +CONFIG_FB_ATY_CT=y +CONFIG_FB_ATY_GENERIC_LCD=y +# CONFIG_FB_ATY_XL_INIT is not set +CONFIG_FB_ATY_GX=y +# CONFIG_FB_SAVAGE is not set +# CONFIG_FB_SIS is not set +# CONFIG_FB_NEOMAGIC is not set +# CONFIG_FB_KYRO is not set +CONFIG_FB_3DFX=y +CONFIG_FB_3DFX_ACCEL=y +# CONFIG_FB_VOODOO1 is not set +# CONFIG_FB_TRIDENT is not set +# CONFIG_FB_S1D13XXX is not set +# CONFIG_FB_VIRTUAL is not set + +# +# Console display driver support +# +# CONFIG_VGA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE=y +# CONFIG_FONTS is not set +CONFIG_FONT_8x8=y +CONFIG_FONT_8x16=y + +# +# Logo configuration +# +CONFIG_LOGO=y +CONFIG_LOGO_LINUX_MONO=y +CONFIG_LOGO_LINUX_VGA16=y +CONFIG_LOGO_LINUX_CLUT224=y +CONFIG_BACKLIGHT_LCD_SUPPORT=y +CONFIG_BACKLIGHT_CLASS_DEVICE=y +CONFIG_BACKLIGHT_DEVICE=y +CONFIG_LCD_CLASS_DEVICE=y +CONFIG_LCD_DEVICE=y + +# +# Sound +# +CONFIG_SOUND=m +CONFIG_DMASOUND_PMAC=m +CONFIG_DMASOUND=m + +# +# Advanced Linux Sound Architecture +# +CONFIG_SND=m +CONFIG_SND_TIMER=m +CONFIG_SND_PCM=m +CONFIG_SND_HWDEP=m +CONFIG_SND_RAWMIDI=m +CONFIG_SND_SEQUENCER=m +CONFIG_SND_SEQ_DUMMY=m +CONFIG_SND_OSSEMUL=y +CONFIG_SND_MIXER_OSS=m +CONFIG_SND_PCM_OSS=m +CONFIG_SND_SEQUENCER_OSS=y +# CONFIG_SND_VERBOSE_PRINTK is not set +# CONFIG_SND_DEBUG is not set + +# +# Generic devices +# +CONFIG_SND_DUMMY=m +# CONFIG_SND_VIRMIDI is not set +# CONFIG_SND_MTPAV is not set +# CONFIG_SND_SERIAL_U16550 is not set +# CONFIG_SND_MPU401 is not set + +# +# PCI devices +# +# CONFIG_SND_ALI5451 is not set +# CONFIG_SND_ATIIXP is not set +# CONFIG_SND_ATIIXP_MODEM is not set +# CONFIG_SND_AU8810 is not set +# CONFIG_SND_AU8820 is not set +# CONFIG_SND_AU8830 is not set +# CONFIG_SND_AZT3328 is not set +# CONFIG_SND_BT87X is not set +# CONFIG_SND_CS46XX is not set +# CONFIG_SND_CS4281 is not set +# CONFIG_SND_EMU10K1 is not set +# CONFIG_SND_EMU10K1X is not set +# CONFIG_SND_CA0106 is not set +# CONFIG_SND_KORG1212 is not set +# CONFIG_SND_MIXART is not set +# CONFIG_SND_NM256 is not set +# CONFIG_SND_RME32 is not set +# CONFIG_SND_RME96 is not set +# CONFIG_SND_RME9652 is not set +# CONFIG_SND_HDSP is not set +# CONFIG_SND_HDSPM is not set +# CONFIG_SND_TRIDENT is not set +# CONFIG_SND_YMFPCI is not set +# CONFIG_SND_ALS4000 is not set +# CONFIG_SND_CMIPCI is not set +# CONFIG_SND_ENS1370 is not set +# CONFIG_SND_ENS1371 is not set +# CONFIG_SND_ES1938 is not set +# CONFIG_SND_ES1968 is not set +# CONFIG_SND_MAESTRO3 is not set +# CONFIG_SND_FM801 is not set +# CONFIG_SND_ICE1712 is not set +# CONFIG_SND_ICE1724 is not set +# CONFIG_SND_INTEL8X0 is not set +# CONFIG_SND_INTEL8X0M is not set +# CONFIG_SND_SONICVIBES is not set +# CONFIG_SND_VIA82XX is not set +# CONFIG_SND_VIA82XX_MODEM is not set +# CONFIG_SND_VX222 is not set +# CONFIG_SND_HDA_INTEL is not set + +# +# ALSA PowerMac devices +# +CONFIG_SND_POWERMAC=m + +# +# USB devices +# +CONFIG_SND_USB_AUDIO=m +CONFIG_SND_USB_USX2Y=m + +# +# PCMCIA devices +# + +# +# Open Sound System +# +# CONFIG_SOUND_PRIME is not set + +# +# USB support +# +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y +CONFIG_USB=y +# CONFIG_USB_DEBUG is not set + +# +# Miscellaneous USB options +# +CONFIG_USB_DEVICEFS=y +# CONFIG_USB_BANDWIDTH is not set +CONFIG_USB_DYNAMIC_MINORS=y +CONFIG_USB_SUSPEND=y +# CONFIG_USB_OTG is not set + +# +# USB Host Controller Drivers +# +# CONFIG_USB_EHCI_HCD is not set +# CONFIG_USB_ISP116X_HCD is not set +CONFIG_USB_OHCI_HCD=y +# CONFIG_USB_OHCI_BIG_ENDIAN is not set +CONFIG_USB_OHCI_LITTLE_ENDIAN=y +# CONFIG_USB_UHCI_HCD is not set +# CONFIG_USB_SL811_HCD is not set + +# +# USB Device Class drivers +# +# CONFIG_USB_AUDIO is not set +# CONFIG_USB_BLUETOOTH_TTY is not set +# CONFIG_USB_MIDI is not set +CONFIG_USB_ACM=m +CONFIG_USB_PRINTER=m + +# +# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information +# +# CONFIG_USB_STORAGE is not set + +# +# USB Input Devices +# +CONFIG_USB_HID=y +CONFIG_USB_HIDINPUT=y +# CONFIG_HID_FF is not set +CONFIG_USB_HIDDEV=y +# CONFIG_USB_AIPTEK is not set +# CONFIG_USB_WACOM is not set +# CONFIG_USB_ACECAD is not set +# CONFIG_USB_KBTAB is not set +# CONFIG_USB_POWERMATE is not set +# CONFIG_USB_MTOUCH is not set +# CONFIG_USB_ITMTOUCH is not set +# CONFIG_USB_EGALAX is not set +# CONFIG_USB_XPAD is not set +# CONFIG_USB_ATI_REMOTE is not set +# CONFIG_USB_KEYSPAN_REMOTE is not set + +# +# USB Imaging devices +# +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_MICROTEK is not set + +# +# USB Multimedia devices +# +# CONFIG_USB_DABUSB is not set + +# +# Video4Linux support is needed for USB Multimedia device support +# + +# +# USB Network Adapters +# +# CONFIG_USB_CATC is not set +# CONFIG_USB_KAWETH is not set +CONFIG_USB_PEGASUS=m +# CONFIG_USB_RTL8150 is not set +# CONFIG_USB_USBNET is not set +# CONFIG_USB_ZD1201 is not set +# CONFIG_USB_MON is not set + +# +# USB port drivers +# + +# +# USB Serial Converter support +# +CONFIG_USB_SERIAL=m +# CONFIG_USB_SERIAL_GENERIC is not set +# CONFIG_USB_SERIAL_AIRPRIME is not set +# CONFIG_USB_SERIAL_BELKIN is not set +# CONFIG_USB_SERIAL_WHITEHEAT is not set +# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set +# CONFIG_USB_SERIAL_CP2101 is not set +# CONFIG_USB_SERIAL_CYPRESS_M8 is not set +# CONFIG_USB_SERIAL_EMPEG is not set +# CONFIG_USB_SERIAL_FTDI_SIO is not set +CONFIG_USB_SERIAL_VISOR=m +# CONFIG_USB_SERIAL_IPAQ is not set +# CONFIG_USB_SERIAL_IR is not set +# CONFIG_USB_SERIAL_EDGEPORT is not set +# CONFIG_USB_SERIAL_EDGEPORT_TI is not set +# CONFIG_USB_SERIAL_GARMIN is not set +# CONFIG_USB_SERIAL_IPW is not set +# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set +CONFIG_USB_SERIAL_KEYSPAN=m +CONFIG_USB_SERIAL_KEYSPAN_MPR=y +CONFIG_USB_SERIAL_KEYSPAN_USA28=y +CONFIG_USB_SERIAL_KEYSPAN_USA28X=y +CONFIG_USB_SERIAL_KEYSPAN_USA28XA=y +CONFIG_USB_SERIAL_KEYSPAN_USA28XB=y +CONFIG_USB_SERIAL_KEYSPAN_USA19=y +CONFIG_USB_SERIAL_KEYSPAN_USA18X=y +CONFIG_USB_SERIAL_KEYSPAN_USA19W=y +CONFIG_USB_SERIAL_KEYSPAN_USA19QW=y +CONFIG_USB_SERIAL_KEYSPAN_USA19QI=y +CONFIG_USB_SERIAL_KEYSPAN_USA49W=y +CONFIG_USB_SERIAL_KEYSPAN_USA49WLC=y +# CONFIG_USB_SERIAL_KLSI is not set +# CONFIG_USB_SERIAL_KOBIL_SCT is not set +# CONFIG_USB_SERIAL_MCT_U232 is not set +# CONFIG_USB_SERIAL_PL2303 is not set +# CONFIG_USB_SERIAL_HP4X is not set +# CONFIG_USB_SERIAL_SAFE is not set +# CONFIG_USB_SERIAL_TI is not set +# CONFIG_USB_SERIAL_CYBERJACK is not set +# CONFIG_USB_SERIAL_XIRCOM is not set +# CONFIG_USB_SERIAL_OPTION is not set +# CONFIG_USB_SERIAL_OMNINET is not set +CONFIG_USB_EZUSB=y + +# +# USB Miscellaneous drivers +# +# CONFIG_USB_EMI62 is not set +# CONFIG_USB_EMI26 is not set +# CONFIG_USB_AUERSWALD is not set +# CONFIG_USB_RIO500 is not set +# CONFIG_USB_LEGOTOWER is not set +# CONFIG_USB_LCD is not set +# CONFIG_USB_LED is not set +# CONFIG_USB_CYTHERM is not set +# CONFIG_USB_PHIDGETKIT is not set +# CONFIG_USB_PHIDGETSERVO is not set +# CONFIG_USB_IDMOUSE is not set +# CONFIG_USB_LD is not set +# CONFIG_USB_TEST is not set + +# +# USB DSL modem support +# + +# +# USB Gadget Support +# +# CONFIG_USB_GADGET is not set + +# +# MMC/SD Card support +# +# CONFIG_MMC is not set + +# +# InfiniBand support +# +# CONFIG_INFINIBAND is not set + +# +# SN Devices +# + +# +# File systems +# +CONFIG_EXT2_FS=y +CONFIG_EXT2_FS_XATTR=y +# CONFIG_EXT2_FS_POSIX_ACL is not set +# CONFIG_EXT2_FS_SECURITY is not set +# CONFIG_EXT2_FS_XIP is not set +CONFIG_EXT3_FS=y +CONFIG_EXT3_FS_XATTR=y +# CONFIG_EXT3_FS_POSIX_ACL is not set +# CONFIG_EXT3_FS_SECURITY is not set +CONFIG_JBD=y +# CONFIG_JBD_DEBUG is not set +CONFIG_FS_MBCACHE=y +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +CONFIG_FS_POSIX_ACL=y + +# +# XFS support +# +# CONFIG_XFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set +CONFIG_INOTIFY=y +# CONFIG_QUOTA is not set +CONFIG_DNOTIFY=y +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set + +# +# CD-ROM/DVD Filesystems +# +CONFIG_ISO9660_FS=y +# CONFIG_JOLIET is not set +# CONFIG_ZISOFS is not set +CONFIG_UDF_FS=m +CONFIG_UDF_NLS=y + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=m +CONFIG_MSDOS_FS=m +CONFIG_VFAT_FS=m +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_KCORE=y +CONFIG_SYSFS=y +CONFIG_DEVPTS_FS_XATTR=y +CONFIG_DEVPTS_FS_SECURITY=y +CONFIG_TMPFS=y +CONFIG_TMPFS_XATTR=y +CONFIG_TMPFS_SECURITY=y +# CONFIG_HUGETLB_PAGE is not set +CONFIG_RAMFS=y + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +CONFIG_HFS_FS=m +CONFIG_HFSPLUS_FS=m +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +CONFIG_CRAMFS=m +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +CONFIG_NFS_FS=y +CONFIG_NFS_V3=y +CONFIG_NFS_V3_ACL=y +# CONFIG_NFS_V4 is not set +# CONFIG_NFS_DIRECTIO is not set +CONFIG_NFSD=y +CONFIG_NFSD_V2_ACL=y +CONFIG_NFSD_V3=y +CONFIG_NFSD_V3_ACL=y +# CONFIG_NFSD_V4 is not set +CONFIG_NFSD_TCP=y +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +CONFIG_EXPORTFS=y +CONFIG_NFS_ACL_SUPPORT=y +CONFIG_NFS_COMMON=y +CONFIG_SUNRPC=y +# CONFIG_RPCSEC_GSS_KRB5 is not set +# CONFIG_RPCSEC_GSS_SPKM3 is not set +CONFIG_SMB_FS=m +# CONFIG_SMB_NLS_DEFAULT is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +CONFIG_MAC_PARTITION=y +CONFIG_MSDOS_PARTITION=y +# CONFIG_BSD_DISKLABEL is not set +# CONFIG_MINIX_SUBPARTITION is not set +# CONFIG_SOLARIS_X86_PARTITION is not set +# CONFIG_UNIXWARE_DISKLABEL is not set +# CONFIG_LDM_PARTITION is not set +# CONFIG_SGI_PARTITION is not set +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_EFI_PARTITION is not set + +# +# Native Language Support +# +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="iso8859-1" +# CONFIG_NLS_CODEPAGE_437 is not set +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +# CONFIG_NLS_CODEPAGE_850 is not set +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +CONFIG_NLS_CODEPAGE_1250=m +CONFIG_NLS_CODEPAGE_1251=m +CONFIG_NLS_ASCII=m +CONFIG_NLS_ISO8859_1=m +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +CONFIG_NLS_ISO8859_15=m +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +CONFIG_NLS_UTF8=m + +# +# Library routines +# +CONFIG_CRC_CCITT=y +CONFIG_CRC32=y +# CONFIG_LIBCRC32C is not set +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y + +# +# Profiling support +# +# CONFIG_PROFILING is not set + +# +# Kernel hacking +# +# CONFIG_PRINTK_TIME is not set +CONFIG_DEBUG_KERNEL=y +CONFIG_MAGIC_SYSRQ=y +CONFIG_LOG_BUF_SHIFT=16 +# CONFIG_SCHEDSTATS is not set +# CONFIG_DEBUG_SLAB is not set +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set +# CONFIG_DEBUG_KOBJECT is not set +# CONFIG_DEBUG_INFO is not set +# CONFIG_DEBUG_FS is not set +# CONFIG_XMON is not set +# CONFIG_BDI_SWITCH is not set +CONFIG_BOOTX_TEXT=y + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Hardware crypto devices +# diff --git a/trunk/arch/ppc/configs/power3_defconfig b/trunk/arch/ppc/configs/power3_defconfig new file mode 100644 index 000000000000..a1ef929bca59 --- /dev/null +++ b/trunk/arch/ppc/configs/power3_defconfig @@ -0,0 +1,1035 @@ +# +# Automatically generated make config: don't edit +# +CONFIG_MMU=y +CONFIG_RWSEM_XCHGADD_ALGORITHM=y +CONFIG_HAVE_DEC_LOCK=y +CONFIG_PPC=y +CONFIG_PPC32=y +CONFIG_GENERIC_NVRAM=y + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +CONFIG_CLEAN_COMPILE=y +# CONFIG_STANDALONE is not set + +# +# General setup +# +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +CONFIG_POSIX_MQUEUE=y +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +# CONFIG_AUDIT is not set +CONFIG_LOG_BUF_SHIFT=15 +# CONFIG_HOTPLUG is not set +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +# CONFIG_EMBEDDED is not set +CONFIG_KALLSYMS=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set + +# +# Loadable module support +# +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +CONFIG_MODULE_FORCE_UNLOAD=y +CONFIG_OBSOLETE_MODPARM=y +# CONFIG_MODVERSIONS is not set +CONFIG_KMOD=y +CONFIG_STOP_MACHINE=y + +# +# Processor +# +# CONFIG_6xx is not set +# CONFIG_40x is not set +# CONFIG_44x is not set +CONFIG_POWER3=y +# CONFIG_POWER4 is not set +# CONFIG_8xx is not set +# CONFIG_CPU_FREQ is not set +CONFIG_PPC64BRIDGE=y +CONFIG_PPC_STD_MMU=y + +# +# Platform options +# +CONFIG_PPC_MULTIPLATFORM=y +# CONFIG_APUS is not set +# CONFIG_WILLOW is not set +# CONFIG_PCORE is not set +# CONFIG_POWERPMC250 is not set +# CONFIG_EV64260 is not set +# CONFIG_SPRUCE is not set +# CONFIG_LOPEC is not set +# CONFIG_MCPN765 is not set +# CONFIG_MVME5100 is not set +# CONFIG_PPLUS is not set +# CONFIG_PRPMC750 is not set +# CONFIG_PRPMC800 is not set +# CONFIG_SANDPOINT is not set +# CONFIG_ADIR is not set +# CONFIG_K2 is not set +# CONFIG_PAL4 is not set +# CONFIG_GEMINI is not set +# CONFIG_EST8260 is not set +# CONFIG_SBS8260 is not set +# CONFIG_RPX6 is not set +# CONFIG_TQM8260 is not set +CONFIG_PPC_CHRP=y +CONFIG_PPC_PMAC=y +CONFIG_PPC_PREP=y +CONFIG_PPC_OF=y +CONFIG_PPCBUG_NVRAM=y +CONFIG_SMP=y +# CONFIG_IRQ_ALL_CPUS is not set +CONFIG_NR_CPUS=32 +# CONFIG_PREEMPT is not set +CONFIG_HIGHMEM=y +CONFIG_KERNEL_ELF=y +CONFIG_BINFMT_ELF=y +CONFIG_BINFMT_MISC=y +CONFIG_PROC_DEVICETREE=y +CONFIG_PPC_RTAS=y +# CONFIG_PREP_RESIDUAL is not set +# CONFIG_CMDLINE_BOOL is not set + +# +# Bus options +# +CONFIG_ISA=y +CONFIG_GENERIC_ISA_DMA=y +CONFIG_PCI=y +CONFIG_PCI_DOMAINS=y +CONFIG_PCI_LEGACY_PROC=y +CONFIG_PCI_NAMES=y + +# +# Advanced setup +# +CONFIG_ADVANCED_OPTIONS=y +# CONFIG_HIGHMEM_START_BOOL is not set +CONFIG_HIGHMEM_START=0xfe000000 +# CONFIG_LOWMEM_SIZE_BOOL is not set +CONFIG_LOWMEM_SIZE=0x30000000 +# CONFIG_KERNEL_START_BOOL is not set +CONFIG_KERNEL_START=0xc0000000 +CONFIG_TASK_SIZE_BOOL=y +CONFIG_TASK_SIZE=0xc0000000 +CONFIG_BOOT_LOAD=0x00800000 + +# +# Device Drivers +# + +# +# Generic Driver Options +# + +# +# Memory Technology Devices (MTD) +# +# CONFIG_MTD is not set + +# +# Parallel port support +# +CONFIG_PARPORT=m +CONFIG_PARPORT_PC=m +CONFIG_PARPORT_PC_CML1=m +# CONFIG_PARPORT_SERIAL is not set +CONFIG_PARPORT_PC_FIFO=y +# CONFIG_PARPORT_PC_SUPERIO is not set +# CONFIG_PARPORT_OTHER is not set +# CONFIG_PARPORT_1284 is not set + +# +# Plug and Play support +# +# CONFIG_PNP is not set + +# +# Block devices +# +CONFIG_BLK_DEV_FD=y +# CONFIG_BLK_DEV_XD is not set +# CONFIG_PARIDE is not set +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_UMEM is not set +CONFIG_BLK_DEV_LOOP=y +# CONFIG_BLK_DEV_CRYPTOLOOP is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_CARMEL is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_SIZE=4096 +CONFIG_BLK_DEV_INITRD=y +CONFIG_LBD=y + +# +# ATA/ATAPI/MFM/RLL support +# +# CONFIG_IDE is not set + +# +# SCSI device support +# +CONFIG_SCSI=y +CONFIG_SCSI_PROC_FS=y + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=y +CONFIG_CHR_DEV_ST=y +# CONFIG_CHR_DEV_OSST is not set +CONFIG_BLK_DEV_SR=y +CONFIG_BLK_DEV_SR_VENDOR=y +CONFIG_CHR_DEV_SG=y + +# +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs +# +# CONFIG_SCSI_MULTI_LUN is not set +# CONFIG_SCSI_REPORT_LUNS is not set +CONFIG_SCSI_CONSTANTS=y +CONFIG_SCSI_LOGGING=y + +# +# SCSI Transport Attributes +# +CONFIG_SCSI_SPI_ATTRS=y +# CONFIG_SCSI_FC_ATTRS is not set + +# +# SCSI low-level drivers +# +# CONFIG_BLK_DEV_3W_XXXX_RAID is not set +# CONFIG_SCSI_7000FASST is not set +# CONFIG_SCSI_ACARD is not set +# CONFIG_SCSI_AHA152X is not set +# CONFIG_SCSI_AHA1542 is not set +# CONFIG_SCSI_AACRAID is not set +# CONFIG_SCSI_AIC7XXX is not set +# CONFIG_SCSI_AIC7XXX_OLD is not set +# CONFIG_SCSI_AIC79XX is not set +# CONFIG_SCSI_ADVANSYS is not set +# CONFIG_SCSI_IN2000 is not set +# CONFIG_SCSI_MEGARAID is not set +# CONFIG_SCSI_SATA is not set +# CONFIG_SCSI_BUSLOGIC is not set +# CONFIG_SCSI_CPQFCTS is not set +# CONFIG_SCSI_DMX3191D is not set +# CONFIG_SCSI_DTC3280 is not set +# CONFIG_SCSI_EATA is not set +# CONFIG_SCSI_EATA_PIO is not set +# CONFIG_SCSI_FUTURE_DOMAIN is not set +# CONFIG_SCSI_GDTH is not set +# CONFIG_SCSI_GENERIC_NCR5380 is not set +# CONFIG_SCSI_GENERIC_NCR5380_MMIO is not set +# CONFIG_SCSI_IPS is not set +# CONFIG_SCSI_INIA100 is not set +# CONFIG_SCSI_PPA is not set +# CONFIG_SCSI_IMM is not set +# CONFIG_SCSI_NCR53C406A is not set +CONFIG_SCSI_SYM53C8XX_2=y +CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=1 +CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16 +CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64 +# CONFIG_SCSI_SYM53C8XX_IOMAPPED is not set +# CONFIG_SCSI_IPR is not set +# CONFIG_SCSI_PAS16 is not set +# CONFIG_SCSI_PSI240I is not set +# CONFIG_SCSI_QLOGIC_FAS is not set +# CONFIG_SCSI_QLOGIC_ISP is not set +# CONFIG_SCSI_QLOGIC_FC is not set +# CONFIG_SCSI_QLOGIC_1280 is not set +CONFIG_SCSI_QLA2XXX=y +# CONFIG_SCSI_QLA21XX is not set +# CONFIG_SCSI_QLA22XX is not set +# CONFIG_SCSI_QLA2300 is not set +# CONFIG_SCSI_QLA2322 is not set +# CONFIG_SCSI_QLA6312 is not set +# CONFIG_SCSI_QLA6322 is not set +# CONFIG_SCSI_SYM53C416 is not set +# CONFIG_SCSI_DC395x is not set +# CONFIG_SCSI_DC390T is not set +# CONFIG_SCSI_T128 is not set +# CONFIG_SCSI_U14_34F is not set +# CONFIG_SCSI_NSP32 is not set +# CONFIG_SCSI_DEBUG is not set +# CONFIG_SCSI_MESH is not set +# CONFIG_SCSI_MAC53C94 is not set + +# +# Old CD-ROM drivers (not SCSI, not IDE) +# +# CONFIG_CD_NO_IDESCSI is not set + +# +# Multi-device support (RAID and LVM) +# +CONFIG_MD=y +CONFIG_BLK_DEV_MD=y +CONFIG_MD_LINEAR=y +CONFIG_MD_RAID0=y +CONFIG_MD_RAID1=y +CONFIG_MD_RAID5=y +CONFIG_MD_RAID6=y +# CONFIG_MD_MULTIPATH is not set +CONFIG_BLK_DEV_DM=y +CONFIG_DM_CRYPT=y + +# +# Fusion MPT device support +# +# CONFIG_FUSION is not set + +# +# IEEE 1394 (FireWire) support +# +# CONFIG_IEEE1394 is not set + +# +# I2O device support +# +# CONFIG_I2O is not set + +# +# Macintosh device drivers +# +# CONFIG_ADB is not set +# CONFIG_ADB_CUDA is not set +# CONFIG_ADB_PMU is not set +# CONFIG_MAC_FLOPPY is not set +# CONFIG_MAC_SERIAL is not set + +# +# Networking support +# +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +# CONFIG_NETLINK_DEV is not set +CONFIG_UNIX=y +# CONFIG_NET_KEY is not set +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +# CONFIG_IP_ADVANCED_ROUTER is not set +# CONFIG_IP_PNP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_IP_MROUTE is not set +# CONFIG_ARPD is not set +CONFIG_SYN_COOKIES=y +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_IPV6 is not set +# CONFIG_NETFILTER is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_SCTP is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_HW_FLOWCONTROL is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +CONFIG_MII=y +# CONFIG_MACE is not set +# CONFIG_BMAC is not set +# CONFIG_OAKNET is not set +# CONFIG_HAPPYMEAL is not set +# CONFIG_SUNGEM is not set +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_LANCE is not set +# CONFIG_NET_VENDOR_SMC is not set +# CONFIG_NET_VENDOR_RACAL is not set + +# +# Tulip family network device support +# +# CONFIG_NET_TULIP is not set +# CONFIG_AT1700 is not set +# CONFIG_DEPCA is not set +# CONFIG_HP100 is not set +# CONFIG_NET_ISA is not set +CONFIG_NET_PCI=y +CONFIG_PCNET32=y +# CONFIG_AMD8111_ETH is not set +# CONFIG_ADAPTEC_STARFIRE is not set +# CONFIG_AC3200 is not set +# CONFIG_APRICOT is not set +# CONFIG_B44 is not set +# CONFIG_FORCEDETH is not set +# CONFIG_CS89x0 is not set +# CONFIG_DGRS is not set +# CONFIG_EEPRO100 is not set +CONFIG_E100=y +# CONFIG_E100_NAPI is not set +# CONFIG_FEALNX is not set +# CONFIG_NATSEMI is not set +# CONFIG_NE2K_PCI is not set +# CONFIG_8139CP is not set +# CONFIG_8139TOO is not set +# CONFIG_SIS900 is not set +# CONFIG_EPIC100 is not set +# CONFIG_SUNDANCE is not set +# CONFIG_TLAN is not set +# CONFIG_VIA_RHINE is not set +# CONFIG_NET_POCKET is not set + +# +# Ethernet (1000 Mbit) +# +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +CONFIG_E1000=y +# CONFIG_E1000_NAPI is not set +# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set +# CONFIG_SK98LIN is not set +# CONFIG_TIGON3 is not set + +# +# Ethernet (10000 Mbit) +# +# CONFIG_IXGB is not set +# CONFIG_S2IO is not set + +# +# Token Ring devices +# +# CONFIG_TR is not set + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PLIP is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_NET_FC is not set +# CONFIG_RCPCI is not set +# CONFIG_SHAPER is not set +# CONFIG_NETCONSOLE is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Telephony Support +# +# CONFIG_PHONE is not set + +# +# Input device support +# +CONFIG_INPUT=y + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=y +CONFIG_INPUT_MOUSEDEV_PSAUX=y +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set +CONFIG_INPUT_EVDEV=y +# CONFIG_INPUT_EVBUG is not set + +# +# Input I/O drivers +# +CONFIG_GAMEPORT=m +CONFIG_SOUND_GAMEPORT=m +# CONFIG_GAMEPORT_NS558 is not set +# CONFIG_GAMEPORT_L4 is not set +# CONFIG_GAMEPORT_EMU10K1 is not set +# CONFIG_GAMEPORT_VORTEX is not set +# CONFIG_GAMEPORT_FM801 is not set +# CONFIG_GAMEPORT_CS461x is not set +CONFIG_SERIO=y +CONFIG_SERIO_I8042=y +CONFIG_SERIO_SERPORT=y +# CONFIG_SERIO_CT82C710 is not set +# CONFIG_SERIO_PARKBD is not set +# CONFIG_SERIO_PCIPS2 is not set + +# +# Input Device Drivers +# +CONFIG_INPUT_KEYBOARD=y +CONFIG_KEYBOARD_ATKBD=y +# CONFIG_KEYBOARD_SUNKBD is not set +# CONFIG_KEYBOARD_LKKBD is not set +# CONFIG_KEYBOARD_XTKBD is not set +# CONFIG_KEYBOARD_NEWTON is not set +CONFIG_INPUT_MOUSE=y +CONFIG_MOUSE_PS2=y +# CONFIG_MOUSE_SERIAL is not set +# CONFIG_MOUSE_INPORT is not set +# CONFIG_MOUSE_LOGIBM is not set +# CONFIG_MOUSE_PC110PAD is not set +# CONFIG_MOUSE_VSXXXAA is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +CONFIG_INPUT_MISC=y +CONFIG_INPUT_UINPUT=y + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_NR_UARTS=4 +# CONFIG_SERIAL_8250_EXTENDED is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +# CONFIG_SERIAL_PMACZILOG is not set +CONFIG_UNIX98_PTYS=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 +CONFIG_PRINTER=m +# CONFIG_LP_CONSOLE is not set +# CONFIG_PPDEV is not set +# CONFIG_TIPAR is not set +# CONFIG_QIC02_TAPE is not set + +# +# IPMI +# +# CONFIG_IPMI_HANDLER is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +CONFIG_NVRAM=y +CONFIG_GEN_RTC=y +# CONFIG_GEN_RTC_X is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_AGP is not set +# CONFIG_DRM is not set +# CONFIG_RAW_DRIVER is not set + +# +# I2C support +# +CONFIG_I2C=y +CONFIG_I2C_CHARDEV=y + +# +# I2C Algorithms +# +CONFIG_I2C_ALGOBIT=y +CONFIG_I2C_ALGOPCF=y + +# +# I2C Hardware Bus support +# +# CONFIG_I2C_ALI1535 is not set +# CONFIG_I2C_ALI1563 is not set +# CONFIG_I2C_ALI15X3 is not set +# CONFIG_I2C_AMD756 is not set +# CONFIG_I2C_AMD8111 is not set +# CONFIG_I2C_HYDRA is not set +# CONFIG_I2C_I801 is not set +# CONFIG_I2C_I810 is not set +# CONFIG_I2C_ISA is not set +# CONFIG_I2C_KEYWEST is not set +# CONFIG_I2C_NFORCE2 is not set +# CONFIG_I2C_PARPORT is not set +# CONFIG_I2C_PARPORT_LIGHT is not set +# CONFIG_I2C_PIIX4 is not set +# CONFIG_I2C_PROSAVAGE is not set +# CONFIG_I2C_SAVAGE4 is not set +# CONFIG_SCx200_ACB is not set +# CONFIG_I2C_SIS5595 is not set +# CONFIG_I2C_SIS630 is not set +# CONFIG_I2C_SIS96X is not set +# CONFIG_I2C_VIA is not set +# CONFIG_I2C_VIAPRO is not set +# CONFIG_I2C_VOODOO3 is not set + +# +# Hardware Sensors Chip support +# +# CONFIG_I2C_SENSOR is not set +# CONFIG_SENSORS_ADM1021 is not set +# CONFIG_SENSORS_ASB100 is not set +# CONFIG_SENSORS_DS1621 is not set +# CONFIG_SENSORS_FSCHER is not set +# CONFIG_SENSORS_GL518SM is not set +# CONFIG_SENSORS_IT87 is not set +# CONFIG_SENSORS_LM75 is not set +# CONFIG_SENSORS_LM78 is not set +# CONFIG_SENSORS_LM80 is not set +# CONFIG_SENSORS_LM83 is not set +# CONFIG_SENSORS_LM85 is not set +# CONFIG_SENSORS_LM90 is not set +# CONFIG_SENSORS_VIA686A is not set +# CONFIG_SENSORS_W83781D is not set +# CONFIG_SENSORS_W83L785TS is not set +# CONFIG_SENSORS_W83627HF is not set + +# +# Other I2C Chip support +# +# CONFIG_SENSORS_EEPROM is not set +# CONFIG_SENSORS_PCF8574 is not set +# CONFIG_SENSORS_PCF8591 is not set +# CONFIG_I2C_DEBUG_CORE is not set +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set +# CONFIG_I2C_DEBUG_CHIP is not set + +# +# Misc devices +# + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set + +# +# Graphics support +# +CONFIG_FB=y +# CONFIG_FB_PM2 is not set +# CONFIG_FB_CYBER2000 is not set +CONFIG_FB_OF=y +# CONFIG_FB_CONTROL is not set +# CONFIG_FB_PLATINUM is not set +# CONFIG_FB_VALKYRIE is not set +# CONFIG_FB_CT65550 is not set +# CONFIG_FB_IMSTT is not set +# CONFIG_FB_S3TRIO is not set +# CONFIG_FB_VGA16 is not set +# CONFIG_FB_RIVA is not set +CONFIG_FB_MATROX=y +CONFIG_FB_MATROX_MILLENIUM=y +CONFIG_FB_MATROX_MYSTIQUE=y +# CONFIG_FB_MATROX_G450 is not set +CONFIG_FB_MATROX_G100A=y +CONFIG_FB_MATROX_G100=y +CONFIG_FB_MATROX_I2C=y +# CONFIG_FB_MATROX_MAVEN is not set +CONFIG_FB_MATROX_MULTIHEAD=y +# CONFIG_FB_RADEON_OLD is not set +# CONFIG_FB_RADEON is not set +# CONFIG_FB_ATY128 is not set +# CONFIG_FB_ATY is not set +# CONFIG_FB_SIS is not set +# CONFIG_FB_NEOMAGIC is not set +# CONFIG_FB_KYRO is not set +# CONFIG_FB_3DFX is not set +# CONFIG_FB_VOODOO1 is not set +# CONFIG_FB_TRIDENT is not set +# CONFIG_FB_VIRTUAL is not set + +# +# Console display driver support +# +# CONFIG_VGA_CONSOLE is not set +# CONFIG_MDA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE=y +CONFIG_PCI_CONSOLE=y +# CONFIG_FONTS is not set +CONFIG_FONT_8x8=y +CONFIG_FONT_8x16=y + +# +# Logo configuration +# +CONFIG_LOGO=y +CONFIG_LOGO_LINUX_MONO=y +CONFIG_LOGO_LINUX_VGA16=y +CONFIG_LOGO_LINUX_CLUT224=y + +# +# Sound +# +CONFIG_SOUND=y +# CONFIG_DMASOUND_PMAC is not set + +# +# Advanced Linux Sound Architecture +# +CONFIG_SND=m +CONFIG_SND_TIMER=m +CONFIG_SND_PCM=m +CONFIG_SND_HWDEP=m +CONFIG_SND_RAWMIDI=m +CONFIG_SND_SEQUENCER=m +CONFIG_SND_SEQ_DUMMY=m +CONFIG_SND_OSSEMUL=y +CONFIG_SND_MIXER_OSS=m +CONFIG_SND_PCM_OSS=m +CONFIG_SND_SEQUENCER_OSS=y +# CONFIG_SND_VERBOSE_PRINTK is not set +# CONFIG_SND_DEBUG is not set + +# +# Generic devices +# +CONFIG_SND_MPU401_UART=m +CONFIG_SND_OPL3_LIB=m +CONFIG_SND_DUMMY=m +# CONFIG_SND_VIRMIDI is not set +# CONFIG_SND_MTPAV is not set +# CONFIG_SND_SERIAL_U16550 is not set +# CONFIG_SND_MPU401 is not set + +# +# ISA devices +# +# CONFIG_SND_AD1848 is not set +# CONFIG_SND_CS4231 is not set +CONFIG_SND_CS4232=m +# CONFIG_SND_CS4236 is not set +# CONFIG_SND_ES1688 is not set +# CONFIG_SND_ES18XX is not set +# CONFIG_SND_GUSCLASSIC is not set +# CONFIG_SND_GUSEXTREME is not set +# CONFIG_SND_GUSMAX is not set +# CONFIG_SND_INTERWAVE is not set +# CONFIG_SND_INTERWAVE_STB is not set +# CONFIG_SND_OPTI92X_AD1848 is not set +# CONFIG_SND_OPTI92X_CS4231 is not set +# CONFIG_SND_OPTI93X is not set +# CONFIG_SND_SB8 is not set +# CONFIG_SND_SB16 is not set +# CONFIG_SND_SBAWE is not set +# CONFIG_SND_WAVEFRONT is not set +# CONFIG_SND_CMI8330 is not set +# CONFIG_SND_OPL3SA2 is not set +# CONFIG_SND_SGALAXY is not set +# CONFIG_SND_SSCAPE is not set + +# +# PCI devices +# +CONFIG_SND_AC97_CODEC=m +# CONFIG_SND_ALI5451 is not set +# CONFIG_SND_ATIIXP is not set +# CONFIG_SND_AU8810 is not set +# CONFIG_SND_AU8820 is not set +# CONFIG_SND_AU8830 is not set +# CONFIG_SND_AZT3328 is not set +# CONFIG_SND_BT87X is not set +CONFIG_SND_CS46XX=m +# CONFIG_SND_CS46XX_NEW_DSP is not set +CONFIG_SND_CS4281=m +# CONFIG_SND_EMU10K1 is not set +# CONFIG_SND_KORG1212 is not set +# CONFIG_SND_MIXART is not set +# CONFIG_SND_NM256 is not set +# CONFIG_SND_RME32 is not set +# CONFIG_SND_RME96 is not set +# CONFIG_SND_RME9652 is not set +# CONFIG_SND_HDSP is not set +# CONFIG_SND_TRIDENT is not set +# CONFIG_SND_YMFPCI is not set +# CONFIG_SND_ALS4000 is not set +# CONFIG_SND_CMIPCI is not set +# CONFIG_SND_ENS1370 is not set +# CONFIG_SND_ENS1371 is not set +# CONFIG_SND_ES1938 is not set +# CONFIG_SND_ES1968 is not set +# CONFIG_SND_MAESTRO3 is not set +# CONFIG_SND_FM801 is not set +# CONFIG_SND_ICE1712 is not set +# CONFIG_SND_ICE1724 is not set +# CONFIG_SND_INTEL8X0 is not set +# CONFIG_SND_INTEL8X0M is not set +# CONFIG_SND_SONICVIBES is not set +# CONFIG_SND_VIA82XX is not set +# CONFIG_SND_VX222 is not set + +# +# ALSA PowerMac devices +# +# CONFIG_SND_POWERMAC is not set + +# +# Open Sound System +# +# CONFIG_SOUND_PRIME is not set + +# +# USB support +# +# CONFIG_USB is not set + +# +# USB Gadget Support +# +# CONFIG_USB_GADGET is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT3_FS is not set +# CONFIG_JBD is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +# CONFIG_XFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_QUOTA is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set + +# +# CD-ROM/DVD Filesystems +# +CONFIG_ISO9660_FS=y +CONFIG_JOLIET=y +# CONFIG_ZISOFS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=y +CONFIG_MSDOS_FS=y +CONFIG_VFAT_FS=y +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_KCORE=y +CONFIG_SYSFS=y +# CONFIG_DEVFS_FS is not set +# CONFIG_DEVPTS_FS_XATTR is not set +CONFIG_TMPFS=y +# CONFIG_HUGETLB_PAGE is not set +CONFIG_RAMFS=y + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_CRAMFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +CONFIG_NFS_FS=y +# CONFIG_NFS_V3 is not set +# CONFIG_NFS_V4 is not set +# CONFIG_NFS_DIRECTIO is not set +CONFIG_NFSD=y +# CONFIG_NFSD_V3 is not set +# CONFIG_NFSD_TCP is not set +CONFIG_LOCKD=y +CONFIG_EXPORTFS=y +CONFIG_SUNRPC=y +# CONFIG_RPCSEC_GSS_KRB5 is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y + +# +# Native Language Support +# +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="iso8859-1" +CONFIG_NLS_CODEPAGE_437=y +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +# CONFIG_NLS_CODEPAGE_850 is not set +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +CONFIG_NLS_ISO8859_1=y +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_15 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +# CONFIG_NLS_UTF8 is not set + +# +# Library routines +# +CONFIG_CRC32=y +# CONFIG_LIBCRC32C is not set +CONFIG_ZLIB_INFLATE=m +CONFIG_ZLIB_DEFLATE=m + +# +# Kernel hacking +# +# CONFIG_DEBUG_KERNEL is not set +CONFIG_BOOTX_TEXT=y + +# +# Security options +# +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +CONFIG_CRYPTO=y +CONFIG_CRYPTO_HMAC=y +CONFIG_CRYPTO_NULL=y +CONFIG_CRYPTO_MD4=m +CONFIG_CRYPTO_MD5=m +CONFIG_CRYPTO_SHA1=m +CONFIG_CRYPTO_SHA256=m +CONFIG_CRYPTO_SHA512=m +CONFIG_CRYPTO_DES=m +CONFIG_CRYPTO_BLOWFISH=m +CONFIG_CRYPTO_TWOFISH=m +# CONFIG_CRYPTO_SERPENT is not set +CONFIG_CRYPTO_AES=m +CONFIG_CRYPTO_CAST5=m +CONFIG_CRYPTO_CAST6=m +CONFIG_CRYPTO_ARC4=m +CONFIG_CRYPTO_DEFLATE=m +CONFIG_CRYPTO_MICHAEL_MIC=m +# CONFIG_CRYPTO_CRC32C is not set +# CONFIG_CRYPTO_TEST is not set diff --git a/trunk/arch/ppc/kernel/Makefile b/trunk/arch/ppc/kernel/Makefile index 466437f4bcbb..e399bbb969a4 100644 --- a/trunk/arch/ppc/kernel/Makefile +++ b/trunk/arch/ppc/kernel/Makefile @@ -1,24 +1,48 @@ # # Makefile for the linux kernel. # +ifneq ($(CONFIG_PPC_MERGE),y) + extra-$(CONFIG_PPC_STD_MMU) := head.o extra-$(CONFIG_40x) := head_4xx.o extra-$(CONFIG_44x) := head_44x.o extra-$(CONFIG_FSL_BOOKE) := head_fsl_booke.o extra-$(CONFIG_8xx) := head_8xx.o +extra-$(CONFIG_6xx) += idle_6xx.o extra-y += vmlinux.lds -obj-y := entry.o traps.o time.o misc.o \ +obj-y := entry.o traps.o idle.o time.o misc.o \ setup.o \ ppc_htab.o -obj-$(CONFIG_MODULES) += ppc_ksyms.o +obj-$(CONFIG_6xx) += l2cr.o cpu_setup_6xx.o +obj-$(CONFIG_SOFTWARE_SUSPEND) += swsusp.o +obj-$(CONFIG_MODULES) += module.o ppc_ksyms.o obj-$(CONFIG_NOT_COHERENT_CACHE) += dma-mapping.o obj-$(CONFIG_PCI) += pci.o obj-$(CONFIG_RAPIDIO) += rio.o obj-$(CONFIG_KGDB) += ppc-stub.o obj-$(CONFIG_SMP) += smp.o smp-tbsync.o +obj-$(CONFIG_TAU) += temp.o +ifndef CONFIG_E200 +obj-$(CONFIG_FSL_BOOKE) += perfmon_fsl_booke.o +endif obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o ifndef CONFIG_MATH_EMULATION obj-$(CONFIG_8xx) += softemu8xx.o endif + +# These are here while we do the architecture merge + +else +obj-y := idle.o +obj-$(CONFIG_6xx) += l2cr.o cpu_setup_6xx.o +obj-$(CONFIG_SOFTWARE_SUSPEND) += swsusp.o +obj-$(CONFIG_MODULES) += module.o +obj-$(CONFIG_NOT_COHERENT_CACHE) += dma-mapping.o +obj-$(CONFIG_KGDB) += ppc-stub.o +obj-$(CONFIG_TAU) += temp.o +ifndef CONFIG_E200 +obj-$(CONFIG_FSL_BOOKE) += perfmon_fsl_booke.o +endif +endif diff --git a/trunk/arch/powerpc/kernel/cpu_setup_6xx.S b/trunk/arch/ppc/kernel/cpu_setup_6xx.S similarity index 100% rename from trunk/arch/powerpc/kernel/cpu_setup_6xx.S rename to trunk/arch/ppc/kernel/cpu_setup_6xx.S diff --git a/trunk/arch/ppc/kernel/entry.S b/trunk/arch/ppc/kernel/entry.S index 5891ecbdc703..3a2815978488 100644 --- a/trunk/arch/ppc/kernel/entry.S +++ b/trunk/arch/ppc/kernel/entry.S @@ -135,10 +135,10 @@ transfer_to_handler: mfspr r11,SPRN_HID0 mtcr r11 BEGIN_FTR_SECTION - bt- 8,4f /* Check DOZE */ + bt- 8,power_save_6xx_restore /* Check DOZE */ END_FTR_SECTION_IFSET(CPU_FTR_CAN_DOZE) BEGIN_FTR_SECTION - bt- 9,4f /* Check NAP */ + bt- 9,power_save_6xx_restore /* Check NAP */ END_FTR_SECTION_IFSET(CPU_FTR_CAN_NAP) #endif /* CONFIG_6xx */ .globl transfer_to_handler_cont @@ -157,10 +157,6 @@ transfer_to_handler_cont: SYNC RFI /* jump to handler, enable MMU */ -#ifdef CONFIG_6xx -4: b power_save_6xx_restore -#endif - /* * On kernel stack overflow, load up an initial stack pointer * and call StackOverflow(regs), which should not return. @@ -930,3 +926,55 @@ END_FTR_SECTION_IFSET(CPU_FTR_601) b 4b .comm ee_restarts,4 + +/* + * PROM code for specific machines follows. Put it + * here so it's easy to add arch-specific sections later. + * -- Cort + */ +#ifdef CONFIG_PPC_OF +/* + * On CHRP, the Run-Time Abstraction Services (RTAS) have to be + * called with the MMU off. + */ +_GLOBAL(enter_rtas) + stwu r1,-INT_FRAME_SIZE(r1) + mflr r0 + stw r0,INT_FRAME_SIZE+4(r1) + lis r4,rtas_data@ha + lwz r4,rtas_data@l(r4) + lis r6,1f@ha /* physical return address for rtas */ + addi r6,r6,1f@l + tophys(r6,r6) + tophys(r7,r1) + lis r8,rtas_entry@ha + lwz r8,rtas_entry@l(r8) + mfmsr r9 + stw r9,8(r1) + LOAD_MSR_KERNEL(r0,MSR_KERNEL) + SYNC /* disable interrupts so SRR0/1 */ + MTMSRD(r0) /* don't get trashed */ + li r9,MSR_KERNEL & ~(MSR_IR|MSR_DR) + mtlr r6 + CLR_TOP32(r7) + mtspr SPRN_SPRG2,r7 + mtspr SPRN_SRR0,r8 + mtspr SPRN_SRR1,r9 + RFI +1: tophys(r9,r1) + lwz r8,INT_FRAME_SIZE+4(r9) /* get return address */ + lwz r9,8(r9) /* original msr value */ + FIX_SRR1(r9,r0) + addi r1,r1,INT_FRAME_SIZE + li r0,0 + mtspr SPRN_SPRG2,r0 + mtspr SPRN_SRR0,r8 + mtspr SPRN_SRR1,r9 + RFI /* return to caller */ + + .globl machine_check_in_rtas +machine_check_in_rtas: + twi 31,0,0 + /* XXX load up BATs and panic */ + +#endif /* CONFIG_PPC_OF */ diff --git a/trunk/arch/ppc/kernel/head.S b/trunk/arch/ppc/kernel/head.S index 01303efeddad..53ea845fb911 100644 --- a/trunk/arch/ppc/kernel/head.S +++ b/trunk/arch/ppc/kernel/head.S @@ -37,6 +37,19 @@ #include #endif +#ifdef CONFIG_PPC64BRIDGE +#define LOAD_BAT(n, reg, RA, RB) \ + ld RA,(n*32)+0(reg); \ + ld RB,(n*32)+8(reg); \ + mtspr SPRN_IBAT##n##U,RA; \ + mtspr SPRN_IBAT##n##L,RB; \ + ld RA,(n*32)+16(reg); \ + ld RB,(n*32)+24(reg); \ + mtspr SPRN_DBAT##n##U,RA; \ + mtspr SPRN_DBAT##n##L,RB; \ + +#else /* CONFIG_PPC64BRIDGE */ + /* 601 only have IBAT; cr0.eq is set on 601 when using this macro */ #define LOAD_BAT(n, reg, RA, RB) \ /* see the comment for clear_bats() -- Cort */ \ @@ -53,6 +66,7 @@ mtspr SPRN_DBAT##n##U,RA; \ mtspr SPRN_DBAT##n##L,RB; \ 1: +#endif /* CONFIG_PPC64BRIDGE */ .text .stabs "arch/ppc/kernel/",N_SO,0,0,0f @@ -115,6 +129,11 @@ _start: .globl __start __start: +/* + * We have to do any OF calls before we map ourselves to KERNELBASE, + * because OF may have I/O devices mapped into that area + * (particularly on CHRP). + */ mr r31,r3 /* save parameters */ mr r30,r4 mr r29,r5 @@ -129,6 +148,14 @@ __start: */ bl early_init +/* + * On POWER4, we first need to tweak some CPU configuration registers + * like real mode cache inhibit or exception base + */ +#ifdef CONFIG_POWER4 + bl __970_cpu_preinit +#endif /* CONFIG_POWER4 */ + #ifdef CONFIG_APUS /* On APUS the __va/__pa constants need to be set to the correct * values before continuing. @@ -142,6 +169,7 @@ __start: */ bl mmu_off __after_mmu_off: +#ifndef CONFIG_POWER4 bl clear_bats bl flush_tlbs @@ -149,6 +177,10 @@ __after_mmu_off: #if !defined(CONFIG_APUS) && defined(CONFIG_BOOTX_TEXT) bl setup_disp_bat #endif +#else /* CONFIG_POWER4 */ + bl reloc_offset + bl initial_mm_power4 +#endif /* CONFIG_POWER4 */ /* * Call setup_cpu for CPU 0 and initialize 6xx Idle @@ -160,11 +192,18 @@ __after_mmu_off: bl reloc_offset bl init_idle_6xx #endif /* CONFIG_6xx */ +#ifdef CONFIG_POWER4 + bl reloc_offset + bl init_idle_power4 +#endif /* CONFIG_POWER4 */ #ifndef CONFIG_APUS /* * We need to run with _start at physical address 0. + * On CHRP, we are loaded at 0x10000 since OF on CHRP uses + * the exception vectors at 0 (and therefore this copy + * overwrites OF's exception vectors with our own). * If the MMU is already turned on, we copy stuff to KERNELBASE, * otherwise we copy it to 0. */ @@ -319,19 +358,51 @@ i##n: \ #endif /* Machine check */ +/* + * On CHRP, this is complicated by the fact that we could get a + * machine check inside RTAS, and we have no guarantee that certain + * critical registers will have the values we expect. The set of + * registers that might have bad values includes all the GPRs + * and all the BATs. We indicate that we are in RTAS by putting + * a non-zero value, the address of the exception frame to use, + * in SPRG2. The machine check handler checks SPRG2 and uses its + * value if it is non-zero. If we ever needed to free up SPRG2, + * we could use a field in the thread_info or thread_struct instead. + * (Other exception handlers assume that r1 is a valid kernel stack + * pointer when we take an exception from supervisor mode.) + * -- paulus. + */ . = 0x200 mtspr SPRN_SPRG0,r10 mtspr SPRN_SPRG1,r11 mfcr r10 +#ifdef CONFIG_PPC_CHRP + mfspr r11,SPRN_SPRG2 + cmpwi 0,r11,0 + bne 7f +#endif /* CONFIG_PPC_CHRP */ EXCEPTION_PROLOG_1 7: EXCEPTION_PROLOG_2 addi r3,r1,STACK_FRAME_OVERHEAD +#ifdef CONFIG_PPC_CHRP + mfspr r4,SPRN_SPRG2 + cmpwi cr1,r4,0 + bne cr1,1f +#endif EXC_XFER_STD(0x200, machine_check_exception) +#ifdef CONFIG_PPC_CHRP +1: b machine_check_in_rtas +#endif /* Data access exception. */ . = 0x300 +#ifdef CONFIG_PPC64BRIDGE + b DataAccess +DataAccessCont: +#else DataAccess: EXCEPTION_PROLOG +#endif /* CONFIG_PPC64BRIDGE */ mfspr r10,SPRN_DSISR andis. r0,r10,0xa470 /* weird error? */ bne 1f /* if not, try to put a PTE */ @@ -343,10 +414,21 @@ DataAccess: mfspr r4,SPRN_DAR EXC_XFER_EE_LITE(0x300, handle_page_fault) +#ifdef CONFIG_PPC64BRIDGE +/* SLB fault on data access. */ + . = 0x380 + b DataSegment +#endif /* CONFIG_PPC64BRIDGE */ + /* Instruction access exception. */ . = 0x400 +#ifdef CONFIG_PPC64BRIDGE + b InstructionAccess +InstructionAccessCont: +#else InstructionAccess: EXCEPTION_PROLOG +#endif /* CONFIG_PPC64BRIDGE */ andis. r0,r9,0x4000 /* no pte found? */ beq 1f /* if so, try to put a PTE */ li r3,0 /* into the hash table */ @@ -356,6 +438,12 @@ InstructionAccess: mr r5,r9 EXC_XFER_EE_LITE(0x400, handle_page_fault) +#ifdef CONFIG_PPC64BRIDGE +/* SLB fault on instruction access. */ + . = 0x480 + b InstructionSegment +#endif /* CONFIG_PPC64BRIDGE */ + /* External interrupt */ EXCEPTION(0x500, HardwareInterrupt, do_IRQ, EXC_XFER_LITE) @@ -620,9 +708,15 @@ DataStoreTLBMiss: EXCEPTION(0x1300, Trap_13, instruction_breakpoint_exception, EXC_XFER_EE) EXCEPTION(0x1400, SMI, SMIException, EXC_XFER_EE) EXCEPTION(0x1500, Trap_15, unknown_exception, EXC_XFER_EE) +#ifdef CONFIG_POWER4 + EXCEPTION(0x1600, Trap_16, unknown_exception, EXC_XFER_EE) + EXCEPTION(0x1700, Trap_17, altivec_assist_exception, EXC_XFER_EE) + EXCEPTION(0x1800, Trap_18, TAUException, EXC_XFER_STD) +#else /* !CONFIG_POWER4 */ EXCEPTION(0x1600, Trap_16, altivec_assist_exception, EXC_XFER_EE) EXCEPTION(0x1700, Trap_17, TAUException, EXC_XFER_STD) EXCEPTION(0x1800, Trap_18, unknown_exception, EXC_XFER_EE) +#endif /* CONFIG_POWER4 */ EXCEPTION(0x1900, Trap_19, unknown_exception, EXC_XFER_EE) EXCEPTION(0x1a00, Trap_1a, unknown_exception, EXC_XFER_EE) EXCEPTION(0x1b00, Trap_1b, unknown_exception, EXC_XFER_EE) @@ -660,6 +754,28 @@ AltiVecUnavailable: addi r3,r1,STACK_FRAME_OVERHEAD EXC_XFER_EE_LITE(0xf20, altivec_unavailable_exception) +#ifdef CONFIG_PPC64BRIDGE +DataAccess: + EXCEPTION_PROLOG + b DataAccessCont + +InstructionAccess: + EXCEPTION_PROLOG + b InstructionAccessCont + +DataSegment: + EXCEPTION_PROLOG + addi r3,r1,STACK_FRAME_OVERHEAD + mfspr r4,SPRN_DAR + stw r4,_DAR(r11) + EXC_XFER_STD(0x380, unknown_exception) + +InstructionSegment: + EXCEPTION_PROLOG + addi r3,r1,STACK_FRAME_OVERHEAD + EXC_XFER_STD(0x480, unknown_exception) +#endif /* CONFIG_PPC64BRIDGE */ + #ifdef CONFIG_ALTIVEC /* Note that the AltiVec support is closely modeled after the FP * support. Changes to one are likely to be applicable to the @@ -932,6 +1048,13 @@ __secondary_start_pmac_0: .globl __secondary_start __secondary_start: +#ifdef CONFIG_PPC64BRIDGE + mfmsr r0 + clrldi r0,r0,1 /* make sure it's in 32-bit mode */ + SYNC + MTMSRD(r0) + isync +#endif /* Copy some CPU settings from CPU 0 */ bl __restore_cpu_setup @@ -942,6 +1065,10 @@ __secondary_start: lis r3,-KERNELBASE@h bl init_idle_6xx #endif /* CONFIG_6xx */ +#ifdef CONFIG_POWER4 + lis r3,-KERNELBASE@h + bl init_idle_power4 +#endif /* CONFIG_POWER4 */ /* get current_thread_info and current */ lis r1,secondary_ti@ha @@ -982,12 +1109,12 @@ __secondary_start: * Those generic dummy functions are kept for CPUs not * included in CONFIG_6xx */ -#if !defined(CONFIG_6xx) +#if !defined(CONFIG_6xx) && !defined(CONFIG_POWER4) _GLOBAL(__save_cpu_setup) blr _GLOBAL(__restore_cpu_setup) blr -#endif /* !defined(CONFIG_6xx) */ +#endif /* !defined(CONFIG_6xx) && !defined(CONFIG_POWER4) */ /* @@ -1005,6 +1132,11 @@ load_up_mmu: tophys(r6,r6) lwz r6,_SDR1@l(r6) mtspr SPRN_SDR1,r6 +#ifdef CONFIG_PPC64BRIDGE + /* clear the ASR so we only use the pseudo-segment registers. */ + li r6,0 + mtasr r6 +#endif /* CONFIG_PPC64BRIDGE */ li r0,16 /* load up segment register values */ mtctr r0 /* for context 0 */ lis r3,0x2000 /* Ku = 1, VSID = 0 */ @@ -1013,7 +1145,7 @@ load_up_mmu: addi r3,r3,0x111 /* increment VSID */ addis r4,r4,0x1000 /* address of next segment */ bdnz 3b - +#ifndef CONFIG_POWER4 /* Load the BAT registers with the values set up by MMU_init. MMU_init takes care of whether we're on a 601 or not. */ mfpvr r3 @@ -1026,7 +1158,7 @@ load_up_mmu: LOAD_BAT(1,r3,r4,r5) LOAD_BAT(2,r3,r4,r5) LOAD_BAT(3,r3,r4,r5) - +#endif /* CONFIG_POWER4 */ blr /* @@ -1137,6 +1269,9 @@ _GLOBAL(set_context) li r4,0 isync 3: +#ifdef CONFIG_PPC64BRIDGE + slbie r4 +#endif /* CONFIG_PPC64BRIDGE */ mtsrin r3,r4 addi r3,r3,0x111 /* next VSID */ rlwinm r3,r3,0,8,3 /* clear out any overflow from VSID field */ @@ -1223,6 +1358,7 @@ mmu_off: sync RFI +#ifndef CONFIG_POWER4 /* * Use the first pair of BAT registers to map the 1st 16MB * of RAM to KERNELBASE. From this point on we can't safely @@ -1230,6 +1366,7 @@ mmu_off: */ initial_bats: lis r11,KERNELBASE@h +#ifndef CONFIG_PPC64BRIDGE mfspr r9,SPRN_PVR rlwinm r9,r9,16,16,31 /* r9 = 1 for 601, 4 for 604 */ cmpwi 0,r9,1 @@ -1244,6 +1381,7 @@ initial_bats: mtspr SPRN_IBAT1L,r10 isync blr +#endif /* CONFIG_PPC64BRIDGE */ 4: tophys(r8,r11) #ifdef CONFIG_SMP @@ -1257,6 +1395,11 @@ initial_bats: ori r11,r11,BL_256M<<2|0x2 /* set up BAT registers for 604 */ #endif /* CONFIG_APUS */ +#ifdef CONFIG_PPC64BRIDGE + /* clear out the high 32 bits in the BAT */ + clrldi r11,r11,32 + clrldi r8,r8,32 +#endif /* CONFIG_PPC64BRIDGE */ mtspr SPRN_DBAT0L,r8 /* N.B. 6xx (not 601) have valid */ mtspr SPRN_DBAT0U,r11 /* bit in upper BAT register */ mtspr SPRN_IBAT0L,r8 @@ -1289,6 +1432,38 @@ setup_disp_bat: #endif /* !defined(CONFIG_APUS) && defined(CONFIG_BOOTX_TEXT) */ +#else /* CONFIG_POWER4 */ +/* + * Load up the SDR1 and segment register values now + * since we don't have the BATs. + * Also make sure we are running in 32-bit mode. + */ + +initial_mm_power4: + addis r14,r3,_SDR1@ha /* get the value from _SDR1 */ + lwz r14,_SDR1@l(r14) /* assume hash table below 4GB */ + mtspr SPRN_SDR1,r14 + slbia + lis r4,0x2000 /* set pseudo-segment reg 12 */ + ori r5,r4,0x0ccc + mtsr 12,r5 +#if 0 + ori r5,r4,0x0888 /* set pseudo-segment reg 8 */ + mtsr 8,r5 /* (for access to serial port) */ +#endif +#ifdef CONFIG_BOOTX_TEXT + ori r5,r4,0x0999 /* set pseudo-segment reg 9 */ + mtsr 9,r5 /* (for access to screen) */ +#endif + mfmsr r0 + clrldi r0,r0,1 + sync + mtmsr r0 + isync + blr + +#endif /* CONFIG_POWER4 */ + #ifdef CONFIG_8260 /* Jump into the system reset for the rom. * We first disable the MMU, and then jump to the ROM reset address. diff --git a/trunk/arch/ppc/kernel/idle.c b/trunk/arch/ppc/kernel/idle.c new file mode 100644 index 000000000000..1be3ca5bae40 --- /dev/null +++ b/trunk/arch/ppc/kernel/idle.c @@ -0,0 +1,112 @@ +/* + * Idle daemon for PowerPC. Idle daemon will handle any action + * that needs to be taken when the system becomes idle. + * + * Written by Cort Dougan (cort@cs.nmt.edu). Subsequently hacked + * on by Tom Rini, Armin Kuster, Paul Mackerras and others. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +void default_idle(void) +{ + void (*powersave)(void); + + powersave = ppc_md.power_save; + + if (!need_resched()) { + if (powersave != NULL) + powersave(); +#ifdef CONFIG_SMP + else { + set_thread_flag(TIF_POLLING_NRFLAG); + while (!need_resched() && + !cpu_is_offline(smp_processor_id())) + barrier(); + clear_thread_flag(TIF_POLLING_NRFLAG); + } +#endif + } +} + +/* + * The body of the idle task. + */ +void cpu_idle(void) +{ + int cpu = smp_processor_id(); + + for (;;) { + while (!need_resched()) { + if (ppc_md.idle != NULL) + ppc_md.idle(); + else + default_idle(); + } + + if (cpu_is_offline(cpu) && system_state == SYSTEM_RUNNING) + cpu_die(); + preempt_enable_no_resched(); + schedule(); + preempt_disable(); + } +} + +#if defined(CONFIG_SYSCTL) && defined(CONFIG_6xx) +/* + * Register the sysctl to set/clear powersave_nap. + */ +extern int powersave_nap; + +static ctl_table powersave_nap_ctl_table[]={ + { + .ctl_name = KERN_PPC_POWERSAVE_NAP, + .procname = "powersave-nap", + .data = &powersave_nap, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec, + }, + { 0, }, +}; +static ctl_table powersave_nap_sysctl_root[] = { + { 1, "kernel", NULL, 0, 0755, powersave_nap_ctl_table, }, + { 0,}, +}; + +static int __init +register_powersave_nap_sysctl(void) +{ + register_sysctl_table(powersave_nap_sysctl_root, 0); + + return 0; +} + +__initcall(register_powersave_nap_sysctl); +#endif diff --git a/trunk/arch/ppc/kernel/idle_6xx.S b/trunk/arch/ppc/kernel/idle_6xx.S new file mode 100644 index 000000000000..1a2194cf6828 --- /dev/null +++ b/trunk/arch/ppc/kernel/idle_6xx.S @@ -0,0 +1,233 @@ +/* + * This file contains the power_save function for 6xx & 7xxx CPUs + * rewritten in assembler + * + * Warning ! This code assumes that if your machine has a 750fx + * it will have PLL 1 set to low speed mode (used during NAP/DOZE). + * if this is not the case some additional changes will have to + * be done to check a runtime var (a bit like powersave-nap) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#undef DEBUG + + .text + +/* + * Init idle, called at early CPU setup time from head.S for each CPU + * Make sure no rest of NAP mode remains in HID0, save default + * values for some CPU specific registers. Called with r24 + * containing CPU number and r3 reloc offset + */ +_GLOBAL(init_idle_6xx) +BEGIN_FTR_SECTION + mfspr r4,SPRN_HID0 + rlwinm r4,r4,0,10,8 /* Clear NAP */ + mtspr SPRN_HID0, r4 + b 1f +END_FTR_SECTION_IFSET(CPU_FTR_CAN_NAP) + blr +1: + slwi r5,r24,2 + add r5,r5,r3 +BEGIN_FTR_SECTION + mfspr r4,SPRN_MSSCR0 + addis r6,r5, nap_save_msscr0@ha + stw r4,nap_save_msscr0@l(r6) +END_FTR_SECTION_IFSET(CPU_FTR_NAP_DISABLE_L2_PR) +BEGIN_FTR_SECTION + mfspr r4,SPRN_HID1 + addis r6,r5,nap_save_hid1@ha + stw r4,nap_save_hid1@l(r6) +END_FTR_SECTION_IFSET(CPU_FTR_DUAL_PLL_750FX) + blr + +/* + * Here is the power_save_6xx function. This could eventually be + * split into several functions & changing the function pointer + * depending on the various features. + */ +_GLOBAL(ppc6xx_idle) + /* Check if we can nap or doze, put HID0 mask in r3 + */ + lis r3, 0 +BEGIN_FTR_SECTION + lis r3,HID0_DOZE@h +END_FTR_SECTION_IFSET(CPU_FTR_CAN_DOZE) +BEGIN_FTR_SECTION + /* We must dynamically check for the NAP feature as it + * can be cleared by CPU init after the fixups are done + */ + lis r4,cur_cpu_spec@ha + lwz r4,cur_cpu_spec@l(r4) + lwz r4,CPU_SPEC_FEATURES(r4) + andi. r0,r4,CPU_FTR_CAN_NAP + beq 1f + /* Now check if user or arch enabled NAP mode */ + lis r4,powersave_nap@ha + lwz r4,powersave_nap@l(r4) + cmpwi 0,r4,0 + beq 1f + lis r3,HID0_NAP@h +1: +END_FTR_SECTION_IFSET(CPU_FTR_CAN_NAP) + cmpwi 0,r3,0 + beqlr + + /* Clear MSR:EE */ + mfmsr r7 + rlwinm r0,r7,0,17,15 + mtmsr r0 + + /* Check current_thread_info()->flags */ + rlwinm r4,r1,0,0,18 + lwz r4,TI_FLAGS(r4) + andi. r0,r4,_TIF_NEED_RESCHED + beq 1f + mtmsr r7 /* out of line this ? */ + blr +1: + /* Some pre-nap cleanups needed on some CPUs */ + andis. r0,r3,HID0_NAP@h + beq 2f +BEGIN_FTR_SECTION + /* Disable L2 prefetch on some 745x and try to ensure + * L2 prefetch engines are idle. As explained by errata + * text, we can't be sure they are, we just hope very hard + * that well be enough (sic !). At least I noticed Apple + * doesn't even bother doing the dcbf's here... + */ + mfspr r4,SPRN_MSSCR0 + rlwinm r4,r4,0,0,29 + sync + mtspr SPRN_MSSCR0,r4 + sync + isync + lis r4,KERNELBASE@h + dcbf 0,r4 + dcbf 0,r4 + dcbf 0,r4 + dcbf 0,r4 +END_FTR_SECTION_IFSET(CPU_FTR_NAP_DISABLE_L2_PR) +#ifdef DEBUG + lis r6,nap_enter_count@ha + lwz r4,nap_enter_count@l(r6) + addi r4,r4,1 + stw r4,nap_enter_count@l(r6) +#endif +2: +BEGIN_FTR_SECTION + /* Go to low speed mode on some 750FX */ + lis r4,powersave_lowspeed@ha + lwz r4,powersave_lowspeed@l(r4) + cmpwi 0,r4,0 + beq 1f + mfspr r4,SPRN_HID1 + oris r4,r4,0x0001 + mtspr SPRN_HID1,r4 +1: +END_FTR_SECTION_IFSET(CPU_FTR_DUAL_PLL_750FX) + + /* Go to NAP or DOZE now */ + mfspr r4,SPRN_HID0 + lis r5,(HID0_NAP|HID0_SLEEP)@h +BEGIN_FTR_SECTION + oris r5,r5,HID0_DOZE@h +END_FTR_SECTION_IFSET(CPU_FTR_CAN_DOZE) + andc r4,r4,r5 + or r4,r4,r3 +BEGIN_FTR_SECTION + oris r4,r4,HID0_DPM@h /* that should be done once for all */ +END_FTR_SECTION_IFCLR(CPU_FTR_NO_DPM) + mtspr SPRN_HID0,r4 +BEGIN_FTR_SECTION + DSSALL + sync +END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) + ori r7,r7,MSR_EE /* Could be ommited (already set) */ + oris r7,r7,MSR_POW@h + sync + isync + mtmsr r7 + isync + sync + blr + +/* + * Return from NAP/DOZE mode, restore some CPU specific registers, + * we are called with DR/IR still off and r2 containing physical + * address of current. + */ +_GLOBAL(power_save_6xx_restore) + mfspr r11,SPRN_HID0 + rlwinm. r11,r11,0,10,8 /* Clear NAP & copy NAP bit !state to cr1 EQ */ + cror 4*cr1+eq,4*cr0+eq,4*cr0+eq +BEGIN_FTR_SECTION + rlwinm r11,r11,0,9,7 /* Clear DOZE */ +END_FTR_SECTION_IFSET(CPU_FTR_CAN_DOZE) + mtspr SPRN_HID0, r11 + +#ifdef DEBUG + beq cr1,1f + lis r11,(nap_return_count-KERNELBASE)@ha + lwz r9,nap_return_count@l(r11) + addi r9,r9,1 + stw r9,nap_return_count@l(r11) +1: +#endif + + rlwinm r9,r1,0,0,18 + tophys(r9,r9) + lwz r11,TI_CPU(r9) + slwi r11,r11,2 + /* Todo make sure all these are in the same page + * and load r22 (@ha part + CPU offset) only once + */ +BEGIN_FTR_SECTION + beq cr1,1f + addis r9,r11,(nap_save_msscr0-KERNELBASE)@ha + lwz r9,nap_save_msscr0@l(r9) + mtspr SPRN_MSSCR0, r9 + sync + isync +1: +END_FTR_SECTION_IFSET(CPU_FTR_NAP_DISABLE_L2_PR) +BEGIN_FTR_SECTION + addis r9,r11,(nap_save_hid1-KERNELBASE)@ha + lwz r9,nap_save_hid1@l(r9) + mtspr SPRN_HID1, r9 +END_FTR_SECTION_IFSET(CPU_FTR_DUAL_PLL_750FX) + b transfer_to_handler_cont + + .data + +_GLOBAL(nap_save_msscr0) + .space 4*NR_CPUS + +_GLOBAL(nap_save_hid1) + .space 4*NR_CPUS + +_GLOBAL(powersave_nap) + .long 0 +_GLOBAL(powersave_lowspeed) + .long 0 + +#ifdef DEBUG +_GLOBAL(nap_enter_count) + .space 4 +_GLOBAL(nap_return_count) + .space 4 +#endif diff --git a/trunk/arch/ppc/kernel/idle_power4.S b/trunk/arch/ppc/kernel/idle_power4.S new file mode 100644 index 000000000000..cc0d535365cd --- /dev/null +++ b/trunk/arch/ppc/kernel/idle_power4.S @@ -0,0 +1,91 @@ +/* + * This file contains the power_save function for 6xx & 7xxx CPUs + * rewritten in assembler + * + * Warning ! This code assumes that if your machine has a 750fx + * it will have PLL 1 set to low speed mode (used during NAP/DOZE). + * if this is not the case some additional changes will have to + * be done to check a runtime var (a bit like powersave-nap) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#undef DEBUG + + .text + +/* + * Init idle, called at early CPU setup time from head.S for each CPU + * So nothing for now. Called with r24 containing CPU number and r3 + * reloc offset + */ + .globl init_idle_power4 +init_idle_power4: + blr + +/* + * Here is the power_save_6xx function. This could eventually be + * split into several functions & changing the function pointer + * depending on the various features. + */ + .globl power4_idle +power4_idle: +BEGIN_FTR_SECTION + blr +END_FTR_SECTION_IFCLR(CPU_FTR_CAN_NAP) + /* We must dynamically check for the NAP feature as it + * can be cleared by CPU init after the fixups are done + */ + lis r4,cur_cpu_spec@ha + lwz r4,cur_cpu_spec@l(r4) + lwz r4,CPU_SPEC_FEATURES(r4) + andi. r0,r4,CPU_FTR_CAN_NAP + beqlr + /* Now check if user or arch enabled NAP mode */ + lis r4,powersave_nap@ha + lwz r4,powersave_nap@l(r4) + cmpwi 0,r4,0 + beqlr + + /* Clear MSR:EE */ + mfmsr r7 + rlwinm r0,r7,0,17,15 + mtmsr r0 + + /* Check current_thread_info()->flags */ + rlwinm r4,r1,0,0,18 + lwz r4,TI_FLAGS(r4) + andi. r0,r4,_TIF_NEED_RESCHED + beq 1f + mtmsr r7 /* out of line this ? */ + blr +1: + /* Go to NAP now */ +BEGIN_FTR_SECTION + DSSALL + sync +END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) + ori r7,r7,MSR_EE /* Could be ommited (already set) */ + oris r7,r7,MSR_POW@h + sync + isync + mtmsr r7 + isync + sync + blr + + .globl powersave_nap +powersave_nap: + .long 0 diff --git a/trunk/arch/powerpc/kernel/l2cr_6xx.S b/trunk/arch/ppc/kernel/l2cr.S similarity index 100% rename from trunk/arch/powerpc/kernel/l2cr_6xx.S rename to trunk/arch/ppc/kernel/l2cr.S diff --git a/trunk/arch/powerpc/kernel/module_32.c b/trunk/arch/ppc/kernel/module.c similarity index 100% rename from trunk/arch/powerpc/kernel/module_32.c rename to trunk/arch/ppc/kernel/module.c diff --git a/trunk/arch/ppc/kernel/pci.c b/trunk/arch/ppc/kernel/pci.c index 809673a36f7a..04d04c5bfdd0 100644 --- a/trunk/arch/ppc/kernel/pci.c +++ b/trunk/arch/ppc/kernel/pci.c @@ -46,6 +46,9 @@ static void pcibios_fixup_resources(struct pci_dev* dev); static void fixup_broken_pcnet32(struct pci_dev* dev); static int reparent_resources(struct resource *parent, struct resource *res); static void fixup_cpc710_pci64(struct pci_dev* dev); +#ifdef CONFIG_PPC_OF +static u8* pci_to_OF_bus_map; +#endif /* By default, we don't re-assign bus numbers. */ @@ -622,13 +625,406 @@ pcibios_alloc_controller(void) return hose; } +#ifdef CONFIG_PPC_OF +/* + * Functions below are used on OpenFirmware machines. + */ +static void +make_one_node_map(struct device_node* node, u8 pci_bus) +{ + int *bus_range; + int len; + + if (pci_bus >= pci_bus_count) + return; + bus_range = (int *) get_property(node, "bus-range", &len); + if (bus_range == NULL || len < 2 * sizeof(int)) { + printk(KERN_WARNING "Can't get bus-range for %s, " + "assuming it starts at 0\n", node->full_name); + pci_to_OF_bus_map[pci_bus] = 0; + } else + pci_to_OF_bus_map[pci_bus] = bus_range[0]; + + for (node=node->child; node != 0;node = node->sibling) { + struct pci_dev* dev; + unsigned int *class_code, *reg; + + class_code = (unsigned int *) get_property(node, "class-code", NULL); + if (!class_code || ((*class_code >> 8) != PCI_CLASS_BRIDGE_PCI && + (*class_code >> 8) != PCI_CLASS_BRIDGE_CARDBUS)) + continue; + reg = (unsigned int *)get_property(node, "reg", NULL); + if (!reg) + continue; + dev = pci_find_slot(pci_bus, ((reg[0] >> 8) & 0xff)); + if (!dev || !dev->subordinate) + continue; + make_one_node_map(node, dev->subordinate->number); + } +} + +void +pcibios_make_OF_bus_map(void) +{ + int i; + struct pci_controller* hose; + u8* of_prop_map; + + pci_to_OF_bus_map = (u8*)kmalloc(pci_bus_count, GFP_KERNEL); + if (!pci_to_OF_bus_map) { + printk(KERN_ERR "Can't allocate OF bus map !\n"); + return; + } + + /* We fill the bus map with invalid values, that helps + * debugging. + */ + for (i=0; inext) { + struct device_node* node; + node = (struct device_node *)hose->arch_data; + if (!node) + continue; + make_one_node_map(node, hose->first_busno); + } + of_prop_map = get_property(find_path_device("/"), "pci-OF-bus-map", NULL); + if (of_prop_map) + memcpy(of_prop_map, pci_to_OF_bus_map, pci_bus_count); +#ifdef DEBUG + printk("PCI->OF bus map:\n"); + for (i=0; i %d\n", i, pci_to_OF_bus_map[i]); + } +#endif +} + +typedef int (*pci_OF_scan_iterator)(struct device_node* node, void* data); + +static struct device_node* +scan_OF_pci_childs(struct device_node* node, pci_OF_scan_iterator filter, void* data) +{ + struct device_node* sub_node; + + for (; node != 0;node = node->sibling) { + unsigned int *class_code; + + if (filter(node, data)) + return node; + + /* For PCI<->PCI bridges or CardBus bridges, we go down + * Note: some OFs create a parent node "multifunc-device" as + * a fake root for all functions of a multi-function device, + * we go down them as well. + */ + class_code = (unsigned int *) get_property(node, "class-code", NULL); + if ((!class_code || ((*class_code >> 8) != PCI_CLASS_BRIDGE_PCI && + (*class_code >> 8) != PCI_CLASS_BRIDGE_CARDBUS)) && + strcmp(node->name, "multifunc-device")) + continue; + sub_node = scan_OF_pci_childs(node->child, filter, data); + if (sub_node) + return sub_node; + } + return NULL; +} + +static int +scan_OF_pci_childs_iterator(struct device_node* node, void* data) +{ + unsigned int *reg; + u8* fdata = (u8*)data; + + reg = (unsigned int *) get_property(node, "reg", NULL); + if (reg && ((reg[0] >> 8) & 0xff) == fdata[1] + && ((reg[0] >> 16) & 0xff) == fdata[0]) + return 1; + return 0; +} + +static struct device_node* +scan_OF_childs_for_device(struct device_node* node, u8 bus, u8 dev_fn) +{ + u8 filter_data[2] = {bus, dev_fn}; + + return scan_OF_pci_childs(node, scan_OF_pci_childs_iterator, filter_data); +} + +/* + * Scans the OF tree for a device node matching a PCI device + */ +struct device_node * +pci_busdev_to_OF_node(struct pci_bus *bus, int devfn) +{ + struct pci_controller *hose; + struct device_node *node; + int busnr; + + if (!have_of) + return NULL; + + /* Lookup the hose */ + busnr = bus->number; + hose = pci_bus_to_hose(busnr); + if (!hose) + return NULL; + + /* Check it has an OF node associated */ + node = (struct device_node *) hose->arch_data; + if (!node) + return NULL; + + /* Fixup bus number according to what OF think it is. */ + if (pci_to_OF_bus_map) + busnr = pci_to_OF_bus_map[busnr]; + if (busnr == 0xff) + return NULL; + + /* Now, lookup childs of the hose */ + return scan_OF_childs_for_device(node->child, busnr, devfn); +} +EXPORT_SYMBOL(pci_busdev_to_OF_node); + +struct device_node* +pci_device_to_OF_node(struct pci_dev *dev) +{ + return pci_busdev_to_OF_node(dev->bus, dev->devfn); +} +EXPORT_SYMBOL(pci_device_to_OF_node); + +/* This routine is meant to be used early during boot, when the + * PCI bus numbers have not yet been assigned, and you need to + * issue PCI config cycles to an OF device. + * It could also be used to "fix" RTAS config cycles if you want + * to set pci_assign_all_buses to 1 and still use RTAS for PCI + * config cycles. + */ +struct pci_controller* pci_find_hose_for_OF_device(struct device_node* node) +{ + if (!have_of) + return NULL; + while(node) { + struct pci_controller* hose; + for (hose=hose_head;hose;hose=hose->next) + if (hose->arch_data == node) + return hose; + node=node->parent; + } + return NULL; +} + +static int +find_OF_pci_device_filter(struct device_node* node, void* data) +{ + return ((void *)node == data); +} + +/* + * Returns the PCI device matching a given OF node + */ +int +pci_device_from_OF_node(struct device_node* node, u8* bus, u8* devfn) +{ + unsigned int *reg; + struct pci_controller* hose; + struct pci_dev* dev = NULL; + + if (!have_of) + return -ENODEV; + /* Make sure it's really a PCI device */ + hose = pci_find_hose_for_OF_device(node); + if (!hose || !hose->arch_data) + return -ENODEV; + if (!scan_OF_pci_childs(((struct device_node*)hose->arch_data)->child, + find_OF_pci_device_filter, (void *)node)) + return -ENODEV; + reg = (unsigned int *) get_property(node, "reg", NULL); + if (!reg) + return -ENODEV; + *bus = (reg[0] >> 16) & 0xff; + *devfn = ((reg[0] >> 8) & 0xff); + + /* Ok, here we need some tweak. If we have already renumbered + * all busses, we can't rely on the OF bus number any more. + * the pci_to_OF_bus_map is not enough as several PCI busses + * may match the same OF bus number. + */ + if (!pci_to_OF_bus_map) + return 0; + + for_each_pci_dev(dev) + if (pci_to_OF_bus_map[dev->bus->number] == *bus && + dev->devfn == *devfn) { + *bus = dev->bus->number; + pci_dev_put(dev); + return 0; + } + + return -ENODEV; +} +EXPORT_SYMBOL(pci_device_from_OF_node); + +void __init +pci_process_bridge_OF_ranges(struct pci_controller *hose, + struct device_node *dev, int primary) +{ + static unsigned int static_lc_ranges[256] __initdata; + unsigned int *dt_ranges, *lc_ranges, *ranges, *prev; + unsigned int size; + int rlen = 0, orig_rlen; + int memno = 0; + struct resource *res; + int np, na = prom_n_addr_cells(dev); + np = na + 5; + + /* First we try to merge ranges to fix a problem with some pmacs + * that can have more than 3 ranges, fortunately using contiguous + * addresses -- BenH + */ + dt_ranges = (unsigned int *) get_property(dev, "ranges", &rlen); + if (!dt_ranges) + return; + /* Sanity check, though hopefully that never happens */ + if (rlen > sizeof(static_lc_ranges)) { + printk(KERN_WARNING "OF ranges property too large !\n"); + rlen = sizeof(static_lc_ranges); + } + lc_ranges = static_lc_ranges; + memcpy(lc_ranges, dt_ranges, rlen); + orig_rlen = rlen; + + /* Let's work on a copy of the "ranges" property instead of damaging + * the device-tree image in memory + */ + ranges = lc_ranges; + prev = NULL; + while ((rlen -= np * sizeof(unsigned int)) >= 0) { + if (prev) { + if (prev[0] == ranges[0] && prev[1] == ranges[1] && + (prev[2] + prev[na+4]) == ranges[2] && + (prev[na+2] + prev[na+4]) == ranges[na+2]) { + prev[na+4] += ranges[na+4]; + ranges[0] = 0; + ranges += np; + continue; + } + } + prev = ranges; + ranges += np; + } + + /* + * The ranges property is laid out as an array of elements, + * each of which comprises: + * cells 0 - 2: a PCI address + * cells 3 or 3+4: a CPU physical address + * (size depending on dev->n_addr_cells) + * cells 4+5 or 5+6: the size of the range + */ + ranges = lc_ranges; + rlen = orig_rlen; + while (ranges && (rlen -= np * sizeof(unsigned int)) >= 0) { + res = NULL; + size = ranges[na+4]; + switch ((ranges[0] >> 24) & 0x3) { + case 1: /* I/O space */ + if (ranges[2] != 0) + break; + hose->io_base_phys = ranges[na+2]; + /* limit I/O space to 16MB */ + if (size > 0x01000000) + size = 0x01000000; + hose->io_base_virt = ioremap(ranges[na+2], size); + if (primary) + isa_io_base = (unsigned long) hose->io_base_virt; + res = &hose->io_resource; + res->flags = IORESOURCE_IO; + res->start = ranges[2]; + DBG("PCI: IO 0x%lx -> 0x%lx\n", + res->start, res->start + size - 1); + break; + case 2: /* memory space */ + memno = 0; + if (ranges[1] == 0 && ranges[2] == 0 + && ranges[na+4] <= (16 << 20)) { + /* 1st 16MB, i.e. ISA memory area */ + if (primary) + isa_mem_base = ranges[na+2]; + memno = 1; + } + while (memno < 3 && hose->mem_resources[memno].flags) + ++memno; + if (memno == 0) + hose->pci_mem_offset = ranges[na+2] - ranges[2]; + if (memno < 3) { + res = &hose->mem_resources[memno]; + res->flags = IORESOURCE_MEM; + if(ranges[0] & 0x40000000) + res->flags |= IORESOURCE_PREFETCH; + res->start = ranges[na+2]; + DBG("PCI: MEM[%d] 0x%lx -> 0x%lx\n", memno, + res->start, res->start + size - 1); + } + break; + } + if (res != NULL) { + res->name = dev->full_name; + res->end = res->start + size - 1; + res->parent = NULL; + res->sibling = NULL; + res->child = NULL; + } + ranges += np; + } +} + +/* We create the "pci-OF-bus-map" property now so it appears in the + * /proc device tree + */ +void __init +pci_create_OF_bus_map(void) +{ + struct property* of_prop; + + of_prop = (struct property*) alloc_bootmem(sizeof(struct property) + 256); + if (of_prop && find_path_device("/")) { + memset(of_prop, -1, sizeof(struct property) + 256); + of_prop->name = "pci-OF-bus-map"; + of_prop->length = 256; + of_prop->value = (unsigned char *)&of_prop[1]; + prom_add_property(find_path_device("/"), of_prop); + } +} + +static ssize_t pci_show_devspec(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct pci_dev *pdev; + struct device_node *np; + + pdev = to_pci_dev (dev); + np = pci_device_to_OF_node(pdev); + if (np == NULL || np->full_name == NULL) + return 0; + return sprintf(buf, "%s", np->full_name); +} +static DEVICE_ATTR(devspec, S_IRUGO, pci_show_devspec, NULL); + +#else /* CONFIG_PPC_OF */ void pcibios_make_OF_bus_map(void) { } +#endif /* CONFIG_PPC_OF */ /* Add sysfs properties */ void pcibios_add_platform_entries(struct pci_dev *pdev) { +#ifdef CONFIG_PPC_OF + device_create_file(&pdev->dev, &dev_attr_devspec); +#endif /* CONFIG_PPC_OF */ } diff --git a/trunk/arch/powerpc/kernel/perfmon_fsl_booke.c b/trunk/arch/ppc/kernel/perfmon_fsl_booke.c similarity index 100% rename from trunk/arch/powerpc/kernel/perfmon_fsl_booke.c rename to trunk/arch/ppc/kernel/perfmon_fsl_booke.c diff --git a/trunk/arch/ppc/kernel/ppc_htab.c b/trunk/arch/ppc/kernel/ppc_htab.c index 75c645043746..9b84bffdefce 100644 --- a/trunk/arch/ppc/kernel/ppc_htab.c +++ b/trunk/arch/ppc/kernel/ppc_htab.c @@ -104,7 +104,7 @@ static char *pmc2_lookup(unsigned long mmcr0) static int ppc_htab_show(struct seq_file *m, void *v) { unsigned long mmcr0 = 0, pmc1 = 0, pmc2 = 0; -#if defined(CONFIG_PPC_STD_MMU) +#if defined(CONFIG_PPC_STD_MMU) && !defined(CONFIG_PPC64BRIDGE) unsigned int kptes = 0, uptes = 0; PTE *ptr; #endif /* CONFIG_PPC_STD_MMU */ @@ -133,6 +133,7 @@ static int ppc_htab_show(struct seq_file *m, void *v) return 0; } +#ifndef CONFIG_PPC64BRIDGE for (ptr = Hash; ptr < Hash_end; ptr++) { unsigned int mctx, vsid; @@ -146,6 +147,7 @@ static int ppc_htab_show(struct seq_file *m, void *v) else uptes++; } +#endif seq_printf(m, "PTE Hash Table Information\n" @@ -153,16 +155,20 @@ static int ppc_htab_show(struct seq_file *m, void *v) "Buckets\t\t: %lu\n" "Address\t\t: %08lx\n" "Entries\t\t: %lu\n" +#ifndef CONFIG_PPC64BRIDGE "User ptes\t: %u\n" "Kernel ptes\t: %u\n" "Percent full\t: %lu%%\n" +#endif , (unsigned long)(Hash_size>>10), (Hash_size/(sizeof(PTE)*8)), (unsigned long)Hash, Hash_size/sizeof(PTE) +#ifndef CONFIG_PPC64BRIDGE , uptes, kptes, ((kptes+uptes)*100) / (Hash_size/sizeof(PTE)) +#endif ); seq_printf(m, diff --git a/trunk/arch/ppc/kernel/ppc_ksyms.c b/trunk/arch/ppc/kernel/ppc_ksyms.c index 865ba74991a9..82adb4601348 100644 --- a/trunk/arch/ppc/kernel/ppc_ksyms.c +++ b/trunk/arch/ppc/kernel/ppc_ksyms.c @@ -18,6 +18,7 @@ #include #include +#include #include #include #include @@ -29,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -206,6 +208,27 @@ EXPORT_SYMBOL(adb_try_handler_change); EXPORT_SYMBOL(cuda_request); EXPORT_SYMBOL(cuda_poll); #endif /* CONFIG_ADB_CUDA */ +#ifdef CONFIG_PPC_OF +EXPORT_SYMBOL(find_devices); +EXPORT_SYMBOL(find_type_devices); +EXPORT_SYMBOL(find_compatible_devices); +EXPORT_SYMBOL(find_path_device); +EXPORT_SYMBOL(device_is_compatible); +EXPORT_SYMBOL(machine_is_compatible); +EXPORT_SYMBOL(find_all_nodes); +EXPORT_SYMBOL(get_property); +EXPORT_SYMBOL(request_OF_resource); +EXPORT_SYMBOL(release_OF_resource); +EXPORT_SYMBOL(of_find_node_by_name); +EXPORT_SYMBOL(of_find_node_by_type); +EXPORT_SYMBOL(of_find_compatible_node); +EXPORT_SYMBOL(of_find_node_by_path); +EXPORT_SYMBOL(of_find_all_nodes); +EXPORT_SYMBOL(of_get_parent); +EXPORT_SYMBOL(of_get_next_child); +EXPORT_SYMBOL(of_node_get); +EXPORT_SYMBOL(of_node_put); +#endif /* CONFIG_PPC_OF */ #if defined(CONFIG_BOOTX_TEXT) EXPORT_SYMBOL(btext_update_display); #endif @@ -239,6 +262,9 @@ EXPORT_SYMBOL(console_drivers); EXPORT_SYMBOL(xmon); EXPORT_SYMBOL(xmon_printf); #endif +EXPORT_SYMBOL(__up); +EXPORT_SYMBOL(__down); +EXPORT_SYMBOL(__down_interruptible); #if defined(CONFIG_KGDB) || defined(CONFIG_XMON) extern void (*debugger)(struct pt_regs *regs); diff --git a/trunk/arch/ppc/kernel/setup.c b/trunk/arch/ppc/kernel/setup.c index 1f79e84ab464..53e9deacee82 100644 --- a/trunk/arch/ppc/kernel/setup.c +++ b/trunk/arch/ppc/kernel/setup.c @@ -1,5 +1,5 @@ /* - * Common prep boot and setup code. + * Common prep/chrp boot and setup code. */ #include @@ -72,12 +72,17 @@ unsigned long ISA_DMA_THRESHOLD; unsigned int DMA_MODE_READ; unsigned int DMA_MODE_WRITE; -#ifdef CONFIG_PPC_PREP +#ifdef CONFIG_PPC_MULTIPLATFORM +int _machine = 0; +EXPORT_SYMBOL(_machine); + extern void prep_init(unsigned long r3, unsigned long r4, unsigned long r5, unsigned long r6, unsigned long r7); +extern void chrp_init(unsigned long r3, unsigned long r4, + unsigned long r5, unsigned long r6, unsigned long r7); dev_t boot_dev; -#endif /* CONFIG_PPC_PREP */ +#endif /* CONFIG_PPC_MULTIPLATFORM */ int have_of; EXPORT_SYMBOL(have_of); @@ -314,12 +319,72 @@ early_init(int r3, int r4, int r5) identify_cpu(offset, 0); do_cpu_ftr_fixups(offset); +#if defined(CONFIG_PPC_OF) + reloc_got2(offset); + + /* + * don't do anything on prep + * for now, don't use bootinfo because it breaks yaboot 0.5 + * and assume that if we didn't find a magic number, we have OF + */ + if (*(unsigned long *)(0) != 0xdeadc0de) + phys = prom_init(r3, r4, (prom_entry)r5); + + reloc_got2(-offset); +#endif + return phys; } -#ifdef CONFIG_PPC_PREP +#ifdef CONFIG_PPC_OF /* - * The PPC_PREP version of platform_init... + * Assume here that all clock rates are the same in a + * smp system. -- Cort + */ +int +of_show_percpuinfo(struct seq_file *m, int i) +{ + struct device_node *cpu_node; + u32 *fp; + int s; + + cpu_node = find_type_devices("cpu"); + if (!cpu_node) + return 0; + for (s = 0; s < i && cpu_node->next; s++) + cpu_node = cpu_node->next; + fp = (u32 *)get_property(cpu_node, "clock-frequency", NULL); + if (fp) + seq_printf(m, "clock\t\t: %dMHz\n", *fp / 1000000); + return 0; +} + +void __init +intuit_machine_type(void) +{ + char *model; + struct device_node *root; + + /* ask the OF info if we're a chrp or pmac */ + root = find_path_device("/"); + if (root != 0) { + /* assume pmac unless proven to be chrp -- Cort */ + _machine = _MACH_Pmac; + model = get_property(root, "device_type", NULL); + if (model && !strncmp("chrp", model, 4)) + _machine = _MACH_chrp; + else { + model = get_property(root, "model", NULL); + if (model && !strncmp(model, "IBM", 3)) + _machine = _MACH_chrp; + } + } +} +#endif + +#ifdef CONFIG_PPC_MULTIPLATFORM +/* + * The PPC_MULTIPLATFORM version of platform_init... */ void __init platform_init(unsigned long r3, unsigned long r4, unsigned long r5, @@ -334,9 +399,161 @@ platform_init(unsigned long r3, unsigned long r4, unsigned long r5, parse_bootinfo(find_bootinfo()); - prep_init(r3, r4, r5, r6, r7); + /* if we didn't get any bootinfo telling us what we are... */ + if (_machine == 0) { + /* prep boot loader tells us if we're prep or not */ + if ( *(unsigned long *)(KERNELBASE) == (0xdeadc0de) ) + _machine = _MACH_prep; + } + +#ifdef CONFIG_PPC_PREP + /* not much more to do here, if prep */ + if (_machine == _MACH_prep) { + prep_init(r3, r4, r5, r6, r7); + return; + } +#endif + +#ifdef CONFIG_PPC_OF + have_of = 1; + + /* prom_init has already been called from __start */ + if (boot_infos) + relocate_nodes(); + + /* If we aren't PReP, we can find out if we're Pmac + * or CHRP with this. */ + if (_machine == 0) + intuit_machine_type(); + + /* finish_device_tree may need _machine defined. */ + finish_device_tree(); + + /* + * If we were booted via quik, r3 points to the physical + * address of the command-line parameters. + * If we were booted from an xcoff image (i.e. netbooted or + * booted from floppy), we get the command line from the + * bootargs property of the /chosen node. + * If an initial ramdisk is present, r3 and r4 + * are used for initrd_start and initrd_size, + * otherwise they contain 0xdeadbeef. + */ + if (r3 >= 0x4000 && r3 < 0x800000 && r4 == 0) { + strlcpy(cmd_line, (char *)r3 + KERNELBASE, + sizeof(cmd_line)); + } else if (boot_infos != 0) { + /* booted by BootX - check for ramdisk */ + if (boot_infos->kernelParamsOffset != 0) + strlcpy(cmd_line, (char *) boot_infos + + boot_infos->kernelParamsOffset, + sizeof(cmd_line)); +#ifdef CONFIG_BLK_DEV_INITRD + if (boot_infos->ramDisk) { + initrd_start = (unsigned long) boot_infos + + boot_infos->ramDisk; + initrd_end = initrd_start + boot_infos->ramDiskSize; + initrd_below_start_ok = 1; + } +#endif + } else { + struct device_node *chosen; + char *p; + +#ifdef CONFIG_BLK_DEV_INITRD + if (r3 && r4 && r4 != 0xdeadbeef) { + if (r3 < KERNELBASE) + r3 += KERNELBASE; + initrd_start = r3; + initrd_end = r3 + r4; + ROOT_DEV = Root_RAM0; + initrd_below_start_ok = 1; + } +#endif + chosen = find_devices("chosen"); + if (chosen != NULL) { + p = get_property(chosen, "bootargs", NULL); + if (p && *p) { + strlcpy(cmd_line, p, sizeof(cmd_line)); + } + } + } +#ifdef CONFIG_ADB + if (strstr(cmd_line, "adb_sync")) { + extern int __adb_probe_sync; + __adb_probe_sync = 1; + } +#endif /* CONFIG_ADB */ + + switch (_machine) { +#ifdef CONFIG_PPC_CHRP + case _MACH_chrp: + chrp_init(r3, r4, r5, r6, r7); + break; +#endif + } +#endif /* CONFIG_PPC_OF */ } -#endif /* CONFIG_PPC_PREP */ +#endif /* CONFIG_PPC_MULTIPLATFORM */ + +#ifdef CONFIG_PPC_OF +#ifdef CONFIG_SERIAL_CORE_CONSOLE +extern char *of_stdout_device; + +static int __init set_preferred_console(void) +{ + struct device_node *prom_stdout; + char *name; + int offset = 0; + + if (of_stdout_device == NULL) + return -ENODEV; + + /* The user has requested a console so this is already set up. */ + if (strstr(saved_command_line, "console=")) + return -EBUSY; + + prom_stdout = find_path_device(of_stdout_device); + if (!prom_stdout) + return -ENODEV; + + name = (char *)get_property(prom_stdout, "name", NULL); + if (!name) + return -ENODEV; + + if (strcmp(name, "serial") == 0) { + int i; + u32 *reg = (u32 *)get_property(prom_stdout, "reg", &i); + if (i > 8) { + switch (reg[1]) { + case 0x3f8: + offset = 0; + break; + case 0x2f8: + offset = 1; + break; + case 0x898: + offset = 2; + break; + case 0x890: + offset = 3; + break; + default: + /* We dont recognise the serial port */ + return -ENODEV; + } + } + } else if (strcmp(name, "ch-a") == 0) + offset = 0; + else if (strcmp(name, "ch-b") == 0) + offset = 1; + else + return -ENODEV; + return add_preferred_console("ttyS", offset, NULL); +} +console_initcall(set_preferred_console); +#endif /* CONFIG_SERIAL_CORE_CONSOLE */ +#endif /* CONFIG_PPC_OF */ struct bi_record *find_bootinfo(void) { @@ -372,6 +589,23 @@ void parse_bootinfo(struct bi_record *rec) initrd_end = data[0] + data[1] + KERNELBASE; break; #endif /* CONFIG_BLK_DEV_INITRD */ +#ifdef CONFIG_PPC_MULTIPLATFORM + case BI_MACHTYPE: + /* Machine types changed with the merge. Since the + * bootinfo are now deprecated, we can just hard code + * the appropriate conversion here for when we are + * called with yaboot which passes us a machine type + * this way. + */ + switch(data[0]) { + case 1: _machine = _MACH_prep; break; + case 2: _machine = _MACH_Pmac; break; + case 4: _machine = _MACH_chrp; break; + default: + _machine = data[0]; + } + break; +#endif case BI_MEMSIZE: boot_mem_size = data[0]; break; @@ -397,6 +631,9 @@ machine_init(unsigned long r3, unsigned long r4, unsigned long r5, #ifdef CONFIG_6xx ppc_md.power_save = ppc6xx_idle; #endif +#ifdef CONFIG_POWER4 + ppc_md.power_save = power4_idle; +#endif platform_init(r3, r4, r5, r6, r7); @@ -474,7 +711,7 @@ int __init ppc_init(void) if ( ppc_md.progress ) ppc_md.progress(" ", 0xffff); /* register CPU devices */ - for_each_possible_cpu(i) + for_each_cpu(i) register_cpu(&cpu_devices[i], i, NULL); /* call platform init */ @@ -562,4 +799,7 @@ void __init setup_arch(char **cmdline_p) if ( ppc_md.progress ) ppc_md.progress("arch: exit", 0x3eab); paging_init(); + + /* this is for modules since _machine can be a define -- Cort */ + ppc_md.ppc_machine = _machine; } diff --git a/trunk/arch/ppc/kernel/smp.c b/trunk/arch/ppc/kernel/smp.c index f77795a64dae..e55cdda6149a 100644 --- a/trunk/arch/ppc/kernel/smp.c +++ b/trunk/arch/ppc/kernel/smp.c @@ -311,7 +311,7 @@ void __init smp_prepare_cpus(unsigned int max_cpus) /* Backup CPU 0 state */ __save_cpu_setup(); - for_each_possible_cpu(cpu) { + for_each_cpu(cpu) { if (cpu == smp_processor_id()) continue; /* create a process for the processor */ diff --git a/trunk/arch/powerpc/kernel/swsusp_32.S b/trunk/arch/ppc/kernel/swsusp.S similarity index 100% rename from trunk/arch/powerpc/kernel/swsusp_32.S rename to trunk/arch/ppc/kernel/swsusp.S diff --git a/trunk/arch/powerpc/kernel/tau_6xx.c b/trunk/arch/ppc/kernel/temp.c similarity index 100% rename from trunk/arch/powerpc/kernel/tau_6xx.c rename to trunk/arch/ppc/kernel/temp.c diff --git a/trunk/arch/ppc/lib/strcase.c b/trunk/arch/ppc/lib/strcase.c index 3b0094cc2b52..36b521091bbc 100644 --- a/trunk/arch/ppc/lib/strcase.c +++ b/trunk/arch/ppc/lib/strcase.c @@ -1,5 +1,4 @@ #include -#include int strcasecmp(const char *s1, const char *s2) { @@ -12,7 +11,7 @@ int strcasecmp(const char *s1, const char *s2) return c1 - c2; } -int strncasecmp(const char *s1, const char *s2, size_t n) +int strncasecmp(const char *s1, const char *s2, int n) { int c1, c2; diff --git a/trunk/arch/powerpc/math-emu/Makefile b/trunk/arch/ppc/math-emu/Makefile similarity index 100% rename from trunk/arch/powerpc/math-emu/Makefile rename to trunk/arch/ppc/math-emu/Makefile diff --git a/trunk/arch/powerpc/math-emu/double.h b/trunk/arch/ppc/math-emu/double.h similarity index 100% rename from trunk/arch/powerpc/math-emu/double.h rename to trunk/arch/ppc/math-emu/double.h diff --git a/trunk/arch/powerpc/math-emu/fabs.c b/trunk/arch/ppc/math-emu/fabs.c similarity index 100% rename from trunk/arch/powerpc/math-emu/fabs.c rename to trunk/arch/ppc/math-emu/fabs.c diff --git a/trunk/arch/powerpc/math-emu/fadd.c b/trunk/arch/ppc/math-emu/fadd.c similarity index 100% rename from trunk/arch/powerpc/math-emu/fadd.c rename to trunk/arch/ppc/math-emu/fadd.c diff --git a/trunk/arch/powerpc/math-emu/fadds.c b/trunk/arch/ppc/math-emu/fadds.c similarity index 100% rename from trunk/arch/powerpc/math-emu/fadds.c rename to trunk/arch/ppc/math-emu/fadds.c diff --git a/trunk/arch/powerpc/math-emu/fcmpo.c b/trunk/arch/ppc/math-emu/fcmpo.c similarity index 100% rename from trunk/arch/powerpc/math-emu/fcmpo.c rename to trunk/arch/ppc/math-emu/fcmpo.c diff --git a/trunk/arch/powerpc/math-emu/fcmpu.c b/trunk/arch/ppc/math-emu/fcmpu.c similarity index 100% rename from trunk/arch/powerpc/math-emu/fcmpu.c rename to trunk/arch/ppc/math-emu/fcmpu.c diff --git a/trunk/arch/powerpc/math-emu/fctiw.c b/trunk/arch/ppc/math-emu/fctiw.c similarity index 100% rename from trunk/arch/powerpc/math-emu/fctiw.c rename to trunk/arch/ppc/math-emu/fctiw.c diff --git a/trunk/arch/powerpc/math-emu/fctiwz.c b/trunk/arch/ppc/math-emu/fctiwz.c similarity index 100% rename from trunk/arch/powerpc/math-emu/fctiwz.c rename to trunk/arch/ppc/math-emu/fctiwz.c diff --git a/trunk/arch/powerpc/math-emu/fdiv.c b/trunk/arch/ppc/math-emu/fdiv.c similarity index 100% rename from trunk/arch/powerpc/math-emu/fdiv.c rename to trunk/arch/ppc/math-emu/fdiv.c diff --git a/trunk/arch/powerpc/math-emu/fdivs.c b/trunk/arch/ppc/math-emu/fdivs.c similarity index 100% rename from trunk/arch/powerpc/math-emu/fdivs.c rename to trunk/arch/ppc/math-emu/fdivs.c diff --git a/trunk/arch/powerpc/math-emu/fmadd.c b/trunk/arch/ppc/math-emu/fmadd.c similarity index 100% rename from trunk/arch/powerpc/math-emu/fmadd.c rename to trunk/arch/ppc/math-emu/fmadd.c diff --git a/trunk/arch/powerpc/math-emu/fmadds.c b/trunk/arch/ppc/math-emu/fmadds.c similarity index 100% rename from trunk/arch/powerpc/math-emu/fmadds.c rename to trunk/arch/ppc/math-emu/fmadds.c diff --git a/trunk/arch/powerpc/math-emu/fmr.c b/trunk/arch/ppc/math-emu/fmr.c similarity index 100% rename from trunk/arch/powerpc/math-emu/fmr.c rename to trunk/arch/ppc/math-emu/fmr.c diff --git a/trunk/arch/powerpc/math-emu/fmsub.c b/trunk/arch/ppc/math-emu/fmsub.c similarity index 100% rename from trunk/arch/powerpc/math-emu/fmsub.c rename to trunk/arch/ppc/math-emu/fmsub.c diff --git a/trunk/arch/powerpc/math-emu/fmsubs.c b/trunk/arch/ppc/math-emu/fmsubs.c similarity index 100% rename from trunk/arch/powerpc/math-emu/fmsubs.c rename to trunk/arch/ppc/math-emu/fmsubs.c diff --git a/trunk/arch/powerpc/math-emu/fmul.c b/trunk/arch/ppc/math-emu/fmul.c similarity index 100% rename from trunk/arch/powerpc/math-emu/fmul.c rename to trunk/arch/ppc/math-emu/fmul.c diff --git a/trunk/arch/powerpc/math-emu/fmuls.c b/trunk/arch/ppc/math-emu/fmuls.c similarity index 100% rename from trunk/arch/powerpc/math-emu/fmuls.c rename to trunk/arch/ppc/math-emu/fmuls.c diff --git a/trunk/arch/powerpc/math-emu/fnabs.c b/trunk/arch/ppc/math-emu/fnabs.c similarity index 100% rename from trunk/arch/powerpc/math-emu/fnabs.c rename to trunk/arch/ppc/math-emu/fnabs.c diff --git a/trunk/arch/powerpc/math-emu/fneg.c b/trunk/arch/ppc/math-emu/fneg.c similarity index 100% rename from trunk/arch/powerpc/math-emu/fneg.c rename to trunk/arch/ppc/math-emu/fneg.c diff --git a/trunk/arch/powerpc/math-emu/fnmadd.c b/trunk/arch/ppc/math-emu/fnmadd.c similarity index 100% rename from trunk/arch/powerpc/math-emu/fnmadd.c rename to trunk/arch/ppc/math-emu/fnmadd.c diff --git a/trunk/arch/powerpc/math-emu/fnmadds.c b/trunk/arch/ppc/math-emu/fnmadds.c similarity index 100% rename from trunk/arch/powerpc/math-emu/fnmadds.c rename to trunk/arch/ppc/math-emu/fnmadds.c diff --git a/trunk/arch/powerpc/math-emu/fnmsub.c b/trunk/arch/ppc/math-emu/fnmsub.c similarity index 100% rename from trunk/arch/powerpc/math-emu/fnmsub.c rename to trunk/arch/ppc/math-emu/fnmsub.c diff --git a/trunk/arch/powerpc/math-emu/fnmsubs.c b/trunk/arch/ppc/math-emu/fnmsubs.c similarity index 100% rename from trunk/arch/powerpc/math-emu/fnmsubs.c rename to trunk/arch/ppc/math-emu/fnmsubs.c diff --git a/trunk/arch/powerpc/math-emu/fres.c b/trunk/arch/ppc/math-emu/fres.c similarity index 100% rename from trunk/arch/powerpc/math-emu/fres.c rename to trunk/arch/ppc/math-emu/fres.c diff --git a/trunk/arch/powerpc/math-emu/frsp.c b/trunk/arch/ppc/math-emu/frsp.c similarity index 100% rename from trunk/arch/powerpc/math-emu/frsp.c rename to trunk/arch/ppc/math-emu/frsp.c diff --git a/trunk/arch/powerpc/math-emu/frsqrte.c b/trunk/arch/ppc/math-emu/frsqrte.c similarity index 100% rename from trunk/arch/powerpc/math-emu/frsqrte.c rename to trunk/arch/ppc/math-emu/frsqrte.c diff --git a/trunk/arch/powerpc/math-emu/fsel.c b/trunk/arch/ppc/math-emu/fsel.c similarity index 100% rename from trunk/arch/powerpc/math-emu/fsel.c rename to trunk/arch/ppc/math-emu/fsel.c diff --git a/trunk/arch/powerpc/math-emu/fsqrt.c b/trunk/arch/ppc/math-emu/fsqrt.c similarity index 100% rename from trunk/arch/powerpc/math-emu/fsqrt.c rename to trunk/arch/ppc/math-emu/fsqrt.c diff --git a/trunk/arch/powerpc/math-emu/fsqrts.c b/trunk/arch/ppc/math-emu/fsqrts.c similarity index 100% rename from trunk/arch/powerpc/math-emu/fsqrts.c rename to trunk/arch/ppc/math-emu/fsqrts.c diff --git a/trunk/arch/powerpc/math-emu/fsub.c b/trunk/arch/ppc/math-emu/fsub.c similarity index 100% rename from trunk/arch/powerpc/math-emu/fsub.c rename to trunk/arch/ppc/math-emu/fsub.c diff --git a/trunk/arch/powerpc/math-emu/fsubs.c b/trunk/arch/ppc/math-emu/fsubs.c similarity index 100% rename from trunk/arch/powerpc/math-emu/fsubs.c rename to trunk/arch/ppc/math-emu/fsubs.c diff --git a/trunk/arch/powerpc/math-emu/lfd.c b/trunk/arch/ppc/math-emu/lfd.c similarity index 100% rename from trunk/arch/powerpc/math-emu/lfd.c rename to trunk/arch/ppc/math-emu/lfd.c diff --git a/trunk/arch/powerpc/math-emu/lfs.c b/trunk/arch/ppc/math-emu/lfs.c similarity index 100% rename from trunk/arch/powerpc/math-emu/lfs.c rename to trunk/arch/ppc/math-emu/lfs.c diff --git a/trunk/arch/powerpc/math-emu/math.c b/trunk/arch/ppc/math-emu/math.c similarity index 100% rename from trunk/arch/powerpc/math-emu/math.c rename to trunk/arch/ppc/math-emu/math.c diff --git a/trunk/arch/powerpc/math-emu/mcrfs.c b/trunk/arch/ppc/math-emu/mcrfs.c similarity index 100% rename from trunk/arch/powerpc/math-emu/mcrfs.c rename to trunk/arch/ppc/math-emu/mcrfs.c diff --git a/trunk/arch/powerpc/math-emu/mffs.c b/trunk/arch/ppc/math-emu/mffs.c similarity index 100% rename from trunk/arch/powerpc/math-emu/mffs.c rename to trunk/arch/ppc/math-emu/mffs.c diff --git a/trunk/arch/powerpc/math-emu/mtfsb0.c b/trunk/arch/ppc/math-emu/mtfsb0.c similarity index 100% rename from trunk/arch/powerpc/math-emu/mtfsb0.c rename to trunk/arch/ppc/math-emu/mtfsb0.c diff --git a/trunk/arch/powerpc/math-emu/mtfsb1.c b/trunk/arch/ppc/math-emu/mtfsb1.c similarity index 100% rename from trunk/arch/powerpc/math-emu/mtfsb1.c rename to trunk/arch/ppc/math-emu/mtfsb1.c diff --git a/trunk/arch/powerpc/math-emu/mtfsf.c b/trunk/arch/ppc/math-emu/mtfsf.c similarity index 100% rename from trunk/arch/powerpc/math-emu/mtfsf.c rename to trunk/arch/ppc/math-emu/mtfsf.c diff --git a/trunk/arch/powerpc/math-emu/mtfsfi.c b/trunk/arch/ppc/math-emu/mtfsfi.c similarity index 100% rename from trunk/arch/powerpc/math-emu/mtfsfi.c rename to trunk/arch/ppc/math-emu/mtfsfi.c diff --git a/trunk/arch/powerpc/math-emu/op-1.h b/trunk/arch/ppc/math-emu/op-1.h similarity index 100% rename from trunk/arch/powerpc/math-emu/op-1.h rename to trunk/arch/ppc/math-emu/op-1.h diff --git a/trunk/arch/powerpc/math-emu/op-2.h b/trunk/arch/ppc/math-emu/op-2.h similarity index 100% rename from trunk/arch/powerpc/math-emu/op-2.h rename to trunk/arch/ppc/math-emu/op-2.h diff --git a/trunk/arch/powerpc/math-emu/op-4.h b/trunk/arch/ppc/math-emu/op-4.h similarity index 100% rename from trunk/arch/powerpc/math-emu/op-4.h rename to trunk/arch/ppc/math-emu/op-4.h diff --git a/trunk/arch/powerpc/math-emu/op-common.h b/trunk/arch/ppc/math-emu/op-common.h similarity index 100% rename from trunk/arch/powerpc/math-emu/op-common.h rename to trunk/arch/ppc/math-emu/op-common.h diff --git a/trunk/arch/powerpc/math-emu/sfp-machine.h b/trunk/arch/ppc/math-emu/sfp-machine.h similarity index 100% rename from trunk/arch/powerpc/math-emu/sfp-machine.h rename to trunk/arch/ppc/math-emu/sfp-machine.h diff --git a/trunk/arch/powerpc/math-emu/single.h b/trunk/arch/ppc/math-emu/single.h similarity index 100% rename from trunk/arch/powerpc/math-emu/single.h rename to trunk/arch/ppc/math-emu/single.h diff --git a/trunk/arch/powerpc/math-emu/soft-fp.h b/trunk/arch/ppc/math-emu/soft-fp.h similarity index 100% rename from trunk/arch/powerpc/math-emu/soft-fp.h rename to trunk/arch/ppc/math-emu/soft-fp.h diff --git a/trunk/arch/powerpc/math-emu/stfd.c b/trunk/arch/ppc/math-emu/stfd.c similarity index 100% rename from trunk/arch/powerpc/math-emu/stfd.c rename to trunk/arch/ppc/math-emu/stfd.c diff --git a/trunk/arch/powerpc/math-emu/stfiwx.c b/trunk/arch/ppc/math-emu/stfiwx.c similarity index 100% rename from trunk/arch/powerpc/math-emu/stfiwx.c rename to trunk/arch/ppc/math-emu/stfiwx.c diff --git a/trunk/arch/powerpc/math-emu/stfs.c b/trunk/arch/ppc/math-emu/stfs.c similarity index 100% rename from trunk/arch/powerpc/math-emu/stfs.c rename to trunk/arch/ppc/math-emu/stfs.c diff --git a/trunk/arch/powerpc/math-emu/types.c b/trunk/arch/ppc/math-emu/types.c similarity index 100% rename from trunk/arch/powerpc/math-emu/types.c rename to trunk/arch/ppc/math-emu/types.c diff --git a/trunk/arch/powerpc/math-emu/udivmodti4.c b/trunk/arch/ppc/math-emu/udivmodti4.c similarity index 100% rename from trunk/arch/powerpc/math-emu/udivmodti4.c rename to trunk/arch/ppc/math-emu/udivmodti4.c diff --git a/trunk/arch/ppc/mm/fault.c b/trunk/arch/ppc/mm/fault.c index 8e08ca32531a..0217188ef465 100644 --- a/trunk/arch/ppc/mm/fault.c +++ b/trunk/arch/ppc/mm/fault.c @@ -202,7 +202,6 @@ int do_page_fault(struct pt_regs *regs, unsigned long address, /* an exec - 4xx/Book-E allows for per-page execute permission */ } else if (TRAP(regs) == 0x400) { pte_t *ptep; - pmd_t *pmdp; #if 0 /* It would be nice to actually enforce the VM execute @@ -216,24 +215,21 @@ int do_page_fault(struct pt_regs *regs, unsigned long address, /* Since 4xx/Book-E supports per-page execute permission, * we lazily flush dcache to icache. */ ptep = NULL; - if (get_pteptr(mm, address, &ptep, &pmdp)) { - spinlock_t *ptl = pte_lockptr(mm, pmdp); - spin_lock(ptl); - if (pte_present(*ptep)) { - struct page *page = pte_page(*ptep); - - if (!test_bit(PG_arch_1, &page->flags)) { - flush_dcache_icache_page(page); - set_bit(PG_arch_1, &page->flags); - } - pte_update(ptep, 0, _PAGE_HWEXEC); - _tlbie(address); - pte_unmap_unlock(ptep, ptl); - up_read(&mm->mmap_sem); - return 0; + if (get_pteptr(mm, address, &ptep) && pte_present(*ptep)) { + struct page *page = pte_page(*ptep); + + if (! test_bit(PG_arch_1, &page->flags)) { + flush_dcache_icache_page(page); + set_bit(PG_arch_1, &page->flags); } - pte_unmap_unlock(ptep, ptl); + pte_update(ptep, 0, _PAGE_HWEXEC); + _tlbie(address); + pte_unmap(ptep); + up_read(&mm->mmap_sem); + return 0; } + if (ptep != NULL) + pte_unmap(ptep); #endif /* a read */ } else { diff --git a/trunk/arch/ppc/mm/hashtable.S b/trunk/arch/ppc/mm/hashtable.S index 31d0a924317c..f09fa88db35a 100644 --- a/trunk/arch/ppc/mm/hashtable.S +++ b/trunk/arch/ppc/mm/hashtable.S @@ -74,6 +74,12 @@ _GLOBAL(hash_page_sync) */ .text _GLOBAL(hash_page) +#ifdef CONFIG_PPC64BRIDGE + mfmsr r0 + clrldi r0,r0,1 /* make sure it's in 32-bit mode */ + MTMSRD(r0) + isync +#endif tophys(r7,0) /* gets -KERNELBASE into r7 */ #ifdef CONFIG_SMP addis r8,r7,mmu_hash_lock@h @@ -297,6 +303,7 @@ Hash_base = 0xc0180000 Hash_bits = 12 /* e.g. 256kB hash table */ Hash_msk = (((1 << Hash_bits) - 1) * 64) +#ifndef CONFIG_PPC64BRIDGE /* defines for the PTE format for 32-bit PPCs */ #define PTE_SIZE 8 #define PTEG_SIZE 64 @@ -310,6 +317,21 @@ Hash_msk = (((1 << Hash_bits) - 1) * 64) #define SET_V(r) oris r,r,PTE_V@h #define CLR_V(r,t) rlwinm r,r,0,1,31 +#else +/* defines for the PTE format for 64-bit PPCs */ +#define PTE_SIZE 16 +#define PTEG_SIZE 128 +#define LG_PTEG_SIZE 7 +#define LDPTEu ldu +#define STPTE std +#define CMPPTE cmpd +#define PTE_H 2 +#define PTE_V 1 +#define TST_V(r) andi. r,r,PTE_V +#define SET_V(r) ori r,r,PTE_V +#define CLR_V(r,t) li t,PTE_V; andc r,r,t +#endif /* CONFIG_PPC64BRIDGE */ + #define HASH_LEFT 31-(LG_PTEG_SIZE+Hash_bits-1) #define HASH_RIGHT 31-LG_PTEG_SIZE @@ -327,8 +349,14 @@ BEGIN_FTR_SECTION END_FTR_SECTION_IFSET(CPU_FTR_NEED_COHERENT) /* Construct the high word of the PPC-style PTE (r5) */ +#ifndef CONFIG_PPC64BRIDGE rlwinm r5,r3,7,1,24 /* put VSID in 0x7fffff80 bits */ rlwimi r5,r4,10,26,31 /* put in API (abbrev page index) */ +#else /* CONFIG_PPC64BRIDGE */ + clrlwi r3,r3,8 /* reduce vsid to 24 bits */ + sldi r5,r3,12 /* shift vsid into position */ + rlwimi r5,r4,16,20,24 /* put in API (abbrev page index) */ +#endif /* CONFIG_PPC64BRIDGE */ SET_V(r5) /* set V (valid) bit */ /* Get the address of the primary PTE group in the hash table (r3) */ @@ -512,8 +540,14 @@ _GLOBAL(flush_hash_pages) add r3,r3,r0 /* note code below trims to 24 bits */ /* Construct the high word of the PPC-style PTE (r11) */ +#ifndef CONFIG_PPC64BRIDGE rlwinm r11,r3,7,1,24 /* put VSID in 0x7fffff80 bits */ rlwimi r11,r4,10,26,31 /* put in API (abbrev page index) */ +#else /* CONFIG_PPC64BRIDGE */ + clrlwi r3,r3,8 /* reduce vsid to 24 bits */ + sldi r11,r3,12 /* shift vsid into position */ + rlwimi r11,r4,16,20,24 /* put in API (abbrev page index) */ +#endif /* CONFIG_PPC64BRIDGE */ SET_V(r11) /* set V (valid) bit */ #ifdef CONFIG_SMP diff --git a/trunk/arch/ppc/mm/init.c b/trunk/arch/ppc/mm/init.c index 386e000bcb73..cb1c294fb932 100644 --- a/trunk/arch/ppc/mm/init.c +++ b/trunk/arch/ppc/mm/init.c @@ -412,6 +412,14 @@ void __init mem_init(void) } #endif /* CONFIG_BLK_DEV_INITRD */ +#ifdef CONFIG_PPC_OF + /* mark the RTAS pages as reserved */ + if ( rtas_data ) + for (addr = (ulong)__va(rtas_data); + addr < PAGE_ALIGN((ulong)__va(rtas_data)+rtas_size) ; + addr += PAGE_SIZE) + SetPageReserved(virt_to_page(addr)); +#endif for (addr = PAGE_OFFSET; addr < (unsigned long)high_memory; addr += PAGE_SIZE) { if (!PageReserved(virt_to_page(addr))) @@ -486,6 +494,11 @@ set_phys_avail(unsigned long total_memory) initrd_end - initrd_start, 1); } #endif /* CONFIG_BLK_DEV_INITRD */ +#ifdef CONFIG_PPC_OF + /* remove the RTAS pages from the available memory */ + if (rtas_data) + mem_pieces_remove(&phys_avail, rtas_data, rtas_size, 1); +#endif } /* Mark some memory as reserved by removing it from phys_avail. */ diff --git a/trunk/arch/ppc/mm/mmu_context.c b/trunk/arch/ppc/mm/mmu_context.c index b4a4b3f02a1c..a8816e0f6a86 100644 --- a/trunk/arch/ppc/mm/mmu_context.c +++ b/trunk/arch/ppc/mm/mmu_context.c @@ -2,7 +2,7 @@ * This file contains the routines for handling the MMU on those * PowerPC implementations where the MMU substantially follows the * architecture specification. This includes the 6xx, 7xx, 7xxx, - * 8260, and 83xx implementations but excludes the 8xx and 4xx. + * 8260, and POWER3 implementations but excludes the 8xx and 4xx. * -- paulus * * Derived from arch/ppc/mm/init.c: diff --git a/trunk/arch/ppc/mm/pgtable.c b/trunk/arch/ppc/mm/pgtable.c index 706bca8eb144..6ea9185fd120 100644 --- a/trunk/arch/ppc/mm/pgtable.c +++ b/trunk/arch/ppc/mm/pgtable.c @@ -39,7 +39,7 @@ unsigned long ioremap_base; unsigned long ioremap_bot; int io_bat_index; -#if defined(CONFIG_6xx) +#if defined(CONFIG_6xx) || defined(CONFIG_POWER3) #define HAVE_BATS 1 #endif @@ -368,7 +368,7 @@ void __init io_block_mapping(unsigned long virt, phys_addr_t phys, * the PTE pointer is unmodified if PTE is not found. */ int -get_pteptr(struct mm_struct *mm, unsigned long addr, pte_t **ptep, pmd_t **pmdp) +get_pteptr(struct mm_struct *mm, unsigned long addr, pte_t **ptep) { pgd_t *pgd; pmd_t *pmd; @@ -383,8 +383,6 @@ get_pteptr(struct mm_struct *mm, unsigned long addr, pte_t **ptep, pmd_t **pmdp) if (pte) { retval = 1; *ptep = pte; - if (pmdp) - *pmdp = pmd; /* XXX caller needs to do pte_unmap, yuck */ } } @@ -422,7 +420,7 @@ unsigned long iopa(unsigned long addr) mm = &init_mm; pa = 0; - if (get_pteptr(mm, addr, &pte, NULL)) { + if (get_pteptr(mm, addr, &pte)) { pa = (pte_val(*pte) & PAGE_MASK) | (addr & ~PAGE_MASK); pte_unmap(pte); } diff --git a/trunk/arch/ppc/mm/ppc_mmu.c b/trunk/arch/ppc/mm/ppc_mmu.c index 25bb6f3347c1..9a381ed5eb21 100644 --- a/trunk/arch/ppc/mm/ppc_mmu.c +++ b/trunk/arch/ppc/mm/ppc_mmu.c @@ -2,7 +2,7 @@ * This file contains the routines for handling the MMU on those * PowerPC implementations where the MMU substantially follows the * architecture specification. This includes the 6xx, 7xx, 7xxx, - * 8260, and 83xx implementations but excludes the 8xx and 4xx. + * 8260, and POWER3 implementations but excludes the 8xx and 4xx. * -- paulus * * Derived from arch/ppc/mm/init.c: @@ -42,7 +42,11 @@ unsigned long _SDR1; union ubat { /* BAT register values to be loaded */ BAT bat; +#ifdef CONFIG_PPC64BRIDGE + u64 word[2]; +#else u32 word[2]; +#endif } BATS[4][2]; /* 4 pairs of IBAT, DBAT */ struct batrange { /* stores address ranges mapped by BATs */ @@ -79,6 +83,9 @@ unsigned long p_mapped_by_bats(unsigned long pa) unsigned long __init mmu_mapin_ram(void) { +#ifdef CONFIG_POWER4 + return 0; +#else unsigned long tot, bl, done; unsigned long max_size = (256<<20); unsigned long align; @@ -115,6 +122,7 @@ unsigned long __init mmu_mapin_ram(void) } return done; +#endif } /* @@ -197,10 +205,27 @@ void __init MMU_init_hw(void) if ( ppc_md.progress ) ppc_md.progress("hash:enter", 0x105); +#ifdef CONFIG_PPC64BRIDGE +#define LG_HPTEG_SIZE 7 /* 128 bytes per HPTEG */ +#define SDR1_LOW_BITS (lg_n_hpteg - 11) +#define MIN_N_HPTEG 2048 /* min 256kB hash table */ +#else #define LG_HPTEG_SIZE 6 /* 64 bytes per HPTEG */ #define SDR1_LOW_BITS ((n_hpteg - 1) >> 10) #define MIN_N_HPTEG 1024 /* min 64kB hash table */ +#endif + +#ifdef CONFIG_POWER4 + /* The hash table has already been allocated and initialized + in prom.c */ + n_hpteg = Hash_size >> LG_HPTEG_SIZE; + lg_n_hpteg = __ilog2(n_hpteg); + + /* Remove the hash table from the available memory */ + if (Hash) + reserve_phys_mem(__pa(Hash), Hash_size); +#else /* CONFIG_POWER4 */ /* * Allow 1 HPTE (1/8 HPTEG) for each page of memory. * This is less than the recommended amount, but then @@ -223,6 +248,7 @@ void __init MMU_init_hw(void) Hash = mem_pieces_find(Hash_size, Hash_size); cacheable_memzero(Hash, Hash_size); _SDR1 = __pa(Hash) | SDR1_LOW_BITS; +#endif /* CONFIG_POWER4 */ Hash_end = (PTE *) ((unsigned long)Hash + Hash_size); diff --git a/trunk/arch/ppc/platforms/Makefile b/trunk/arch/ppc/platforms/Makefile index 90c622294423..e8b91a33ce91 100644 --- a/trunk/arch/ppc/platforms/Makefile +++ b/trunk/arch/ppc/platforms/Makefile @@ -2,10 +2,18 @@ # Makefile for the linux kernel. # +# Extra CFLAGS so we don't have to do relative includes +CFLAGS_chrp_setup.o += -Iarch/$(ARCH)/mm + obj-$(CONFIG_APUS) += apus_setup.o ifeq ($(CONFIG_APUS),y) obj-$(CONFIG_PCI) += apus_pci.o endif +obj-$(CONFIG_PPC_CHRP) += chrp_setup.o chrp_time.o chrp_pci.o \ + chrp_pegasos_eth.o +ifeq ($(CONFIG_PPC_CHRP),y) +obj-$(CONFIG_NVRAM) += chrp_nvram.o +endif obj-$(CONFIG_PPC_PREP) += prep_pci.o prep_setup.o obj-$(CONFIG_PREP_RESIDUAL) += residual.o obj-$(CONFIG_PQ2ADS) += pq2ads.o @@ -32,3 +40,7 @@ obj-$(CONFIG_EV64360) += ev64360.o obj-$(CONFIG_MPC86XADS) += mpc866ads_setup.o obj-$(CONFIG_MPC885ADS) += mpc885ads_setup.o obj-$(CONFIG_ADS8272) += mpc8272ads_setup.o + +ifeq ($(CONFIG_SMP),y) +obj-$(CONFIG_PPC_CHRP) += chrp_smp.o +endif diff --git a/trunk/arch/ppc/platforms/chrp_nvram.c b/trunk/arch/ppc/platforms/chrp_nvram.c new file mode 100644 index 000000000000..465ba9b090ef --- /dev/null +++ b/trunk/arch/ppc/platforms/chrp_nvram.c @@ -0,0 +1,83 @@ +/* + * c 2001 PPC 64 Team, IBM Corp + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + * + * /dev/nvram driver for PPC + * + */ + +#include +#include +#include +#include +#include +#include +#include + +static unsigned int nvram_size; +static unsigned char nvram_buf[4]; +static DEFINE_SPINLOCK(nvram_lock); + +static unsigned char chrp_nvram_read(int addr) +{ + unsigned long done, flags; + unsigned char ret; + + if (addr >= nvram_size) { + printk(KERN_DEBUG "%s: read addr %d > nvram_size %u\n", + current->comm, addr, nvram_size); + return 0xff; + } + spin_lock_irqsave(&nvram_lock, flags); + if ((call_rtas("nvram-fetch", 3, 2, &done, addr, __pa(nvram_buf), 1) != 0) || 1 != done) + ret = 0xff; + else + ret = nvram_buf[0]; + spin_unlock_irqrestore(&nvram_lock, flags); + + return ret; +} + +static void chrp_nvram_write(int addr, unsigned char val) +{ + unsigned long done, flags; + + if (addr >= nvram_size) { + printk(KERN_DEBUG "%s: write addr %d > nvram_size %u\n", + current->comm, addr, nvram_size); + return; + } + spin_lock_irqsave(&nvram_lock, flags); + nvram_buf[0] = val; + if ((call_rtas("nvram-store", 3, 2, &done, addr, __pa(nvram_buf), 1) != 0) || 1 != done) + printk(KERN_DEBUG "rtas IO error storing 0x%02x at %d", val, addr); + spin_unlock_irqrestore(&nvram_lock, flags); +} + +void __init chrp_nvram_init(void) +{ + struct device_node *nvram; + unsigned int *nbytes_p, proplen; + + nvram = of_find_node_by_type(NULL, "nvram"); + if (nvram == NULL) + return; + + nbytes_p = (unsigned int *)get_property(nvram, "#bytes", &proplen); + if (nbytes_p == NULL || proplen != sizeof(unsigned int)) + return; + + nvram_size = *nbytes_p; + + printk(KERN_INFO "CHRP nvram contains %u bytes\n", nvram_size); + of_node_put(nvram); + + ppc_md.nvram_read_val = chrp_nvram_read; + ppc_md.nvram_write_val = chrp_nvram_write; + + return; +} diff --git a/trunk/arch/ppc/platforms/chrp_pci.c b/trunk/arch/ppc/platforms/chrp_pci.c new file mode 100644 index 000000000000..c7fe6182bb77 --- /dev/null +++ b/trunk/arch/ppc/platforms/chrp_pci.c @@ -0,0 +1,309 @@ +/* + * CHRP pci routines. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* LongTrail */ +void __iomem *gg2_pci_config_base; + +/* + * The VLSI Golden Gate II has only 512K of PCI configuration space, so we + * limit the bus number to 3 bits + */ + +int gg2_read_config(struct pci_bus *bus, unsigned int devfn, int off, + int len, u32 *val) +{ + volatile void __iomem *cfg_data; + struct pci_controller *hose = bus->sysdata; + + if (bus->number > 7) + return PCIBIOS_DEVICE_NOT_FOUND; + /* + * Note: the caller has already checked that off is + * suitably aligned and that len is 1, 2 or 4. + */ + cfg_data = hose->cfg_data + ((bus->number<<16) | (devfn<<8) | off); + switch (len) { + case 1: + *val = in_8(cfg_data); + break; + case 2: + *val = in_le16(cfg_data); + break; + default: + *val = in_le32(cfg_data); + break; + } + return PCIBIOS_SUCCESSFUL; +} + +int gg2_write_config(struct pci_bus *bus, unsigned int devfn, int off, + int len, u32 val) +{ + volatile void __iomem *cfg_data; + struct pci_controller *hose = bus->sysdata; + + if (bus->number > 7) + return PCIBIOS_DEVICE_NOT_FOUND; + /* + * Note: the caller has already checked that off is + * suitably aligned and that len is 1, 2 or 4. + */ + cfg_data = hose->cfg_data + ((bus->number<<16) | (devfn<<8) | off); + switch (len) { + case 1: + out_8(cfg_data, val); + break; + case 2: + out_le16(cfg_data, val); + break; + default: + out_le32(cfg_data, val); + break; + } + return PCIBIOS_SUCCESSFUL; +} + +static struct pci_ops gg2_pci_ops = +{ + gg2_read_config, + gg2_write_config +}; + +/* + * Access functions for PCI config space using RTAS calls. + */ +int +rtas_read_config(struct pci_bus *bus, unsigned int devfn, int offset, + int len, u32 *val) +{ + struct pci_controller *hose = bus->sysdata; + unsigned long addr = (offset & 0xff) | ((devfn & 0xff) << 8) + | (((bus->number - hose->first_busno) & 0xff) << 16) + | (hose->index << 24); + unsigned long ret = ~0UL; + int rval; + + rval = call_rtas("read-pci-config", 2, 2, &ret, addr, len); + *val = ret; + return rval? PCIBIOS_DEVICE_NOT_FOUND: PCIBIOS_SUCCESSFUL; +} + +int +rtas_write_config(struct pci_bus *bus, unsigned int devfn, int offset, + int len, u32 val) +{ + struct pci_controller *hose = bus->sysdata; + unsigned long addr = (offset & 0xff) | ((devfn & 0xff) << 8) + | (((bus->number - hose->first_busno) & 0xff) << 16) + | (hose->index << 24); + int rval; + + rval = call_rtas("write-pci-config", 3, 1, NULL, addr, len, val); + return rval? PCIBIOS_DEVICE_NOT_FOUND: PCIBIOS_SUCCESSFUL; +} + +static struct pci_ops rtas_pci_ops = +{ + rtas_read_config, + rtas_write_config +}; + +volatile struct Hydra __iomem *Hydra = NULL; + +int __init +hydra_init(void) +{ + struct device_node *np; + + np = find_devices("mac-io"); + if (np == NULL || np->n_addrs == 0) + return 0; + Hydra = ioremap(np->addrs[0].address, np->addrs[0].size); + printk("Hydra Mac I/O at %x\n", np->addrs[0].address); + printk("Hydra Feature_Control was %x", + in_le32(&Hydra->Feature_Control)); + out_le32(&Hydra->Feature_Control, (HYDRA_FC_SCC_CELL_EN | + HYDRA_FC_SCSI_CELL_EN | + HYDRA_FC_SCCA_ENABLE | + HYDRA_FC_SCCB_ENABLE | + HYDRA_FC_ARB_BYPASS | + HYDRA_FC_MPIC_ENABLE | + HYDRA_FC_SLOW_SCC_PCLK | + HYDRA_FC_MPIC_IS_MASTER)); + printk(", now %x\n", in_le32(&Hydra->Feature_Control)); + return 1; +} + +void __init +chrp_pcibios_fixup(void) +{ + struct pci_dev *dev = NULL; + struct device_node *np; + + /* PCI interrupts are controlled by the OpenPIC */ + for_each_pci_dev(dev) { + np = pci_device_to_OF_node(dev); + if ((np != 0) && (np->n_intrs > 0) && (np->intrs[0].line != 0)) + dev->irq = np->intrs[0].line; + pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq); + } +} + +#define PRG_CL_RESET_VALID 0x00010000 + +static void __init +setup_python(struct pci_controller *hose, struct device_node *dev) +{ + u32 __iomem *reg; + u32 val; + unsigned long addr = dev->addrs[0].address; + + setup_indirect_pci(hose, addr + 0xf8000, addr + 0xf8010); + + /* Clear the magic go-slow bit */ + reg = ioremap(dev->addrs[0].address + 0xf6000, 0x40); + val = in_be32(®[12]); + if (val & PRG_CL_RESET_VALID) { + out_be32(®[12], val & ~PRG_CL_RESET_VALID); + in_be32(®[12]); + } + iounmap(reg); +} + +/* Marvell Discovery II based Pegasos 2 */ +static void __init setup_peg2(struct pci_controller *hose, struct device_node *dev) +{ + struct device_node *root = find_path_device("/"); + struct device_node *rtas; + + rtas = of_find_node_by_name (root, "rtas"); + if (rtas) { + hose->ops = &rtas_pci_ops; + } else { + printk ("RTAS supporting Pegasos OF not found, please upgrade" + " your firmware\n"); + } + pci_assign_all_buses = 1; +} + +void __init +chrp_find_bridges(void) +{ + struct device_node *dev; + int *bus_range; + int len, index = -1; + struct pci_controller *hose; + unsigned int *dma; + char *model, *machine; + int is_longtrail = 0, is_mot = 0, is_pegasos = 0; + struct device_node *root = find_path_device("/"); + + /* + * The PCI host bridge nodes on some machines don't have + * properties to adequately identify them, so we have to + * look at what sort of machine this is as well. + */ + machine = get_property(root, "model", NULL); + if (machine != NULL) { + is_longtrail = strncmp(machine, "IBM,LongTrail", 13) == 0; + is_mot = strncmp(machine, "MOT", 3) == 0; + if (strncmp(machine, "Pegasos2", 8) == 0) + is_pegasos = 2; + else if (strncmp(machine, "Pegasos", 7) == 0) + is_pegasos = 1; + } + for (dev = root->child; dev != NULL; dev = dev->sibling) { + if (dev->type == NULL || strcmp(dev->type, "pci") != 0) + continue; + ++index; + /* The GG2 bridge on the LongTrail doesn't have an address */ + if (dev->n_addrs < 1 && !is_longtrail) { + printk(KERN_WARNING "Can't use %s: no address\n", + dev->full_name); + continue; + } + bus_range = (int *) get_property(dev, "bus-range", &len); + if (bus_range == NULL || len < 2 * sizeof(int)) { + printk(KERN_WARNING "Can't get bus-range for %s\n", + dev->full_name); + continue; + } + if (bus_range[1] == bus_range[0]) + printk(KERN_INFO "PCI bus %d", bus_range[0]); + else + printk(KERN_INFO "PCI buses %d..%d", + bus_range[0], bus_range[1]); + printk(" controlled by %s", dev->type); + if (dev->n_addrs > 0) + printk(" at %x", dev->addrs[0].address); + printk("\n"); + + hose = pcibios_alloc_controller(); + if (!hose) { + printk("Can't allocate PCI controller structure for %s\n", + dev->full_name); + continue; + } + hose->arch_data = dev; + hose->first_busno = bus_range[0]; + hose->last_busno = bus_range[1]; + + model = get_property(dev, "model", NULL); + if (model == NULL) + model = ""; + if (device_is_compatible(dev, "IBM,python")) { + setup_python(hose, dev); + } else if (is_mot + || strncmp(model, "Motorola, Grackle", 17) == 0) { + setup_indirect_pci(hose, 0xfec00000, 0xfee00000); + } else if (is_longtrail) { + void __iomem *p = ioremap(GG2_PCI_CONFIG_BASE, 0x80000); + hose->ops = &gg2_pci_ops; + hose->cfg_data = p; + gg2_pci_config_base = p; + } else if (is_pegasos == 1) { + setup_indirect_pci(hose, 0xfec00cf8, 0xfee00cfc); + } else if (is_pegasos == 2) { + setup_peg2(hose, dev); + } else { + printk("No methods for %s (model %s), using RTAS\n", + dev->full_name, model); + hose->ops = &rtas_pci_ops; + } + + pci_process_bridge_OF_ranges(hose, dev, index == 0); + + /* check the first bridge for a property that we can + use to set pci_dram_offset */ + dma = (unsigned int *) + get_property(dev, "ibm,dma-ranges", &len); + if (index == 0 && dma != NULL && len >= 6 * sizeof(*dma)) { + pci_dram_offset = dma[2] - dma[3]; + printk("pci_dram_offset = %lx\n", pci_dram_offset); + } + } + + /* Do not fixup interrupts from OF tree on pegasos */ + if (is_pegasos == 0) + ppc_md.pcibios_fixup = chrp_pcibios_fixup; +} diff --git a/trunk/arch/ppc/platforms/chrp_pegasos_eth.c b/trunk/arch/ppc/platforms/chrp_pegasos_eth.c new file mode 100644 index 000000000000..9305c8aa1373 --- /dev/null +++ b/trunk/arch/ppc/platforms/chrp_pegasos_eth.c @@ -0,0 +1,211 @@ +/* + * Copyright (C) 2005 Sven Luther + * Thanks to : + * Dale Farnsworth + * Mark A. Greer + * Nicolas DET + * Benjamin Herrenschmidt + * And anyone else who helped me on this. + */ + +#include +#include +#include +#include +#include +#include + +#define PEGASOS2_MARVELL_REGBASE (0xf1000000) +#define PEGASOS2_MARVELL_REGSIZE (0x00004000) +#define PEGASOS2_SRAM_BASE (0xf2000000) +#define PEGASOS2_SRAM_SIZE (256*1024) + +#define PEGASOS2_SRAM_BASE_ETH0 (PEGASOS2_SRAM_BASE) +#define PEGASOS2_SRAM_BASE_ETH1 (PEGASOS2_SRAM_BASE_ETH0 + (PEGASOS2_SRAM_SIZE / 2) ) + + +#define PEGASOS2_SRAM_RXRING_SIZE (PEGASOS2_SRAM_SIZE/4) +#define PEGASOS2_SRAM_TXRING_SIZE (PEGASOS2_SRAM_SIZE/4) + +#undef BE_VERBOSE + +static struct resource mv643xx_eth_shared_resources[] = { + [0] = { + .name = "ethernet shared base", + .start = 0xf1000000 + MV643XX_ETH_SHARED_REGS, + .end = 0xf1000000 + MV643XX_ETH_SHARED_REGS + + MV643XX_ETH_SHARED_REGS_SIZE - 1, + .flags = IORESOURCE_MEM, + }, +}; + +static struct platform_device mv643xx_eth_shared_device = { + .name = MV643XX_ETH_SHARED_NAME, + .id = 0, + .num_resources = ARRAY_SIZE(mv643xx_eth_shared_resources), + .resource = mv643xx_eth_shared_resources, +}; + +static struct resource mv643xx_eth0_resources[] = { + [0] = { + .name = "eth0 irq", + .start = 9, + .end = 9, + .flags = IORESOURCE_IRQ, + }, +}; + + +static struct mv643xx_eth_platform_data eth0_pd = { + .tx_sram_addr = PEGASOS2_SRAM_BASE_ETH0, + .tx_sram_size = PEGASOS2_SRAM_TXRING_SIZE, + .tx_queue_size = PEGASOS2_SRAM_TXRING_SIZE/16, + + .rx_sram_addr = PEGASOS2_SRAM_BASE_ETH0 + PEGASOS2_SRAM_TXRING_SIZE, + .rx_sram_size = PEGASOS2_SRAM_RXRING_SIZE, + .rx_queue_size = PEGASOS2_SRAM_RXRING_SIZE/16, +}; + +static struct platform_device eth0_device = { + .name = MV643XX_ETH_NAME, + .id = 0, + .num_resources = ARRAY_SIZE(mv643xx_eth0_resources), + .resource = mv643xx_eth0_resources, + .dev = { + .platform_data = ð0_pd, + }, +}; + +static struct resource mv643xx_eth1_resources[] = { + [0] = { + .name = "eth1 irq", + .start = 9, + .end = 9, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct mv643xx_eth_platform_data eth1_pd = { + .tx_sram_addr = PEGASOS2_SRAM_BASE_ETH1, + .tx_sram_size = PEGASOS2_SRAM_TXRING_SIZE, + .tx_queue_size = PEGASOS2_SRAM_TXRING_SIZE/16, + + .rx_sram_addr = PEGASOS2_SRAM_BASE_ETH1 + PEGASOS2_SRAM_TXRING_SIZE, + .rx_sram_size = PEGASOS2_SRAM_RXRING_SIZE, + .rx_queue_size = PEGASOS2_SRAM_RXRING_SIZE/16, +}; + +static struct platform_device eth1_device = { + .name = MV643XX_ETH_NAME, + .id = 1, + .num_resources = ARRAY_SIZE(mv643xx_eth1_resources), + .resource = mv643xx_eth1_resources, + .dev = { + .platform_data = ð1_pd, + }, +}; + +static struct platform_device *mv643xx_eth_pd_devs[] __initdata = { + &mv643xx_eth_shared_device, + ð0_device, + ð1_device, +}; + +/***********/ +/***********/ +#define MV_READ(offset,val) { val = readl(mv643xx_reg_base + offset); } +#define MV_WRITE(offset,data) writel(data, mv643xx_reg_base + offset) + +static void __iomem *mv643xx_reg_base; + +static int Enable_SRAM(void) +{ + u32 ALong; + + if (mv643xx_reg_base == NULL) + mv643xx_reg_base = ioremap(PEGASOS2_MARVELL_REGBASE, + PEGASOS2_MARVELL_REGSIZE); + + if (mv643xx_reg_base == NULL) + return -ENOMEM; + +#ifdef BE_VERBOSE + printk("Pegasos II/Marvell MV64361: register remapped from %p to %p\n", + (void *)PEGASOS2_MARVELL_REGBASE, (void *)mv643xx_reg_base); +#endif + + MV_WRITE(MV64340_SRAM_CONFIG, 0); + + MV_WRITE(MV64340_INTEGRATED_SRAM_BASE_ADDR, PEGASOS2_SRAM_BASE >> 16); + + MV_READ(MV64340_BASE_ADDR_ENABLE, ALong); + ALong &= ~(1 << 19); + MV_WRITE(MV64340_BASE_ADDR_ENABLE, ALong); + + ALong = 0x02; + ALong |= PEGASOS2_SRAM_BASE & 0xffff0000; + MV_WRITE(MV643XX_ETH_BAR_4, ALong); + + MV_WRITE(MV643XX_ETH_SIZE_REG_4, (PEGASOS2_SRAM_SIZE-1) & 0xffff0000); + + MV_READ(MV643XX_ETH_BASE_ADDR_ENABLE_REG, ALong); + ALong &= ~(1 << 4); + MV_WRITE(MV643XX_ETH_BASE_ADDR_ENABLE_REG, ALong); + +#ifdef BE_VERBOSE + printk("Pegasos II/Marvell MV64361: register unmapped\n"); + printk("Pegasos II/Marvell MV64361: SRAM at %p, size=%x\n", (void*) PEGASOS2_SRAM_BASE, PEGASOS2_SRAM_SIZE); +#endif + + iounmap(mv643xx_reg_base); + mv643xx_reg_base = NULL; + + return 1; +} + + +/***********/ +/***********/ +int mv643xx_eth_add_pds(void) +{ + int ret = 0; + static struct pci_device_id pci_marvell_mv64360[] = { + { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, PCI_DEVICE_ID_MARVELL_MV64360) }, + { } + }; + +#ifdef BE_VERBOSE + printk("Pegasos II/Marvell MV64361: init\n"); +#endif + + if (pci_dev_present(pci_marvell_mv64360)) { + ret = platform_add_devices(mv643xx_eth_pd_devs, + ARRAY_SIZE(mv643xx_eth_pd_devs)); + + if ( Enable_SRAM() < 0) + { + eth0_pd.tx_sram_addr = 0; + eth0_pd.tx_sram_size = 0; + eth0_pd.rx_sram_addr = 0; + eth0_pd.rx_sram_size = 0; + + eth1_pd.tx_sram_addr = 0; + eth1_pd.tx_sram_size = 0; + eth1_pd.rx_sram_addr = 0; + eth1_pd.rx_sram_size = 0; + +#ifdef BE_VERBOSE + printk("Pegasos II/Marvell MV64361: Can't enable the " + "SRAM\n"); +#endif + } + } + +#ifdef BE_VERBOSE + printk("Pegasos II/Marvell MV64361: init is over\n"); +#endif + + return ret; +} + +device_initcall(mv643xx_eth_add_pds); diff --git a/trunk/arch/ppc/platforms/chrp_setup.c b/trunk/arch/ppc/platforms/chrp_setup.c new file mode 100644 index 000000000000..f9fd3f4f8e2e --- /dev/null +++ b/trunk/arch/ppc/platforms/chrp_setup.c @@ -0,0 +1,669 @@ +/* + * Copyright (C) 1995 Linus Torvalds + * Adapted from 'alpha' version by Gary Thomas + * Modified by Cort Dougan (cort@cs.nmt.edu) + */ + +/* + * bootup setup stuff.. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "mem_pieces.h" + +unsigned long chrp_get_rtc_time(void); +int chrp_set_rtc_time(unsigned long nowtime); +void chrp_calibrate_decr(void); +long chrp_time_init(void); + +void chrp_find_bridges(void); +void chrp_event_scan(void); +void rtas_display_progress(char *, unsigned short); +void rtas_indicator_progress(char *, unsigned short); +void btext_progress(char *, unsigned short); + +extern int of_show_percpuinfo(struct seq_file *, int); + +int _chrp_type; +EXPORT_SYMBOL(_chrp_type); + +/* + * XXX this should be in xmon.h, but putting it there means xmon.h + * has to include (to get irqreturn_t), which + * causes all sorts of problems. -- paulus + */ +extern irqreturn_t xmon_irq(int, void *, struct pt_regs *); + +extern dev_t boot_dev; + +extern PTE *Hash, *Hash_end; +extern unsigned long Hash_size, Hash_mask; +extern int probingmem; +extern unsigned long loops_per_jiffy; +static int max_width; + +#ifdef CONFIG_SMP +extern struct smp_ops_t chrp_smp_ops; +#endif + +static const char *gg2_memtypes[4] = { + "FPM", "SDRAM", "EDO", "BEDO" +}; +static const char *gg2_cachesizes[4] = { + "256 KB", "512 KB", "1 MB", "Reserved" +}; +static const char *gg2_cachetypes[4] = { + "Asynchronous", "Reserved", "Flow-Through Synchronous", + "Pipelined Synchronous" +}; +static const char *gg2_cachemodes[4] = { + "Disabled", "Write-Through", "Copy-Back", "Transparent Mode" +}; + +int +chrp_show_cpuinfo(struct seq_file *m) +{ + int i, sdramen; + unsigned int t; + struct device_node *root; + const char *model = ""; + + root = find_path_device("/"); + if (root) + model = get_property(root, "model", NULL); + seq_printf(m, "machine\t\t: CHRP %s\n", model); + + /* longtrail (goldengate) stuff */ + if (!strncmp(model, "IBM,LongTrail", 13)) { + /* VLSI VAS96011/12 `Golden Gate 2' */ + /* Memory banks */ + sdramen = (in_le32(gg2_pci_config_base + GG2_PCI_DRAM_CTRL) + >>31) & 1; + for (i = 0; i < (sdramen ? 4 : 6); i++) { + t = in_le32(gg2_pci_config_base+ + GG2_PCI_DRAM_BANK0+ + i*4); + if (!(t & 1)) + continue; + switch ((t>>8) & 0x1f) { + case 0x1f: + model = "4 MB"; + break; + case 0x1e: + model = "8 MB"; + break; + case 0x1c: + model = "16 MB"; + break; + case 0x18: + model = "32 MB"; + break; + case 0x10: + model = "64 MB"; + break; + case 0x00: + model = "128 MB"; + break; + default: + model = "Reserved"; + break; + } + seq_printf(m, "memory bank %d\t: %s %s\n", i, model, + gg2_memtypes[sdramen ? 1 : ((t>>1) & 3)]); + } + /* L2 cache */ + t = in_le32(gg2_pci_config_base+GG2_PCI_CC_CTRL); + seq_printf(m, "board l2\t: %s %s (%s)\n", + gg2_cachesizes[(t>>7) & 3], + gg2_cachetypes[(t>>2) & 3], + gg2_cachemodes[t & 3]); + } + return 0; +} + +/* + * Fixes for the National Semiconductor PC78308VUL SuperI/O + * + * Some versions of Open Firmware incorrectly initialize the IRQ settings + * for keyboard and mouse + */ +static inline void __init sio_write(u8 val, u8 index) +{ + outb(index, 0x15c); + outb(val, 0x15d); +} + +static inline u8 __init sio_read(u8 index) +{ + outb(index, 0x15c); + return inb(0x15d); +} + +static void __init sio_fixup_irq(const char *name, u8 device, u8 level, + u8 type) +{ + u8 level0, type0, active; + + /* select logical device */ + sio_write(device, 0x07); + active = sio_read(0x30); + level0 = sio_read(0x70); + type0 = sio_read(0x71); + if (level0 != level || type0 != type || !active) { + printk(KERN_WARNING "sio: %s irq level %d, type %d, %sactive: " + "remapping to level %d, type %d, active\n", + name, level0, type0, !active ? "in" : "", level, type); + sio_write(0x01, 0x30); + sio_write(level, 0x70); + sio_write(type, 0x71); + } +} + +static void __init sio_init(void) +{ + struct device_node *root; + + if ((root = find_path_device("/")) && + !strncmp(get_property(root, "model", NULL), "IBM,LongTrail", 13)) { + /* logical device 0 (KBC/Keyboard) */ + sio_fixup_irq("keyboard", 0, 1, 2); + /* select logical device 1 (KBC/Mouse) */ + sio_fixup_irq("mouse", 1, 12, 2); + } +} + + +static void __init pegasos_set_l2cr(void) +{ + struct device_node *np; + + /* On Pegasos, enable the l2 cache if needed, as the OF forgets it */ + if (_chrp_type != _CHRP_Pegasos) + return; + + /* Enable L2 cache if needed */ + np = find_type_devices("cpu"); + if (np != NULL) { + unsigned int *l2cr = (unsigned int *) + get_property (np, "l2cr", NULL); + if (l2cr == NULL) { + printk ("Pegasos l2cr : no cpu l2cr property found\n"); + return; + } + if (!((*l2cr) & 0x80000000)) { + printk ("Pegasos l2cr : L2 cache was not active, " + "activating\n"); + _set_L2CR(0); + _set_L2CR((*l2cr) | 0x80000000); + } + } +} + +void __init chrp_setup_arch(void) +{ + struct device_node *device; + + /* init to some ~sane value until calibrate_delay() runs */ + loops_per_jiffy = 50000000/HZ; + +#ifdef CONFIG_BLK_DEV_INITRD + /* this is fine for chrp */ + initrd_below_start_ok = 1; + + if (initrd_start) + ROOT_DEV = Root_RAM0; + else +#endif + ROOT_DEV = Root_SDA2; /* sda2 (sda1 is for the kernel) */ + + /* On pegasos, enable the L2 cache if not already done by OF */ + pegasos_set_l2cr(); + + /* Lookup PCI host bridges */ + chrp_find_bridges(); + +#ifndef CONFIG_PPC64BRIDGE + /* + * Temporary fixes for PCI devices. + * -- Geert + */ + hydra_init(); /* Mac I/O */ + +#endif /* CONFIG_PPC64BRIDGE */ + + /* + * Fix the Super I/O configuration + */ + sio_init(); + + /* Get the event scan rate for the rtas so we know how + * often it expects a heartbeat. -- Cort + */ + if ( rtas_data ) { + struct property *p; + device = find_devices("rtas"); + for ( p = device->properties; + p && strncmp(p->name, "rtas-event-scan-rate", 20); + p = p->next ) + /* nothing */ ; + if ( p && *(unsigned long *)p->value ) { + ppc_md.heartbeat = chrp_event_scan; + ppc_md.heartbeat_reset = (HZ/(*(unsigned long *)p->value)*30)-1; + ppc_md.heartbeat_count = 1; + printk("RTAS Event Scan Rate: %lu (%lu jiffies)\n", + *(unsigned long *)p->value, ppc_md.heartbeat_reset ); + } + } + + pci_create_OF_bus_map(); +} + +void +chrp_event_scan(void) +{ + unsigned char log[1024]; + unsigned long ret = 0; + /* XXX: we should loop until the hardware says no more error logs -- Cort */ + call_rtas( "event-scan", 4, 1, &ret, 0xffffffff, 0, + __pa(log), 1024 ); + ppc_md.heartbeat_count = ppc_md.heartbeat_reset; +} + +void +chrp_restart(char *cmd) +{ + printk("RTAS system-reboot returned %d\n", + call_rtas("system-reboot", 0, 1, NULL)); + for (;;); +} + +void +chrp_power_off(void) +{ + /* allow power on only with power button press */ + printk("RTAS power-off returned %d\n", + call_rtas("power-off", 2, 1, NULL,0xffffffff,0xffffffff)); + for (;;); +} + +void +chrp_halt(void) +{ + chrp_power_off(); +} + +/* + * Finds the open-pic node and sets OpenPIC_Addr based on its reg property. + * Then checks if it has an interrupt-ranges property. If it does then + * we have a distributed open-pic, so call openpic_set_sources to tell + * the openpic code where to find the interrupt source registers. + */ +static void __init chrp_find_openpic(void) +{ + struct device_node *np; + int len, i; + unsigned int *iranges; + void __iomem *isu; + + np = find_type_devices("open-pic"); + if (np == NULL || np->n_addrs == 0) + return; + printk(KERN_INFO "OpenPIC at %x (size %x)\n", + np->addrs[0].address, np->addrs[0].size); + OpenPIC_Addr = ioremap(np->addrs[0].address, 0x40000); + if (OpenPIC_Addr == NULL) { + printk(KERN_ERR "Failed to map OpenPIC!\n"); + return; + } + + iranges = (unsigned int *) get_property(np, "interrupt-ranges", &len); + if (iranges == NULL || len < 2 * sizeof(unsigned int)) + return; /* not distributed */ + + /* + * The first pair of cells in interrupt-ranges refers to the + * IDU; subsequent pairs refer to the ISUs. + */ + len /= 2 * sizeof(unsigned int); + if (np->n_addrs < len) { + printk(KERN_ERR "Insufficient addresses for distributed" + " OpenPIC (%d < %d)\n", np->n_addrs, len); + return; + } + if (iranges[1] != 0) { + printk(KERN_INFO "OpenPIC irqs %d..%d in IDU\n", + iranges[0], iranges[0] + iranges[1] - 1); + openpic_set_sources(iranges[0], iranges[1], NULL); + } + for (i = 1; i < len; ++i) { + iranges += 2; + printk(KERN_INFO "OpenPIC irqs %d..%d in ISU at %x (%x)\n", + iranges[0], iranges[0] + iranges[1] - 1, + np->addrs[i].address, np->addrs[i].size); + isu = ioremap(np->addrs[i].address, np->addrs[i].size); + if (isu != NULL) + openpic_set_sources(iranges[0], iranges[1], isu); + else + printk(KERN_ERR "Failed to map OpenPIC ISU at %x!\n", + np->addrs[i].address); + } +} + +#if defined(CONFIG_VT) && defined(CONFIG_INPUT_ADBHID) && defined(XMON) +static struct irqaction xmon_irqaction = { + .handler = xmon_irq, + .mask = CPU_MASK_NONE, + .name = "XMON break", +}; +#endif + +void __init chrp_init_IRQ(void) +{ + struct device_node *np; + unsigned long chrp_int_ack = 0; + unsigned char init_senses[NR_IRQS - NUM_8259_INTERRUPTS]; +#if defined(CONFIG_VT) && defined(CONFIG_INPUT_ADBHID) && defined(XMON) + struct device_node *kbd; +#endif + + for (np = find_devices("pci"); np != NULL; np = np->next) { + unsigned int *addrp = (unsigned int *) + get_property(np, "8259-interrupt-acknowledge", NULL); + + if (addrp == NULL) + continue; + chrp_int_ack = addrp[prom_n_addr_cells(np)-1]; + break; + } + if (np == NULL) + printk(KERN_ERR "Cannot find PCI interrupt acknowledge address\n"); + + chrp_find_openpic(); + + if (OpenPIC_Addr) { + prom_get_irq_senses(init_senses, NUM_8259_INTERRUPTS, NR_IRQS); + OpenPIC_InitSenses = init_senses; + OpenPIC_NumInitSenses = NR_IRQS - NUM_8259_INTERRUPTS; + + openpic_init(NUM_8259_INTERRUPTS); + /* We have a cascade on OpenPIC IRQ 0, Linux IRQ 16 */ + openpic_hookup_cascade(NUM_8259_INTERRUPTS, "82c59 cascade", + i8259_irq); + + } + i8259_init(chrp_int_ack, 0); + +#if defined(CONFIG_VT) && defined(CONFIG_INPUT_ADBHID) && defined(XMON) + /* see if there is a keyboard in the device tree + with a parent of type "adb" */ + for (kbd = find_devices("keyboard"); kbd; kbd = kbd->next) + if (kbd->parent && kbd->parent->type + && strcmp(kbd->parent->type, "adb") == 0) + break; + if (kbd) + setup_irq(HYDRA_INT_ADB_NMI, &xmon_irqaction); +#endif +} + +void __init +chrp_init2(void) +{ +#ifdef CONFIG_NVRAM + chrp_nvram_init(); +#endif + + request_region(0x20,0x20,"pic1"); + request_region(0xa0,0x20,"pic2"); + request_region(0x00,0x20,"dma1"); + request_region(0x40,0x20,"timer"); + request_region(0x80,0x10,"dma page reg"); + request_region(0xc0,0x20,"dma2"); + + if (ppc_md.progress) + ppc_md.progress(" Have fun! ", 0x7777); +} + +static struct device_node *memory_node; + +static int __init get_mem_prop(char *name, struct mem_pieces *mp) +{ + struct reg_property *rp; + int i, s; + unsigned int *ip; + int nac = prom_n_addr_cells(memory_node); + int nsc = prom_n_size_cells(memory_node); + + ip = (unsigned int *) get_property(memory_node, name, &s); + if (ip == NULL) { + printk(KERN_ERR "error: couldn't get %s property on /memory\n", + name); + return 0; + } + s /= (nsc + nac) * 4; + rp = mp->regions; + for (i = 0; i < s; ++i, ip += nac+nsc) { + if (nac >= 2 && ip[nac-2] != 0) + continue; + rp->address = ip[nac-1]; + if (nsc >= 2 && ip[nac+nsc-2] != 0) + rp->size = ~0U; + else + rp->size = ip[nac+nsc-1]; + ++rp; + } + mp->n_regions = rp - mp->regions; + + /* Make sure the pieces are sorted. */ + mem_pieces_sort(mp); + mem_pieces_coalesce(mp); + return 1; +} + +static unsigned long __init chrp_find_end_of_memory(void) +{ + unsigned long a, total; + struct mem_pieces phys_mem; + + /* + * Find out where physical memory is, and check that it + * starts at 0 and is contiguous. It seems that RAM is + * always physically contiguous on Power Macintoshes. + * + * Supporting discontiguous physical memory isn't hard, + * it just makes the virtual <-> physical mapping functions + * more complicated (or else you end up wasting space + * in mem_map). + */ + memory_node = find_devices("memory"); + if (memory_node == NULL || !get_mem_prop("reg", &phys_mem) + || phys_mem.n_regions == 0) + panic("No RAM??"); + a = phys_mem.regions[0].address; + if (a != 0) + panic("RAM doesn't start at physical address 0"); + total = phys_mem.regions[0].size; + + if (phys_mem.n_regions > 1) { + printk("RAM starting at 0x%x is not contiguous\n", + phys_mem.regions[1].address); + printk("Using RAM from 0 to 0x%lx\n", total-1); + } + + return total; +} + +void __init +chrp_init(unsigned long r3, unsigned long r4, unsigned long r5, + unsigned long r6, unsigned long r7) +{ + struct device_node *root = find_path_device ("/"); + char *machine = NULL; + +#ifdef CONFIG_BLK_DEV_INITRD + /* take care of initrd if we have one */ + if ( r6 ) + { + initrd_start = r6 + KERNELBASE; + initrd_end = r6 + r7 + KERNELBASE; + } +#endif /* CONFIG_BLK_DEV_INITRD */ + + ISA_DMA_THRESHOLD = ~0L; + DMA_MODE_READ = 0x44; + DMA_MODE_WRITE = 0x48; + isa_io_base = CHRP_ISA_IO_BASE; /* default value */ + ppc_do_canonicalize_irqs = 1; + + if (root) + machine = get_property(root, "model", NULL); + if (machine && strncmp(machine, "Pegasos", 7) == 0) { + _chrp_type = _CHRP_Pegasos; + } else if (machine && strncmp(machine, "IBM", 3) == 0) { + _chrp_type = _CHRP_IBM; + } else if (machine && strncmp(machine, "MOT", 3) == 0) { + _chrp_type = _CHRP_Motorola; + } else { + /* Let's assume it is an IBM chrp if all else fails */ + _chrp_type = _CHRP_IBM; + } + + ppc_md.setup_arch = chrp_setup_arch; + ppc_md.show_percpuinfo = of_show_percpuinfo; + ppc_md.show_cpuinfo = chrp_show_cpuinfo; + + ppc_md.init_IRQ = chrp_init_IRQ; + if (_chrp_type == _CHRP_Pegasos) + ppc_md.get_irq = i8259_irq; + else + ppc_md.get_irq = openpic_get_irq; + + ppc_md.init = chrp_init2; + + ppc_md.phys_mem_access_prot = pci_phys_mem_access_prot; + + ppc_md.restart = chrp_restart; + ppc_md.power_off = chrp_power_off; + ppc_md.halt = chrp_halt; + + ppc_md.time_init = chrp_time_init; + ppc_md.set_rtc_time = chrp_set_rtc_time; + ppc_md.get_rtc_time = chrp_get_rtc_time; + ppc_md.calibrate_decr = chrp_calibrate_decr; + + ppc_md.find_end_of_memory = chrp_find_end_of_memory; + + if (rtas_data) { + struct device_node *rtas; + unsigned int *p; + + rtas = find_devices("rtas"); + if (rtas != NULL) { + if (get_property(rtas, "display-character", NULL)) { + ppc_md.progress = rtas_display_progress; + p = (unsigned int *) get_property + (rtas, "ibm,display-line-length", NULL); + if (p) + max_width = *p; + } else if (get_property(rtas, "set-indicator", NULL)) + ppc_md.progress = rtas_indicator_progress; + } + } +#ifdef CONFIG_BOOTX_TEXT + if (ppc_md.progress == NULL && boot_text_mapped) + ppc_md.progress = btext_progress; +#endif + +#ifdef CONFIG_SMP + smp_ops = &chrp_smp_ops; +#endif /* CONFIG_SMP */ + + /* + * Print the banner, then scroll down so boot progress + * can be printed. -- Cort + */ + if (ppc_md.progress) ppc_md.progress("Linux/PPC "UTS_RELEASE"\n", 0x0); +} + +void +rtas_display_progress(char *s, unsigned short hex) +{ + int width; + char *os = s; + + if ( call_rtas( "display-character", 1, 1, NULL, '\r' ) ) + return; + + width = max_width; + while ( *os ) + { + if ( (*os == '\n') || (*os == '\r') ) + width = max_width; + else + width--; + call_rtas( "display-character", 1, 1, NULL, *os++ ); + /* if we overwrite the screen length */ + if ( width == 0 ) + while ( (*os != 0) && (*os != '\n') && (*os != '\r') ) + os++; + } + + /*while ( width-- > 0 )*/ + call_rtas( "display-character", 1, 1, NULL, ' ' ); +} + +void +rtas_indicator_progress(char *s, unsigned short hex) +{ + call_rtas("set-indicator", 3, 1, NULL, 6, 0, hex); +} + +#ifdef CONFIG_BOOTX_TEXT +void +btext_progress(char *s, unsigned short hex) +{ + prom_print(s); + prom_print("\n"); +} +#endif /* CONFIG_BOOTX_TEXT */ diff --git a/trunk/arch/ppc/platforms/chrp_smp.c b/trunk/arch/ppc/platforms/chrp_smp.c new file mode 100644 index 000000000000..97e539557ecb --- /dev/null +++ b/trunk/arch/ppc/platforms/chrp_smp.c @@ -0,0 +1,99 @@ +/* + * Smp support for CHRP machines. + * + * Written by Cort Dougan (cort@cs.nmt.edu) borrowing a great + * deal of code from the sparc and intel versions. + * + * Copyright (C) 1999 Cort Dougan + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +extern unsigned long smp_chrp_cpu_nr; + +static int __init +smp_chrp_probe(void) +{ + if (smp_chrp_cpu_nr > 1) + openpic_request_IPIs(); + + return smp_chrp_cpu_nr; +} + +static void __devinit +smp_chrp_kick_cpu(int nr) +{ + *(unsigned long *)KERNELBASE = nr; + asm volatile("dcbf 0,%0"::"r"(KERNELBASE):"memory"); +} + +static void __devinit +smp_chrp_setup_cpu(int cpu_nr) +{ + if (OpenPIC_Addr) + do_openpic_setup_cpu(); +} + +static DEFINE_SPINLOCK(timebase_lock); +static unsigned int timebase_upper = 0, timebase_lower = 0; + +void __devinit +smp_chrp_give_timebase(void) +{ + spin_lock(&timebase_lock); + call_rtas("freeze-time-base", 0, 1, NULL); + timebase_upper = get_tbu(); + timebase_lower = get_tbl(); + spin_unlock(&timebase_lock); + + while (timebase_upper || timebase_lower) + barrier(); + call_rtas("thaw-time-base", 0, 1, NULL); +} + +void __devinit +smp_chrp_take_timebase(void) +{ + while (!(timebase_upper || timebase_lower)) + barrier(); + spin_lock(&timebase_lock); + set_tb(timebase_upper, timebase_lower); + timebase_upper = 0; + timebase_lower = 0; + spin_unlock(&timebase_lock); + printk("CPU %i taken timebase\n", smp_processor_id()); +} + +/* CHRP with openpic */ +struct smp_ops_t chrp_smp_ops = { + .message_pass = smp_openpic_message_pass, + .probe = smp_chrp_probe, + .kick_cpu = smp_chrp_kick_cpu, + .setup_cpu = smp_chrp_setup_cpu, + .give_timebase = smp_chrp_give_timebase, + .take_timebase = smp_chrp_take_timebase, +}; diff --git a/trunk/arch/ppc/platforms/chrp_time.c b/trunk/arch/ppc/platforms/chrp_time.c new file mode 100644 index 000000000000..51e06ad66168 --- /dev/null +++ b/trunk/arch/ppc/platforms/chrp_time.c @@ -0,0 +1,235 @@ +/* + * Copyright (C) 1991, 1992, 1995 Linus Torvalds + * + * Adapted for PowerPC (PReP) by Gary Thomas + * Modified by Cort Dougan (cort@cs.nmt.edu). + * Copied and modified from arch/i386/kernel/time.c + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +extern spinlock_t rtc_lock; + +static int nvram_as1 = NVRAM_AS1; +static int nvram_as0 = NVRAM_AS0; +static int nvram_data = NVRAM_DATA; + +long __init chrp_time_init(void) +{ + struct device_node *rtcs; + int base; + + rtcs = find_compatible_devices("rtc", "pnpPNP,b00"); + if (rtcs == NULL) + rtcs = find_compatible_devices("rtc", "ds1385-rtc"); + if (rtcs == NULL || rtcs->addrs == NULL) + return 0; + base = rtcs->addrs[0].address; + nvram_as1 = 0; + nvram_as0 = base; + nvram_data = base + 1; + + return 0; +} + +int chrp_cmos_clock_read(int addr) +{ + if (nvram_as1 != 0) + outb(addr>>8, nvram_as1); + outb(addr, nvram_as0); + return (inb(nvram_data)); +} + +void chrp_cmos_clock_write(unsigned long val, int addr) +{ + if (nvram_as1 != 0) + outb(addr>>8, nvram_as1); + outb(addr, nvram_as0); + outb(val, nvram_data); + return; +} + +/* + * Set the hardware clock. -- Cort + */ +int chrp_set_rtc_time(unsigned long nowtime) +{ + unsigned char save_control, save_freq_select; + struct rtc_time tm; + + spin_lock(&rtc_lock); + to_tm(nowtime, &tm); + + save_control = chrp_cmos_clock_read(RTC_CONTROL); /* tell the clock it's being set */ + + chrp_cmos_clock_write((save_control|RTC_SET), RTC_CONTROL); + + save_freq_select = chrp_cmos_clock_read(RTC_FREQ_SELECT); /* stop and reset prescaler */ + + chrp_cmos_clock_write((save_freq_select|RTC_DIV_RESET2), RTC_FREQ_SELECT); + + tm.tm_year -= 1900; + if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) { + BIN_TO_BCD(tm.tm_sec); + BIN_TO_BCD(tm.tm_min); + BIN_TO_BCD(tm.tm_hour); + BIN_TO_BCD(tm.tm_mon); + BIN_TO_BCD(tm.tm_mday); + BIN_TO_BCD(tm.tm_year); + } + chrp_cmos_clock_write(tm.tm_sec,RTC_SECONDS); + chrp_cmos_clock_write(tm.tm_min,RTC_MINUTES); + chrp_cmos_clock_write(tm.tm_hour,RTC_HOURS); + chrp_cmos_clock_write(tm.tm_mon,RTC_MONTH); + chrp_cmos_clock_write(tm.tm_mday,RTC_DAY_OF_MONTH); + chrp_cmos_clock_write(tm.tm_year,RTC_YEAR); + + /* The following flags have to be released exactly in this order, + * otherwise the DS12887 (popular MC146818A clone with integrated + * battery and quartz) will not reset the oscillator and will not + * update precisely 500 ms later. You won't find this mentioned in + * the Dallas Semiconductor data sheets, but who believes data + * sheets anyway ... -- Markus Kuhn + */ + chrp_cmos_clock_write(save_control, RTC_CONTROL); + chrp_cmos_clock_write(save_freq_select, RTC_FREQ_SELECT); + + spin_unlock(&rtc_lock); + return 0; +} + +unsigned long chrp_get_rtc_time(void) +{ + unsigned int year, mon, day, hour, min, sec; + + do { + sec = chrp_cmos_clock_read(RTC_SECONDS); + min = chrp_cmos_clock_read(RTC_MINUTES); + hour = chrp_cmos_clock_read(RTC_HOURS); + day = chrp_cmos_clock_read(RTC_DAY_OF_MONTH); + mon = chrp_cmos_clock_read(RTC_MONTH); + year = chrp_cmos_clock_read(RTC_YEAR); + } while (sec != chrp_cmos_clock_read(RTC_SECONDS)); + + if (!(chrp_cmos_clock_read(RTC_CONTROL) & RTC_DM_BINARY) + || RTC_ALWAYS_BCD) { + BCD_TO_BIN(sec); + BCD_TO_BIN(min); + BCD_TO_BIN(hour); + BCD_TO_BIN(day); + BCD_TO_BIN(mon); + BCD_TO_BIN(year); + } + + year += 1900; + if (year < 1970) + year += 100; + return mktime(year, mon, day, hour, min, sec); +} + +/* + * Calibrate the decrementer frequency with the VIA timer 1. + */ +#define VIA_TIMER_FREQ_6 4700000 /* time 1 frequency * 6 */ + +/* VIA registers */ +#define RS 0x200 /* skip between registers */ +#define T1CL (4*RS) /* Timer 1 ctr/latch (low 8 bits) */ +#define T1CH (5*RS) /* Timer 1 counter (high 8 bits) */ +#define T1LL (6*RS) /* Timer 1 latch (low 8 bits) */ +#define T1LH (7*RS) /* Timer 1 latch (high 8 bits) */ +#define ACR (11*RS) /* Auxiliary control register */ +#define IFR (13*RS) /* Interrupt flag register */ + +/* Bits in ACR */ +#define T1MODE 0xc0 /* Timer 1 mode */ +#define T1MODE_CONT 0x40 /* continuous interrupts */ + +/* Bits in IFR and IER */ +#define T1_INT 0x40 /* Timer 1 interrupt */ + +static int __init chrp_via_calibrate_decr(void) +{ + struct device_node *vias; + volatile unsigned char __iomem *via; + int count = VIA_TIMER_FREQ_6 / 100; + unsigned int dstart, dend; + + vias = find_devices("via-cuda"); + if (vias == 0) + vias = find_devices("via"); + if (vias == 0 || vias->n_addrs == 0) + return 0; + via = ioremap(vias->addrs[0].address, vias->addrs[0].size); + + /* set timer 1 for continuous interrupts */ + out_8(&via[ACR], (via[ACR] & ~T1MODE) | T1MODE_CONT); + /* set the counter to a small value */ + out_8(&via[T1CH], 2); + /* set the latch to `count' */ + out_8(&via[T1LL], count); + out_8(&via[T1LH], count >> 8); + /* wait until it hits 0 */ + while ((in_8(&via[IFR]) & T1_INT) == 0) + ; + dstart = get_dec(); + /* clear the interrupt & wait until it hits 0 again */ + in_8(&via[T1CL]); + while ((in_8(&via[IFR]) & T1_INT) == 0) + ; + dend = get_dec(); + + tb_ticks_per_jiffy = (dstart - dend) / ((6 * HZ)/100); + tb_to_us = mulhwu_scale_factor(dstart - dend, 60000); + + printk(KERN_INFO "via_calibrate_decr: ticks per jiffy = %u (%u ticks)\n", + tb_ticks_per_jiffy, dstart - dend); + + iounmap(via); + + return 1; +} + +void __init chrp_calibrate_decr(void) +{ + struct device_node *cpu; + unsigned int freq, *fp; + + if (chrp_via_calibrate_decr()) + return; + + /* + * The cpu node should have a timebase-frequency property + * to tell us the rate at which the decrementer counts. + */ + freq = 16666000; /* hardcoded default */ + cpu = find_type_devices("cpu"); + if (cpu != 0) { + fp = (unsigned int *) + get_property(cpu, "timebase-frequency", NULL); + if (fp != 0) + freq = *fp; + } + printk("time_init: decrementer frequency = %u.%.6u MHz\n", + freq/1000000, freq%1000000); + tb_ticks_per_jiffy = freq / HZ; + tb_to_us = mulhwu_scale_factor(freq, 1000000); +} diff --git a/trunk/arch/ppc/platforms/lite5200.c b/trunk/arch/ppc/platforms/lite5200.c index fecbe9adc9e0..5171b53bccb5 100644 --- a/trunk/arch/ppc/platforms/lite5200.c +++ b/trunk/arch/ppc/platforms/lite5200.c @@ -34,7 +34,8 @@ #include #include #include -#include + +#include extern int powersave_nap; @@ -67,53 +68,44 @@ lite5200_show_cpuinfo(struct seq_file *m) } #ifdef CONFIG_PCI -#ifdef CONFIG_LITE5200B -static int -lite5200_map_irq(struct pci_dev *dev, unsigned char idsel, - unsigned char pin) -{ - static char pci_irq_table[][4] = - /* - * PCI IDSEL/INTPIN->INTLINE - * A B C D - */ - { - {MPC52xx_IRQ0, MPC52xx_IRQ1, MPC52xx_IRQ2, MPC52xx_IRQ3}, - {MPC52xx_IRQ1, MPC52xx_IRQ2, MPC52xx_IRQ3, MPC52xx_IRQ0}, - }; - - const long min_idsel = 24, max_idsel = 25, irqs_per_slot = 4; - return PCI_IRQ_TABLE_LOOKUP; -} -#else /* Original Lite */ static int lite5200_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin) { return (pin == 1) && (idsel==24) ? MPC52xx_IRQ0 : -1; } #endif -#endif static void __init lite5200_setup_cpu(void) { + struct mpc52xx_cdm __iomem *cdm; struct mpc52xx_gpio __iomem *gpio; struct mpc52xx_intr __iomem *intr; + struct mpc52xx_xlb __iomem *xlb; u32 port_config; u32 intr_ctrl; /* Map zones */ + cdm = ioremap(MPC52xx_PA(MPC52xx_CDM_OFFSET), MPC52xx_CDM_SIZE); gpio = ioremap(MPC52xx_PA(MPC52xx_GPIO_OFFSET), MPC52xx_GPIO_SIZE); + xlb = ioremap(MPC52xx_PA(MPC52xx_XLB_OFFSET), MPC52xx_XLB_SIZE); intr = ioremap(MPC52xx_PA(MPC52xx_INTR_OFFSET), MPC52xx_INTR_SIZE); - if (!gpio || !intr) { - printk(KERN_ERR __FILE__ ": " - "Error while mapping GPIO/INTR during " - "lite5200_setup_cpu\n"); + if (!cdm || !gpio || !xlb || !intr) { + printk("lite5200.c: Error while mapping CDM/GPIO/XLB/INTR during" + "lite5200_setup_cpu\n"); goto unmap_regs; } + /* Use internal 48 Mhz */ + out_8(&cdm->ext_48mhz_en, 0x00); + out_8(&cdm->fd_enable, 0x01); + if (in_be32(&cdm->rstcfg) & 0x40) /* Assumes 33Mhz clock */ + out_be16(&cdm->fd_counters, 0x0001); + else + out_be16(&cdm->fd_counters, 0x5555); + /* Get port mux config */ port_config = in_be32(&gpio->port_config); @@ -124,29 +116,29 @@ lite5200_setup_cpu(void) port_config &= ~0x00007000; /* Differential mode - USB1 only */ port_config |= 0x00001000; - /* ATA CS is on csb_4/5 */ - port_config &= ~0x03000000; - port_config |= 0x01000000; - /* Commit port config */ out_be32(&gpio->port_config, port_config); - /* IRQ[0-3] setup */ + /* Configure the XLB Arbiter */ + out_be32(&xlb->master_pri_enable, 0xff); + out_be32(&xlb->master_priority, 0x11111111); + + /* Enable ram snooping for 1GB window */ + out_be32(&xlb->config, in_be32(&xlb->config) | MPC52xx_XLB_CFG_SNOOP); + out_be32(&xlb->snoop_window, MPC52xx_PCI_TARGET_MEM | 0x1d); + + /* IRQ[0-3] setup : IRQ0 - Level Active Low */ + /* IRQ[1-3] - Level Active High */ intr_ctrl = in_be32(&intr->ctrl); intr_ctrl &= ~0x00ff0000; -#ifdef CONFIG_LITE5200B - /* IRQ[0-3] Level Active Low */ - intr_ctrl |= 0x00ff0000; -#else - /* IRQ0 Level Active Low - * IRQ[1-3] Level Active High */ - intr_ctrl |= 0x00c00000; -#endif + intr_ctrl |= 0x00c00000; out_be32(&intr->ctrl, intr_ctrl); /* Unmap reg zone */ unmap_regs: + if (cdm) iounmap(cdm); if (gpio) iounmap(gpio); + if (xlb) iounmap(xlb); if (intr) iounmap(intr); } @@ -154,8 +146,7 @@ static void __init lite5200_setup_arch(void) { /* CPU & Port mux setup */ - mpc52xx_setup_cpu(); /* Generic */ - lite5200_setup_cpu(); /* Platform specific */ + lite5200_setup_cpu(); #ifdef CONFIG_PCI /* PCI Bridge setup */ diff --git a/trunk/arch/ppc/platforms/prep_setup.c b/trunk/arch/ppc/platforms/prep_setup.c index e86f6156d589..d95c05d9824d 100644 --- a/trunk/arch/ppc/platforms/prep_setup.c +++ b/trunk/arch/ppc/platforms/prep_setup.c @@ -1067,13 +1067,15 @@ prep_map_io(void) static int __init prep_request_io(void) { + if (_machine == _MACH_prep) { #ifdef CONFIG_NVRAM - request_region(PREP_NVRAM_AS0, 0x8, "nvram"); + request_region(PREP_NVRAM_AS0, 0x8, "nvram"); #endif - request_region(0x00,0x20,"dma1"); - request_region(0x40,0x20,"timer"); - request_region(0x80,0x10,"dma page reg"); - request_region(0xc0,0x20,"dma2"); + request_region(0x00,0x20,"dma1"); + request_region(0x40,0x20,"timer"); + request_region(0x80,0x10,"dma page reg"); + request_region(0xc0,0x20,"dma2"); + } return 0; } diff --git a/trunk/arch/ppc/syslib/Makefile b/trunk/arch/ppc/syslib/Makefile index 490749ca88f9..5cb62c6a51c8 100644 --- a/trunk/arch/ppc/syslib/Makefile +++ b/trunk/arch/ppc/syslib/Makefile @@ -38,6 +38,8 @@ endif obj-$(CONFIG_8xx) += m8xx_setup.o ppc8xx_pic.o $(wdt-mpc8xx-y) \ ppc_sys.o mpc8xx_devices.o mpc8xx_sys.o obj-$(CONFIG_PCI_QSPAN) += qspan_pci.o +obj-$(CONFIG_PPC_OF) += prom_init.o prom.o +obj-$(CONFIG_PPC_CHRP) += open_pic.o obj-$(CONFIG_PPC_PREP) += open_pic.o todc_time.o obj-$(CONFIG_BAMBOO) += pci_auto.o todc_time.o obj-$(CONFIG_CPCI690) += todc_time.o pci_auto.o diff --git a/trunk/arch/ppc/syslib/mpc52xx_pci.c b/trunk/arch/ppc/syslib/mpc52xx_pci.c index 5a5a7a9cd248..9ec525f9fe98 100644 --- a/trunk/arch/ppc/syslib/mpc52xx_pci.c +++ b/trunk/arch/ppc/syslib/mpc52xx_pci.c @@ -225,8 +225,7 @@ mpc52xx_pci_fixup_resources(struct pci_dev *dev) /* The PCI Host bridge of MPC52xx has a prefetch memory resource fixed to 1Gb. Doesn't fit in the resource system so we remove it */ if ( (dev->vendor == PCI_VENDOR_ID_MOTOROLA) && - ( dev->device == PCI_DEVICE_ID_MOTOROLA_MPC5200 - || dev->device == PCI_DEVICE_ID_MOTOROLA_MPC5200B) ) { + (dev->device == PCI_DEVICE_ID_MOTOROLA_MPC5200) ) { struct resource *res = &dev->resource[1]; res->start = res->end = res->flags = 0; } diff --git a/trunk/arch/ppc/syslib/mpc52xx_setup.c b/trunk/arch/ppc/syslib/mpc52xx_setup.c index ee6379bb415e..2ee48ce0a517 100644 --- a/trunk/arch/ppc/syslib/mpc52xx_setup.c +++ b/trunk/arch/ppc/syslib/mpc52xx_setup.c @@ -24,8 +24,6 @@ #include #include -#include - extern bd_t __res; static int core_mult[] = { /* CPU Frequency multiplier, taken */ @@ -218,52 +216,6 @@ mpc52xx_calibrate_decr(void) tb_to_us = mulhwu_scale_factor(xlbfreq / divisor, 1000000); } - -void __init -mpc52xx_setup_cpu(void) -{ - struct mpc52xx_cdm __iomem *cdm; - struct mpc52xx_xlb __iomem *xlb; - - /* Map zones */ - cdm = ioremap(MPC52xx_PA(MPC52xx_CDM_OFFSET), MPC52xx_CDM_SIZE); - xlb = ioremap(MPC52xx_PA(MPC52xx_XLB_OFFSET), MPC52xx_XLB_SIZE); - - if (!cdm || !xlb) { - printk(KERN_ERR __FILE__ ": " - "Error while mapping CDM/XLB during " - "mpc52xx_setup_cpu\n"); - goto unmap_regs; - } - - /* Use internal 48 Mhz */ - out_8(&cdm->ext_48mhz_en, 0x00); - out_8(&cdm->fd_enable, 0x01); - if (in_be32(&cdm->rstcfg) & 0x40) /* Assumes 33Mhz clock */ - out_be16(&cdm->fd_counters, 0x0001); - else - out_be16(&cdm->fd_counters, 0x5555); - - /* Configure the XLB Arbiter priorities */ - out_be32(&xlb->master_pri_enable, 0xff); - out_be32(&xlb->master_priority, 0x11111111); - - /* Enable ram snooping for 1GB window */ - out_be32(&xlb->config, in_be32(&xlb->config) | MPC52xx_XLB_CFG_SNOOP); - out_be32(&xlb->snoop_window, MPC52xx_PCI_TARGET_MEM | 0x1d); - - /* Disable XLB pipelining */ - /* (cfr errate 292. We could do this only just before ATA PIO - transaction and re-enable it after ...) */ - out_be32(&xlb->config, in_be32(&xlb->config) | MPC52xx_XLB_CFG_PLDIS); - - /* Unmap reg zone */ -unmap_regs: - if (cdm) iounmap(cdm); - if (xlb) iounmap(xlb); -} - - int mpc52xx_match_psc_function(int psc_idx, const char *func) { struct mpc52xx_psc_func *cf = mpc52xx_psc_functions; diff --git a/trunk/arch/ppc/syslib/open_pic.c b/trunk/arch/ppc/syslib/open_pic.c index 70456c8f998c..38e5b93fbe41 100644 --- a/trunk/arch/ppc/syslib/open_pic.c +++ b/trunk/arch/ppc/syslib/open_pic.c @@ -216,7 +216,7 @@ static void openpic_safe_writefield(volatile u_int __iomem *addr, u_int mask, u_int openpic_read_IPI(volatile u_int __iomem * addr) { u_int val = 0; -#if defined(OPENPIC_BIG_ENDIAN) +#if defined(OPENPIC_BIG_ENDIAN) || defined(CONFIG_POWER3) val = in_be32(addr); #else val = in_le32(addr); diff --git a/trunk/arch/ppc/syslib/prom.c b/trunk/arch/ppc/syslib/prom.c new file mode 100644 index 000000000000..482f837fd373 --- /dev/null +++ b/trunk/arch/ppc/syslib/prom.c @@ -0,0 +1,1429 @@ +/* + * Procedures for interfacing to the Open Firmware PROM on + * Power Macintosh computers. + * + * In particular, we are interested in the device tree + * and in using some of its services (exit, write to stdout). + * + * Paul Mackerras August 1996. + * Copyright (C) 1996 Paul Mackerras. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +struct pci_address { + unsigned a_hi; + unsigned a_mid; + unsigned a_lo; +}; + +struct pci_reg_property { + struct pci_address addr; + unsigned size_hi; + unsigned size_lo; +}; + +struct isa_reg_property { + unsigned space; + unsigned address; + unsigned size; +}; + +typedef unsigned long interpret_func(struct device_node *, unsigned long, + int, int); +static interpret_func interpret_pci_props; +static interpret_func interpret_dbdma_props; +static interpret_func interpret_isa_props; +static interpret_func interpret_macio_props; +static interpret_func interpret_root_props; + +extern char *klimit; + +/* Set for a newworld or CHRP machine */ +int use_of_interrupt_tree; +struct device_node *dflt_interrupt_controller; +int num_interrupt_controllers; + +extern unsigned int rtas_entry; /* physical pointer */ + +extern struct device_node *allnodes; + +static unsigned long finish_node(struct device_node *, unsigned long, + interpret_func *, int, int); +static unsigned long finish_node_interrupts(struct device_node *, unsigned long); +static struct device_node *find_phandle(phandle); + +extern void enter_rtas(void *); +void phys_call_rtas(int, int, int, ...); + +extern char cmd_line[512]; /* XXX */ +extern boot_infos_t *boot_infos; +unsigned long dev_tree_size; + +void +phys_call_rtas(int service, int nargs, int nret, ...) +{ + va_list list; + union { + unsigned long words[16]; + double align; + } u; + void (*rtas)(void *, unsigned long); + int i; + + u.words[0] = service; + u.words[1] = nargs; + u.words[2] = nret; + va_start(list, nret); + for (i = 0; i < nargs; ++i) + u.words[i+3] = va_arg(list, unsigned long); + va_end(list); + + rtas = (void (*)(void *, unsigned long)) rtas_entry; + rtas(&u, rtas_data); +} + +/* + * finish_device_tree is called once things are running normally + * (i.e. with text and data mapped to the address they were linked at). + * It traverses the device tree and fills in the name, type, + * {n_}addrs and {n_}intrs fields of each node. + */ +void __init +finish_device_tree(void) +{ + unsigned long mem = (unsigned long) klimit; + struct device_node *np; + + /* All CHRPs now use the interrupt tree */ + for (np = allnodes; np != NULL; np = np->allnext) { + if (get_property(np, "interrupt-parent", NULL)) { + use_of_interrupt_tree = 1; + break; + } + } + + if (use_of_interrupt_tree) { + /* + * We want to find out here how many interrupt-controller + * nodes there are, and if we are booted from BootX, + * we need a pointer to the first (and hopefully only) + * such node. But we can't use find_devices here since + * np->name has not been set yet. -- paulus + */ + int n = 0; + char *name, *ic; + int iclen; + + for (np = allnodes; np != NULL; np = np->allnext) { + ic = get_property(np, "interrupt-controller", &iclen); + name = get_property(np, "name", NULL); + /* checking iclen makes sure we don't get a false + match on /chosen.interrupt_controller */ + if ((name != NULL + && strcmp(name, "interrupt-controller") == 0) + || (ic != NULL && iclen == 0 && strcmp(name, "AppleKiwi"))) { + if (n == 0) + dflt_interrupt_controller = np; + ++n; + } + } + num_interrupt_controllers = n; + } + + mem = finish_node(allnodes, mem, NULL, 1, 1); + dev_tree_size = mem - (unsigned long) allnodes; + klimit = (char *) mem; +} + +static unsigned long __init +finish_node(struct device_node *np, unsigned long mem_start, + interpret_func *ifunc, int naddrc, int nsizec) +{ + struct device_node *child; + int *ip; + + np->name = get_property(np, "name", NULL); + np->type = get_property(np, "device_type", NULL); + + if (!np->name) + np->name = ""; + if (!np->type) + np->type = ""; + + /* get the device addresses and interrupts */ + if (ifunc != NULL) + mem_start = ifunc(np, mem_start, naddrc, nsizec); + + if (use_of_interrupt_tree) + mem_start = finish_node_interrupts(np, mem_start); + + /* Look for #address-cells and #size-cells properties. */ + ip = (int *) get_property(np, "#address-cells", NULL); + if (ip != NULL) + naddrc = *ip; + ip = (int *) get_property(np, "#size-cells", NULL); + if (ip != NULL) + nsizec = *ip; + + if (np->parent == NULL) + ifunc = interpret_root_props; + else if (np->type == 0) + ifunc = NULL; + else if (!strcmp(np->type, "pci") || !strcmp(np->type, "vci")) + ifunc = interpret_pci_props; + else if (!strcmp(np->type, "dbdma")) + ifunc = interpret_dbdma_props; + else if (!strcmp(np->type, "mac-io") + || ifunc == interpret_macio_props) + ifunc = interpret_macio_props; + else if (!strcmp(np->type, "isa")) + ifunc = interpret_isa_props; + else if (!strcmp(np->name, "uni-n") || !strcmp(np->name, "u3")) + ifunc = interpret_root_props; + else if (!((ifunc == interpret_dbdma_props + || ifunc == interpret_macio_props) + && (!strcmp(np->type, "escc") + || !strcmp(np->type, "media-bay")))) + ifunc = NULL; + + /* if we were booted from BootX, convert the full name */ + if (boot_infos + && strncmp(np->full_name, "Devices:device-tree", 19) == 0) { + if (np->full_name[19] == 0) { + strcpy(np->full_name, "/"); + } else if (np->full_name[19] == ':') { + char *p = np->full_name + 19; + np->full_name = p; + for (; *p; ++p) + if (*p == ':') + *p = '/'; + } + } + + for (child = np->child; child != NULL; child = child->sibling) + mem_start = finish_node(child, mem_start, ifunc, + naddrc, nsizec); + + return mem_start; +} + +/* + * Find the interrupt parent of a node. + */ +static struct device_node * __init +intr_parent(struct device_node *p) +{ + phandle *parp; + + parp = (phandle *) get_property(p, "interrupt-parent", NULL); + if (parp == NULL) + return p->parent; + p = find_phandle(*parp); + if (p != NULL) + return p; + /* + * On a powermac booted with BootX, we don't get to know the + * phandles for any nodes, so find_phandle will return NULL. + * Fortunately these machines only have one interrupt controller + * so there isn't in fact any ambiguity. -- paulus + */ + if (num_interrupt_controllers == 1) + p = dflt_interrupt_controller; + return p; +} + +/* + * Find out the size of each entry of the interrupts property + * for a node. + */ +static int __init +prom_n_intr_cells(struct device_node *np) +{ + struct device_node *p; + unsigned int *icp; + + for (p = np; (p = intr_parent(p)) != NULL; ) { + icp = (unsigned int *) + get_property(p, "#interrupt-cells", NULL); + if (icp != NULL) + return *icp; + if (get_property(p, "interrupt-controller", NULL) != NULL + || get_property(p, "interrupt-map", NULL) != NULL) { + printk("oops, node %s doesn't have #interrupt-cells\n", + p->full_name); + return 1; + } + } + printk("prom_n_intr_cells failed for %s\n", np->full_name); + return 1; +} + +/* + * Map an interrupt from a device up to the platform interrupt + * descriptor. + */ +static int __init +map_interrupt(unsigned int **irq, struct device_node **ictrler, + struct device_node *np, unsigned int *ints, int nintrc) +{ + struct device_node *p, *ipar; + unsigned int *imap, *imask, *ip; + int i, imaplen, match; + int newintrc = 1, newaddrc = 1; + unsigned int *reg; + int naddrc; + + reg = (unsigned int *) get_property(np, "reg", NULL); + naddrc = prom_n_addr_cells(np); + p = intr_parent(np); + while (p != NULL) { + if (get_property(p, "interrupt-controller", NULL) != NULL) + /* this node is an interrupt controller, stop here */ + break; + imap = (unsigned int *) + get_property(p, "interrupt-map", &imaplen); + if (imap == NULL) { + p = intr_parent(p); + continue; + } + imask = (unsigned int *) + get_property(p, "interrupt-map-mask", NULL); + if (imask == NULL) { + printk("oops, %s has interrupt-map but no mask\n", + p->full_name); + return 0; + } + imaplen /= sizeof(unsigned int); + match = 0; + ipar = NULL; + while (imaplen > 0 && !match) { + /* check the child-interrupt field */ + match = 1; + for (i = 0; i < naddrc && match; ++i) + match = ((reg[i] ^ imap[i]) & imask[i]) == 0; + for (; i < naddrc + nintrc && match; ++i) + match = ((ints[i-naddrc] ^ imap[i]) & imask[i]) == 0; + imap += naddrc + nintrc; + imaplen -= naddrc + nintrc; + /* grab the interrupt parent */ + ipar = find_phandle((phandle) *imap++); + --imaplen; + if (ipar == NULL && num_interrupt_controllers == 1) + /* cope with BootX not giving us phandles */ + ipar = dflt_interrupt_controller; + if (ipar == NULL) { + printk("oops, no int parent %x in map of %s\n", + imap[-1], p->full_name); + return 0; + } + /* find the parent's # addr and intr cells */ + ip = (unsigned int *) + get_property(ipar, "#interrupt-cells", NULL); + if (ip == NULL) { + printk("oops, no #interrupt-cells on %s\n", + ipar->full_name); + return 0; + } + newintrc = *ip; + ip = (unsigned int *) + get_property(ipar, "#address-cells", NULL); + newaddrc = (ip == NULL)? 0: *ip; + imap += newaddrc + newintrc; + imaplen -= newaddrc + newintrc; + } + if (imaplen < 0) { + printk("oops, error decoding int-map on %s, len=%d\n", + p->full_name, imaplen); + return 0; + } + if (!match) { + printk("oops, no match in %s int-map for %s\n", + p->full_name, np->full_name); + return 0; + } + p = ipar; + naddrc = newaddrc; + nintrc = newintrc; + ints = imap - nintrc; + reg = ints - naddrc; + } + if (p == NULL) + printk("hmmm, int tree for %s doesn't have ctrler\n", + np->full_name); + *irq = ints; + *ictrler = p; + return nintrc; +} + +/* + * New version of finish_node_interrupts. + */ +static unsigned long __init +finish_node_interrupts(struct device_node *np, unsigned long mem_start) +{ + unsigned int *ints; + int intlen, intrcells; + int i, j, n, offset; + unsigned int *irq; + struct device_node *ic; + + ints = (unsigned int *) get_property(np, "interrupts", &intlen); + if (ints == NULL) + return mem_start; + intrcells = prom_n_intr_cells(np); + intlen /= intrcells * sizeof(unsigned int); + np->n_intrs = intlen; + np->intrs = (struct interrupt_info *) mem_start; + mem_start += intlen * sizeof(struct interrupt_info); + + for (i = 0; i < intlen; ++i) { + np->intrs[i].line = 0; + np->intrs[i].sense = 1; + n = map_interrupt(&irq, &ic, np, ints, intrcells); + if (n <= 0) + continue; + offset = 0; + /* + * On a CHRP we have an 8259 which is subordinate to + * the openpic in the interrupt tree, but we want the + * openpic's interrupt numbers offsetted, not the 8259's. + * So we apply the offset if the controller is at the + * root of the interrupt tree, i.e. has no interrupt-parent. + * This doesn't cope with the general case of multiple + * cascaded interrupt controllers, but then neither will + * irq.c at the moment either. -- paulus + * The G5 triggers that code, I add a machine test. On + * those machines, we want to offset interrupts from the + * second openpic by 128 -- BenH + */ + if (num_interrupt_controllers > 1 + && ic != NULL + && get_property(ic, "interrupt-parent", NULL) == NULL) + offset = 16; + + np->intrs[i].line = irq[0] + offset; + if (n > 1) + np->intrs[i].sense = irq[1]; + if (n > 2) { + printk("hmmm, got %d intr cells for %s:", n, + np->full_name); + for (j = 0; j < n; ++j) + printk(" %d", irq[j]); + printk("\n"); + } + ints += intrcells; + } + + return mem_start; +} + +/* + * When BootX makes a copy of the device tree from the MacOS + * Name Registry, it is in the format we use but all of the pointers + * are offsets from the start of the tree. + * This procedure updates the pointers. + */ +void __init +relocate_nodes(void) +{ + unsigned long base; + struct device_node *np; + struct property *pp; + +#define ADDBASE(x) (x = (typeof (x))((x)? ((unsigned long)(x) + base): 0)) + + base = (unsigned long) boot_infos + boot_infos->deviceTreeOffset; + allnodes = (struct device_node *)(base + 4); + for (np = allnodes; np != 0; np = np->allnext) { + ADDBASE(np->full_name); + ADDBASE(np->properties); + ADDBASE(np->parent); + ADDBASE(np->child); + ADDBASE(np->sibling); + ADDBASE(np->allnext); + for (pp = np->properties; pp != 0; pp = pp->next) { + ADDBASE(pp->name); + ADDBASE(pp->value); + ADDBASE(pp->next); + } + } +} + +int +prom_n_addr_cells(struct device_node* np) +{ + int* ip; + do { + if (np->parent) + np = np->parent; + ip = (int *) get_property(np, "#address-cells", NULL); + if (ip != NULL) + return *ip; + } while (np->parent); + /* No #address-cells property for the root node, default to 1 */ + return 1; +} + +int +prom_n_size_cells(struct device_node* np) +{ + int* ip; + do { + if (np->parent) + np = np->parent; + ip = (int *) get_property(np, "#size-cells", NULL); + if (ip != NULL) + return *ip; + } while (np->parent); + /* No #size-cells property for the root node, default to 1 */ + return 1; +} + +static unsigned long __init +map_addr(struct device_node *np, unsigned long space, unsigned long addr) +{ + int na; + unsigned int *ranges; + int rlen = 0; + unsigned int type; + + type = (space >> 24) & 3; + if (type == 0) + return addr; + + while ((np = np->parent) != NULL) { + if (strcmp(np->type, "pci") != 0) + continue; + /* PCI bridge: map the address through the ranges property */ + na = prom_n_addr_cells(np); + ranges = (unsigned int *) get_property(np, "ranges", &rlen); + while ((rlen -= (na + 5) * sizeof(unsigned int)) >= 0) { + if (((ranges[0] >> 24) & 3) == type + && ranges[2] <= addr + && addr - ranges[2] < ranges[na+4]) { + /* ok, this matches, translate it */ + addr += ranges[na+2] - ranges[2]; + break; + } + ranges += na + 5; + } + } + return addr; +} + +static unsigned long __init +interpret_pci_props(struct device_node *np, unsigned long mem_start, + int naddrc, int nsizec) +{ + struct address_range *adr; + struct pci_reg_property *pci_addrs; + int i, l, *ip; + + pci_addrs = (struct pci_reg_property *) + get_property(np, "assigned-addresses", &l); + if (pci_addrs != 0 && l >= sizeof(struct pci_reg_property)) { + i = 0; + adr = (struct address_range *) mem_start; + while ((l -= sizeof(struct pci_reg_property)) >= 0) { + adr[i].space = pci_addrs[i].addr.a_hi; + adr[i].address = map_addr(np, pci_addrs[i].addr.a_hi, + pci_addrs[i].addr.a_lo); + adr[i].size = pci_addrs[i].size_lo; + ++i; + } + np->addrs = adr; + np->n_addrs = i; + mem_start += i * sizeof(struct address_range); + } + + if (use_of_interrupt_tree) + return mem_start; + + ip = (int *) get_property(np, "AAPL,interrupts", &l); + if (ip == 0 && np->parent) + ip = (int *) get_property(np->parent, "AAPL,interrupts", &l); + if (ip == 0) + ip = (int *) get_property(np, "interrupts", &l); + if (ip != 0) { + np->intrs = (struct interrupt_info *) mem_start; + np->n_intrs = l / sizeof(int); + mem_start += np->n_intrs * sizeof(struct interrupt_info); + for (i = 0; i < np->n_intrs; ++i) { + np->intrs[i].line = *ip++; + np->intrs[i].sense = 1; + } + } + + return mem_start; +} + +static unsigned long __init +interpret_dbdma_props(struct device_node *np, unsigned long mem_start, + int naddrc, int nsizec) +{ + struct reg_property *rp; + struct address_range *adr; + unsigned long base_address; + int i, l, *ip; + struct device_node *db; + + base_address = 0; + for (db = np->parent; db != NULL; db = db->parent) { + if (!strcmp(db->type, "dbdma") && db->n_addrs != 0) { + base_address = db->addrs[0].address; + break; + } + } + + rp = (struct reg_property *) get_property(np, "reg", &l); + if (rp != 0 && l >= sizeof(struct reg_property)) { + i = 0; + adr = (struct address_range *) mem_start; + while ((l -= sizeof(struct reg_property)) >= 0) { + adr[i].space = 2; + adr[i].address = rp[i].address + base_address; + adr[i].size = rp[i].size; + ++i; + } + np->addrs = adr; + np->n_addrs = i; + mem_start += i * sizeof(struct address_range); + } + + if (use_of_interrupt_tree) + return mem_start; + + ip = (int *) get_property(np, "AAPL,interrupts", &l); + if (ip == 0) + ip = (int *) get_property(np, "interrupts", &l); + if (ip != 0) { + np->intrs = (struct interrupt_info *) mem_start; + np->n_intrs = l / sizeof(int); + mem_start += np->n_intrs * sizeof(struct interrupt_info); + for (i = 0; i < np->n_intrs; ++i) { + np->intrs[i].line = *ip++; + np->intrs[i].sense = 1; + } + } + + return mem_start; +} + +static unsigned long __init +interpret_macio_props(struct device_node *np, unsigned long mem_start, + int naddrc, int nsizec) +{ + struct reg_property *rp; + struct address_range *adr; + unsigned long base_address; + int i, l, *ip; + struct device_node *db; + + base_address = 0; + for (db = np->parent; db != NULL; db = db->parent) { + if (!strcmp(db->type, "mac-io") && db->n_addrs != 0) { + base_address = db->addrs[0].address; + break; + } + } + + rp = (struct reg_property *) get_property(np, "reg", &l); + if (rp != 0 && l >= sizeof(struct reg_property)) { + i = 0; + adr = (struct address_range *) mem_start; + while ((l -= sizeof(struct reg_property)) >= 0) { + adr[i].space = 2; + adr[i].address = rp[i].address + base_address; + adr[i].size = rp[i].size; + ++i; + } + np->addrs = adr; + np->n_addrs = i; + mem_start += i * sizeof(struct address_range); + } + + if (use_of_interrupt_tree) + return mem_start; + + ip = (int *) get_property(np, "interrupts", &l); + if (ip == 0) + ip = (int *) get_property(np, "AAPL,interrupts", &l); + if (ip != 0) { + np->intrs = (struct interrupt_info *) mem_start; + np->n_intrs = l / sizeof(int); + for (i = 0; i < np->n_intrs; ++i) { + np->intrs[i].line = *ip++; + np->intrs[i].sense = 1; + } + mem_start += np->n_intrs * sizeof(struct interrupt_info); + } + + return mem_start; +} + +static unsigned long __init +interpret_isa_props(struct device_node *np, unsigned long mem_start, + int naddrc, int nsizec) +{ + struct isa_reg_property *rp; + struct address_range *adr; + int i, l, *ip; + + rp = (struct isa_reg_property *) get_property(np, "reg", &l); + if (rp != 0 && l >= sizeof(struct isa_reg_property)) { + i = 0; + adr = (struct address_range *) mem_start; + while ((l -= sizeof(struct reg_property)) >= 0) { + adr[i].space = rp[i].space; + adr[i].address = rp[i].address + + (adr[i].space? 0: _ISA_MEM_BASE); + adr[i].size = rp[i].size; + ++i; + } + np->addrs = adr; + np->n_addrs = i; + mem_start += i * sizeof(struct address_range); + } + + if (use_of_interrupt_tree) + return mem_start; + + ip = (int *) get_property(np, "interrupts", &l); + if (ip != 0) { + np->intrs = (struct interrupt_info *) mem_start; + np->n_intrs = l / (2 * sizeof(int)); + mem_start += np->n_intrs * sizeof(struct interrupt_info); + for (i = 0; i < np->n_intrs; ++i) { + np->intrs[i].line = *ip++; + np->intrs[i].sense = *ip++; + } + } + + return mem_start; +} + +static unsigned long __init +interpret_root_props(struct device_node *np, unsigned long mem_start, + int naddrc, int nsizec) +{ + struct address_range *adr; + int i, l, *ip; + unsigned int *rp; + int rpsize = (naddrc + nsizec) * sizeof(unsigned int); + + rp = (unsigned int *) get_property(np, "reg", &l); + if (rp != 0 && l >= rpsize) { + i = 0; + adr = (struct address_range *) mem_start; + while ((l -= rpsize) >= 0) { + adr[i].space = (naddrc >= 2? rp[naddrc-2]: 2); + adr[i].address = rp[naddrc - 1]; + adr[i].size = rp[naddrc + nsizec - 1]; + ++i; + rp += naddrc + nsizec; + } + np->addrs = adr; + np->n_addrs = i; + mem_start += i * sizeof(struct address_range); + } + + if (use_of_interrupt_tree) + return mem_start; + + ip = (int *) get_property(np, "AAPL,interrupts", &l); + if (ip == 0) + ip = (int *) get_property(np, "interrupts", &l); + if (ip != 0) { + np->intrs = (struct interrupt_info *) mem_start; + np->n_intrs = l / sizeof(int); + mem_start += np->n_intrs * sizeof(struct interrupt_info); + for (i = 0; i < np->n_intrs; ++i) { + np->intrs[i].line = *ip++; + np->intrs[i].sense = 1; + } + } + + return mem_start; +} + +/* + * Work out the sense (active-low level / active-high edge) + * of each interrupt from the device tree. + */ +void __init +prom_get_irq_senses(unsigned char *senses, int off, int max) +{ + struct device_node *np; + int i, j; + + /* default to level-triggered */ + memset(senses, 1, max - off); + if (!use_of_interrupt_tree) + return; + + for (np = allnodes; np != 0; np = np->allnext) { + for (j = 0; j < np->n_intrs; j++) { + i = np->intrs[j].line; + if (i >= off && i < max) { + if (np->intrs[j].sense == 1) + senses[i-off] = (IRQ_SENSE_LEVEL + | IRQ_POLARITY_NEGATIVE); + else + senses[i-off] = (IRQ_SENSE_EDGE + | IRQ_POLARITY_POSITIVE); + } + } + } +} + +/* + * Construct and return a list of the device_nodes with a given name. + */ +struct device_node * +find_devices(const char *name) +{ + struct device_node *head, **prevp, *np; + + prevp = &head; + for (np = allnodes; np != 0; np = np->allnext) { + if (np->name != 0 && strcasecmp(np->name, name) == 0) { + *prevp = np; + prevp = &np->next; + } + } + *prevp = NULL; + return head; +} + +/* + * Construct and return a list of the device_nodes with a given type. + */ +struct device_node * +find_type_devices(const char *type) +{ + struct device_node *head, **prevp, *np; + + prevp = &head; + for (np = allnodes; np != 0; np = np->allnext) { + if (np->type != 0 && strcasecmp(np->type, type) == 0) { + *prevp = np; + prevp = &np->next; + } + } + *prevp = NULL; + return head; +} + +/* + * Returns all nodes linked together + */ +struct device_node * +find_all_nodes(void) +{ + struct device_node *head, **prevp, *np; + + prevp = &head; + for (np = allnodes; np != 0; np = np->allnext) { + *prevp = np; + prevp = &np->next; + } + *prevp = NULL; + return head; +} + +/* Checks if the given "compat" string matches one of the strings in + * the device's "compatible" property + */ +int +device_is_compatible(struct device_node *device, const char *compat) +{ + const char* cp; + int cplen, l; + + cp = (char *) get_property(device, "compatible", &cplen); + if (cp == NULL) + return 0; + while (cplen > 0) { + if (strncasecmp(cp, compat, strlen(compat)) == 0) + return 1; + l = strlen(cp) + 1; + cp += l; + cplen -= l; + } + + return 0; +} + + +/* + * Indicates whether the root node has a given value in its + * compatible property. + */ +int +machine_is_compatible(const char *compat) +{ + struct device_node *root; + + root = find_path_device("/"); + if (root == 0) + return 0; + return device_is_compatible(root, compat); +} + +/* + * Construct and return a list of the device_nodes with a given type + * and compatible property. + */ +struct device_node * +find_compatible_devices(const char *type, const char *compat) +{ + struct device_node *head, **prevp, *np; + + prevp = &head; + for (np = allnodes; np != 0; np = np->allnext) { + if (type != NULL + && !(np->type != 0 && strcasecmp(np->type, type) == 0)) + continue; + if (device_is_compatible(np, compat)) { + *prevp = np; + prevp = &np->next; + } + } + *prevp = NULL; + return head; +} + +/* + * Find the device_node with a given full_name. + */ +struct device_node * +find_path_device(const char *path) +{ + struct device_node *np; + + for (np = allnodes; np != 0; np = np->allnext) + if (np->full_name != 0 && strcasecmp(np->full_name, path) == 0) + return np; + return NULL; +} + +/******* + * + * New implementation of the OF "find" APIs, return a refcounted + * object, call of_node_put() when done. Currently, still lacks + * locking as old implementation, this is beeing done for ppc64. + * + * Note that property management will need some locking as well, + * this isn't dealt with yet + * + *******/ + +/** + * of_find_node_by_name - Find a node by it's "name" property + * @from: The node to start searching from or NULL, the node + * you pass will not be searched, only the next one + * will; typically, you pass what the previous call + * returned. of_node_put() will be called on it + * @name: The name string to match against + * + * Returns a node pointer with refcount incremented, use + * of_node_put() on it when done. + */ +struct device_node *of_find_node_by_name(struct device_node *from, + const char *name) +{ + struct device_node *np = from ? from->allnext : allnodes; + + for (; np != 0; np = np->allnext) + if (np->name != 0 && strcasecmp(np->name, name) == 0) + break; + if (from) + of_node_put(from); + return of_node_get(np); +} + +/** + * of_find_node_by_type - Find a node by it's "device_type" property + * @from: The node to start searching from or NULL, the node + * you pass will not be searched, only the next one + * will; typically, you pass what the previous call + * returned. of_node_put() will be called on it + * @name: The type string to match against + * + * Returns a node pointer with refcount incremented, use + * of_node_put() on it when done. + */ +struct device_node *of_find_node_by_type(struct device_node *from, + const char *type) +{ + struct device_node *np = from ? from->allnext : allnodes; + + for (; np != 0; np = np->allnext) + if (np->type != 0 && strcasecmp(np->type, type) == 0) + break; + if (from) + of_node_put(from); + return of_node_get(np); +} + +/** + * of_find_compatible_node - Find a node based on type and one of the + * tokens in it's "compatible" property + * @from: The node to start searching from or NULL, the node + * you pass will not be searched, only the next one + * will; typically, you pass what the previous call + * returned. of_node_put() will be called on it + * @type: The type string to match "device_type" or NULL to ignore + * @compatible: The string to match to one of the tokens in the device + * "compatible" list. + * + * Returns a node pointer with refcount incremented, use + * of_node_put() on it when done. + */ +struct device_node *of_find_compatible_node(struct device_node *from, + const char *type, const char *compatible) +{ + struct device_node *np = from ? from->allnext : allnodes; + + for (; np != 0; np = np->allnext) { + if (type != NULL + && !(np->type != 0 && strcasecmp(np->type, type) == 0)) + continue; + if (device_is_compatible(np, compatible)) + break; + } + if (from) + of_node_put(from); + return of_node_get(np); +} + +/** + * of_find_node_by_path - Find a node matching a full OF path + * @path: The full path to match + * + * Returns a node pointer with refcount incremented, use + * of_node_put() on it when done. + */ +struct device_node *of_find_node_by_path(const char *path) +{ + struct device_node *np = allnodes; + + for (; np != 0; np = np->allnext) + if (np->full_name != 0 && strcasecmp(np->full_name, path) == 0) + break; + return of_node_get(np); +} + +/** + * of_find_all_nodes - Get next node in global list + * @prev: Previous node or NULL to start iteration + * of_node_put() will be called on it + * + * Returns a node pointer with refcount incremented, use + * of_node_put() on it when done. + */ +struct device_node *of_find_all_nodes(struct device_node *prev) +{ + return of_node_get(prev ? prev->allnext : allnodes); +} + +/** + * of_get_parent - Get a node's parent if any + * @node: Node to get parent + * + * Returns a node pointer with refcount incremented, use + * of_node_put() on it when done. + */ +struct device_node *of_get_parent(const struct device_node *node) +{ + return node ? of_node_get(node->parent) : NULL; +} + +/** + * of_get_next_child - Iterate a node childs + * @node: parent node + * @prev: previous child of the parent node, or NULL to get first + * + * Returns a node pointer with refcount incremented, use + * of_node_put() on it when done. + */ +struct device_node *of_get_next_child(const struct device_node *node, + struct device_node *prev) +{ + struct device_node *next = prev ? prev->sibling : node->child; + + for (; next != 0; next = next->sibling) + if (of_node_get(next)) + break; + if (prev) + of_node_put(prev); + return next; +} + +/** + * of_node_get - Increment refcount of a node + * @node: Node to inc refcount, NULL is supported to + * simplify writing of callers + * + * Returns the node itself or NULL if gone. Current implementation + * does nothing as we don't yet do dynamic node allocation on ppc32 + */ +struct device_node *of_node_get(struct device_node *node) +{ + return node; +} + +/** + * of_node_put - Decrement refcount of a node + * @node: Node to dec refcount, NULL is supported to + * simplify writing of callers + * + * Current implementation does nothing as we don't yet do dynamic node + * allocation on ppc32 + */ +void of_node_put(struct device_node *node) +{ +} + +/* + * Find the device_node with a given phandle. + */ +static struct device_node * __init +find_phandle(phandle ph) +{ + struct device_node *np; + + for (np = allnodes; np != 0; np = np->allnext) + if (np->node == ph) + return np; + return NULL; +} + +/* + * Find a property with a given name for a given node + * and return the value. + */ +unsigned char * +get_property(struct device_node *np, const char *name, int *lenp) +{ + struct property *pp; + + for (pp = np->properties; pp != 0; pp = pp->next) + if (pp->name != NULL && strcmp(pp->name, name) == 0) { + if (lenp != 0) + *lenp = pp->length; + return pp->value; + } + return NULL; +} + +/* + * Add a property to a node + */ +int +prom_add_property(struct device_node* np, struct property* prop) +{ + struct property **next = &np->properties; + + prop->next = NULL; + while (*next) + next = &(*next)->next; + *next = prop; + + return 0; +} + +/* I quickly hacked that one, check against spec ! */ +static inline unsigned long +bus_space_to_resource_flags(unsigned int bus_space) +{ + u8 space = (bus_space >> 24) & 0xf; + if (space == 0) + space = 0x02; + if (space == 0x02) + return IORESOURCE_MEM; + else if (space == 0x01) + return IORESOURCE_IO; + else { + printk(KERN_WARNING "prom.c: bus_space_to_resource_flags(), space: %x\n", + bus_space); + return 0; + } +} + +static struct resource* +find_parent_pci_resource(struct pci_dev* pdev, struct address_range *range) +{ + unsigned long mask; + int i; + + /* Check this one */ + mask = bus_space_to_resource_flags(range->space); + for (i=0; iresource[i].flags & mask) == mask && + pdev->resource[i].start <= range->address && + pdev->resource[i].end > range->address) { + if ((range->address + range->size - 1) > pdev->resource[i].end) { + /* Add better message */ + printk(KERN_WARNING "PCI/OF resource overlap !\n"); + return NULL; + } + break; + } + } + if (i == DEVICE_COUNT_RESOURCE) + return NULL; + return &pdev->resource[i]; +} + +/* + * Request an OF device resource. Currently handles child of PCI devices, + * or other nodes attached to the root node. Ultimately, put some + * link to resources in the OF node. + */ +struct resource* +request_OF_resource(struct device_node* node, int index, const char* name_postfix) +{ + struct pci_dev* pcidev; + u8 pci_bus, pci_devfn; + unsigned long iomask; + struct device_node* nd; + struct resource* parent; + struct resource *res = NULL; + int nlen, plen; + + if (index >= node->n_addrs) + goto fail; + + /* Sanity check on bus space */ + iomask = bus_space_to_resource_flags(node->addrs[index].space); + if (iomask & IORESOURCE_MEM) + parent = &iomem_resource; + else if (iomask & IORESOURCE_IO) + parent = &ioport_resource; + else + goto fail; + + /* Find a PCI parent if any */ + nd = node; + pcidev = NULL; + while(nd) { + if (!pci_device_from_OF_node(nd, &pci_bus, &pci_devfn)) + pcidev = pci_find_slot(pci_bus, pci_devfn); + if (pcidev) break; + nd = nd->parent; + } + if (pcidev) + parent = find_parent_pci_resource(pcidev, &node->addrs[index]); + if (!parent) { + printk(KERN_WARNING "request_OF_resource(%s), parent not found\n", + node->name); + goto fail; + } + + res = __request_region(parent, node->addrs[index].address, node->addrs[index].size, NULL); + if (!res) + goto fail; + nlen = strlen(node->name); + plen = name_postfix ? strlen(name_postfix) : 0; + res->name = (const char *)kmalloc(nlen+plen+1, GFP_KERNEL); + if (res->name) { + strcpy((char *)res->name, node->name); + if (plen) + strcpy((char *)res->name+nlen, name_postfix); + } + return res; +fail: + return NULL; +} + +int +release_OF_resource(struct device_node* node, int index) +{ + struct pci_dev* pcidev; + u8 pci_bus, pci_devfn; + unsigned long iomask, start, end; + struct device_node* nd; + struct resource* parent; + struct resource *res = NULL; + + if (index >= node->n_addrs) + return -EINVAL; + + /* Sanity check on bus space */ + iomask = bus_space_to_resource_flags(node->addrs[index].space); + if (iomask & IORESOURCE_MEM) + parent = &iomem_resource; + else if (iomask & IORESOURCE_IO) + parent = &ioport_resource; + else + return -EINVAL; + + /* Find a PCI parent if any */ + nd = node; + pcidev = NULL; + while(nd) { + if (!pci_device_from_OF_node(nd, &pci_bus, &pci_devfn)) + pcidev = pci_find_slot(pci_bus, pci_devfn); + if (pcidev) break; + nd = nd->parent; + } + if (pcidev) + parent = find_parent_pci_resource(pcidev, &node->addrs[index]); + if (!parent) { + printk(KERN_WARNING "release_OF_resource(%s), parent not found\n", + node->name); + return -ENODEV; + } + + /* Find us in the parent and its childs */ + res = parent->child; + start = node->addrs[index].address; + end = start + node->addrs[index].size - 1; + while (res) { + if (res->start == start && res->end == end && + (res->flags & IORESOURCE_BUSY)) + break; + if (res->start <= start && res->end >= end) + res = res->child; + else + res = res->sibling; + } + if (!res) + return -ENODEV; + + kfree(res->name); + res->name = NULL; + release_resource(res); + kfree(res); + + return 0; +} + +#if 0 +void +print_properties(struct device_node *np) +{ + struct property *pp; + char *cp; + int i, n; + + for (pp = np->properties; pp != 0; pp = pp->next) { + printk(KERN_INFO "%s", pp->name); + for (i = strlen(pp->name); i < 16; ++i) + printk(" "); + cp = (char *) pp->value; + for (i = pp->length; i > 0; --i, ++cp) + if ((i > 1 && (*cp < 0x20 || *cp > 0x7e)) + || (i == 1 && *cp != 0)) + break; + if (i == 0 && pp->length > 1) { + /* looks like a string */ + printk(" %s\n", (char *) pp->value); + } else { + /* dump it in hex */ + n = pp->length; + if (n > 64) + n = 64; + if (pp->length % 4 == 0) { + unsigned int *p = (unsigned int *) pp->value; + + n /= 4; + for (i = 0; i < n; ++i) { + if (i != 0 && (i % 4) == 0) + printk("\n "); + printk(" %08x", *p++); + } + } else { + unsigned char *bp = pp->value; + + for (i = 0; i < n; ++i) { + if (i != 0 && (i % 16) == 0) + printk("\n "); + printk(" %02x", *bp++); + } + } + printk("\n"); + if (pp->length > 64) + printk(" ... (length = %d)\n", + pp->length); + } + } +} +#endif + +static DEFINE_SPINLOCK(rtas_lock); + +/* this can be called after setup -- Cort */ +int +call_rtas(const char *service, int nargs, int nret, + unsigned long *outputs, ...) +{ + va_list list; + int i; + unsigned long s; + struct device_node *rtas; + int *tokp; + union { + unsigned long words[16]; + double align; + } u; + + rtas = find_devices("rtas"); + if (rtas == NULL) + return -1; + tokp = (int *) get_property(rtas, service, NULL); + if (tokp == NULL) { + printk(KERN_ERR "No RTAS service called %s\n", service); + return -1; + } + u.words[0] = *tokp; + u.words[1] = nargs; + u.words[2] = nret; + va_start(list, outputs); + for (i = 0; i < nargs; ++i) + u.words[i+3] = va_arg(list, unsigned long); + va_end(list); + + /* + * RTAS doesn't use floating point. + * Or at least, according to the CHRP spec we enter RTAS + * with FP disabled, and it doesn't change the FP registers. + * -- paulus. + */ + spin_lock_irqsave(&rtas_lock, s); + enter_rtas((void *)__pa(&u)); + spin_unlock_irqrestore(&rtas_lock, s); + + if (nret > 1 && outputs != NULL) + for (i = 0; i < nret-1; ++i) + outputs[i] = u.words[i+nargs+4]; + return u.words[nargs+3]; +} diff --git a/trunk/arch/ppc/syslib/prom_init.c b/trunk/arch/ppc/syslib/prom_init.c new file mode 100644 index 000000000000..df14422ae1c6 --- /dev/null +++ b/trunk/arch/ppc/syslib/prom_init.c @@ -0,0 +1,1011 @@ +/* + * Note that prom_init() and anything called from prom_init() + * may be running at an address that is different from the address + * that it was linked at. References to static data items are + * handled by compiling this file with -mrelocatable-lib. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef CONFIG_LOGO_LINUX_CLUT224 +#include +extern const struct linux_logo logo_linux_clut224; +#endif + +/* + * Properties whose value is longer than this get excluded from our + * copy of the device tree. This way we don't waste space storing + * things like "driver,AAPL,MacOS,PowerPC" properties. But this value + * does need to be big enough to ensure that we don't lose things + * like the interrupt-map property on a PCI-PCI bridge. + */ +#define MAX_PROPERTY_LENGTH 4096 + +#ifndef FB_MAX /* avoid pulling in all of the fb stuff */ +#define FB_MAX 8 +#endif + +#define ALIGNUL(x) (((x) + sizeof(unsigned long)-1) & -sizeof(unsigned long)) + +typedef u32 prom_arg_t; + +struct prom_args { + const char *service; + int nargs; + int nret; + prom_arg_t args[10]; +}; + +struct pci_address { + unsigned a_hi; + unsigned a_mid; + unsigned a_lo; +}; + +struct pci_reg_property { + struct pci_address addr; + unsigned size_hi; + unsigned size_lo; +}; + +struct pci_range { + struct pci_address addr; + unsigned phys; + unsigned size_hi; + unsigned size_lo; +}; + +struct isa_reg_property { + unsigned space; + unsigned address; + unsigned size; +}; + +struct pci_intr_map { + struct pci_address addr; + unsigned dunno; + phandle int_ctrler; + unsigned intr; +}; + +static void prom_exit(void); +static int call_prom(const char *service, int nargs, int nret, ...); +static int call_prom_ret(const char *service, int nargs, int nret, + prom_arg_t *rets, ...); +static void prom_print_hex(unsigned int v); +static int prom_set_color(ihandle ih, int i, int r, int g, int b); +static int prom_next_node(phandle *nodep); +static unsigned long check_display(unsigned long mem); +static void setup_disp_fake_bi(ihandle dp); +static unsigned long copy_device_tree(unsigned long mem_start, + unsigned long mem_end); +static unsigned long inspect_node(phandle node, struct device_node *dad, + unsigned long mem_start, unsigned long mem_end, + struct device_node ***allnextpp); +static void prom_hold_cpus(unsigned long mem); +static void prom_instantiate_rtas(void); +static void * early_get_property(unsigned long base, unsigned long node, + char *prop); + +prom_entry prom __initdata; +ihandle prom_chosen __initdata; +ihandle prom_stdout __initdata; + +static char *prom_display_paths[FB_MAX] __initdata; +static phandle prom_display_nodes[FB_MAX] __initdata; +static unsigned int prom_num_displays __initdata; +static ihandle prom_disp_node __initdata; +char *of_stdout_device __initdata; + +unsigned int rtas_data; /* physical pointer */ +unsigned int rtas_entry; /* physical pointer */ +unsigned int rtas_size; +unsigned int old_rtas; + +boot_infos_t *boot_infos; +char *bootpath; +char *bootdevice; +struct device_node *allnodes; + +extern char *klimit; + +static void __init +prom_exit(void) +{ + struct prom_args args; + + args.service = "exit"; + args.nargs = 0; + args.nret = 0; + prom(&args); + for (;;) /* should never get here */ + ; +} + +static int __init +call_prom(const char *service, int nargs, int nret, ...) +{ + va_list list; + int i; + struct prom_args prom_args; + + prom_args.service = service; + prom_args.nargs = nargs; + prom_args.nret = nret; + va_start(list, nret); + for (i = 0; i < nargs; ++i) + prom_args.args[i] = va_arg(list, prom_arg_t); + va_end(list); + for (i = 0; i < nret; ++i) + prom_args.args[i + nargs] = 0; + prom(&prom_args); + return prom_args.args[nargs]; +} + +static int __init +call_prom_ret(const char *service, int nargs, int nret, prom_arg_t *rets, ...) +{ + va_list list; + int i; + struct prom_args prom_args; + + prom_args.service = service; + prom_args.nargs = nargs; + prom_args.nret = nret; + va_start(list, rets); + for (i = 0; i < nargs; ++i) + prom_args.args[i] = va_arg(list, int); + va_end(list); + for (i = 0; i < nret; ++i) + prom_args.args[i + nargs] = 0; + prom(&prom_args); + for (i = 1; i < nret; ++i) + rets[i-1] = prom_args.args[nargs + i]; + return prom_args.args[nargs]; +} + +void __init +prom_print(const char *msg) +{ + const char *p, *q; + + if (prom_stdout == 0) + return; + + for (p = msg; *p != 0; p = q) { + for (q = p; *q != 0 && *q != '\n'; ++q) + ; + if (q > p) + call_prom("write", 3, 1, prom_stdout, p, q - p); + if (*q != 0) { + ++q; + call_prom("write", 3, 1, prom_stdout, "\r\n", 2); + } + } +} + +static void __init +prom_print_hex(unsigned int v) +{ + char buf[16]; + int i, c; + + for (i = 0; i < 8; ++i) { + c = (v >> ((7-i)*4)) & 0xf; + c += (c >= 10)? ('a' - 10): '0'; + buf[i] = c; + } + buf[i] = ' '; + buf[i+1] = 0; + prom_print(buf); +} + +static int __init +prom_set_color(ihandle ih, int i, int r, int g, int b) +{ + return call_prom("call-method", 6, 1, "color!", ih, i, b, g, r); +} + +static int __init +prom_next_node(phandle *nodep) +{ + phandle node; + + if ((node = *nodep) != 0 + && (*nodep = call_prom("child", 1, 1, node)) != 0) + return 1; + if ((*nodep = call_prom("peer", 1, 1, node)) != 0) + return 1; + for (;;) { + if ((node = call_prom("parent", 1, 1, node)) == 0) + return 0; + if ((*nodep = call_prom("peer", 1, 1, node)) != 0) + return 1; + } +} + +#ifdef CONFIG_POWER4 +/* + * Set up a hash table with a set of entries in it to map the + * first 64MB of RAM. This is used on 64-bit machines since + * some of them don't have BATs. + */ + +static inline void make_pte(unsigned long htab, unsigned int hsize, + unsigned int va, unsigned int pa, int mode) +{ + unsigned int *pteg; + unsigned int hash, i, vsid; + + vsid = ((va >> 28) * 0x111) << 12; + hash = ((va ^ vsid) >> 5) & 0x7fff80; + pteg = (unsigned int *)(htab + (hash & (hsize - 1))); + for (i = 0; i < 8; ++i, pteg += 4) { + if ((pteg[1] & 1) == 0) { + pteg[1] = vsid | ((va >> 16) & 0xf80) | 1; + pteg[3] = pa | mode; + break; + } + } +} + +extern unsigned long _SDR1; +extern PTE *Hash; +extern unsigned long Hash_size; + +static void __init +prom_alloc_htab(void) +{ + unsigned int hsize; + unsigned long htab; + unsigned int addr; + + /* + * Because of OF bugs we can't use the "claim" client + * interface to allocate memory for the hash table. + * This code is only used on 64-bit PPCs, and the only + * 64-bit PPCs at the moment are RS/6000s, and their + * OF is based at 0xc00000 (the 12M point), so we just + * arbitrarily use the 0x800000 - 0xc00000 region for the + * hash table. + * -- paulus. + */ + hsize = 4 << 20; /* POWER4 has no BATs */ + htab = (8 << 20); + call_prom("claim", 3, 1, htab, hsize, 0); + Hash = (void *)(htab + KERNELBASE); + Hash_size = hsize; + _SDR1 = htab + __ilog2(hsize) - 18; + + /* + * Put in PTEs for the first 64MB of RAM + */ + memset((void *)htab, 0, hsize); + for (addr = 0; addr < 0x4000000; addr += 0x1000) + make_pte(htab, hsize, addr + KERNELBASE, addr, + _PAGE_ACCESSED | _PAGE_COHERENT | PP_RWXX); +#if 0 /* DEBUG stuff mapping the SCC */ + make_pte(htab, hsize, 0x80013000, 0x80013000, + _PAGE_ACCESSED | _PAGE_NO_CACHE | _PAGE_GUARDED | PP_RWXX); +#endif +} +#endif /* CONFIG_POWER4 */ + + +/* + * If we have a display that we don't know how to drive, + * we will want to try to execute OF's open method for it + * later. However, OF will probably fall over if we do that + * we've taken over the MMU. + * So we check whether we will need to open the display, + * and if so, open it now. + */ +static unsigned long __init +check_display(unsigned long mem) +{ + phandle node; + ihandle ih; + int i, j; + char type[16], *path; + static unsigned char default_colors[] = { + 0x00, 0x00, 0x00, + 0x00, 0x00, 0xaa, + 0x00, 0xaa, 0x00, + 0x00, 0xaa, 0xaa, + 0xaa, 0x00, 0x00, + 0xaa, 0x00, 0xaa, + 0xaa, 0xaa, 0x00, + 0xaa, 0xaa, 0xaa, + 0x55, 0x55, 0x55, + 0x55, 0x55, 0xff, + 0x55, 0xff, 0x55, + 0x55, 0xff, 0xff, + 0xff, 0x55, 0x55, + 0xff, 0x55, 0xff, + 0xff, 0xff, 0x55, + 0xff, 0xff, 0xff + }; + const unsigned char *clut; + + prom_disp_node = 0; + + for (node = 0; prom_next_node(&node); ) { + type[0] = 0; + call_prom("getprop", 4, 1, node, "device_type", + type, sizeof(type)); + if (strcmp(type, "display") != 0) + continue; + /* It seems OF doesn't null-terminate the path :-( */ + path = (char *) mem; + memset(path, 0, 256); + if (call_prom("package-to-path", 3, 1, node, path, 255) < 0) + continue; + + /* + * If this display is the device that OF is using for stdout, + * move it to the front of the list. + */ + mem += strlen(path) + 1; + i = prom_num_displays++; + if (of_stdout_device != 0 && i > 0 + && strcmp(of_stdout_device, path) == 0) { + for (; i > 0; --i) { + prom_display_paths[i] + = prom_display_paths[i-1]; + prom_display_nodes[i] + = prom_display_nodes[i-1]; + } + } + prom_display_paths[i] = path; + prom_display_nodes[i] = node; + if (i == 0) + prom_disp_node = node; + if (prom_num_displays >= FB_MAX) + break; + } + + for (j=0; j 0) { + prom_disp_node = prom_display_nodes[j]; + j--; + } else + prom_disp_node = 0; + continue; + } else { + prom_print("... ok\n"); + call_prom("setprop", 4, 1, node, "linux,opened", 0, 0); + + /* + * Setup a usable color table when the appropriate + * method is available. + * Should update this to use set-colors. + */ + clut = default_colors; + for (i = 0; i < 32; i++, clut += 3) + if (prom_set_color(ih, i, clut[0], clut[1], + clut[2]) != 0) + break; + +#ifdef CONFIG_LOGO_LINUX_CLUT224 + clut = PTRRELOC(logo_linux_clut224.clut); + for (i = 0; i < logo_linux_clut224.clutsize; + i++, clut += 3) + if (prom_set_color(ih, i + 32, clut[0], + clut[1], clut[2]) != 0) + break; +#endif /* CONFIG_LOGO_LINUX_CLUT224 */ + } + } + + if (prom_stdout) { + phandle p; + p = call_prom("instance-to-package", 1, 1, prom_stdout); + if (p && p != -1) { + type[0] = 0; + call_prom("getprop", 4, 1, p, "device_type", + type, sizeof(type)); + if (strcmp(type, "display") == 0) + call_prom("setprop", 4, 1, p, "linux,boot-display", + 0, 0); + } + } + + return ALIGNUL(mem); +} + +/* This function will enable the early boot text when doing OF booting. This + * way, xmon output should work too + */ +static void __init +setup_disp_fake_bi(ihandle dp) +{ +#ifdef CONFIG_BOOTX_TEXT + int width = 640, height = 480, depth = 8, pitch; + unsigned address; + struct pci_reg_property addrs[8]; + int i, naddrs; + char name[32]; + char *getprop = "getprop"; + + prom_print("Initializing fake screen: "); + + memset(name, 0, sizeof(name)); + call_prom(getprop, 4, 1, dp, "name", name, sizeof(name)); + name[sizeof(name)-1] = 0; + prom_print(name); + prom_print("\n"); + call_prom(getprop, 4, 1, dp, "width", &width, sizeof(width)); + call_prom(getprop, 4, 1, dp, "height", &height, sizeof(height)); + call_prom(getprop, 4, 1, dp, "depth", &depth, sizeof(depth)); + pitch = width * ((depth + 7) / 8); + call_prom(getprop, 4, 1, dp, "linebytes", + &pitch, sizeof(pitch)); + if (pitch == 1) + pitch = 0x1000; /* for strange IBM display */ + address = 0; + call_prom(getprop, 4, 1, dp, "address", + &address, sizeof(address)); + if (address == 0) { + /* look for an assigned address with a size of >= 1MB */ + naddrs = call_prom(getprop, 4, 1, dp, "assigned-addresses", + addrs, sizeof(addrs)); + naddrs /= sizeof(struct pci_reg_property); + for (i = 0; i < naddrs; ++i) { + if (addrs[i].size_lo >= (1 << 20)) { + address = addrs[i].addr.a_lo; + /* use the BE aperture if possible */ + if (addrs[i].size_lo >= (16 << 20)) + address += (8 << 20); + break; + } + } + if (address == 0) { + prom_print("Failed to get address\n"); + return; + } + } + /* kludge for valkyrie */ + if (strcmp(name, "valkyrie") == 0) + address += 0x1000; + +#ifdef CONFIG_POWER4 +#if CONFIG_TASK_SIZE > 0x80000000 +#error CONFIG_TASK_SIZE cannot be above 0x80000000 with BOOTX_TEXT on G5 +#endif + { + extern boot_infos_t disp_bi; + unsigned long va, pa, i, offset; + va = 0x90000000; + pa = address & 0xfffff000ul; + offset = address & 0x00000fff; + + for (i=0; i<0x4000; i++) { + make_pte((unsigned long)Hash - KERNELBASE, Hash_size, va, pa, + _PAGE_ACCESSED | _PAGE_NO_CACHE | + _PAGE_GUARDED | PP_RWXX); + va += 0x1000; + pa += 0x1000; + } + btext_setup_display(width, height, depth, pitch, 0x90000000 | offset); + disp_bi.dispDeviceBase = (u8 *)address; + } +#else /* CONFIG_POWER4 */ + btext_setup_display(width, height, depth, pitch, address); + btext_prepare_BAT(); +#endif /* CONFIG_POWER4 */ +#endif /* CONFIG_BOOTX_TEXT */ +} + +/* + * Make a copy of the device tree from the PROM. + */ +static unsigned long __init +copy_device_tree(unsigned long mem_start, unsigned long mem_end) +{ + phandle root; + unsigned long new_start; + struct device_node **allnextp; + + root = call_prom("peer", 1, 1, (phandle)0); + if (root == (phandle)0) { + prom_print("couldn't get device tree root\n"); + prom_exit(); + } + allnextp = &allnodes; + mem_start = ALIGNUL(mem_start); + new_start = inspect_node(root, NULL, mem_start, mem_end, &allnextp); + *allnextp = NULL; + return new_start; +} + +static unsigned long __init +inspect_node(phandle node, struct device_node *dad, + unsigned long mem_start, unsigned long mem_end, + struct device_node ***allnextpp) +{ + int l; + phandle child; + struct device_node *np; + struct property *pp, **prev_propp; + char *prev_name, *namep; + unsigned char *valp; + + np = (struct device_node *) mem_start; + mem_start += sizeof(struct device_node); + memset(np, 0, sizeof(*np)); + np->node = node; + **allnextpp = PTRUNRELOC(np); + *allnextpp = &np->allnext; + if (dad != 0) { + np->parent = PTRUNRELOC(dad); + /* we temporarily use the `next' field as `last_child'. */ + if (dad->next == 0) + dad->child = PTRUNRELOC(np); + else + dad->next->sibling = PTRUNRELOC(np); + dad->next = np; + } + + /* get and store all properties */ + prev_propp = &np->properties; + prev_name = ""; + for (;;) { + pp = (struct property *) mem_start; + namep = (char *) (pp + 1); + pp->name = PTRUNRELOC(namep); + if (call_prom("nextprop", 3, 1, node, prev_name, namep) <= 0) + break; + mem_start = ALIGNUL((unsigned long)namep + strlen(namep) + 1); + prev_name = namep; + valp = (unsigned char *) mem_start; + pp->value = PTRUNRELOC(valp); + pp->length = call_prom("getprop", 4, 1, node, namep, + valp, mem_end - mem_start); + if (pp->length < 0) + continue; +#ifdef MAX_PROPERTY_LENGTH + if (pp->length > MAX_PROPERTY_LENGTH) + continue; /* ignore this property */ +#endif + mem_start = ALIGNUL(mem_start + pp->length); + *prev_propp = PTRUNRELOC(pp); + prev_propp = &pp->next; + } + if (np->node != 0) { + /* Add a "linux,phandle" property" */ + pp = (struct property *) mem_start; + *prev_propp = PTRUNRELOC(pp); + prev_propp = &pp->next; + namep = (char *) (pp + 1); + pp->name = PTRUNRELOC(namep); + strcpy(namep, "linux,phandle"); + mem_start = ALIGNUL((unsigned long)namep + strlen(namep) + 1); + pp->value = (unsigned char *) PTRUNRELOC(&np->node); + pp->length = sizeof(np->node); + } + *prev_propp = NULL; + + /* get the node's full name */ + l = call_prom("package-to-path", 3, 1, node, + mem_start, mem_end - mem_start); + if (l >= 0) { + char *p, *ep; + + np->full_name = PTRUNRELOC((char *) mem_start); + *(char *)(mem_start + l) = 0; + /* Fixup an Apple bug where they have bogus \0 chars in the + * middle of the path in some properties + */ + for (p = (char *)mem_start, ep = p + l; p < ep; p++) + if ((*p) == '\0') { + memmove(p, p+1, ep - p); + ep--; + } + mem_start = ALIGNUL(mem_start + l + 1); + } + + /* do all our children */ + child = call_prom("child", 1, 1, node); + while (child != 0) { + mem_start = inspect_node(child, np, mem_start, mem_end, + allnextpp); + child = call_prom("peer", 1, 1, child); + } + + return mem_start; +} + +unsigned long smp_chrp_cpu_nr __initdata = 0; + +/* + * With CHRP SMP we need to use the OF to start the other + * processors so we can't wait until smp_boot_cpus (the OF is + * trashed by then) so we have to put the processors into + * a holding pattern controlled by the kernel (not OF) before + * we destroy the OF. + * + * This uses a chunk of high memory, puts some holding pattern + * code there and sends the other processors off to there until + * smp_boot_cpus tells them to do something. We do that by using + * physical address 0x0. The holding pattern checks that address + * until its cpu # is there, when it is that cpu jumps to + * __secondary_start(). smp_boot_cpus() takes care of setting those + * values. + * + * We also use physical address 0x4 here to tell when a cpu + * is in its holding pattern code. + * + * -- Cort + * + * Note that we have to do this if we have more than one CPU, + * even if this is a UP kernel. Otherwise when we trash OF + * the other CPUs will start executing some random instructions + * and crash the system. -- paulus + */ +static void __init +prom_hold_cpus(unsigned long mem) +{ + extern void __secondary_hold(void); + unsigned long i; + int cpu; + phandle node; + char type[16], *path; + unsigned int reg; + + /* + * XXX: hack to make sure we're chrp, assume that if we're + * chrp we have a device_type property -- Cort + */ + node = call_prom("finddevice", 1, 1, "/"); + if (call_prom("getprop", 4, 1, node, + "device_type", type, sizeof(type)) <= 0) + return; + + /* copy the holding pattern code to someplace safe (0) */ + /* the holding pattern is now within the first 0x100 + bytes of the kernel image -- paulus */ + memcpy((void *)0, _stext, 0x100); + flush_icache_range(0, 0x100); + + /* look for cpus */ + *(unsigned long *)(0x0) = 0; + asm volatile("dcbf 0,%0": : "r" (0) : "memory"); + for (node = 0; prom_next_node(&node); ) { + type[0] = 0; + call_prom("getprop", 4, 1, node, "device_type", + type, sizeof(type)); + if (strcmp(type, "cpu") != 0) + continue; + path = (char *) mem; + memset(path, 0, 256); + if (call_prom("package-to-path", 3, 1, node, path, 255) < 0) + continue; + reg = -1; + call_prom("getprop", 4, 1, node, "reg", ®, sizeof(reg)); + cpu = smp_chrp_cpu_nr++; +#ifdef CONFIG_SMP + smp_hw_index[cpu] = reg; +#endif /* CONFIG_SMP */ + /* XXX: hack - don't start cpu 0, this cpu -- Cort */ + if (cpu == 0) + continue; + prom_print("starting cpu "); + prom_print(path); + *(ulong *)(0x4) = 0; + call_prom("start-cpu", 3, 0, node, + (char *)__secondary_hold - _stext, cpu); + prom_print("..."); + for ( i = 0 ; (i < 10000) && (*(ulong *)(0x4) == 0); i++ ) + ; + if (*(ulong *)(0x4) == cpu) + prom_print("ok\n"); + else { + prom_print("failed: "); + prom_print_hex(*(ulong *)0x4); + prom_print("\n"); + } + } +} + +static void __init +prom_instantiate_rtas(void) +{ + ihandle prom_rtas; + prom_arg_t result; + + prom_rtas = call_prom("finddevice", 1, 1, "/rtas"); + if (prom_rtas == -1) + return; + + rtas_size = 0; + call_prom("getprop", 4, 1, prom_rtas, + "rtas-size", &rtas_size, sizeof(rtas_size)); + prom_print("instantiating rtas"); + if (rtas_size == 0) { + rtas_data = 0; + } else { + /* + * Ask OF for some space for RTAS. + * Actually OF has bugs so we just arbitrarily + * use memory at the 6MB point. + */ + rtas_data = 6 << 20; + prom_print(" at "); + prom_print_hex(rtas_data); + } + + prom_rtas = call_prom("open", 1, 1, "/rtas"); + prom_print("..."); + rtas_entry = 0; + if (call_prom_ret("call-method", 3, 2, &result, + "instantiate-rtas", prom_rtas, rtas_data) == 0) + rtas_entry = result; + if ((rtas_entry == -1) || (rtas_entry == 0)) + prom_print(" failed\n"); + else + prom_print(" done\n"); +} + +/* + * We enter here early on, when the Open Firmware prom is still + * handling exceptions and the MMU hash table for us. + */ +unsigned long __init +prom_init(int r3, int r4, prom_entry pp) +{ + unsigned long mem; + ihandle prom_mmu; + unsigned long offset = reloc_offset(); + int i, l; + char *p, *d; + unsigned long phys; + prom_arg_t result[3]; + char model[32]; + phandle node; + int rc; + + /* Default */ + phys = (unsigned long) &_stext; + + /* First get a handle for the stdout device */ + prom = pp; + prom_chosen = call_prom("finddevice", 1, 1, "/chosen"); + if (prom_chosen == -1) + prom_exit(); + if (call_prom("getprop", 4, 1, prom_chosen, "stdout", + &prom_stdout, sizeof(prom_stdout)) <= 0) + prom_exit(); + + /* Get the full OF pathname of the stdout device */ + mem = (unsigned long) klimit + offset; + p = (char *) mem; + memset(p, 0, 256); + call_prom("instance-to-path", 3, 1, prom_stdout, p, 255); + of_stdout_device = p; + mem += strlen(p) + 1; + + /* Get the boot device and translate it to a full OF pathname. */ + p = (char *) mem; + l = call_prom("getprop", 4, 1, prom_chosen, "bootpath", p, 1<<20); + if (l > 0) { + p[l] = 0; /* should already be null-terminated */ + bootpath = PTRUNRELOC(p); + mem += l + 1; + d = (char *) mem; + *d = 0; + call_prom("canon", 3, 1, p, d, 1<<20); + bootdevice = PTRUNRELOC(d); + mem = ALIGNUL(mem + strlen(d) + 1); + } + + prom_instantiate_rtas(); + +#ifdef CONFIG_POWER4 + /* + * Find out how much memory we have and allocate a + * suitably-sized hash table. + */ + prom_alloc_htab(); +#endif + mem = check_display(mem); + + prom_print("copying OF device tree..."); + mem = copy_device_tree(mem, mem + (1<<20)); + prom_print("done\n"); + + prom_hold_cpus(mem); + + klimit = (char *) (mem - offset); + + node = call_prom("finddevice", 1, 1, "/"); + rc = call_prom("getprop", 4, 1, node, "model", model, sizeof(model)); + if (rc > 0 && !strncmp (model, "Pegasos", 7) + && strncmp (model, "Pegasos2", 8)) { + /* Pegasos 1 has a broken translate method in the OF, + * and furthermore the BATs are mapped 1:1 so the phys + * address calculated above is correct, so let's use + * it directly. + */ + } else if (offset == 0) { + /* If we are already running at 0xc0000000, we assume we were + * loaded by an OF bootloader which did set a BAT for us. + * This breaks OF translate so we force phys to be 0. + */ + prom_print("(already at 0xc0000000) phys=0\n"); + phys = 0; + } else if (call_prom("getprop", 4, 1, prom_chosen, "mmu", + &prom_mmu, sizeof(prom_mmu)) <= 0) { + prom_print(" no MMU found\n"); + } else if (call_prom_ret("call-method", 4, 4, result, "translate", + prom_mmu, &_stext, 1) != 0) { + prom_print(" (translate failed)\n"); + } else { + /* We assume the phys. address size is 3 cells */ + phys = result[2]; + } + + if (prom_disp_node != 0) + setup_disp_fake_bi(prom_disp_node); + + /* Use quiesce call to get OF to shut down any devices it's using */ + prom_print("Calling quiesce ...\n"); + call_prom("quiesce", 0, 0); + + /* Relocate various pointers which will be used once the + kernel is running at the address it was linked at. */ + for (i = 0; i < prom_num_displays; ++i) + prom_display_paths[i] = PTRUNRELOC(prom_display_paths[i]); + +#ifdef CONFIG_SERIAL_CORE_CONSOLE + /* Relocate the of stdout for console autodetection */ + of_stdout_device = PTRUNRELOC(of_stdout_device); +#endif + + prom_print("returning 0x"); + prom_print_hex(phys); + prom_print("from prom_init\n"); + prom_stdout = 0; + + return phys; +} + +/* + * early_get_property is used to access the device tree image prepared + * by BootX very early on, before the pointers in it have been relocated. + */ +static void * __init +early_get_property(unsigned long base, unsigned long node, char *prop) +{ + struct device_node *np = (struct device_node *)(base + node); + struct property *pp; + + for (pp = np->properties; pp != 0; pp = pp->next) { + pp = (struct property *) (base + (unsigned long)pp); + if (strcmp((char *)((unsigned long)pp->name + base), + prop) == 0) { + return (void *)((unsigned long)pp->value + base); + } + } + return NULL; +} + +/* Is boot-info compatible ? */ +#define BOOT_INFO_IS_COMPATIBLE(bi) ((bi)->compatible_version <= BOOT_INFO_VERSION) +#define BOOT_INFO_IS_V2_COMPATIBLE(bi) ((bi)->version >= 2) +#define BOOT_INFO_IS_V4_COMPATIBLE(bi) ((bi)->version >= 4) + +void __init +bootx_init(unsigned long r4, unsigned long phys) +{ + boot_infos_t *bi = (boot_infos_t *) r4; + unsigned long space; + unsigned long ptr, x; + char *model; + + boot_infos = PTRUNRELOC(bi); + if (!BOOT_INFO_IS_V2_COMPATIBLE(bi)) + bi->logicalDisplayBase = NULL; + +#ifdef CONFIG_BOOTX_TEXT + btext_init(bi); + + /* + * Test if boot-info is compatible. Done only in config + * CONFIG_BOOTX_TEXT since there is nothing much we can do + * with an incompatible version, except display a message + * and eventually hang the processor... + * + * I'll try to keep enough of boot-info compatible in the + * future to always allow display of this message; + */ + if (!BOOT_INFO_IS_COMPATIBLE(bi)) { + btext_drawstring(" !!! WARNING - Incompatible version of BootX !!!\n\n\n"); + btext_flushscreen(); + } +#endif /* CONFIG_BOOTX_TEXT */ + + /* New BootX enters kernel with MMU off, i/os are not allowed + here. This hack will have been done by the boostrap anyway. + */ + if (bi->version < 4) { + /* + * XXX If this is an iMac, turn off the USB controller. + */ + model = (char *) early_get_property + (r4 + bi->deviceTreeOffset, 4, "model"); + if (model + && (strcmp(model, "iMac,1") == 0 + || strcmp(model, "PowerMac1,1") == 0)) { + out_le32((unsigned *)0x80880008, 1); /* XXX */ + } + } + + /* Move klimit to enclose device tree, args, ramdisk, etc... */ + if (bi->version < 5) { + space = bi->deviceTreeOffset + bi->deviceTreeSize; + if (bi->ramDisk) + space = bi->ramDisk + bi->ramDiskSize; + } else + space = bi->totalParamsSize; + klimit = PTRUNRELOC((char *) bi + space); + + /* New BootX will have flushed all TLBs and enters kernel with + MMU switched OFF, so this should not be useful anymore. + */ + if (bi->version < 4) { + /* + * Touch each page to make sure the PTEs for them + * are in the hash table - the aim is to try to avoid + * getting DSI exceptions while copying the kernel image. + */ + for (ptr = ((unsigned long) &_stext) & PAGE_MASK; + ptr < (unsigned long)bi + space; ptr += PAGE_SIZE) + x = *(volatile unsigned long *)ptr; + } + +#ifdef CONFIG_BOOTX_TEXT + /* + * Note that after we call btext_prepare_BAT, we can't do + * prom_draw*, flushscreen or clearscreen until we turn the MMU + * on, since btext_prepare_BAT sets disp_bi.logicalDisplayBase + * to a virtual address. + */ + btext_prepare_BAT(); +#endif +} diff --git a/trunk/arch/ppc/xmon/start.c b/trunk/arch/ppc/xmon/start.c index cfc2d6ad464d..ff86b2d814cb 100644 --- a/trunk/arch/ppc/xmon/start.c +++ b/trunk/arch/ppc/xmon/start.c @@ -58,7 +58,7 @@ static struct sysrq_key_op sysrq_xmon_op = void xmon_map_scc(void) { -#ifdef CONFIG_PPC_PREP +#ifdef CONFIG_PPC_MULTIPLATFORM volatile unsigned char *base; #elif defined(CONFIG_GEMINI) diff --git a/trunk/arch/s390/kernel/smp.c b/trunk/arch/s390/kernel/smp.c index 343120c9223d..2b8841f85534 100644 --- a/trunk/arch/s390/kernel/smp.c +++ b/trunk/arch/s390/kernel/smp.c @@ -801,7 +801,7 @@ void __init smp_prepare_cpus(unsigned int max_cpus) */ print_cpu_info(&S390_lowcore.cpu_data); - for_each_possible_cpu(i) { + for_each_cpu(i) { lowcore_ptr[i] = (struct _lowcore *) __get_free_pages(GFP_KERNEL|GFP_DMA, sizeof(void*) == 8 ? 1 : 0); @@ -831,7 +831,7 @@ void __init smp_prepare_cpus(unsigned int max_cpus) #endif set_prefix((u32)(unsigned long) lowcore_ptr[smp_processor_id()]); - for_each_possible_cpu(cpu) + for_each_cpu(cpu) if (cpu != smp_processor_id()) smp_create_idle(cpu); } @@ -868,7 +868,7 @@ static int __init topology_init(void) int cpu; int ret; - for_each_possible_cpu(cpu) { + for_each_cpu(cpu) { ret = register_cpu(&per_cpu(cpu_devices, cpu), cpu, NULL); if (ret) printk(KERN_WARNING "topology_init: register_cpu %d " diff --git a/trunk/arch/sh/kernel/cpu/init.c b/trunk/arch/sh/kernel/cpu/init.c index 868e68b28880..cf94e8ef17c5 100644 --- a/trunk/arch/sh/kernel/cpu/init.c +++ b/trunk/arch/sh/kernel/cpu/init.c @@ -30,7 +30,7 @@ static int x##_disabled __initdata = 0; \ static int __init x##_setup(char *opts) \ { \ x##_disabled = 1; \ - return 1; \ + return 0; \ } \ __setup("no" __stringify(x), x##_setup); diff --git a/trunk/arch/sh/kernel/setup.c b/trunk/arch/sh/kernel/setup.c index bb229ef030f3..7ee4ca203616 100644 --- a/trunk/arch/sh/kernel/setup.c +++ b/trunk/arch/sh/kernel/setup.c @@ -401,7 +401,7 @@ static int __init topology_init(void) { int cpu_id; - for_each_possible_cpu(cpu_id) + for_each_cpu(cpu_id) register_cpu(&cpu[cpu_id], cpu_id, NULL); return 0; diff --git a/trunk/arch/um/Kconfig b/trunk/arch/um/Kconfig index 05fbb20636cb..5982fe2753e0 100644 --- a/trunk/arch/um/Kconfig +++ b/trunk/arch/um/Kconfig @@ -22,9 +22,6 @@ config SBUS config PCI bool -config PCMCIA - bool - config GENERIC_CALIBRATE_DELAY bool default y diff --git a/trunk/arch/um/Makefile b/trunk/arch/um/Makefile index 24790bed2054..8d14c7a831be 100644 --- a/trunk/arch/um/Makefile +++ b/trunk/arch/um/Makefile @@ -20,7 +20,7 @@ core-y += $(ARCH_DIR)/kernel/ \ # Have to precede the include because the included Makefiles reference them. SYMLINK_HEADERS := archparam.h system.h sigcontext.h processor.h ptrace.h \ - module.h vm-flags.h elf.h host_ldt.h + module.h vm-flags.h elf.h ldt.h SYMLINK_HEADERS := $(foreach header,$(SYMLINK_HEADERS),include/asm-um/$(header)) # XXX: The "os" symlink is only used by arch/um/include/os.h, which includes @@ -129,7 +129,7 @@ CPPFLAGS_vmlinux.lds = -U$(SUBARCH) \ -DSTART=$(START) -DELF_ARCH=$(ELF_ARCH) \ -DELF_FORMAT="$(ELF_FORMAT)" $(CPP_MODE-y) \ -DKERNEL_STACK_SIZE=$(STACK_SIZE) \ - -DUNMAP_PATH=arch/um/sys-$(SUBARCH)/unmap.o + -DUNMAP_PATH=arch/um/sys-$(SUBARCH)/unmap_fin.o #The wrappers will select whether using "malloc" or the kernel allocator. LINK_WRAPS = -Wl,--wrap,malloc -Wl,--wrap,free -Wl,--wrap,calloc @@ -150,7 +150,8 @@ CLEAN_FILES += linux x.i gmon.out $(ARCH_DIR)/include/uml-config.h \ $(ARCH_DIR)/include/user_constants.h \ $(ARCH_DIR)/include/kern_constants.h $(ARCH_DIR)/Kconfig.arch -MRPROPER_FILES += $(ARCH_SYMLINKS) +MRPROPER_FILES += $(SYMLINK_HEADERS) $(ARCH_SYMLINKS) \ + $(addprefix $(ARCH_DIR)/kernel/,$(KERN_SYMLINKS)) $(ARCH_DIR)/os archclean: @find . \( -name '*.bb' -o -name '*.bbg' -o -name '*.da' \ diff --git a/trunk/arch/um/Makefile-x86_64 b/trunk/arch/um/Makefile-x86_64 index dfd88b652fbe..38df311e75dc 100644 --- a/trunk/arch/um/Makefile-x86_64 +++ b/trunk/arch/um/Makefile-x86_64 @@ -1,7 +1,7 @@ # Copyright 2003 - 2004 Pathscale, Inc # Released under the GPL -core-y += arch/um/sys-x86_64/ +libs-y += arch/um/sys-x86_64/ START := 0x60000000 #We #undef __x86_64__ for kernelspace, not for userspace where diff --git a/trunk/arch/um/drivers/daemon_kern.c b/trunk/arch/um/drivers/daemon_kern.c index 53d09ed78b42..a61b7b46bc02 100644 --- a/trunk/arch/um/drivers/daemon_kern.c +++ b/trunk/arch/um/drivers/daemon_kern.c @@ -95,7 +95,18 @@ static struct transport daemon_transport = { static int register_daemon(void) { register_transport(&daemon_transport); - return 0; + return(1); } __initcall(register_daemon); + +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * Emacs will notice this stuff at the end of the file and automatically + * adjust the settings for this buffer only. This must remain at the end + * of the file. + * --------------------------------------------------------------------------- + * Local variables: + * c-file-style: "linux" + * End: + */ diff --git a/trunk/arch/um/drivers/harddog_kern.c b/trunk/arch/um/drivers/harddog_kern.c index d18a974735e6..49acb2badf32 100644 --- a/trunk/arch/um/drivers/harddog_kern.c +++ b/trunk/arch/um/drivers/harddog_kern.c @@ -104,7 +104,7 @@ static int harddog_release(struct inode *inode, struct file *file) extern int ping_watchdog(int fd); -static ssize_t harddog_write(struct file *file, const char __user *data, size_t len, +static ssize_t harddog_write(struct file *file, const char *data, size_t len, loff_t *ppos) { /* @@ -118,7 +118,6 @@ static ssize_t harddog_write(struct file *file, const char __user *data, size_t static int harddog_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { - void __user *argp= (void __user *)arg; static struct watchdog_info ident = { WDIOC_SETTIMEOUT, 0, @@ -128,12 +127,13 @@ static int harddog_ioctl(struct inode *inode, struct file *file, default: return -ENOTTY; case WDIOC_GETSUPPORT: - if(copy_to_user(argp, &ident, sizeof(ident))) + if(copy_to_user((struct harddog_info *)arg, &ident, + sizeof(ident))) return -EFAULT; return 0; case WDIOC_GETSTATUS: case WDIOC_GETBOOTSTATUS: - return put_user(0,(int __user *)argp); + return put_user(0,(int *)arg); case WDIOC_KEEPALIVE: return(ping_watchdog(harddog_out_fd)); } diff --git a/trunk/arch/um/drivers/hostaudio_kern.c b/trunk/arch/um/drivers/hostaudio_kern.c index 37232f908cd7..59602b81b240 100644 --- a/trunk/arch/um/drivers/hostaudio_kern.c +++ b/trunk/arch/um/drivers/hostaudio_kern.c @@ -67,8 +67,8 @@ MODULE_PARM_DESC(mixer, MIXER_HELP); /* /dev/dsp file operations */ -static ssize_t hostaudio_read(struct file *file, char __user *buffer, - size_t count, loff_t *ppos) +static ssize_t hostaudio_read(struct file *file, char *buffer, size_t count, + loff_t *ppos) { struct hostaudio_state *state = file->private_data; void *kbuf; @@ -94,7 +94,7 @@ static ssize_t hostaudio_read(struct file *file, char __user *buffer, return(err); } -static ssize_t hostaudio_write(struct file *file, const char __user *buffer, +static ssize_t hostaudio_write(struct file *file, const char *buffer, size_t count, loff_t *ppos) { struct hostaudio_state *state = file->private_data; @@ -152,7 +152,7 @@ static int hostaudio_ioctl(struct inode *inode, struct file *file, case SNDCTL_DSP_CHANNELS: case SNDCTL_DSP_SUBDIVIDE: case SNDCTL_DSP_SETFRAGMENT: - if(get_user(data, (int __user *) arg)) + if(get_user(data, (int *) arg)) return(-EFAULT); break; default: @@ -168,7 +168,7 @@ static int hostaudio_ioctl(struct inode *inode, struct file *file, case SNDCTL_DSP_CHANNELS: case SNDCTL_DSP_SUBDIVIDE: case SNDCTL_DSP_SETFRAGMENT: - if(put_user(data, (int __user *) arg)) + if(put_user(data, (int *) arg)) return(-EFAULT); break; default: diff --git a/trunk/arch/um/drivers/mcast_kern.c b/trunk/arch/um/drivers/mcast_kern.c index 3a7af18cf944..c9b078fba03e 100644 --- a/trunk/arch/um/drivers/mcast_kern.c +++ b/trunk/arch/um/drivers/mcast_kern.c @@ -124,7 +124,18 @@ static struct transport mcast_transport = { static int register_mcast(void) { register_transport(&mcast_transport); - return 0; + return(1); } __initcall(register_mcast); + +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * Emacs will notice this stuff at the end of the file and automatically + * adjust the settings for this buffer only. This must remain at the end + * of the file. + * --------------------------------------------------------------------------- + * Local variables: + * c-file-style: "linux" + * End: + */ diff --git a/trunk/arch/um/drivers/mconsole_kern.c b/trunk/arch/um/drivers/mconsole_kern.c index 28e3760e8b98..1488816588ea 100644 --- a/trunk/arch/um/drivers/mconsole_kern.c +++ b/trunk/arch/um/drivers/mconsole_kern.c @@ -20,8 +20,6 @@ #include "linux/namei.h" #include "linux/proc_fs.h" #include "linux/syscalls.h" -#include "linux/list.h" -#include "linux/mm.h" #include "linux/console.h" #include "asm/irq.h" #include "asm/uaccess.h" @@ -349,142 +347,6 @@ static struct mc_device *mconsole_find_dev(char *name) return(NULL); } -#define UNPLUGGED_PER_PAGE \ - ((PAGE_SIZE - sizeof(struct list_head)) / sizeof(unsigned long)) - -struct unplugged_pages { - struct list_head list; - void *pages[UNPLUGGED_PER_PAGE]; -}; - -static unsigned long long unplugged_pages_count = 0; -static struct list_head unplugged_pages = LIST_HEAD_INIT(unplugged_pages); -static int unplug_index = UNPLUGGED_PER_PAGE; - -static int mem_config(char *str) -{ - unsigned long long diff; - int err = -EINVAL, i, add; - char *ret; - - if(str[0] != '=') - goto out; - - str++; - if(str[0] == '-') - add = 0; - else if(str[0] == '+'){ - add = 1; - } - else goto out; - - str++; - diff = memparse(str, &ret); - if(*ret != '\0') - goto out; - - diff /= PAGE_SIZE; - - for(i = 0; i < diff; i++){ - struct unplugged_pages *unplugged; - void *addr; - - if(add){ - if(list_empty(&unplugged_pages)) - break; - - unplugged = list_entry(unplugged_pages.next, - struct unplugged_pages, list); - if(unplug_index > 0) - addr = unplugged->pages[--unplug_index]; - else { - list_del(&unplugged->list); - addr = unplugged; - unplug_index = UNPLUGGED_PER_PAGE; - } - - free_page((unsigned long) addr); - unplugged_pages_count--; - } - else { - struct page *page; - - page = alloc_page(GFP_ATOMIC); - if(page == NULL) - break; - - unplugged = page_address(page); - if(unplug_index == UNPLUGGED_PER_PAGE){ - INIT_LIST_HEAD(&unplugged->list); - list_add(&unplugged->list, &unplugged_pages); - unplug_index = 0; - } - else { - struct list_head *entry = unplugged_pages.next; - addr = unplugged; - - unplugged = list_entry(entry, - struct unplugged_pages, - list); - unplugged->pages[unplug_index++] = addr; - err = os_drop_memory(addr, PAGE_SIZE); - if(err) - printk("Failed to release memory - " - "errno = %d\n", err); - } - - unplugged_pages_count++; - } - } - - err = 0; -out: - return err; -} - -static int mem_get_config(char *name, char *str, int size, char **error_out) -{ - char buf[sizeof("18446744073709551615")]; - int len = 0; - - sprintf(buf, "%ld", uml_physmem); - CONFIG_CHUNK(str, size, len, buf, 1); - - return len; -} - -static int mem_id(char **str, int *start_out, int *end_out) -{ - *start_out = 0; - *end_out = 0; - - return 0; -} - -static int mem_remove(int n) -{ - return -EBUSY; -} - -static struct mc_device mem_mc = { - .name = "mem", - .config = mem_config, - .get_config = mem_get_config, - .id = mem_id, - .remove = mem_remove, -}; - -static int mem_mc_init(void) -{ - if(can_drop_memory()) - mconsole_register_dev(&mem_mc); - else printk("Can't release memory to the host - memory hotplug won't " - "be supported\n"); - return 0; -} - -__initcall(mem_mc_init); - #define CONFIG_BUF_SIZE 64 static void mconsole_get_config(int (*get_config)(char *, char *, int, @@ -616,7 +478,7 @@ static void console_write(struct console *console, const char *string, return; while(1){ - n = min((size_t)len, ARRAY_SIZE(console_buf) - console_index); + n = min(len, ARRAY_SIZE(console_buf) - console_index); strncpy(&console_buf[console_index], string, n); console_index += n; string += n; diff --git a/trunk/arch/um/drivers/pcap_kern.c b/trunk/arch/um/drivers/pcap_kern.c index 466ff2c2f918..07c80f2156ef 100644 --- a/trunk/arch/um/drivers/pcap_kern.c +++ b/trunk/arch/um/drivers/pcap_kern.c @@ -106,7 +106,18 @@ static struct transport pcap_transport = { static int register_pcap(void) { register_transport(&pcap_transport); - return 0; + return(1); } __initcall(register_pcap); + +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * Emacs will notice this stuff at the end of the file and automatically + * adjust the settings for this buffer only. This must remain at the end + * of the file. + * --------------------------------------------------------------------------- + * Local variables: + * c-file-style: "linux" + * End: + */ diff --git a/trunk/arch/um/drivers/slip_kern.c b/trunk/arch/um/drivers/slip_kern.c index 163ee0d5f75e..a62f5ef445cf 100644 --- a/trunk/arch/um/drivers/slip_kern.c +++ b/trunk/arch/um/drivers/slip_kern.c @@ -93,7 +93,18 @@ static struct transport slip_transport = { static int register_slip(void) { register_transport(&slip_transport); - return 0; + return(1); } __initcall(register_slip); + +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * Emacs will notice this stuff at the end of the file and automatically + * adjust the settings for this buffer only. This must remain at the end + * of the file. + * --------------------------------------------------------------------------- + * Local variables: + * c-file-style: "linux" + * End: + */ diff --git a/trunk/arch/um/drivers/slirp_kern.c b/trunk/arch/um/drivers/slirp_kern.c index 95e50c943e14..33d7982be5d3 100644 --- a/trunk/arch/um/drivers/slirp_kern.c +++ b/trunk/arch/um/drivers/slirp_kern.c @@ -77,7 +77,7 @@ static int slirp_setup(char *str, char **mac_out, void *data) int i=0; *init = ((struct slirp_init) - { .argw = { { "slirp", NULL } } }); + { argw : { { "slirp", NULL } } }); str = split_if_spec(str, mac_out, NULL); @@ -116,7 +116,18 @@ static struct transport slirp_transport = { static int register_slirp(void) { register_transport(&slirp_transport); - return 0; + return(1); } __initcall(register_slirp); + +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * Emacs will notice this stuff at the end of the file and automatically + * adjust the settings for this buffer only. This must remain at the end + * of the file. + * --------------------------------------------------------------------------- + * Local variables: + * c-file-style: "linux" + * End: + */ diff --git a/trunk/arch/um/drivers/ubd_kern.c b/trunk/arch/um/drivers/ubd_kern.c index 0897852b09a3..0336575d2448 100644 --- a/trunk/arch/um/drivers/ubd_kern.c +++ b/trunk/arch/um/drivers/ubd_kern.c @@ -891,7 +891,7 @@ int ubd_driver_init(void){ SA_INTERRUPT, "ubd", ubd_dev); if(err != 0) printk(KERN_ERR "um_request_irq failed - errno = %d\n", -err); - return 0; + return(err); } device_initcall(ubd_driver_init); diff --git a/trunk/arch/um/include/kern_util.h b/trunk/arch/um/include/kern_util.h index 42557130a408..07176d92e1c9 100644 --- a/trunk/arch/um/include/kern_util.h +++ b/trunk/arch/um/include/kern_util.h @@ -116,11 +116,7 @@ extern void *get_current(void); extern struct task_struct *get_task(int pid, int require); extern void machine_halt(void); extern int is_syscall(unsigned long addr); - -extern void arch_switch_to_tt(struct task_struct *from, struct task_struct *to); - -extern void arch_switch_to_skas(struct task_struct *from, struct task_struct *to); - +extern void arch_switch(void); extern void free_irq(unsigned int, void *); extern int cpu(void); diff --git a/trunk/arch/um/include/line.h b/trunk/arch/um/include/line.h index 6ac0f8252e21..6f4d680dc1d4 100644 --- a/trunk/arch/um/include/line.h +++ b/trunk/arch/um/include/line.h @@ -58,17 +58,23 @@ struct line { }; #define LINE_INIT(str, d) \ - { .init_str = str, \ - .init_pri = INIT_STATIC, \ - .valid = 1, \ - .lock = SPIN_LOCK_UNLOCKED, \ - .driver = d } + { init_str : str, \ + init_pri : INIT_STATIC, \ + valid : 1, \ + throttled : 0, \ + lock : SPIN_LOCK_UNLOCKED, \ + buffer : NULL, \ + head : NULL, \ + tail : NULL, \ + sigio : 0, \ + driver : d, \ + have_irq : 0 } struct lines { int num; }; -#define LINES_INIT(n) { .num = n } +#define LINES_INIT(n) { num : n } extern void line_close(struct tty_struct *tty, struct file * filp); extern int line_open(struct line *lines, struct tty_struct *tty); diff --git a/trunk/arch/um/include/mem_user.h b/trunk/arch/um/include/mem_user.h index a54514d2cc3a..a1064c5823bf 100644 --- a/trunk/arch/um/include/mem_user.h +++ b/trunk/arch/um/include/mem_user.h @@ -49,6 +49,7 @@ extern int iomem_size; extern unsigned long host_task_size; extern unsigned long task_size; +extern void check_devanon(void); extern int init_mem_user(void); extern void setup_memory(void *entry); extern unsigned long find_iomem(char *driver, unsigned long *len_out); diff --git a/trunk/arch/um/include/os.h b/trunk/arch/um/include/os.h index f88856c28a66..d3d1bc6074ef 100644 --- a/trunk/arch/um/include/os.h +++ b/trunk/arch/um/include/os.h @@ -13,7 +13,6 @@ #include "kern_util.h" #include "skas/mm_id.h" #include "irq_user.h" -#include "sysdep/tls.h" #define OS_TYPE_FILE 1 #define OS_TYPE_DIR 2 @@ -173,7 +172,6 @@ extern int os_fchange_dir(int fd); extern void os_early_checks(void); extern int can_do_skas(void); extern void os_check_bugs(void); -extern void check_host_supports_tls(int *supports_tls, int *tls_min); /* Make sure they are clear when running in TT mode. Required by * SEGV_MAYBE_FIXABLE */ @@ -207,8 +205,6 @@ extern int os_map_memory(void *virt, int fd, unsigned long long off, extern int os_protect_memory(void *addr, unsigned long len, int r, int w, int x); extern int os_unmap_memory(void *addr, int len); -extern int os_drop_memory(void *addr, int length); -extern int can_drop_memory(void); extern void os_flush_stdout(void); /* tt.c @@ -238,12 +234,8 @@ extern int run_helper_thread(int (*proc)(void *), void *arg, int stack_order); extern int helper_wait(int pid); - -/* tls.c */ -extern int os_set_thread_area(user_desc_t *info, int pid); -extern int os_get_thread_area(user_desc_t *info, int pid); - /* umid.c */ + extern int umid_file_name(char *name, char *buf, int len); extern int set_umid(char *name); extern char *get_umid(void); diff --git a/trunk/arch/um/include/sysdep-i386/checksum.h b/trunk/arch/um/include/sysdep-i386/checksum.h index 052bb061a978..7d3d202d7fff 100644 --- a/trunk/arch/um/include/sysdep-i386/checksum.h +++ b/trunk/arch/um/include/sysdep-i386/checksum.h @@ -48,8 +48,7 @@ unsigned int csum_partial_copy_nocheck(const unsigned char *src, unsigned char * */ static __inline__ -unsigned int csum_partial_copy_from_user(const unsigned char __user *src, - unsigned char *dst, +unsigned int csum_partial_copy_from_user(const unsigned char *src, unsigned char *dst, int len, int sum, int *err_ptr) { if(copy_from_user(dst, src, len)){ @@ -193,7 +192,7 @@ static __inline__ unsigned short int csum_ipv6_magic(struct in6_addr *saddr, */ #define HAVE_CSUM_COPY_USER static __inline__ unsigned int csum_and_copy_to_user(const unsigned char *src, - unsigned char __user *dst, + unsigned char *dst, int len, int sum, int *err_ptr) { if (access_ok(VERIFY_WRITE, dst, len)){ diff --git a/trunk/arch/um/include/sysdep-i386/ptrace.h b/trunk/arch/um/include/sysdep-i386/ptrace.h index 6670cc992ecb..c8ee9559f3ab 100644 --- a/trunk/arch/um/include/sysdep-i386/ptrace.h +++ b/trunk/arch/um/include/sysdep-i386/ptrace.h @@ -14,12 +14,7 @@ #define MAX_REG_NR (UM_FRAME_SIZE / sizeof(unsigned long)) #define MAX_REG_OFFSET (UM_FRAME_SIZE) -#ifdef UML_CONFIG_PT_PROXY extern void update_debugregs(int seq); -#else -static inline void update_debugregs(int seq) {} -#endif - /* syscall emulation path in ptrace */ diff --git a/trunk/arch/um/include/sysdep-i386/tls.h b/trunk/arch/um/include/sysdep-i386/tls.h deleted file mode 100644 index 918fd3c5ff9c..000000000000 --- a/trunk/arch/um/include/sysdep-i386/tls.h +++ /dev/null @@ -1,32 +0,0 @@ -#ifndef _SYSDEP_TLS_H -#define _SYSDEP_TLS_H - -# ifndef __KERNEL__ - -/* Change name to avoid conflicts with the original one from , which - * may be named user_desc (but in 2.4 and in header matching its API was named - * modify_ldt_ldt_s). */ - -typedef struct um_dup_user_desc { - unsigned int entry_number; - unsigned int base_addr; - unsigned int limit; - unsigned int seg_32bit:1; - unsigned int contents:2; - unsigned int read_exec_only:1; - unsigned int limit_in_pages:1; - unsigned int seg_not_present:1; - unsigned int useable:1; -} user_desc_t; - -# else /* __KERNEL__ */ - -# include -typedef struct user_desc user_desc_t; - -# endif /* __KERNEL__ */ - -#define GDT_ENTRY_TLS_MIN_I386 6 -#define GDT_ENTRY_TLS_MIN_X86_64 12 - -#endif /* _SYSDEP_TLS_H */ diff --git a/trunk/arch/um/include/sysdep-x86_64/tls.h b/trunk/arch/um/include/sysdep-x86_64/tls.h deleted file mode 100644 index 35f19f25bd3b..000000000000 --- a/trunk/arch/um/include/sysdep-x86_64/tls.h +++ /dev/null @@ -1,29 +0,0 @@ -#ifndef _SYSDEP_TLS_H -#define _SYSDEP_TLS_H - -# ifndef __KERNEL__ - -/* Change name to avoid conflicts with the original one from , which - * may be named user_desc (but in 2.4 and in header matching its API was named - * modify_ldt_ldt_s). */ - -typedef struct um_dup_user_desc { - unsigned int entry_number; - unsigned int base_addr; - unsigned int limit; - unsigned int seg_32bit:1; - unsigned int contents:2; - unsigned int read_exec_only:1; - unsigned int limit_in_pages:1; - unsigned int seg_not_present:1; - unsigned int useable:1; - unsigned int lm:1; -} user_desc_t; - -# else /* __KERNEL__ */ - -# include -typedef struct user_desc user_desc_t; - -# endif /* __KERNEL__ */ -#endif /* _SYSDEP_TLS_H */ diff --git a/trunk/arch/um/include/user_util.h b/trunk/arch/um/include/user_util.h index fe0c29b5144d..992a7e1e0fca 100644 --- a/trunk/arch/um/include/user_util.h +++ b/trunk/arch/um/include/user_util.h @@ -8,9 +8,6 @@ #include "sysdep/ptrace.h" -/* Copied from kernel.h */ -#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) - #define CATCH_EINTR(expr) while ((errno = 0, ((expr) < 0)) && (errno == EINTR)) extern int mode_tt; @@ -34,7 +31,7 @@ extern unsigned long uml_physmem; extern unsigned long uml_reserved; extern unsigned long end_vm; extern unsigned long start_vm; -extern unsigned long long highmem; +extern unsigned long highmem; extern char host_info[]; diff --git a/trunk/arch/um/kernel/exec_kern.c b/trunk/arch/um/kernel/exec_kern.c index c0cb627bf594..1ca84319317d 100644 --- a/trunk/arch/um/kernel/exec_kern.c +++ b/trunk/arch/um/kernel/exec_kern.c @@ -22,7 +22,6 @@ void flush_thread(void) { - arch_flush_thread(¤t->thread.arch); CHOOSE_MODE(flush_thread_tt(), flush_thread_skas()); } @@ -59,14 +58,14 @@ long um_execve(char *file, char __user *__user *argv, char __user *__user *env) return(err); } -long sys_execve(char __user *file, char __user *__user *argv, +long sys_execve(char *file, char __user *__user *argv, char __user *__user *env) { long error; char *filename; lock_kernel(); - filename = getname(file); + filename = getname((char __user *) file); error = PTR_ERR(filename); if (IS_ERR(filename)) goto out; error = execve1(filename, argv, env); @@ -75,3 +74,14 @@ long sys_execve(char __user *file, char __user *__user *argv, unlock_kernel(); return(error); } + +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * Emacs will notice this stuff at the end of the file and automatically + * adjust the settings for this buffer only. This must remain at the end + * of the file. + * --------------------------------------------------------------------------- + * Local variables: + * c-file-style: "linux" + * End: + */ diff --git a/trunk/arch/um/kernel/mem.c b/trunk/arch/um/kernel/mem.c index 44e41a35f000..92cce96b5e24 100644 --- a/trunk/arch/um/kernel/mem.c +++ b/trunk/arch/um/kernel/mem.c @@ -30,7 +30,7 @@ extern char __binary_start; unsigned long *empty_zero_page = NULL; unsigned long *empty_bad_page = NULL; pgd_t swapper_pg_dir[PTRS_PER_PGD]; -unsigned long long highmem; +unsigned long highmem; int kmalloc_ok = 0; static unsigned long brk_end; diff --git a/trunk/arch/um/kernel/process_kern.c b/trunk/arch/um/kernel/process_kern.c index f6a5a502120b..3113cab8675e 100644 --- a/trunk/arch/um/kernel/process_kern.c +++ b/trunk/arch/um/kernel/process_kern.c @@ -156,25 +156,9 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long sp, unsigned long stack_top, struct task_struct * p, struct pt_regs *regs) { - int ret; - p->thread = (struct thread_struct) INIT_THREAD; - ret = CHOOSE_MODE_PROC(copy_thread_tt, copy_thread_skas, nr, - clone_flags, sp, stack_top, p, regs); - - if (ret || !current->thread.forking) - goto out; - - clear_flushed_tls(p); - - /* - * Set a new TLS for the child thread? - */ - if (clone_flags & CLONE_SETTLS) - ret = arch_copy_tls(p); - -out: - return ret; + return(CHOOSE_MODE_PROC(copy_thread_tt, copy_thread_skas, nr, + clone_flags, sp, stack_top, p, regs)); } void initial_thread_cb(void (*proc)(void *), void *arg) @@ -201,6 +185,10 @@ void default_idle(void) { CHOOSE_MODE(uml_idle_timer(), (void) 0); + atomic_inc(&init_mm.mm_count); + current->mm = &init_mm; + current->active_mm = &init_mm; + while(1){ /* endless idle loop with no priority at all */ @@ -419,7 +407,7 @@ static int proc_read_sysemu(char *buf, char **start, off_t offset, int size,int return strlen(buf); } -static int proc_write_sysemu(struct file *file,const char __user *buf, unsigned long count,void *data) +static int proc_write_sysemu(struct file *file,const char *buf, unsigned long count,void *data) { char tmp[2]; diff --git a/trunk/arch/um/kernel/ptrace.c b/trunk/arch/um/kernel/ptrace.c index 60d2eda995c1..98e09395c093 100644 --- a/trunk/arch/um/kernel/ptrace.c +++ b/trunk/arch/um/kernel/ptrace.c @@ -46,7 +46,6 @@ extern int poke_user(struct task_struct * child, long addr, long data); long arch_ptrace(struct task_struct *child, long request, long addr, long data) { int i, ret; - unsigned long __user *p = (void __user *)(unsigned long)data; switch (request) { /* when I and D space are separate, these will need to be fixed. */ @@ -59,7 +58,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 0); if (copied != sizeof(tmp)) break; - ret = put_user(tmp, p); + ret = put_user(tmp, (unsigned long __user *) data); break; } @@ -137,13 +136,15 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) #ifdef PTRACE_GETREGS case PTRACE_GETREGS: { /* Get all gp regs from the child. */ - if (!access_ok(VERIFY_WRITE, p, MAX_REG_OFFSET)) { + if (!access_ok(VERIFY_WRITE, (unsigned long *)data, + MAX_REG_OFFSET)) { ret = -EIO; break; } for ( i = 0; i < MAX_REG_OFFSET; i += sizeof(long) ) { - __put_user(getreg(child, i), p); - p++; + __put_user(getreg(child, i), + (unsigned long __user *) data); + data += sizeof(long); } ret = 0; break; @@ -152,14 +153,15 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) #ifdef PTRACE_SETREGS case PTRACE_SETREGS: { /* Set all gp regs in the child. */ unsigned long tmp = 0; - if (!access_ok(VERIFY_READ, p, MAX_REG_OFFSET)) { + if (!access_ok(VERIFY_READ, (unsigned *)data, + MAX_REG_OFFSET)) { ret = -EIO; break; } for ( i = 0; i < MAX_REG_OFFSET; i += sizeof(long) ) { - __get_user(tmp, p); + __get_user(tmp, (unsigned long __user *) data); putreg(child, i, tmp); - p++; + data += sizeof(long); } ret = 0; break; @@ -185,23 +187,14 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) ret = set_fpxregs(data, child); break; #endif - case PTRACE_GET_THREAD_AREA: - ret = ptrace_get_thread_area(child, addr, - (struct user_desc __user *) data); - break; - - case PTRACE_SET_THREAD_AREA: - ret = ptrace_set_thread_area(child, addr, - (struct user_desc __user *) data); - break; - case PTRACE_FAULTINFO: { - /* Take the info from thread->arch->faultinfo, - * but transfer max. sizeof(struct ptrace_faultinfo). - * On i386, ptrace_faultinfo is smaller! - */ - ret = copy_to_user(p, &child->thread.arch.faultinfo, - sizeof(struct ptrace_faultinfo)); + /* Take the info from thread->arch->faultinfo, + * but transfer max. sizeof(struct ptrace_faultinfo). + * On i386, ptrace_faultinfo is smaller! + */ + ret = copy_to_user((unsigned long __user *) data, + &child->thread.arch.faultinfo, + sizeof(struct ptrace_faultinfo)); if(ret) break; break; @@ -211,7 +204,8 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) case PTRACE_LDT: { struct ptrace_ldt ldt; - if(copy_from_user(&ldt, p, sizeof(ldt))){ + if(copy_from_user(&ldt, (unsigned long __user *) data, + sizeof(ldt))){ ret = -EIO; break; } diff --git a/trunk/arch/um/kernel/skas/process_kern.c b/trunk/arch/um/kernel/skas/process_kern.c index 2135eaf98a93..3f70a2e12f06 100644 --- a/trunk/arch/um/kernel/skas/process_kern.c +++ b/trunk/arch/um/kernel/skas/process_kern.c @@ -35,8 +35,6 @@ void switch_to_skas(void *prev, void *next) switch_threads(&from->thread.mode.skas.switch_buf, to->thread.mode.skas.switch_buf); - arch_switch_to_skas(current->thread.prev_sched, current); - if(current->pid == 0) switch_timers(1); } @@ -91,17 +89,10 @@ void fork_handler(int sig) panic("blech"); schedule_tail(current->thread.prev_sched); - - /* XXX: if interrupt_end() calls schedule, this call to - * arch_switch_to_skas isn't needed. We could want to apply this to - * improve performance. -bb */ - arch_switch_to_skas(current->thread.prev_sched, current); - current->thread.prev_sched = NULL; /* Handle any immediate reschedules or signals */ interrupt_end(); - userspace(¤t->thread.regs.regs); } @@ -118,8 +109,6 @@ int copy_thread_skas(int nr, unsigned long clone_flags, unsigned long sp, if(sp != 0) REGS_SP(p->thread.regs.regs.skas.regs) = sp; handler = fork_handler; - - arch_copy_thread(¤t->thread.arch, &p->thread.arch); } else { init_thread_registers(&p->thread.regs.regs); diff --git a/trunk/arch/um/kernel/syscall_kern.c b/trunk/arch/um/kernel/syscall_kern.c index 37d3978337d8..8e1a3501ff46 100644 --- a/trunk/arch/um/kernel/syscall_kern.c +++ b/trunk/arch/um/kernel/syscall_kern.c @@ -104,7 +104,7 @@ long sys_pipe(unsigned long __user * fildes) } -long sys_uname(struct old_utsname __user * name) +long sys_uname(struct old_utsname * name) { long err; if (!name) @@ -115,7 +115,7 @@ long sys_uname(struct old_utsname __user * name) return err?-EFAULT:0; } -long sys_olduname(struct oldold_utsname __user * name) +long sys_olduname(struct oldold_utsname * name) { long error; diff --git a/trunk/arch/um/kernel/trap_kern.c b/trunk/arch/um/kernel/trap_kern.c index 02f6d4d8dc3a..d56046c2aba2 100644 --- a/trunk/arch/um/kernel/trap_kern.c +++ b/trunk/arch/um/kernel/trap_kern.c @@ -198,7 +198,7 @@ unsigned long segv(struct faultinfo fi, unsigned long ip, int is_user, void *sc) si.si_signo = SIGBUS; si.si_errno = 0; si.si_code = BUS_ADRERR; - si.si_addr = (void __user *)address; + si.si_addr = (void *)address; current->thread.arch.faultinfo = fi; force_sig_info(SIGBUS, &si, current); } else if (err == -ENOMEM) { @@ -207,7 +207,7 @@ unsigned long segv(struct faultinfo fi, unsigned long ip, int is_user, void *sc) } else { BUG_ON(err != -EFAULT); si.si_signo = SIGSEGV; - si.si_addr = (void __user *) address; + si.si_addr = (void *) address; current->thread.arch.faultinfo = fi; force_sig_info(SIGSEGV, &si, current); } @@ -220,8 +220,8 @@ void bad_segv(struct faultinfo fi, unsigned long ip) si.si_signo = SIGSEGV; si.si_code = SEGV_ACCERR; - si.si_addr = (void __user *) FAULT_ADDRESS(fi); - current->thread.arch.faultinfo = fi; + si.si_addr = (void *) FAULT_ADDRESS(fi); + current->thread.arch.faultinfo = fi; force_sig_info(SIGSEGV, &si, current); } diff --git a/trunk/arch/um/kernel/tt/process_kern.c b/trunk/arch/um/kernel/tt/process_kern.c index a9c1443fc548..295c1ac817b3 100644 --- a/trunk/arch/um/kernel/tt/process_kern.c +++ b/trunk/arch/um/kernel/tt/process_kern.c @@ -51,13 +51,6 @@ void switch_to_tt(void *prev, void *next) c = 0; - /* Notice that here we "up" the semaphore on which "to" is waiting, and - * below (the read) we wait on this semaphore (which is implemented by - * switch_pipe) and go sleeping. Thus, after that, we have resumed in - * "to", and can't use any more the value of "from" (which is outdated), - * nor the value in "to" (since it was the task which stole us the CPU, - * which we don't care about). */ - err = os_write_file(to->thread.mode.tt.switch_pipe[1], &c, sizeof(c)); if(err != sizeof(c)) panic("write of switch_pipe failed, err = %d", -err); @@ -84,7 +77,7 @@ void switch_to_tt(void *prev, void *next) change_sig(SIGALRM, alrm); change_sig(SIGPROF, prof); - arch_switch_to_tt(prev_sched, current); + arch_switch(); flush_tlb_all(); local_irq_restore(flags); @@ -148,6 +141,7 @@ static void new_thread_handler(int sig) set_cmdline("(kernel thread)"); change_sig(SIGUSR1, 1); + change_sig(SIGVTALRM, 1); change_sig(SIGPROF, 1); local_irq_enable(); if(!run_kernel_thread(fn, arg, ¤t->thread.exec_buf)) diff --git a/trunk/arch/um/os-Linux/Makefile b/trunk/arch/um/os-Linux/Makefile index f4bfc4c7ccac..1659386b42bb 100644 --- a/trunk/arch/um/os-Linux/Makefile +++ b/trunk/arch/um/os-Linux/Makefile @@ -4,7 +4,7 @@ # obj-y = aio.o elf_aux.o file.o helper.o irq.o main.o mem.o process.o sigio.o \ - signal.o start_up.o time.o trap.o tt.o tty.o uaccess.o umid.o tls.o \ + signal.o start_up.o time.o trap.o tt.o tty.o uaccess.o umid.o \ user_syms.o util.o drivers/ sys-$(SUBARCH)/ obj-$(CONFIG_MODE_SKAS) += skas/ @@ -12,9 +12,12 @@ obj-$(CONFIG_TTY_LOG) += tty_log.o user-objs-$(CONFIG_TTY_LOG) += tty_log.o USER_OBJS := $(user-objs-y) aio.o elf_aux.o file.o helper.o irq.o main.o mem.o \ - process.o sigio.o signal.o start_up.o time.o trap.o tt.o tty.o tls.o \ + process.o sigio.o signal.o start_up.o time.o trap.o tt.o tty.o \ uaccess.o umid.o util.o +elf_aux.o: $(ARCH_DIR)/kernel-offsets.h +CFLAGS_elf_aux.o += -I$(objtree)/arch/um + CFLAGS_user_syms.o += -DSUBARCH_$(SUBARCH) HAVE_AIO_ABI := $(shell [ -r /usr/include/linux/aio_abi.h ] && \ diff --git a/trunk/arch/um/os-Linux/drivers/ethertap_kern.c b/trunk/arch/um/os-Linux/drivers/ethertap_kern.c index 768606bec233..6ae4b19d9f50 100644 --- a/trunk/arch/um/os-Linux/drivers/ethertap_kern.c +++ b/trunk/arch/um/os-Linux/drivers/ethertap_kern.c @@ -102,7 +102,18 @@ static struct transport ethertap_transport = { static int register_ethertap(void) { register_transport(ðertap_transport); - return 0; + return(1); } __initcall(register_ethertap); + +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * Emacs will notice this stuff at the end of the file and automatically + * adjust the settings for this buffer only. This must remain at the end + * of the file. + * --------------------------------------------------------------------------- + * Local variables: + * c-file-style: "linux" + * End: + */ diff --git a/trunk/arch/um/os-Linux/drivers/tuntap_kern.c b/trunk/arch/um/os-Linux/drivers/tuntap_kern.c index 190009a6f89c..4202b9ebad4c 100644 --- a/trunk/arch/um/os-Linux/drivers/tuntap_kern.c +++ b/trunk/arch/um/os-Linux/drivers/tuntap_kern.c @@ -87,7 +87,18 @@ static struct transport tuntap_transport = { static int register_tuntap(void) { register_transport(&tuntap_transport); - return 0; + return(1); } __initcall(register_tuntap); + +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * Emacs will notice this stuff at the end of the file and automatically + * adjust the settings for this buffer only. This must remain at the end + * of the file. + * --------------------------------------------------------------------------- + * Local variables: + * c-file-style: "linux" + * End: + */ diff --git a/trunk/arch/um/os-Linux/mem.c b/trunk/arch/um/os-Linux/mem.c index 6ab372da9657..9d7d69a523bb 100644 --- a/trunk/arch/um/os-Linux/mem.c +++ b/trunk/arch/um/os-Linux/mem.c @@ -121,11 +121,36 @@ int create_tmp_file(unsigned long long len) return(fd); } +static int create_anon_file(unsigned long long len) +{ + void *addr; + int fd; + + fd = open("/dev/anon", O_RDWR); + if(fd < 0) { + perror("opening /dev/anon"); + exit(1); + } + + addr = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0); + if(addr == MAP_FAILED){ + perror("mapping physmem file"); + exit(1); + } + munmap(addr, len); + + return(fd); +} + +extern int have_devanon; + int create_mem_file(unsigned long long len) { int err, fd; - fd = create_tmp_file(len); + if(have_devanon) + fd = create_anon_file(len); + else fd = create_tmp_file(len); err = os_set_exec_close(fd, 1); if(err < 0){ diff --git a/trunk/arch/um/os-Linux/process.c b/trunk/arch/um/os-Linux/process.c index 8176b0b52047..d261888f39c4 100644 --- a/trunk/arch/um/os-Linux/process.c +++ b/trunk/arch/um/os-Linux/process.c @@ -11,7 +11,6 @@ #include #include #include -#include #include "ptrace_user.h" #include "os.h" #include "user.h" @@ -21,7 +20,6 @@ #include "kern_util.h" #include "longjmp.h" #include "skas_ptrace.h" -#include "kern_constants.h" #define ARBITRARY_ADDR -1 #define FAILURE_PID -1 @@ -189,48 +187,6 @@ int os_unmap_memory(void *addr, int len) return(0); } -#ifndef MADV_REMOVE -#define MADV_REMOVE 0x5 /* remove these pages & resources */ -#endif - -int os_drop_memory(void *addr, int length) -{ - int err; - - err = madvise(addr, length, MADV_REMOVE); - if(err < 0) - err = -errno; - return err; -} - -int can_drop_memory(void) -{ - void *addr; - int fd; - - printk("Checking host MADV_REMOVE support..."); - fd = create_mem_file(UM_KERN_PAGE_SIZE); - if(fd < 0){ - printk("Creating test memory file failed, err = %d\n", -fd); - return 0; - } - - addr = mmap64(NULL, UM_KERN_PAGE_SIZE, PROT_READ | PROT_WRITE, - MAP_PRIVATE, fd, 0); - if(addr == MAP_FAILED){ - printk("Mapping test memory file failed, err = %d\n", -errno); - return 0; - } - - if(madvise(addr, UM_KERN_PAGE_SIZE, MADV_REMOVE) != 0){ - printk("MADV_REMOVE failed, err = %d\n", -errno); - return 0; - } - - printk("OK\n"); - return 1; -} - void init_new_thread_stack(void *sig_stack, void (*usr1_handler)(int)) { int flags = 0, pages; diff --git a/trunk/arch/um/os-Linux/start_up.c b/trunk/arch/um/os-Linux/start_up.c index 387e26af301a..32753131f8d8 100644 --- a/trunk/arch/um/os-Linux/start_up.c +++ b/trunk/arch/um/os-Linux/start_up.c @@ -470,6 +470,25 @@ int can_do_skas(void) } #endif +int have_devanon = 0; + +/* Runs on boot kernel stack - already safe to use printk. */ + +void check_devanon(void) +{ + int fd; + + printk("Checking for /dev/anon on the host..."); + fd = open("/dev/anon", O_RDWR); + if(fd < 0){ + printk("Not available (open failed with errno %d)\n", errno); + return; + } + + printk("OK\n"); + have_devanon = 1; +} + int __init parse_iomem(char *str, int *add) { struct iomem_region *new; @@ -645,5 +664,6 @@ void os_check_bugs(void) { check_ptrace(); check_sigio(); + check_devanon(); } diff --git a/trunk/arch/um/os-Linux/sys-i386/Makefile b/trunk/arch/um/os-Linux/sys-i386/Makefile index b3213613c41c..340ef26f5944 100644 --- a/trunk/arch/um/os-Linux/sys-i386/Makefile +++ b/trunk/arch/um/os-Linux/sys-i386/Makefile @@ -3,7 +3,7 @@ # Licensed under the GPL # -obj-$(CONFIG_MODE_SKAS) = registers.o tls.o +obj-$(CONFIG_MODE_SKAS) = registers.o USER_OBJS := $(obj-y) diff --git a/trunk/arch/um/os-Linux/sys-i386/tls.c b/trunk/arch/um/os-Linux/sys-i386/tls.c deleted file mode 100644 index ba21f0e04a2f..000000000000 --- a/trunk/arch/um/os-Linux/sys-i386/tls.c +++ /dev/null @@ -1,33 +0,0 @@ -#include -#include "sysdep/tls.h" -#include "user_util.h" - -static _syscall1(int, get_thread_area, user_desc_t *, u_info); - -/* Checks whether host supports TLS, and sets *tls_min according to the value - * valid on the host. - * i386 host have it == 6; x86_64 host have it == 12, for i386 emulation. */ -void check_host_supports_tls(int *supports_tls, int *tls_min) { - /* Values for x86 and x86_64.*/ - int val[] = {GDT_ENTRY_TLS_MIN_I386, GDT_ENTRY_TLS_MIN_X86_64}; - int i; - - for (i = 0; i < ARRAY_SIZE(val); i++) { - user_desc_t info; - info.entry_number = val[i]; - - if (get_thread_area(&info) == 0) { - *tls_min = val[i]; - *supports_tls = 1; - return; - } else { - if (errno == EINVAL) - continue; - else if (errno == ENOSYS) - *supports_tls = 0; - return; - } - } - - *supports_tls = 0; -} diff --git a/trunk/arch/um/os-Linux/tls.c b/trunk/arch/um/os-Linux/tls.c deleted file mode 100644 index 9cb09a45546b..000000000000 --- a/trunk/arch/um/os-Linux/tls.c +++ /dev/null @@ -1,76 +0,0 @@ -#include -#include -#include -#include "sysdep/tls.h" -#include "uml-config.h" - -/* TLS support - we basically rely on the host's one.*/ - -/* In TT mode, this should be called only by the tracing thread, and makes sense - * only for PTRACE_SET_THREAD_AREA. In SKAS mode, it's used normally. - * - */ - -#ifndef PTRACE_GET_THREAD_AREA -#define PTRACE_GET_THREAD_AREA 25 -#endif - -#ifndef PTRACE_SET_THREAD_AREA -#define PTRACE_SET_THREAD_AREA 26 -#endif - -int os_set_thread_area(user_desc_t *info, int pid) -{ - int ret; - - ret = ptrace(PTRACE_SET_THREAD_AREA, pid, info->entry_number, - (unsigned long) info); - if (ret < 0) - ret = -errno; - return ret; -} - -#ifdef UML_CONFIG_MODE_SKAS - -int os_get_thread_area(user_desc_t *info, int pid) -{ - int ret; - - ret = ptrace(PTRACE_GET_THREAD_AREA, pid, info->entry_number, - (unsigned long) info); - if (ret < 0) - ret = -errno; - return ret; -} - -#endif - -#ifdef UML_CONFIG_MODE_TT -#include "linux/unistd.h" - -static _syscall1(int, get_thread_area, user_desc_t *, u_info); -static _syscall1(int, set_thread_area, user_desc_t *, u_info); - -int do_set_thread_area_tt(user_desc_t *info) -{ - int ret; - - ret = set_thread_area(info); - if (ret < 0) { - ret = -errno; - } - return ret; -} - -int do_get_thread_area_tt(user_desc_t *info) -{ - int ret; - - ret = get_thread_area(info); - if (ret < 0) { - ret = -errno; - } - return ret; -} - -#endif /* UML_CONFIG_MODE_TT */ diff --git a/trunk/arch/um/scripts/Makefile.rules b/trunk/arch/um/scripts/Makefile.rules index b696b451774c..2e41cabd3d93 100644 --- a/trunk/arch/um/scripts/Makefile.rules +++ b/trunk/arch/um/scripts/Makefile.rules @@ -20,7 +20,25 @@ define unprofile $(patsubst -pg,,$(patsubst -fprofile-arcs -ftest-coverage,,$(1))) endef -ifdef subarch-obj-y -obj-y += subarch.o -subarch-y = $(addprefix ../../$(SUBARCH)/,$(subarch-obj-y)) -endif + +# cmd_make_link checks to see if the $(foo-dir) variable starts with a /. If +# so, it's considered to be a path relative to $(srcdir) rather than +# $(srcdir)/arch/$(SUBARCH). This is because x86_64 wants to get ldt.c from +# arch/um/sys-i386 rather than arch/i386 like the other borrowed files. So, +# it sets $(ldt.c-dir) to /arch/um/sys-i386. +quiet_cmd_make_link = SYMLINK $@ +cmd_make_link = rm -f $@; ln -sf $(srctree)$(if $(filter-out /%,$($(notdir $@)-dir)),/arch/$(SUBARCH))/$($(notdir $@)-dir)/$(notdir $@) $@ + +# this needs to be before the foreach, because targets does not accept +# complete paths like $(obj)/$(f). To make sure this works, use a := assignment +# or we will get $(obj)/$(f) in the "targets" value. +# Also, this forces you to use the := syntax when assigning to targets. +# Otherwise the line below will cause an infinite loop (if you don't know why, +# just do it). + +targets := $(targets) $(SYMLINKS) + +SYMLINKS := $(foreach f,$(SYMLINKS),$(obj)/$(f)) + +$(SYMLINKS): FORCE + $(call if_changed,make_link) diff --git a/trunk/arch/um/scripts/Makefile.unmap b/trunk/arch/um/scripts/Makefile.unmap new file mode 100644 index 000000000000..b2165188d942 --- /dev/null +++ b/trunk/arch/um/scripts/Makefile.unmap @@ -0,0 +1,22 @@ +clean-files += unmap_tmp.o unmap_fin.o unmap.o + +ifdef CONFIG_MODE_TT + +#Always build unmap_fin.o +extra-y += unmap_fin.o +#Do dependency tracking for unmap.o (it will be always built, but won't get the tracking unless we use this). +targets += unmap.o + +#XXX: partially copied from arch/um/scripts/Makefile.rules +$(obj)/unmap.o: _c_flags = $(call unprofile,$(CFLAGS)) + +quiet_cmd_wrapld = LD $@ +define cmd_wrapld + $(LD) $(LDFLAGS) -r -o $(obj)/unmap_tmp.o $< ; \ + $(OBJCOPY) $(UML_OBJCOPYFLAGS) $(obj)/unmap_tmp.o $@ -G switcheroo +endef + +$(obj)/unmap_fin.o : $(obj)/unmap.o FORCE + $(call if_changed,wrapld) + +endif diff --git a/trunk/arch/um/sys-i386/Makefile b/trunk/arch/um/sys-i386/Makefile index 98b20b7bba4f..f5fd5b0156d0 100644 --- a/trunk/arch/um/sys-i386/Makefile +++ b/trunk/arch/um/sys-i386/Makefile @@ -1,18 +1,23 @@ -obj-y = bugs.o checksum.o delay.o fault.o ksyms.o ldt.o ptrace.o \ - ptrace_user.o signal.o sigcontext.o syscalls.o sysrq.o \ - sys_call_table.o tls.o +obj-y := bitops.o bugs.o checksum.o delay.o fault.o ksyms.o ldt.o ptrace.o \ + ptrace_user.o semaphore.o signal.o sigcontext.o syscalls.o sysrq.o \ + sys_call_table.o obj-$(CONFIG_MODE_SKAS) += stub.o stub_segv.o -subarch-obj-y = lib/bitops.o kernel/semaphore.o -subarch-obj-$(CONFIG_HIGHMEM) += mm/highmem.o -subarch-obj-$(CONFIG_MODULES) += kernel/module.o +obj-$(CONFIG_HIGHMEM) += highmem.o +obj-$(CONFIG_MODULES) += module.o USER_OBJS := bugs.o ptrace_user.o sigcontext.o fault.o stub_segv.o +SYMLINKS = bitops.c semaphore.c highmem.c module.c + include arch/um/scripts/Makefile.rules -extra-$(CONFIG_MODE_TT) += unmap.o +bitops.c-dir = lib +semaphore.c-dir = kernel +highmem.c-dir = mm +module.c-dir = kernel + +$(obj)/stub_segv.o : _c_flags = $(call unprofile,$(CFLAGS)) -$(obj)/stub_segv.o $(obj)/unmap.o: \ - _c_flags = $(call unprofile,$(CFLAGS)) +include arch/um/scripts/Makefile.unmap diff --git a/trunk/arch/um/sys-i386/ptrace.c b/trunk/arch/um/sys-i386/ptrace.c index 6028bc7cc01b..8032a105949a 100644 --- a/trunk/arch/um/sys-i386/ptrace.c +++ b/trunk/arch/um/sys-i386/ptrace.c @@ -15,22 +15,9 @@ #include "sysdep/sigcontext.h" #include "sysdep/sc.h" -void arch_switch_to_tt(struct task_struct *from, struct task_struct *to) +void arch_switch(void) { - update_debugregs(to->thread.arch.debugregs_seq); - arch_switch_tls_tt(from, to); -} - -void arch_switch_to_skas(struct task_struct *from, struct task_struct *to) -{ - int err = arch_switch_tls_skas(from, to); - if (!err) - return; - - if (err != -EINVAL) - printk(KERN_WARNING "arch_switch_tls_skas failed, errno %d, not EINVAL\n", -err); - else - printk(KERN_WARNING "arch_switch_tls_skas failed, errno = EINVAL\n"); + update_debugregs(current->thread.arch.debugregs_seq); } int is_syscall(unsigned long addr) @@ -137,22 +124,22 @@ unsigned long getreg(struct task_struct *child, int regno) int peek_user(struct task_struct *child, long addr, long data) { /* read the word at location addr in the USER area. */ - unsigned long tmp; + unsigned long tmp; - if ((addr & 3) || addr < 0) - return -EIO; + if ((addr & 3) || addr < 0) + return -EIO; - tmp = 0; /* Default return condition */ - if(addr < MAX_REG_OFFSET){ - tmp = getreg(child, addr); - } - else if((addr >= offsetof(struct user, u_debugreg[0])) && - (addr <= offsetof(struct user, u_debugreg[7]))){ - addr -= offsetof(struct user, u_debugreg[0]); - addr = addr >> 2; - tmp = child->thread.arch.debugregs[addr]; - } - return put_user(tmp, (unsigned long __user *) data); + tmp = 0; /* Default return condition */ + if(addr < MAX_REG_OFFSET){ + tmp = getreg(child, addr); + } + else if((addr >= offsetof(struct user, u_debugreg[0])) && + (addr <= offsetof(struct user, u_debugreg[7]))){ + addr -= offsetof(struct user, u_debugreg[0]); + addr = addr >> 2; + tmp = child->thread.arch.debugregs[addr]; + } + return put_user(tmp, (unsigned long *) data); } struct i387_fxsave_struct { diff --git a/trunk/arch/um/sys-i386/ptrace_user.c b/trunk/arch/um/sys-i386/ptrace_user.c index 9f3bd8ed78f5..7c376c95de50 100644 --- a/trunk/arch/um/sys-i386/ptrace_user.c +++ b/trunk/arch/um/sys-i386/ptrace_user.c @@ -14,7 +14,6 @@ #include "sysdep/thread.h" #include "user.h" #include "os.h" -#include "uml-config.h" int ptrace_getregs(long pid, unsigned long *regs_out) { @@ -44,7 +43,6 @@ int ptrace_setfpregs(long pid, unsigned long *regs) return 0; } -/* All the below stuff is of interest for TT mode only */ static void write_debugregs(int pid, unsigned long *regs) { struct user *dummy; @@ -77,6 +75,7 @@ static void read_debugregs(int pid, unsigned long *regs) /* Accessed only by the tracing thread */ static unsigned long kernel_debugregs[8] = { [ 0 ... 7 ] = 0 }; +static int debugregs_seq = 0; void arch_enter_kernel(void *task, int pid) { @@ -90,11 +89,6 @@ void arch_leave_kernel(void *task, int pid) write_debugregs(pid, TASK_DEBUGREGS(task)); } -#ifdef UML_CONFIG_PT_PROXY -/* Accessed only by the tracing thread */ -static int debugregs_seq; - -/* Only called by the ptrace proxy */ void ptrace_pokeuser(unsigned long addr, unsigned long data) { if((addr < offsetof(struct user, u_debugreg[0])) || @@ -115,7 +109,6 @@ static void update_debugregs_cb(void *arg) write_debugregs(pid, kernel_debugregs); } -/* Optimized out in its header when not defined */ void update_debugregs(int seq) { int me; @@ -125,7 +118,6 @@ void update_debugregs(int seq) me = os_getpid(); initial_thread_cb(update_debugregs_cb, &me); } -#endif /* * Overrides for Emacs so that we follow Linus's tabbing style. diff --git a/trunk/arch/um/sys-i386/signal.c b/trunk/arch/um/sys-i386/signal.c index f5d0e1c37ea2..33a40f5ef0d2 100644 --- a/trunk/arch/um/sys-i386/signal.c +++ b/trunk/arch/um/sys-i386/signal.c @@ -19,7 +19,7 @@ #include "skas.h" static int copy_sc_from_user_skas(struct pt_regs *regs, - struct sigcontext __user *from) + struct sigcontext *from) { struct sigcontext sc; unsigned long fpregs[HOST_FP_SIZE]; @@ -57,7 +57,7 @@ static int copy_sc_from_user_skas(struct pt_regs *regs, return(0); } -int copy_sc_to_user_skas(struct sigcontext *to, struct _fpstate __user *to_fp, +int copy_sc_to_user_skas(struct sigcontext *to, struct _fpstate *to_fp, struct pt_regs *regs, unsigned long sp) { struct sigcontext sc; @@ -92,7 +92,7 @@ int copy_sc_to_user_skas(struct sigcontext *to, struct _fpstate __user *to_fp, "errno = %d\n", err); return(1); } - to_fp = (to_fp ? to_fp : (struct _fpstate __user *) (to + 1)); + to_fp = (to_fp ? to_fp : (struct _fpstate *) (to + 1)); sc.fpstate = to_fp; if(err) @@ -113,11 +113,10 @@ int copy_sc_to_user_skas(struct sigcontext *to, struct _fpstate __user *to_fp, * saved pointer is in the kernel, but the sigcontext is in userspace, so we * copy_to_user it. */ -int copy_sc_from_user_tt(struct sigcontext *to, struct sigcontext __user *from, +int copy_sc_from_user_tt(struct sigcontext *to, struct sigcontext *from, int fpsize) { - struct _fpstate *to_fp; - struct _fpstate __user *from_fp; + struct _fpstate *to_fp, *from_fp; unsigned long sigs; int err; @@ -132,14 +131,13 @@ int copy_sc_from_user_tt(struct sigcontext *to, struct sigcontext __user *from, return(err); } -int copy_sc_to_user_tt(struct sigcontext *to, struct _fpstate __user *fp, +int copy_sc_to_user_tt(struct sigcontext *to, struct _fpstate *fp, struct sigcontext *from, int fpsize, unsigned long sp) { - struct _fpstate __user *to_fp; - struct _fpstate *from_fp; + struct _fpstate *to_fp, *from_fp; int err; - to_fp = (fp ? fp : (struct _fpstate __user *) (to + 1)); + to_fp = (fp ? fp : (struct _fpstate *) (to + 1)); from_fp = from->fpstate; err = copy_to_user(to, from, sizeof(*to)); @@ -167,7 +165,7 @@ static int copy_sc_from_user(struct pt_regs *to, void __user *from) return(ret); } -static int copy_sc_to_user(struct sigcontext *to, struct _fpstate __user *fp, +static int copy_sc_to_user(struct sigcontext *to, struct _fpstate *fp, struct pt_regs *from, unsigned long sp) { return(CHOOSE_MODE(copy_sc_to_user_tt(to, fp, UPT_SC(&from->regs), @@ -175,7 +173,7 @@ static int copy_sc_to_user(struct sigcontext *to, struct _fpstate __user *fp, copy_sc_to_user_skas(to, fp, from, sp))); } -static int copy_ucontext_to_user(struct ucontext __user *uc, struct _fpstate __user *fp, +static int copy_ucontext_to_user(struct ucontext *uc, struct _fpstate *fp, sigset_t *set, unsigned long sp) { int err = 0; @@ -190,7 +188,7 @@ static int copy_ucontext_to_user(struct ucontext __user *uc, struct _fpstate __u struct sigframe { - char __user *pretcode; + char *pretcode; int sig; struct sigcontext sc; struct _fpstate fpstate; @@ -200,10 +198,10 @@ struct sigframe struct rt_sigframe { - char __user *pretcode; + char *pretcode; int sig; - struct siginfo __user *pinfo; - void __user *puc; + struct siginfo *pinfo; + void *puc; struct siginfo info; struct ucontext uc; struct _fpstate fpstate; @@ -215,16 +213,16 @@ int setup_signal_stack_sc(unsigned long stack_top, int sig, sigset_t *mask) { struct sigframe __user *frame; - void __user *restorer; + void *restorer; unsigned long save_sp = PT_REGS_SP(regs); int err = 0; stack_top &= -8UL; - frame = (struct sigframe __user *) stack_top - 1; + frame = (struct sigframe *) stack_top - 1; if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) return 1; - restorer = frame->retcode; + restorer = (void *) frame->retcode; if(ka->sa.sa_flags & SA_RESTORER) restorer = ka->sa.sa_restorer; @@ -280,16 +278,16 @@ int setup_signal_stack_si(unsigned long stack_top, int sig, siginfo_t *info, sigset_t *mask) { struct rt_sigframe __user *frame; - void __user *restorer; + void *restorer; unsigned long save_sp = PT_REGS_SP(regs); int err = 0; stack_top &= -8UL; - frame = (struct rt_sigframe __user *) stack_top - 1; + frame = (struct rt_sigframe *) stack_top - 1; if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) return 1; - restorer = frame->retcode; + restorer = (void *) frame->retcode; if(ka->sa.sa_flags & SA_RESTORER) restorer = ka->sa.sa_restorer; @@ -335,7 +333,7 @@ int setup_signal_stack_si(unsigned long stack_top, int sig, long sys_sigreturn(struct pt_regs regs) { unsigned long sp = PT_REGS_SP(¤t->thread.regs); - struct sigframe __user *frame = (struct sigframe __user *)(sp - 8); + struct sigframe __user *frame = (struct sigframe *)(sp - 8); sigset_t set; struct sigcontext __user *sc = &frame->sc; unsigned long __user *oldmask = &sc->oldmask; @@ -367,8 +365,8 @@ long sys_sigreturn(struct pt_regs regs) long sys_rt_sigreturn(struct pt_regs regs) { - unsigned long sp = PT_REGS_SP(¤t->thread.regs); - struct rt_sigframe __user *frame = (struct rt_sigframe __user *) (sp - 4); + unsigned long __user sp = PT_REGS_SP(¤t->thread.regs); + struct rt_sigframe __user *frame = (struct rt_sigframe *) (sp - 4); sigset_t set; struct ucontext __user *uc = &frame->uc; int sig_size = _NSIG_WORDS * sizeof(unsigned long); diff --git a/trunk/arch/um/sys-i386/sys_call_table.S b/trunk/arch/um/sys-i386/sys_call_table.S index 1ff61474b25c..ad75c27afe38 100644 --- a/trunk/arch/um/sys-i386/sys_call_table.S +++ b/trunk/arch/um/sys-i386/sys_call_table.S @@ -6,6 +6,8 @@ #define sys_vm86old sys_ni_syscall #define sys_vm86 sys_ni_syscall +#define sys_set_thread_area sys_ni_syscall +#define sys_get_thread_area sys_ni_syscall #define sys_stime um_stime #define sys_time um_time diff --git a/trunk/arch/um/sys-i386/syscalls.c b/trunk/arch/um/sys-i386/syscalls.c index 749dd1bfe60f..83e9be820a86 100644 --- a/trunk/arch/um/sys-i386/syscalls.c +++ b/trunk/arch/um/sys-i386/syscalls.c @@ -61,27 +61,21 @@ long old_select(struct sel_arg_struct __user *arg) return sys_select(a.n, a.inp, a.outp, a.exp, a.tvp); } -/* - * The prototype on i386 is: - * - * int clone(int flags, void * child_stack, int * parent_tidptr, struct user_desc * newtls, int * child_tidptr) - * - * and the "newtls" arg. on i386 is read by copy_thread directly from the - * register saved on the stack. +/* The i386 version skips reading from %esi, the fourth argument. So we must do + * this, too. */ long sys_clone(unsigned long clone_flags, unsigned long newsp, - int __user *parent_tid, void *newtls, int __user *child_tid) + int __user *parent_tid, int unused, int __user *child_tid) { long ret; if (!newsp) newsp = UPT_SP(¤t->thread.regs.regs); - current->thread.forking = 1; ret = do_fork(clone_flags, newsp, ¤t->thread.regs, 0, parent_tid, child_tid); current->thread.forking = 0; - return ret; + return(ret); } /* @@ -110,7 +104,7 @@ long sys_ipc (uint call, int first, int second, union semun fourth; if (!ptr) return -EINVAL; - if (get_user(fourth.__pad, (void __user * __user *) ptr)) + if (get_user(fourth.__pad, (void **) ptr)) return -EFAULT; return sys_semctl (first, second, third, fourth); } diff --git a/trunk/arch/um/sys-i386/tls.c b/trunk/arch/um/sys-i386/tls.c deleted file mode 100644 index a3188e861cc7..000000000000 --- a/trunk/arch/um/sys-i386/tls.c +++ /dev/null @@ -1,384 +0,0 @@ -/* - * Copyright (C) 2005 Paolo 'Blaisorblade' Giarrusso - * Licensed under the GPL - */ - -#include "linux/config.h" -#include "linux/kernel.h" -#include "linux/sched.h" -#include "linux/slab.h" -#include "linux/types.h" -#include "asm/uaccess.h" -#include "asm/ptrace.h" -#include "asm/segment.h" -#include "asm/smp.h" -#include "asm/desc.h" -#include "choose-mode.h" -#include "kern.h" -#include "kern_util.h" -#include "mode_kern.h" -#include "os.h" -#include "mode.h" - -#ifdef CONFIG_MODE_SKAS -#include "skas.h" -#endif - -/* If needed we can detect when it's uninitialized. */ -static int host_supports_tls = -1; -int host_gdt_entry_tls_min = -1; - -#ifdef CONFIG_MODE_SKAS -int do_set_thread_area_skas(struct user_desc *info) -{ - int ret; - u32 cpu; - - cpu = get_cpu(); - ret = os_set_thread_area(info, userspace_pid[cpu]); - put_cpu(); - return ret; -} - -int do_get_thread_area_skas(struct user_desc *info) -{ - int ret; - u32 cpu; - - cpu = get_cpu(); - ret = os_get_thread_area(info, userspace_pid[cpu]); - put_cpu(); - return ret; -} -#endif - -/* - * sys_get_thread_area: get a yet unused TLS descriptor index. - * XXX: Consider leaving one free slot for glibc usage at first place. This must - * be done here (and by changing GDT_ENTRY_TLS_* macros) and nowhere else. - * - * Also, this must be tested when compiling in SKAS mode with dinamic linking - * and running against NPTL. - */ -static int get_free_idx(struct task_struct* task) -{ - struct thread_struct *t = &task->thread; - int idx; - - if (!t->arch.tls_array) - return GDT_ENTRY_TLS_MIN; - - for (idx = 0; idx < GDT_ENTRY_TLS_ENTRIES; idx++) - if (!t->arch.tls_array[idx].present) - return idx + GDT_ENTRY_TLS_MIN; - return -ESRCH; -} - -static inline void clear_user_desc(struct user_desc* info) -{ - /* Postcondition: LDT_empty(info) returns true. */ - memset(info, 0, sizeof(*info)); - - /* Check the LDT_empty or the i386 sys_get_thread_area code - we obtain - * indeed an empty user_desc. - */ - info->read_exec_only = 1; - info->seg_not_present = 1; -} - -#define O_FORCE 1 - -static int load_TLS(int flags, struct task_struct *to) -{ - int ret = 0; - int idx; - - for (idx = GDT_ENTRY_TLS_MIN; idx < GDT_ENTRY_TLS_MAX; idx++) { - struct uml_tls_struct* curr = &to->thread.arch.tls_array[idx - GDT_ENTRY_TLS_MIN]; - - /* Actually, now if it wasn't flushed it gets cleared and - * flushed to the host, which will clear it.*/ - if (!curr->present) { - if (!curr->flushed) { - clear_user_desc(&curr->tls); - curr->tls.entry_number = idx; - } else { - WARN_ON(!LDT_empty(&curr->tls)); - continue; - } - } - - if (!(flags & O_FORCE) && curr->flushed) - continue; - - ret = do_set_thread_area(&curr->tls); - if (ret) - goto out; - - curr->flushed = 1; - } -out: - return ret; -} - -/* Verify if we need to do a flush for the new process, i.e. if there are any - * present desc's, only if they haven't been flushed. - */ -static inline int needs_TLS_update(struct task_struct *task) -{ - int i; - int ret = 0; - - for (i = GDT_ENTRY_TLS_MIN; i < GDT_ENTRY_TLS_MAX; i++) { - struct uml_tls_struct* curr = &task->thread.arch.tls_array[i - GDT_ENTRY_TLS_MIN]; - - /* Can't test curr->present, we may need to clear a descriptor - * which had a value. */ - if (curr->flushed) - continue; - ret = 1; - break; - } - return ret; -} - -/* On a newly forked process, the TLS descriptors haven't yet been flushed. So - * we mark them as such and the first switch_to will do the job. - */ -void clear_flushed_tls(struct task_struct *task) -{ - int i; - - for (i = GDT_ENTRY_TLS_MIN; i < GDT_ENTRY_TLS_MAX; i++) { - struct uml_tls_struct* curr = &task->thread.arch.tls_array[i - GDT_ENTRY_TLS_MIN]; - - /* Still correct to do this, if it wasn't present on the host it - * will remain as flushed as it was. */ - if (!curr->present) - continue; - - curr->flushed = 0; - } -} - -/* In SKAS0 mode, currently, multiple guest threads sharing the same ->mm have a - * common host process. So this is needed in SKAS0 too. - * - * However, if each thread had a different host process (and this was discussed - * for SMP support) this won't be needed. - * - * And this will not need be used when (and if) we'll add support to the host - * SKAS patch. */ - -int arch_switch_tls_skas(struct task_struct *from, struct task_struct *to) -{ - if (!host_supports_tls) - return 0; - - /* We have no need whatsoever to switch TLS for kernel threads; beyond - * that, that would also result in us calling os_set_thread_area with - * userspace_pid[cpu] == 0, which gives an error. */ - if (likely(to->mm)) - return load_TLS(O_FORCE, to); - - return 0; -} - -int arch_switch_tls_tt(struct task_struct *from, struct task_struct *to) -{ - if (!host_supports_tls) - return 0; - - if (needs_TLS_update(to)) - return load_TLS(0, to); - - return 0; -} - -static int set_tls_entry(struct task_struct* task, struct user_desc *info, - int idx, int flushed) -{ - struct thread_struct *t = &task->thread; - - if (idx < GDT_ENTRY_TLS_MIN || idx > GDT_ENTRY_TLS_MAX) - return -EINVAL; - - t->arch.tls_array[idx - GDT_ENTRY_TLS_MIN].tls = *info; - t->arch.tls_array[idx - GDT_ENTRY_TLS_MIN].present = 1; - t->arch.tls_array[idx - GDT_ENTRY_TLS_MIN].flushed = flushed; - - return 0; -} - -int arch_copy_tls(struct task_struct *new) -{ - struct user_desc info; - int idx, ret = -EFAULT; - - if (copy_from_user(&info, - (void __user *) UPT_ESI(&new->thread.regs.regs), - sizeof(info))) - goto out; - - ret = -EINVAL; - if (LDT_empty(&info)) - goto out; - - idx = info.entry_number; - - ret = set_tls_entry(new, &info, idx, 0); -out: - return ret; -} - -/* XXX: use do_get_thread_area to read the host value? I'm not at all sure! */ -static int get_tls_entry(struct task_struct* task, struct user_desc *info, int idx) -{ - struct thread_struct *t = &task->thread; - - if (!t->arch.tls_array) - goto clear; - - if (idx < GDT_ENTRY_TLS_MIN || idx > GDT_ENTRY_TLS_MAX) - return -EINVAL; - - if (!t->arch.tls_array[idx - GDT_ENTRY_TLS_MIN].present) - goto clear; - - *info = t->arch.tls_array[idx - GDT_ENTRY_TLS_MIN].tls; - -out: - /* Temporary debugging check, to make sure that things have been - * flushed. This could be triggered if load_TLS() failed. - */ - if (unlikely(task == current && !t->arch.tls_array[idx - GDT_ENTRY_TLS_MIN].flushed)) { - printk(KERN_ERR "get_tls_entry: task with pid %d got here " - "without flushed TLS.", current->pid); - } - - return 0; -clear: - /* When the TLS entry has not been set, the values read to user in the - * tls_array are 0 (because it's cleared at boot, see - * arch/i386/kernel/head.S:cpu_gdt_table). Emulate that. - */ - clear_user_desc(info); - info->entry_number = idx; - goto out; -} - -asmlinkage int sys_set_thread_area(struct user_desc __user *user_desc) -{ - struct user_desc info; - int idx, ret; - - if (!host_supports_tls) - return -ENOSYS; - - if (copy_from_user(&info, user_desc, sizeof(info))) - return -EFAULT; - - idx = info.entry_number; - - if (idx == -1) { - idx = get_free_idx(current); - if (idx < 0) - return idx; - info.entry_number = idx; - /* Tell the user which slot we chose for him.*/ - if (put_user(idx, &user_desc->entry_number)) - return -EFAULT; - } - - ret = CHOOSE_MODE_PROC(do_set_thread_area_tt, do_set_thread_area_skas, &info); - if (ret) - return ret; - return set_tls_entry(current, &info, idx, 1); -} - -/* - * Perform set_thread_area on behalf of the traced child. - * Note: error handling is not done on the deferred load, and this differ from - * i386. However the only possible error are caused by bugs. - */ -int ptrace_set_thread_area(struct task_struct *child, int idx, - struct user_desc __user *user_desc) -{ - struct user_desc info; - - if (!host_supports_tls) - return -EIO; - - if (copy_from_user(&info, user_desc, sizeof(info))) - return -EFAULT; - - return set_tls_entry(child, &info, idx, 0); -} - -asmlinkage int sys_get_thread_area(struct user_desc __user *user_desc) -{ - struct user_desc info; - int idx, ret; - - if (!host_supports_tls) - return -ENOSYS; - - if (get_user(idx, &user_desc->entry_number)) - return -EFAULT; - - ret = get_tls_entry(current, &info, idx); - if (ret < 0) - goto out; - - if (copy_to_user(user_desc, &info, sizeof(info))) - ret = -EFAULT; - -out: - return ret; -} - -/* - * Perform get_thread_area on behalf of the traced child. - */ -int ptrace_get_thread_area(struct task_struct *child, int idx, - struct user_desc __user *user_desc) -{ - struct user_desc info; - int ret; - - if (!host_supports_tls) - return -EIO; - - ret = get_tls_entry(child, &info, idx); - if (ret < 0) - goto out; - - if (copy_to_user(user_desc, &info, sizeof(info))) - ret = -EFAULT; -out: - return ret; -} - - -/* XXX: This part is probably common to i386 and x86-64. Don't create a common - * file for now, do that when implementing x86-64 support.*/ -static int __init __setup_host_supports_tls(void) { - check_host_supports_tls(&host_supports_tls, &host_gdt_entry_tls_min); - if (host_supports_tls) { - printk(KERN_INFO "Host TLS support detected\n"); - printk(KERN_INFO "Detected host type: "); - switch (host_gdt_entry_tls_min) { - case GDT_ENTRY_TLS_MIN_I386: - printk("i386\n"); - break; - case GDT_ENTRY_TLS_MIN_X86_64: - printk("x86_64\n"); - break; - } - } else - printk(KERN_ERR " Host TLS support NOT detected! " - "TLS support inside UML will not work\n"); - return 1; -} - -__initcall(__setup_host_supports_tls); diff --git a/trunk/arch/um/sys-x86_64/Makefile b/trunk/arch/um/sys-x86_64/Makefile index b5fc22babddf..a351091fbd99 100644 --- a/trunk/arch/um/sys-x86_64/Makefile +++ b/trunk/arch/um/sys-x86_64/Makefile @@ -4,23 +4,31 @@ # Licensed under the GPL # -obj-y = bugs.o delay.o fault.o ldt.o mem.o ptrace.o ptrace_user.o \ - sigcontext.o signal.o syscalls.o syscall_table.o sysrq.o ksyms.o \ - tls.o +#XXX: why into lib-y? +lib-y = bitops.o bugs.o csum-partial.o delay.o fault.o ldt.o mem.o memcpy.o \ + ptrace.o ptrace_user.o sigcontext.o signal.o syscalls.o \ + syscall_table.o sysrq.o thunk.o +lib-$(CONFIG_MODE_SKAS) += stub.o stub_segv.o -obj-$(CONFIG_MODE_SKAS) += stub.o stub_segv.o -obj-$(CONFIG_MODULES) += um_module.o - -subarch-obj-y = lib/bitops.o lib/csum-partial.o lib/memcpy.o lib/thunk.o -subarch-obj-$(CONFIG_MODULES) += kernel/module.o - -ldt-y = ../sys-i386/ldt.o +obj-y := ksyms.o +obj-$(CONFIG_MODULES) += module.o um_module.o USER_OBJS := ptrace_user.o sigcontext.o stub_segv.o +SYMLINKS = bitops.c csum-copy.S csum-partial.c csum-wrappers.c ldt.c memcpy.S \ + thunk.S module.c + include arch/um/scripts/Makefile.rules -extra-$(CONFIG_MODE_TT) += unmap.o +bitops.c-dir = lib +csum-copy.S-dir = lib +csum-partial.c-dir = lib +csum-wrappers.c-dir = lib +ldt.c-dir = /arch/um/sys-i386 +memcpy.S-dir = lib +thunk.S-dir = lib +module.c-dir = kernel + +$(obj)/stub_segv.o: _c_flags = $(call unprofile,$(CFLAGS)) -$(obj)/stub_segv.o $(obj)/unmap.o: \ - _c_flags = $(call unprofile,$(CFLAGS)) +include arch/um/scripts/Makefile.unmap diff --git a/trunk/arch/um/sys-x86_64/tls.c b/trunk/arch/um/sys-x86_64/tls.c deleted file mode 100644 index ce1bf1b81c43..000000000000 --- a/trunk/arch/um/sys-x86_64/tls.c +++ /dev/null @@ -1,14 +0,0 @@ -#include "linux/sched.h" - -void debug_arch_force_load_TLS(void) -{ -} - -void clear_flushed_tls(struct task_struct *task) -{ -} - -int arch_copy_tls(struct task_struct *t) -{ - return 0; -} diff --git a/trunk/arch/x86_64/ia32/vsyscall-sigreturn.S b/trunk/arch/x86_64/ia32/vsyscall-sigreturn.S index 1384367cdbe1..d90321fe9bba 100644 --- a/trunk/arch/x86_64/ia32/vsyscall-sigreturn.S +++ b/trunk/arch/x86_64/ia32/vsyscall-sigreturn.S @@ -32,28 +32,9 @@ __kernel_rt_sigreturn: .size __kernel_rt_sigreturn,.-.LSTART_rt_sigreturn .section .eh_frame,"a",@progbits -.LSTARTFRAMES: - .long .LENDCIES-.LSTARTCIES -.LSTARTCIES: - .long 0 /* CIE ID */ - .byte 1 /* Version number */ - .string "zRS" /* NUL-terminated augmentation string */ - .uleb128 1 /* Code alignment factor */ - .sleb128 -4 /* Data alignment factor */ - .byte 8 /* Return address register column */ - .uleb128 1 /* Augmentation value length */ - .byte 0x1b /* DW_EH_PE_pcrel|DW_EH_PE_sdata4. */ - .byte 0x0c /* DW_CFA_def_cfa */ - .uleb128 4 - .uleb128 4 - .byte 0x88 /* DW_CFA_offset, column 0x8 */ - .uleb128 1 - .align 4 -.LENDCIES: - .long .LENDFDE2-.LSTARTFDE2 /* Length FDE */ .LSTARTFDE2: - .long .LSTARTFDE2-.LSTARTFRAMES /* CIE pointer */ + .long .LSTARTFDE2-.LSTARTFRAME /* CIE pointer */ /* HACK: The dwarf2 unwind routines will subtract 1 from the return address to get an address in the middle of the presumed call instruction. Since we didn't get here via @@ -116,7 +97,7 @@ __kernel_rt_sigreturn: .long .LENDFDE3-.LSTARTFDE3 /* Length FDE */ .LSTARTFDE3: - .long .LSTARTFDE3-.LSTARTFRAMES /* CIE pointer */ + .long .LSTARTFDE3-.LSTARTFRAME /* CIE pointer */ /* HACK: See above wrt unwind library assumptions. */ .long .LSTART_rt_sigreturn-1-. /* PC-relative start address */ .long .LEND_rt_sigreturn-.LSTART_rt_sigreturn+1 diff --git a/trunk/arch/x86_64/kernel/apic.c b/trunk/arch/x86_64/kernel/apic.c index 100a30c40044..d54620147e8e 100644 --- a/trunk/arch/x86_64/kernel/apic.c +++ b/trunk/arch/x86_64/kernel/apic.c @@ -615,7 +615,7 @@ static int __init apic_set_verbosity(char *str) printk(KERN_WARNING "APIC Verbosity level %s not recognised" " use apic=verbose or apic=debug", str); - return 1; + return 0; } __setup("apic=", apic_set_verbosity); @@ -1137,35 +1137,35 @@ int __init APIC_init_uniprocessor (void) static __init int setup_disableapic(char *str) { disable_apic = 1; - return 1; + return 0; } static __init int setup_nolapic(char *str) { disable_apic = 1; - return 1; + return 0; } static __init int setup_noapictimer(char *str) { if (str[0] != ' ' && str[0] != 0) - return 0; + return -1; disable_apic_timer = 1; - return 1; + return 0; } static __init int setup_apicmaintimer(char *str) { apic_runs_main_timer = 1; nohpet = 1; - return 1; + return 0; } __setup("apicmaintimer", setup_apicmaintimer); static __init int setup_noapicmaintimer(char *str) { apic_runs_main_timer = -1; - return 1; + return 0; } __setup("noapicmaintimer", setup_noapicmaintimer); diff --git a/trunk/arch/x86_64/kernel/early_printk.c b/trunk/arch/x86_64/kernel/early_printk.c index b93ef5b51980..13af920b6594 100644 --- a/trunk/arch/x86_64/kernel/early_printk.c +++ b/trunk/arch/x86_64/kernel/early_printk.c @@ -221,7 +221,7 @@ int __init setup_early_printk(char *opt) char buf[256]; if (early_console_initialized) - return 1; + return -1; strlcpy(buf,opt,sizeof(buf)); space = strchr(buf, ' '); diff --git a/trunk/arch/x86_64/kernel/mce.c b/trunk/arch/x86_64/kernel/mce.c index 10b3e348fc99..04282ef9fbd4 100644 --- a/trunk/arch/x86_64/kernel/mce.c +++ b/trunk/arch/x86_64/kernel/mce.c @@ -501,7 +501,7 @@ static struct miscdevice mce_log_device = { static int __init mcheck_disable(char *str) { mce_dont_init = 1; - return 1; + return 0; } /* mce=off disables machine check. Note you can reenable it later @@ -521,7 +521,7 @@ static int __init mcheck_enable(char *str) get_option(&str, &tolerant); else printk("mce= argument %s ignored. Please use /sys", str); - return 1; + return 0; } __setup("nomce", mcheck_disable); diff --git a/trunk/arch/x86_64/kernel/pmtimer.c b/trunk/arch/x86_64/kernel/pmtimer.c index b0444a415bd6..ee5ee4891f3d 100644 --- a/trunk/arch/x86_64/kernel/pmtimer.c +++ b/trunk/arch/x86_64/kernel/pmtimer.c @@ -121,7 +121,7 @@ unsigned int do_gettimeoffset_pm(void) static int __init nopmtimer_setup(char *s) { pmtmr_ioport = 0; - return 1; + return 0; } __setup("nopmtimer", nopmtimer_setup); diff --git a/trunk/arch/x86_64/kernel/setup.c b/trunk/arch/x86_64/kernel/setup.c index 0856ad444f90..d1f3e9272c05 100644 --- a/trunk/arch/x86_64/kernel/setup.c +++ b/trunk/arch/x86_64/kernel/setup.c @@ -540,7 +540,7 @@ void __init alternative_instructions(void) static int __init noreplacement_setup(char *s) { no_replacement = 1; - return 1; + return 0; } __setup("noreplacement", noreplacement_setup); diff --git a/trunk/arch/x86_64/kernel/setup64.c b/trunk/arch/x86_64/kernel/setup64.c index 8a691fa6d393..eabdb63fec31 100644 --- a/trunk/arch/x86_64/kernel/setup64.c +++ b/trunk/arch/x86_64/kernel/setup64.c @@ -55,7 +55,7 @@ int __init nonx_setup(char *str) do_not_nx = 1; __supported_pte_mask &= ~_PAGE_NX; } - return 1; + return 0; } __setup("noexec=", nonx_setup); /* parsed early actually */ @@ -74,7 +74,7 @@ static int __init nonx32_setup(char *str) force_personality32 &= ~READ_IMPLIES_EXEC; else if (!strcmp(str, "off")) force_personality32 |= READ_IMPLIES_EXEC; - return 1; + return 0; } __setup("noexec32=", nonx32_setup); diff --git a/trunk/arch/x86_64/kernel/smpboot.c b/trunk/arch/x86_64/kernel/smpboot.c index 71a7222cf9ce..ea48fa638070 100644 --- a/trunk/arch/x86_64/kernel/smpboot.c +++ b/trunk/arch/x86_64/kernel/smpboot.c @@ -353,7 +353,7 @@ static void __cpuinit tsc_sync_wait(void) static __init int notscsync_setup(char *s) { notscsync = 1; - return 1; + return 0; } __setup("notscsync", notscsync_setup); diff --git a/trunk/arch/x86_64/kernel/time.c b/trunk/arch/x86_64/kernel/time.c index ef8bc46dc140..473b514b66e4 100644 --- a/trunk/arch/x86_64/kernel/time.c +++ b/trunk/arch/x86_64/kernel/time.c @@ -1306,7 +1306,7 @@ irqreturn_t hpet_rtc_interrupt(int irq, void *dev_id, struct pt_regs *regs) static int __init nohpet_setup(char *s) { nohpet = 1; - return 1; + return 0; } __setup("nohpet", nohpet_setup); @@ -1314,7 +1314,7 @@ __setup("nohpet", nohpet_setup); int __init notsc_setup(char *s) { notsc = 1; - return 1; + return 0; } __setup("notsc", notsc_setup); diff --git a/trunk/arch/x86_64/kernel/traps.c b/trunk/arch/x86_64/kernel/traps.c index 6bda322d3caf..edaa9fe654dc 100644 --- a/trunk/arch/x86_64/kernel/traps.c +++ b/trunk/arch/x86_64/kernel/traps.c @@ -973,14 +973,14 @@ void __init trap_init(void) static int __init oops_dummy(char *s) { panic_on_oops = 1; - return 1; + return -1; } __setup("oops=", oops_dummy); static int __init kstack_setup(char *s) { kstack_depth_to_print = simple_strtoul(s,NULL,0); - return 1; + return 0; } __setup("kstack=", kstack_setup); diff --git a/trunk/arch/x86_64/kernel/x8664_ksyms.c b/trunk/arch/x86_64/kernel/x8664_ksyms.c index d78f46056bda..d96a9348e5a2 100644 --- a/trunk/arch/x86_64/kernel/x8664_ksyms.c +++ b/trunk/arch/x86_64/kernel/x8664_ksyms.c @@ -102,6 +102,8 @@ EXPORT_SYMBOL(cpu_callout_map); EXPORT_SYMBOL(screen_info); #endif +EXPORT_SYMBOL(get_wchan); + EXPORT_SYMBOL(rtc_lock); EXPORT_SYMBOL_GPL(set_nmi_callback); diff --git a/trunk/arch/x86_64/mm/fault.c b/trunk/arch/x86_64/mm/fault.c index 55250593d8c9..316c53de47bd 100644 --- a/trunk/arch/x86_64/mm/fault.c +++ b/trunk/arch/x86_64/mm/fault.c @@ -623,6 +623,6 @@ void vmalloc_sync_all(void) static int __init enable_pagefaulttrace(char *str) { page_fault_trace = 1; - return 1; + return 0; } __setup("pagefaulttrace", enable_pagefaulttrace); diff --git a/trunk/arch/xtensa/kernel/xtensa_ksyms.c b/trunk/arch/xtensa/kernel/xtensa_ksyms.c index 152b9370789b..efae56a51475 100644 --- a/trunk/arch/xtensa/kernel/xtensa_ksyms.c +++ b/trunk/arch/xtensa/kernel/xtensa_ksyms.c @@ -113,6 +113,8 @@ EXPORT_SYMBOL(__xtensa_copy_user); // FIXME EXPORT_SYMBOL(screen_info); #endif +EXPORT_SYMBOL(get_wchan); + EXPORT_SYMBOL(outsb); EXPORT_SYMBOL(outsw); EXPORT_SYMBOL(outsl); diff --git a/trunk/block/Kconfig b/trunk/block/Kconfig index b6f5f0a79655..5536839886ff 100644 --- a/trunk/block/Kconfig +++ b/trunk/block/Kconfig @@ -27,10 +27,10 @@ config BLK_DEV_IO_TRACE config LSF bool "Support for Large Single Files" depends on X86 || (MIPS && 32BIT) || PPC32 || ARCH_S390_31 || SUPERH || UML + default n help - Say Y here if you want to be able to handle very large files (bigger - than 2TB), otherwise say N. - - If unsure, say Y. + When CONFIG_LBD is disabled, say Y here if you want to + handle large file(bigger than 2TB), otherwise say N. + When CONFIG_LBD is enabled, Y is set automatically. source block/Kconfig.iosched diff --git a/trunk/block/elevator.c b/trunk/block/elevator.c index 0d6be03d929e..56c2ed06a9e2 100644 --- a/trunk/block/elevator.c +++ b/trunk/block/elevator.c @@ -145,7 +145,7 @@ static int __init elevator_setup(char *str) strcpy(chosen_elevator, "anticipatory"); else strncpy(chosen_elevator, str, sizeof(chosen_elevator) - 1); - return 1; + return 0; } __setup("elevator=", elevator_setup); diff --git a/trunk/block/genhd.c b/trunk/block/genhd.c index 5a8d3bf02f17..db4c60c802d6 100644 --- a/trunk/block/genhd.c +++ b/trunk/block/genhd.c @@ -17,6 +17,8 @@ #include #include +#define MAX_PROBE_HASH 255 /* random */ + static struct subsystem block_subsys; static DEFINE_MUTEX(block_subsys_lock); @@ -29,29 +31,108 @@ static struct blk_major_name { struct blk_major_name *next; int major; char name[16]; -} *major_names[BLKDEV_MAJOR_HASH_SIZE]; +} *major_names[MAX_PROBE_HASH]; /* index in the above - for now: assume no multimajor ranges */ static inline int major_to_index(int major) { - return major % BLKDEV_MAJOR_HASH_SIZE; + return major % MAX_PROBE_HASH; +} + +struct blkdev_info { + int index; + struct blk_major_name *bd; +}; + +/* + * iterate over a list of blkdev_info structures. allows + * the major_names array to be iterated over from outside this file + * must be called with the block_subsys_lock held + */ +void *get_next_blkdev(void *dev) +{ + struct blkdev_info *info; + + if (dev == NULL) { + info = kmalloc(sizeof(*info), GFP_KERNEL); + if (!info) + goto out; + info->index=0; + info->bd = major_names[info->index]; + if (info->bd) + goto out; + } else { + info = dev; + } + + while (info->index < ARRAY_SIZE(major_names)) { + if (info->bd) + info->bd = info->bd->next; + if (info->bd) + goto out; + /* + * No devices on this chain, move to the next + */ + info->index++; + info->bd = (info->index < ARRAY_SIZE(major_names)) ? + major_names[info->index] : NULL; + if (info->bd) + goto out; + } + +out: + return info; +} + +void *acquire_blkdev_list(void) +{ + mutex_lock(&block_subsys_lock); + return get_next_blkdev(NULL); +} + +void release_blkdev_list(void *dev) +{ + mutex_unlock(&block_subsys_lock); + kfree(dev); } -#ifdef CONFIG_PROC_FS -void blkdev_show(struct seq_file *f, off_t offset) +/* + * Count the number of records in the blkdev_list. + * must be called with the block_subsys_lock held + */ +int count_blkdev_list(void) { - struct blk_major_name *dp; + struct blk_major_name *n; + int i, count; - if (offset < BLKDEV_MAJOR_HASH_SIZE) { - mutex_lock(&block_subsys_lock); - for (dp = major_names[offset]; dp; dp = dp->next) - seq_printf(f, "%3d %s\n", dp->major, dp->name); - mutex_unlock(&block_subsys_lock); + count = 0; + + for (i = 0; i < ARRAY_SIZE(major_names); i++) { + for (n = major_names[i]; n; n = n->next) + count++; } + + return count; +} + +/* + * extract the major and name values from a blkdev_info struct + * passed in as a void to *dev. Must be called with + * block_subsys_lock held + */ +int get_blkdev_info(void *dev, int *major, char **name) +{ + struct blkdev_info *info = dev; + + if (info->bd == NULL) + return 1; + + *major = info->bd->major; + *name = info->bd->name; + return 0; } -#endif /* CONFIG_PROC_FS */ int register_blkdev(unsigned int major, const char *name) { diff --git a/trunk/drivers/Kconfig b/trunk/drivers/Kconfig index 5c91d6afb117..9f5c0da57c90 100644 --- a/trunk/drivers/Kconfig +++ b/trunk/drivers/Kconfig @@ -64,8 +64,6 @@ source "drivers/usb/Kconfig" source "drivers/mmc/Kconfig" -source "drivers/leds/Kconfig" - source "drivers/infiniband/Kconfig" source "drivers/sn/Kconfig" diff --git a/trunk/drivers/Makefile b/trunk/drivers/Makefile index d6e8ffbd8132..424955274e60 100644 --- a/trunk/drivers/Makefile +++ b/trunk/drivers/Makefile @@ -69,7 +69,6 @@ obj-$(CONFIG_MCA) += mca/ obj-$(CONFIG_EISA) += eisa/ obj-$(CONFIG_CPU_FREQ) += cpufreq/ obj-$(CONFIG_MMC) += mmc/ -obj-$(CONFIG_NEW_LEDS) += leds/ obj-$(CONFIG_INFINIBAND) += infiniband/ obj-$(CONFIG_SGI_SN) += sn/ obj-y += firmware/ diff --git a/trunk/drivers/acpi/ec.c b/trunk/drivers/acpi/ec.c index eee0864ba300..79b09d76c180 100644 --- a/trunk/drivers/acpi/ec.c +++ b/trunk/drivers/acpi/ec.c @@ -1572,7 +1572,7 @@ static void __exit acpi_ec_exit(void) static int __init acpi_fake_ecdt_setup(char *str) { acpi_fake_ecdt_enabled = 1; - return 1; + return 0; } __setup("acpi_fake_ecdt", acpi_fake_ecdt_setup); @@ -1591,7 +1591,7 @@ static int __init acpi_ec_set_intr_mode(char *str) acpi_ec_driver.ops.add = acpi_ec_poll_add; } printk(KERN_INFO PREFIX "EC %s mode.\n", intr ? "interrupt" : "polling"); - return 1; + return 0; } __setup("ec_intr=", acpi_ec_set_intr_mode); diff --git a/trunk/drivers/block/amiflop.c b/trunk/drivers/block/amiflop.c index 2a8af685926f..b6e290956214 100644 --- a/trunk/drivers/block/amiflop.c +++ b/trunk/drivers/block/amiflop.c @@ -1850,7 +1850,6 @@ static int __init amiga_floppy_setup (char *str) return 0; printk (KERN_INFO "amiflop: Setting default df0 to %x\n", n); fd_def_df0 = n; - return 1; } __setup("floppy=", amiga_floppy_setup); diff --git a/trunk/drivers/char/Kconfig b/trunk/drivers/char/Kconfig index 889cad07774e..73d30bf01582 100644 --- a/trunk/drivers/char/Kconfig +++ b/trunk/drivers/char/Kconfig @@ -561,31 +561,14 @@ config TIPAR If unsure, say N. -config HVC_DRIVER - bool - help - Users of pSeries machines that want to utilize the hvc console front-end - module for their backend console driver should select this option. - It will automatically be selected if one of the back-end console drivers - is selected. - - config HVC_CONSOLE bool "pSeries Hypervisor Virtual Console support" depends on PPC_PSERIES - select HVC_DRIVER help pSeries machines when partitioned support a hypervisor virtual console. This driver allows each pSeries partition to have a console which is accessed via the HMC. -config HVC_RTAS - bool "IBM RTAS Console support" - depends on PPC_RTAS - select HVC_DRIVER - help - IBM Console device driver which makes use of RTAS - config HVCS tristate "IBM Hypervisor Virtual Console Server support" depends on PPC_PSERIES diff --git a/trunk/drivers/char/Makefile b/trunk/drivers/char/Makefile index a73cb4956928..b2a11245fa95 100644 --- a/trunk/drivers/char/Makefile +++ b/trunk/drivers/char/Makefile @@ -41,9 +41,7 @@ obj-$(CONFIG_N_HDLC) += n_hdlc.o obj-$(CONFIG_AMIGA_BUILTIN_SERIAL) += amiserial.o obj-$(CONFIG_SX) += sx.o generic_serial.o obj-$(CONFIG_RIO) += rio/ generic_serial.o -obj-$(CONFIG_HVC_DRIVER) += hvc_console.o -obj-$(CONFIG_HVC_CONSOLE) += hvc_vio.o hvsi.o -obj-$(CONFIG_HVC_RTAS) += hvc_rtas.o +obj-$(CONFIG_HVC_CONSOLE) += hvc_console.o hvc_vio.o hvsi.o obj-$(CONFIG_RAW_DRIVER) += raw.o obj-$(CONFIG_SGI_SNSC) += snsc.o snsc_event.o obj-$(CONFIG_MMTIMER) += mmtimer.o diff --git a/trunk/drivers/char/drm/drmP.h b/trunk/drivers/char/drm/drmP.h index edc72a6348a7..107df9fdba4e 100644 --- a/trunk/drivers/char/drm/drmP.h +++ b/trunk/drivers/char/drm/drmP.h @@ -357,12 +357,6 @@ typedef struct drm_freelist { spinlock_t lock; } drm_freelist_t; -typedef struct drm_dma_handle { - dma_addr_t busaddr; - void *vaddr; - size_t size; -} drm_dma_handle_t; - /** * Buffer entry. There is one of this for each buffer size order. */ @@ -372,7 +366,7 @@ typedef struct drm_buf_entry { drm_buf_t *buflist; /**< buffer list */ int seg_count; int page_order; - drm_dma_handle_t **seglist; + unsigned long *seglist; drm_freelist_t freelist; } drm_buf_entry_t; @@ -489,6 +483,12 @@ typedef struct drm_sigdata { drm_hw_lock_t *lock; } drm_sigdata_t; +typedef struct drm_dma_handle { + dma_addr_t busaddr; + void *vaddr; + size_t size; +} drm_dma_handle_t; + /** * Mappings list */ @@ -813,6 +813,8 @@ extern void drm_mem_init(void); extern int drm_mem_info(char *buf, char **start, off_t offset, int request, int *eof, void *data); extern void *drm_realloc(void *oldpt, size_t oldsize, size_t size, int area); +extern unsigned long drm_alloc_pages(int order, int area); +extern void drm_free_pages(unsigned long address, int order, int area); extern void *drm_ioremap(unsigned long offset, unsigned long size, drm_device_t * dev); extern void *drm_ioremap_nocache(unsigned long offset, unsigned long size, diff --git a/trunk/drivers/char/drm/drm_bufs.c b/trunk/drivers/char/drm/drm_bufs.c index 8a9cf12e6183..e2637b4d51de 100644 --- a/trunk/drivers/char/drm/drm_bufs.c +++ b/trunk/drivers/char/drm/drm_bufs.c @@ -474,7 +474,8 @@ static void drm_cleanup_buf_error(drm_device_t * dev, drm_buf_entry_t * entry) if (entry->seg_count) { for (i = 0; i < entry->seg_count; i++) { if (entry->seglist[i]) { - drm_pci_free(dev, entry->seglist[i]); + drm_free_pages(entry->seglist[i], + entry->page_order, DRM_MEM_DMA); } } drm_free(entry->seglist, @@ -677,7 +678,7 @@ int drm_addbufs_pci(drm_device_t * dev, drm_buf_desc_t * request) int total; int page_order; drm_buf_entry_t *entry; - drm_dma_handle_t *dmah; + unsigned long page; drm_buf_t *buf; int alignment; unsigned long offset; @@ -780,10 +781,8 @@ int drm_addbufs_pci(drm_device_t * dev, drm_buf_desc_t * request) page_count = 0; while (entry->buf_count < count) { - - dmah = drm_pci_alloc(dev, PAGE_SIZE << page_order, 0x1000, 0xfffffffful); - - if (!dmah) { + page = drm_alloc_pages(page_order, DRM_MEM_DMA); + if (!page) { /* Set count correctly so we free the proper amount. */ entry->buf_count = count; entry->seg_count = count; @@ -795,13 +794,13 @@ int drm_addbufs_pci(drm_device_t * dev, drm_buf_desc_t * request) atomic_dec(&dev->buf_alloc); return -ENOMEM; } - entry->seglist[entry->seg_count++] = dmah; + entry->seglist[entry->seg_count++] = page; for (i = 0; i < (1 << page_order); i++) { DRM_DEBUG("page %d @ 0x%08lx\n", dma->page_count + page_count, - (unsigned long)dmah->vaddr + PAGE_SIZE * i); + page + PAGE_SIZE * i); temp_pagelist[dma->page_count + page_count++] - = (unsigned long)dmah->vaddr + PAGE_SIZE * i; + = page + PAGE_SIZE * i; } for (offset = 0; offset + size <= total && entry->buf_count < count; @@ -812,8 +811,7 @@ int drm_addbufs_pci(drm_device_t * dev, drm_buf_desc_t * request) buf->order = order; buf->used = 0; buf->offset = (dma->byte_count + byte_count + offset); - buf->address = (void *)(dmah->vaddr + offset); - buf->bus_address = dmah->busaddr + offset; + buf->address = (void *)(page + offset); buf->next = NULL; buf->waiting = 0; buf->pending = 0; diff --git a/trunk/drivers/char/drm/drm_dma.c b/trunk/drivers/char/drm/drm_dma.c index 892db7096986..2afab95ca036 100644 --- a/trunk/drivers/char/drm/drm_dma.c +++ b/trunk/drivers/char/drm/drm_dma.c @@ -85,7 +85,9 @@ void drm_dma_takedown(drm_device_t * dev) dma->bufs[i].seg_count); for (j = 0; j < dma->bufs[i].seg_count; j++) { if (dma->bufs[i].seglist[j]) { - drm_pci_free(dev, dma->bufs[i].seglist[j]); + drm_free_pages(dma->bufs[i].seglist[j], + dma->bufs[i].page_order, + DRM_MEM_DMA); } } drm_free(dma->bufs[i].seglist, diff --git a/trunk/drivers/char/drm/drm_memory.c b/trunk/drivers/char/drm/drm_memory.c index dddf8de66143..8074771e348f 100644 --- a/trunk/drivers/char/drm/drm_memory.c +++ b/trunk/drivers/char/drm/drm_memory.c @@ -79,6 +79,65 @@ void *drm_realloc(void *oldpt, size_t oldsize, size_t size, int area) return pt; } +/** + * Allocate pages. + * + * \param order size order. + * \param area memory area. (Not used.) + * \return page address on success, or zero on failure. + * + * Allocate and reserve free pages. + */ +unsigned long drm_alloc_pages(int order, int area) +{ + unsigned long address; + unsigned long bytes = PAGE_SIZE << order; + unsigned long addr; + unsigned int sz; + + address = __get_free_pages(GFP_KERNEL|__GFP_COMP, order); + if (!address) + return 0; + + /* Zero */ + memset((void *)address, 0, bytes); + + /* Reserve */ + for (addr = address, sz = bytes; + sz > 0; addr += PAGE_SIZE, sz -= PAGE_SIZE) { + SetPageReserved(virt_to_page(addr)); + } + + return address; +} + +/** + * Free pages. + * + * \param address address of the pages to free. + * \param order size order. + * \param area memory area. (Not used.) + * + * Unreserve and free pages allocated by alloc_pages(). + */ +void drm_free_pages(unsigned long address, int order, int area) +{ + unsigned long bytes = PAGE_SIZE << order; + unsigned long addr; + unsigned int sz; + + if (!address) + return; + + /* Unreserve */ + for (addr = address, sz = bytes; + sz > 0; addr += PAGE_SIZE, sz -= PAGE_SIZE) { + ClearPageReserved(virt_to_page(addr)); + } + + free_pages(address, order); +} + #if __OS_HAS_AGP /** Wrapper around agp_allocate_memory() */ DRM_AGP_MEM *drm_alloc_agp(drm_device_t * dev, int pages, u32 type) diff --git a/trunk/drivers/char/drm/drm_memory_debug.h b/trunk/drivers/char/drm/drm_memory_debug.h index 7868341817da..e84605fc54af 100644 --- a/trunk/drivers/char/drm/drm_memory_debug.h +++ b/trunk/drivers/char/drm/drm_memory_debug.h @@ -206,6 +206,76 @@ void drm_free (void *pt, size_t size, int area) { } } +unsigned long drm_alloc_pages (int order, int area) { + unsigned long address; + unsigned long bytes = PAGE_SIZE << order; + unsigned long addr; + unsigned int sz; + + spin_lock(&drm_mem_lock); + if ((drm_ram_used >> PAGE_SHIFT) + > (DRM_RAM_PERCENT * drm_ram_available) / 100) { + spin_unlock(&drm_mem_lock); + return 0; + } + spin_unlock(&drm_mem_lock); + + address = __get_free_pages(GFP_KERNEL|__GFP_COMP, order); + if (!address) { + spin_lock(&drm_mem_lock); + ++drm_mem_stats[area].fail_count; + spin_unlock(&drm_mem_lock); + return 0; + } + spin_lock(&drm_mem_lock); + ++drm_mem_stats[area].succeed_count; + drm_mem_stats[area].bytes_allocated += bytes; + drm_ram_used += bytes; + spin_unlock(&drm_mem_lock); + + /* Zero outside the lock */ + memset((void *)address, 0, bytes); + + /* Reserve */ + for (addr = address, sz = bytes; + sz > 0; addr += PAGE_SIZE, sz -= PAGE_SIZE) { + SetPageReserved(virt_to_page(addr)); + } + + return address; +} + +void drm_free_pages (unsigned long address, int order, int area) { + unsigned long bytes = PAGE_SIZE << order; + int alloc_count; + int free_count; + unsigned long addr; + unsigned int sz; + + if (!address) { + DRM_MEM_ERROR(area, "Attempt to free address 0\n"); + } else { + /* Unreserve */ + for (addr = address, sz = bytes; + sz > 0; addr += PAGE_SIZE, sz -= PAGE_SIZE) { + ClearPageReserved(virt_to_page(addr)); + } + free_pages(address, order); + } + + spin_lock(&drm_mem_lock); + free_count = ++drm_mem_stats[area].free_count; + alloc_count = drm_mem_stats[area].succeed_count; + drm_mem_stats[area].bytes_freed += bytes; + drm_ram_used -= bytes; + spin_unlock(&drm_mem_lock); + if (free_count > alloc_count) { + DRM_MEM_ERROR(area, + "Excess frees: %d frees, %d allocs\n", + free_count, alloc_count); + } +} + void *drm_ioremap (unsigned long offset, unsigned long size, drm_device_t * dev) { void *pt; diff --git a/trunk/drivers/char/drm/drm_pci.c b/trunk/drivers/char/drm/drm_pci.c index b28ca9cea8a2..1fd7ff164817 100644 --- a/trunk/drivers/char/drm/drm_pci.c +++ b/trunk/drivers/char/drm/drm_pci.c @@ -50,10 +50,6 @@ drm_dma_handle_t *drm_pci_alloc(drm_device_t * dev, size_t size, size_t align, dma_addr_t maxaddr) { drm_dma_handle_t *dmah; -#if 1 - unsigned long addr; - size_t sz; -#endif #ifdef DRM_DEBUG_MEMORY int area = DRM_MEM_DMA; @@ -83,7 +79,7 @@ drm_dma_handle_t *drm_pci_alloc(drm_device_t * dev, size_t size, size_t align, return NULL; dmah->size = size; - dmah->vaddr = dma_alloc_coherent(&dev->pdev->dev, size, &dmah->busaddr, GFP_KERNEL | __GFP_COMP); + dmah->vaddr = pci_alloc_consistent(dev->pdev, size, &dmah->busaddr); #ifdef DRM_DEBUG_MEMORY if (dmah->vaddr == NULL) { @@ -108,29 +104,18 @@ drm_dma_handle_t *drm_pci_alloc(drm_device_t * dev, size_t size, size_t align, memset(dmah->vaddr, 0, size); - /* XXX - Is virt_to_page() legal for consistent mem? */ - /* Reserve */ - for (addr = (unsigned long)dmah->vaddr, sz = size; - sz > 0; addr += PAGE_SIZE, sz -= PAGE_SIZE) { - SetPageReserved(virt_to_page(addr)); - } - return dmah; } EXPORT_SYMBOL(drm_pci_alloc); /** - * \brief Free a PCI consistent memory block without freeing its descriptor. + * \brief Free a PCI consistent memory block with freeing its descriptor. * * This function is for internal use in the Linux-specific DRM core code. */ void __drm_pci_free(drm_device_t * dev, drm_dma_handle_t * dmah) { -#if 1 - unsigned long addr; - size_t sz; -#endif #ifdef DRM_DEBUG_MEMORY int area = DRM_MEM_DMA; int alloc_count; @@ -142,14 +127,8 @@ void __drm_pci_free(drm_device_t * dev, drm_dma_handle_t * dmah) DRM_MEM_ERROR(area, "Attempt to free address 0\n"); #endif } else { - /* XXX - Is virt_to_page() legal for consistent mem? */ - /* Unreserve */ - for (addr = (unsigned long)dmah->vaddr, sz = dmah->size; - sz > 0; addr += PAGE_SIZE, sz -= PAGE_SIZE) { - ClearPageReserved(virt_to_page(addr)); - } - dma_free_coherent(&dev->pdev->dev, dmah->size, dmah->vaddr, - dmah->busaddr); + pci_free_consistent(dev->pdev, dmah->size, dmah->vaddr, + dmah->busaddr); } #ifdef DRM_DEBUG_MEMORY diff --git a/trunk/drivers/char/drm/drm_pciids.h b/trunk/drivers/char/drm/drm_pciids.h index b1bb3c7b568d..2c17e88a8847 100644 --- a/trunk/drivers/char/drm/drm_pciids.h +++ b/trunk/drivers/char/drm/drm_pciids.h @@ -3,69 +3,49 @@ Please contact dri-devel@lists.sf.net to add new cards to this list */ #define radeon_PCI_IDS \ - {0x1002, 0x3150, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|CHIP_IS_MOBILITY}, \ - {0x1002, 0x3152, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|CHIP_IS_MOBILITY|CHIP_NEW_MEMMAP}, \ - {0x1002, 0x3154, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|CHIP_IS_MOBILITY|CHIP_NEW_MEMMAP}, \ - {0x1002, 0x3E50, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|CHIP_NEW_MEMMAP}, \ - {0x1002, 0x3E54, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|CHIP_NEW_MEMMAP}, \ + {0x1002, 0x3150, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350},\ {0x1002, 0x4136, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS100|CHIP_IS_IGP}, \ {0x1002, 0x4137, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS200|CHIP_IS_IGP}, \ {0x1002, 0x4144, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R300}, \ {0x1002, 0x4145, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R300}, \ {0x1002, 0x4146, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R300}, \ {0x1002, 0x4147, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R300}, \ - {0x1002, 0x4148, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R350}, \ - {0x1002, 0x4149, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R350}, \ - {0x1002, 0x414A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R350}, \ - {0x1002, 0x414B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R350}, \ {0x1002, 0x4150, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350}, \ {0x1002, 0x4151, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350}, \ {0x1002, 0x4152, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350}, \ {0x1002, 0x4153, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350}, \ {0x1002, 0x4154, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350}, \ - {0x1002, 0x4155, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350}, \ {0x1002, 0x4156, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350}, \ - {0x1002, 0x4237, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS200|CHIP_IS_IGP}, \ + {0x1002, 0x4237, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS250|CHIP_IS_IGP}, \ {0x1002, 0x4242, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R200}, \ {0x1002, 0x4243, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R200}, \ {0x1002, 0x4336, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS100|CHIP_IS_IGP|CHIP_IS_MOBILITY}, \ {0x1002, 0x4337, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS200|CHIP_IS_IGP|CHIP_IS_MOBILITY}, \ - {0x1002, 0x4437, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS200|CHIP_IS_IGP|CHIP_IS_MOBILITY}, \ - {0x1002, 0x4966, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV250}, \ - {0x1002, 0x4967, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV250}, \ - {0x1002, 0x4A48, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \ - {0x1002, 0x4A49, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \ - {0x1002, 0x4A4A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \ - {0x1002, 0x4A4B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \ - {0x1002, 0x4A4C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \ - {0x1002, 0x4A4D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \ - {0x1002, 0x4A4E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_IS_MOBILITY|CHIP_NEW_MEMMAP}, \ - {0x1002, 0x4A4F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \ - {0x1002, 0x4A50, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \ - {0x1002, 0x4A54, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \ - {0x1002, 0x4B49, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \ - {0x1002, 0x4B4A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \ - {0x1002, 0x4B4B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \ - {0x1002, 0x4B4C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \ + {0x1002, 0x4437, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS250|CHIP_IS_IGP|CHIP_IS_MOBILITY}, \ + {0x1002, 0x4964, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R250}, \ + {0x1002, 0x4965, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R250}, \ + {0x1002, 0x4966, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R250}, \ + {0x1002, 0x4967, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R250}, \ + {0x1002, 0x4A49, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420}, \ + {0x1002, 0x4A4B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420}, \ {0x1002, 0x4C57, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV200|CHIP_IS_MOBILITY}, \ {0x1002, 0x4C58, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV200|CHIP_IS_MOBILITY}, \ {0x1002, 0x4C59, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV100|CHIP_IS_MOBILITY}, \ {0x1002, 0x4C5A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV100|CHIP_IS_MOBILITY}, \ - {0x1002, 0x4C64, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV250|CHIP_IS_MOBILITY}, \ - {0x1002, 0x4C66, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV250|CHIP_IS_MOBILITY}, \ - {0x1002, 0x4C67, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV250|CHIP_IS_MOBILITY}, \ + {0x1002, 0x4C64, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R250|CHIP_IS_MOBILITY}, \ + {0x1002, 0x4C65, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R250|CHIP_IS_MOBILITY}, \ + {0x1002, 0x4C66, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R250|CHIP_IS_MOBILITY}, \ + {0x1002, 0x4C67, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R250|CHIP_IS_MOBILITY}, \ {0x1002, 0x4E44, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R300}, \ {0x1002, 0x4E45, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R300}, \ - {0x1002, 0x4E46, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R300}, \ + {0x1002, 0x4E46, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350}, \ {0x1002, 0x4E47, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R300}, \ {0x1002, 0x4E48, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R350}, \ {0x1002, 0x4E49, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R350}, \ - {0x1002, 0x4E4A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R350}, \ + {0x1002, 0x4E4A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350}, \ {0x1002, 0x4E4B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R350}, \ {0x1002, 0x4E50, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350|CHIP_IS_MOBILITY}, \ {0x1002, 0x4E51, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350|CHIP_IS_MOBILITY}, \ - {0x1002, 0x4E52, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350|CHIP_IS_MOBILITY}, \ - {0x1002, 0x4E53, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350|CHIP_IS_MOBILITY}, \ {0x1002, 0x4E54, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350|CHIP_IS_MOBILITY}, \ {0x1002, 0x4E56, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350|CHIP_IS_MOBILITY}, \ {0x1002, 0x5144, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R100|CHIP_SINGLE_CRTC}, \ @@ -73,66 +53,44 @@ {0x1002, 0x5146, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R100|CHIP_SINGLE_CRTC}, \ {0x1002, 0x5147, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R100|CHIP_SINGLE_CRTC}, \ {0x1002, 0x5148, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R200}, \ + {0x1002, 0x5149, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R200}, \ + {0x1002, 0x514A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R200}, \ + {0x1002, 0x514B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R200}, \ {0x1002, 0x514C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R200}, \ {0x1002, 0x514D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R200}, \ + {0x1002, 0x514E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R200}, \ + {0x1002, 0x514F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R200}, \ {0x1002, 0x5157, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV200}, \ {0x1002, 0x5158, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV200}, \ {0x1002, 0x5159, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV100}, \ {0x1002, 0x515A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV100}, \ {0x1002, 0x515E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV100}, \ - {0x1002, 0x5460, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|CHIP_IS_MOBILITY}, \ - {0x1002, 0x5462, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|CHIP_IS_MOBILITY}, \ - {0x1002, 0x5464, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|CHIP_IS_MOBILITY}, \ - {0x1002, 0x5548, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \ - {0x1002, 0x5549, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \ - {0x1002, 0x554A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \ - {0x1002, 0x554B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \ - {0x1002, 0x554C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \ - {0x1002, 0x554D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \ - {0x1002, 0x554E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \ - {0x1002, 0x554F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \ - {0x1002, 0x5550, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \ - {0x1002, 0x5551, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \ - {0x1002, 0x5552, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \ - {0x1002, 0x5554, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \ - {0x1002, 0x564A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|CHIP_IS_MOBILITY|CHIP_NEW_MEMMAP}, \ - {0x1002, 0x564B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|CHIP_IS_MOBILITY|CHIP_NEW_MEMMAP}, \ - {0x1002, 0x564F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|CHIP_IS_MOBILITY|CHIP_NEW_MEMMAP}, \ - {0x1002, 0x5652, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|CHIP_IS_MOBILITY|CHIP_NEW_MEMMAP}, \ - {0x1002, 0x5653, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|CHIP_IS_MOBILITY|CHIP_NEW_MEMMAP}, \ + {0x1002, 0x5168, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R200}, \ + {0x1002, 0x5169, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R200}, \ + {0x1002, 0x516A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R200}, \ + {0x1002, 0x516B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R200}, \ + {0x1002, 0x516C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R200}, \ + {0x1002, 0x5460, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350}, \ + {0x1002, 0x554F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R350}, \ {0x1002, 0x5834, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|CHIP_IS_IGP}, \ {0x1002, 0x5835, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|CHIP_IS_IGP|CHIP_IS_MOBILITY}, \ + {0x1002, 0x5836, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|CHIP_IS_IGP}, \ + {0x1002, 0x5837, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|CHIP_IS_IGP}, \ {0x1002, 0x5960, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \ {0x1002, 0x5961, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \ {0x1002, 0x5962, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \ + {0x1002, 0x5963, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \ {0x1002, 0x5964, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \ - {0x1002, 0x5965, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \ + {0x1002, 0x5968, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \ {0x1002, 0x5969, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV100}, \ - {0x1002, 0x5b60, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|CHIP_NEW_MEMMAP}, \ - {0x1002, 0x5b62, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|CHIP_NEW_MEMMAP}, \ - {0x1002, 0x5b63, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|CHIP_NEW_MEMMAP}, \ - {0x1002, 0x5b64, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|CHIP_NEW_MEMMAP}, \ - {0x1002, 0x5b65, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|CHIP_NEW_MEMMAP}, \ + {0x1002, 0x596A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \ + {0x1002, 0x596B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \ {0x1002, 0x5c61, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280|CHIP_IS_MOBILITY}, \ + {0x1002, 0x5c62, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \ {0x1002, 0x5c63, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280|CHIP_IS_MOBILITY}, \ - {0x1002, 0x5d48, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_IS_MOBILITY|CHIP_NEW_MEMMAP}, \ - {0x1002, 0x5d49, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_IS_MOBILITY|CHIP_NEW_MEMMAP}, \ - {0x1002, 0x5d4a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_IS_MOBILITY|CHIP_NEW_MEMMAP}, \ - {0x1002, 0x5d4c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \ - {0x1002, 0x5d4d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \ - {0x1002, 0x5d4e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \ - {0x1002, 0x5d4f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \ - {0x1002, 0x5d50, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \ - {0x1002, 0x5d52, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \ - {0x1002, 0x5d57, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \ - {0x1002, 0x5e48, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|CHIP_NEW_MEMMAP}, \ - {0x1002, 0x5e4a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|CHIP_NEW_MEMMAP}, \ - {0x1002, 0x5e4b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|CHIP_NEW_MEMMAP}, \ - {0x1002, 0x5e4c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|CHIP_NEW_MEMMAP}, \ - {0x1002, 0x5e4d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|CHIP_NEW_MEMMAP}, \ - {0x1002, 0x5e4f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|CHIP_NEW_MEMMAP}, \ - {0x1002, 0x7834, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|CHIP_IS_IGP|CHIP_NEW_MEMMAP}, \ - {0x1002, 0x7835, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|CHIP_IS_IGP|CHIP_IS_MOBILITY|CHIP_NEW_MEMMAP}, \ + {0x1002, 0x5c64, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \ + {0x1002, 0x5d4d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R350}, \ + {0x1002, 0x5e4b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420}, \ {0, 0, 0} #define r128_PCI_IDS \ diff --git a/trunk/drivers/char/drm/i915_dma.c b/trunk/drivers/char/drm/i915_dma.c index 9f4b8ce4c05e..1ff4c7ca0bff 100644 --- a/trunk/drivers/char/drm/i915_dma.c +++ b/trunk/drivers/char/drm/i915_dma.c @@ -495,6 +495,8 @@ static int i915_dispatch_batchbuffer(drm_device_t * dev, } } + dev_priv->sarea_priv->last_enqueue = dev_priv->counter++; + i915_emit_breadcrumb(dev); return 0; diff --git a/trunk/drivers/char/drm/i915_irq.c b/trunk/drivers/char/drm/i915_irq.c index a752afd86ab8..d3879ac9970f 100644 --- a/trunk/drivers/char/drm/i915_irq.c +++ b/trunk/drivers/char/drm/i915_irq.c @@ -53,8 +53,6 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) I915_WRITE16(I915REG_INT_IDENTITY_R, temp); - dev_priv->sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv); - if (temp & USER_INT_FLAG) DRM_WAKEUP(&dev_priv->irq_queue); diff --git a/trunk/drivers/char/drm/r300_cmdbuf.c b/trunk/drivers/char/drm/r300_cmdbuf.c index b108c7f913b2..c08fa5076f05 100644 --- a/trunk/drivers/char/drm/r300_cmdbuf.c +++ b/trunk/drivers/char/drm/r300_cmdbuf.c @@ -214,13 +214,13 @@ void r300_init_reg_flags(void) ADD_RANGE(0x4F54, 1); ADD_RANGE(R300_TX_FILTER_0, 16); - ADD_RANGE(R300_TX_FILTER1_0, 16); + ADD_RANGE(R300_TX_UNK1_0, 16); ADD_RANGE(R300_TX_SIZE_0, 16); ADD_RANGE(R300_TX_FORMAT_0, 16); ADD_RANGE(R300_TX_PITCH_0, 16); /* Texture offset is dangerous and needs more checking */ ADD_RANGE_MARK(R300_TX_OFFSET_0, 16, MARK_CHECK_OFFSET); - ADD_RANGE(R300_TX_CHROMA_KEY_0, 16); + ADD_RANGE(R300_TX_UNK4_0, 16); ADD_RANGE(R300_TX_BORDER_COLOR_0, 16); /* Sporadic registers used as primitives are emitted */ @@ -242,10 +242,8 @@ static __inline__ int r300_check_range(unsigned reg, int count) return 0; } -/* - * we expect offsets passed to the framebuffer to be either within video - * memory or within AGP space - */ + /* we expect offsets passed to the framebuffer to be either within video memory or + within AGP space */ static __inline__ int r300_check_offset(drm_radeon_private_t *dev_priv, u32 offset) { @@ -253,11 +251,11 @@ static __inline__ int r300_check_offset(drm_radeon_private_t *dev_priv, but this value is not being kept. This code is correct for now (does the same thing as the code that sets MC_FB_LOCATION) in radeon_cp.c */ - if (offset >= dev_priv->fb_location && - offset < (dev_priv->fb_location + dev_priv->fb_size)) + if ((offset >= dev_priv->fb_location) && + (offset < dev_priv->gart_vm_start)) return 0; - if (offset >= dev_priv->gart_vm_start && - offset < (dev_priv->gart_vm_start + dev_priv->gart_size)) + if ((offset >= dev_priv->gart_vm_start) && + (offset < dev_priv->gart_vm_start + dev_priv->gart_size)) return 0; return 1; } @@ -492,7 +490,6 @@ static __inline__ int r300_emit_3d_load_vbpntr(drm_radeon_private_t *dev_priv, return 0; } - static __inline__ int r300_emit_bitblt_multi(drm_radeon_private_t *dev_priv, drm_radeon_kcmd_buffer_t *cmdbuf) { @@ -704,64 +701,6 @@ static void r300_discard_buffer(drm_device_t * dev, drm_buf_t * buf) buf->used = 0; } -static int r300_scratch(drm_radeon_private_t *dev_priv, - drm_radeon_kcmd_buffer_t *cmdbuf, - drm_r300_cmd_header_t header) -{ - u32 *ref_age_base; - u32 i, buf_idx, h_pending; - RING_LOCALS; - - if (cmdbuf->bufsz < - (sizeof(u64) + header.scratch.n_bufs * sizeof(buf_idx))) { - return DRM_ERR(EINVAL); - } - - if (header.scratch.reg >= 5) { - return DRM_ERR(EINVAL); - } - - dev_priv->scratch_ages[header.scratch.reg]++; - - ref_age_base = *(u32 **)cmdbuf->buf; - - cmdbuf->buf += sizeof(u64); - cmdbuf->bufsz -= sizeof(u64); - - for (i=0; i < header.scratch.n_bufs; i++) { - buf_idx = *(u32 *)cmdbuf->buf; - buf_idx *= 2; /* 8 bytes per buf */ - - if (DRM_COPY_TO_USER(ref_age_base + buf_idx, &dev_priv->scratch_ages[header.scratch.reg], sizeof(u32))) { - return DRM_ERR(EINVAL); - } - - if (DRM_COPY_FROM_USER(&h_pending, ref_age_base + buf_idx + 1, sizeof(u32))) { - return DRM_ERR(EINVAL); - } - - if (h_pending == 0) { - return DRM_ERR(EINVAL); - } - - h_pending--; - - if (DRM_COPY_TO_USER(ref_age_base + buf_idx + 1, &h_pending, sizeof(u32))) { - return DRM_ERR(EINVAL); - } - - cmdbuf->buf += sizeof(buf_idx); - cmdbuf->bufsz -= sizeof(buf_idx); - } - - BEGIN_RING(2); - OUT_RING(CP_PACKET0(RADEON_SCRATCH_REG0 + header.scratch.reg * 4, 0)); - OUT_RING(dev_priv->scratch_ages[header.scratch.reg]); - ADVANCE_RING(); - - return 0; -} - /** * Parses and validates a user-supplied command buffer and emits appropriate * commands on the DMA ring buffer. @@ -899,15 +838,6 @@ int r300_do_cp_cmdbuf(drm_device_t *dev, } break; - case R300_CMD_SCRATCH: - DRM_DEBUG("R300_CMD_SCRATCH\n"); - ret = r300_scratch(dev_priv, cmdbuf, header); - if (ret) { - DRM_ERROR("r300_scratch failed\n"); - goto cleanup; - } - break; - default: DRM_ERROR("bad cmd_type %i at %p\n", header.header.cmd_type, diff --git a/trunk/drivers/char/drm/r300_reg.h b/trunk/drivers/char/drm/r300_reg.h index a881f96c983e..d1e19954406b 100644 --- a/trunk/drivers/char/drm/r300_reg.h +++ b/trunk/drivers/char/drm/r300_reg.h @@ -711,22 +711,8 @@ I am fairly certain that they are correct unless stated otherwise in comments. # define R300_TX_MAX_ANISO_16_TO_1 (8 << 21) # define R300_TX_MAX_ANISO_MASK (14 << 21) -#define R300_TX_FILTER1_0 0x4440 -# define R300_CHROMA_KEY_MODE_DISABLE 0 -# define R300_CHROMA_KEY_FORCE 1 -# define R300_CHROMA_KEY_BLEND 2 -# define R300_MC_ROUND_NORMAL (0<<2) -# define R300_MC_ROUND_MPEG4 (1<<2) +#define R300_TX_UNK1_0 0x4440 # define R300_LOD_BIAS_MASK 0x1fff -# define R300_EDGE_ANISO_EDGE_DIAG (0<<13) -# define R300_EDGE_ANISO_EDGE_ONLY (1<<13) -# define R300_MC_COORD_TRUNCATE_DISABLE (0<<14) -# define R300_MC_COORD_TRUNCATE_MPEG (1<<14) -# define R300_TX_TRI_PERF_0_8 (0<<15) -# define R300_TX_TRI_PERF_1_8 (1<<15) -# define R300_TX_TRI_PERF_1_4 (2<<15) -# define R300_TX_TRI_PERF_3_8 (3<<15) -# define R300_ANISO_THRESHOLD_MASK (7<<17) #define R300_TX_SIZE_0 0x4480 # define R300_TX_WIDTHMASK_SHIFT 0 @@ -736,8 +722,6 @@ I am fairly certain that they are correct unless stated otherwise in comments. # define R300_TX_UNK23 (1 << 23) # define R300_TX_SIZE_SHIFT 26 /* largest of width, height */ # define R300_TX_SIZE_MASK (15 << 26) -# define R300_TX_SIZE_PROJECTED (1<<30) -# define R300_TX_SIZE_TXPITCH_EN (1<<31) #define R300_TX_FORMAT_0 0x44C0 /* The interpretation of the format word by Wladimir van der Laan */ /* The X, Y, Z and W refer to the layout of the components. @@ -766,8 +750,7 @@ I am fairly certain that they are correct unless stated otherwise in comments. # define R300_TX_FORMAT_B8G8_B8G8 0x14 /* no swizzle */ # define R300_TX_FORMAT_G8R8_G8B8 0x15 /* no swizzle */ /* 0x16 - some 16 bit green format.. ?? */ -# define R300_TX_FORMAT_UNK25 (1 << 25) /* no swizzle */ -# define R300_TX_FORMAT_CUBIC_MAP (1 << 26) +# define R300_TX_FORMAT_UNK25 (1 << 25) /* no swizzle */ /* gap */ /* Floating point formats */ @@ -817,20 +800,18 @@ I am fairly certain that they are correct unless stated otherwise in comments. # define R300_TX_FORMAT_YUV_MODE 0x00800000 -#define R300_TX_PITCH_0 0x4500 /* obvious missing in gap */ +#define R300_TX_PITCH_0 0x4500 #define R300_TX_OFFSET_0 0x4540 /* BEGIN: Guess from R200 */ # define R300_TXO_ENDIAN_NO_SWAP (0 << 0) # define R300_TXO_ENDIAN_BYTE_SWAP (1 << 0) # define R300_TXO_ENDIAN_WORD_SWAP (2 << 0) # define R300_TXO_ENDIAN_HALFDW_SWAP (3 << 0) -# define R300_TXO_MACRO_TILE (1 << 2) -# define R300_TXO_MICRO_TILE (1 << 3) # define R300_TXO_OFFSET_MASK 0xffffffe0 # define R300_TXO_OFFSET_SHIFT 5 /* END */ -#define R300_TX_CHROMA_KEY_0 0x4580 /* 32 bit chroma key */ -#define R300_TX_BORDER_COLOR_0 0x45C0 //ff00ff00 == { 0, 1.0, 0, 1.0 } +#define R300_TX_UNK4_0 0x4580 +#define R300_TX_BORDER_COLOR_0 0x45C0 //ff00ff00 == { 0, 1.0, 0, 1.0 } /* END */ @@ -887,9 +868,7 @@ I am fairly certain that they are correct unless stated otherwise in comments. # define R300_PFS_NODE_TEX_OFFSET_MASK (31 << 12) # define R300_PFS_NODE_TEX_END_SHIFT 17 # define R300_PFS_NODE_TEX_END_MASK (31 << 17) -/*# define R300_PFS_NODE_LAST_NODE (1 << 22) */ -# define R300_PFS_NODE_OUTPUT_COLOR (1 << 22) -# define R300_PFS_NODE_OUTPUT_DEPTH (1 << 23) +# define R300_PFS_NODE_LAST_NODE (1 << 22) /* TEX // As far as I can tell, texture instructions cannot write into output @@ -908,7 +887,6 @@ I am fairly certain that they are correct unless stated otherwise in comments. */ # define R300_FPITX_OPCODE_SHIFT 15 # define R300_FPITX_OP_TEX 1 -# define R300_FPITX_OP_KIL 2 # define R300_FPITX_OP_TXP 3 # define R300_FPITX_OP_TXB 4 @@ -984,11 +962,9 @@ I am fairly certain that they are correct unless stated otherwise in comments. # define R300_FPI1_SRC2C_CONST (1 << 17) # define R300_FPI1_DSTC_SHIFT 18 # define R300_FPI1_DSTC_MASK (31 << 18) -# define R300_FPI1_DSTC_REG_MASK_SHIFT 23 # define R300_FPI1_DSTC_REG_X (1 << 23) # define R300_FPI1_DSTC_REG_Y (1 << 24) # define R300_FPI1_DSTC_REG_Z (1 << 25) -# define R300_FPI1_DSTC_OUTPUT_MASK_SHIFT 26 # define R300_FPI1_DSTC_OUTPUT_X (1 << 26) # define R300_FPI1_DSTC_OUTPUT_Y (1 << 27) # define R300_FPI1_DSTC_OUTPUT_Z (1 << 28) @@ -1007,7 +983,6 @@ I am fairly certain that they are correct unless stated otherwise in comments. # define R300_FPI3_DSTA_MASK (31 << 18) # define R300_FPI3_DSTA_REG (1 << 23) # define R300_FPI3_DSTA_OUTPUT (1 << 24) -# define R300_FPI3_DSTA_DEPTH (1 << 27) #define R300_PFS_INSTR0_0 0x48C0 # define R300_FPI0_ARGC_SRC0C_XYZ 0 @@ -1061,7 +1036,7 @@ I am fairly certain that they are correct unless stated otherwise in comments. # define R300_FPI0_OUTC_FRC (9 << 23) # define R300_FPI0_OUTC_REPL_ALPHA (10 << 23) # define R300_FPI0_OUTC_SAT (1 << 30) -# define R300_FPI0_INSERT_NOP (1 << 31) +# define R300_FPI0_UNKNOWN_31 (1 << 31) #define R300_PFS_INSTR2_0 0x49C0 # define R300_FPI2_ARGA_SRC0C_X 0 diff --git a/trunk/drivers/char/drm/radeon_cp.c b/trunk/drivers/char/drm/radeon_cp.c index 7f949c9c9691..9bb8ae0c1c27 100644 --- a/trunk/drivers/char/drm/radeon_cp.c +++ b/trunk/drivers/char/drm/radeon_cp.c @@ -1118,20 +1118,14 @@ static void radeon_cp_init_ring_buffer(drm_device_t * dev, { u32 ring_start, cur_read_ptr; u32 tmp; - - /* Initialize the memory controller. With new memory map, the fb location - * is not changed, it should have been properly initialized already. Part - * of the problem is that the code below is bogus, assuming the GART is - * always appended to the fb which is not necessarily the case - */ - if (!dev_priv->new_memmap) - RADEON_WRITE(RADEON_MC_FB_LOCATION, - ((dev_priv->gart_vm_start - 1) & 0xffff0000) - | (dev_priv->fb_location >> 16)); + + /* Initialize the memory controller */ + RADEON_WRITE(RADEON_MC_FB_LOCATION, + ((dev_priv->gart_vm_start - 1) & 0xffff0000) + | (dev_priv->fb_location >> 16)); #if __OS_HAS_AGP if (dev_priv->flags & CHIP_IS_AGP) { - RADEON_WRITE(RADEON_AGP_BASE, (unsigned int)dev->agp->base); RADEON_WRITE(RADEON_MC_AGP_LOCATION, (((dev_priv->gart_vm_start - 1 + dev_priv->gart_size) & 0xffff0000) | @@ -1159,6 +1153,8 @@ static void radeon_cp_init_ring_buffer(drm_device_t * dev, #if __OS_HAS_AGP if (dev_priv->flags & CHIP_IS_AGP) { + /* set RADEON_AGP_BASE here instead of relying on X from user space */ + RADEON_WRITE(RADEON_AGP_BASE, (unsigned int)dev->agp->base); RADEON_WRITE(RADEON_CP_RB_RPTR_ADDR, dev_priv->ring_rptr->offset - dev->agp->base + dev_priv->gart_vm_start); @@ -1178,17 +1174,6 @@ static void radeon_cp_init_ring_buffer(drm_device_t * dev, entry->handle + tmp_ofs); } - /* Set ring buffer size */ -#ifdef __BIG_ENDIAN - RADEON_WRITE(RADEON_CP_RB_CNTL, - dev_priv->ring.size_l2qw | RADEON_BUF_SWAP_32BIT); -#else - RADEON_WRITE(RADEON_CP_RB_CNTL, dev_priv->ring.size_l2qw); -#endif - - /* Start with assuming that writeback doesn't work */ - dev_priv->writeback_works = 0; - /* Initialize the scratch register pointer. This will cause * the scratch register values to be written out to memory * whenever they are updated. @@ -1205,9 +1190,28 @@ static void radeon_cp_init_ring_buffer(drm_device_t * dev, RADEON_WRITE(RADEON_SCRATCH_UMSK, 0x7); - /* Turn on bus mastering */ - tmp = RADEON_READ(RADEON_BUS_CNTL) & ~RADEON_BUS_MASTER_DIS; - RADEON_WRITE(RADEON_BUS_CNTL, tmp); + /* Writeback doesn't seem to work everywhere, test it first */ + DRM_WRITE32(dev_priv->ring_rptr, RADEON_SCRATCHOFF(1), 0); + RADEON_WRITE(RADEON_SCRATCH_REG1, 0xdeadbeef); + + for (tmp = 0; tmp < dev_priv->usec_timeout; tmp++) { + if (DRM_READ32(dev_priv->ring_rptr, RADEON_SCRATCHOFF(1)) == + 0xdeadbeef) + break; + DRM_UDELAY(1); + } + + if (tmp < dev_priv->usec_timeout) { + dev_priv->writeback_works = 1; + DRM_DEBUG("writeback test succeeded, tmp=%d\n", tmp); + } else { + dev_priv->writeback_works = 0; + DRM_DEBUG("writeback test failed\n"); + } + if (radeon_no_wb == 1) { + dev_priv->writeback_works = 0; + DRM_DEBUG("writeback forced off\n"); + } dev_priv->sarea_priv->last_frame = dev_priv->scratch[0] = 0; RADEON_WRITE(RADEON_LAST_FRAME_REG, dev_priv->sarea_priv->last_frame); @@ -1219,45 +1223,26 @@ static void radeon_cp_init_ring_buffer(drm_device_t * dev, dev_priv->sarea_priv->last_clear = dev_priv->scratch[2] = 0; RADEON_WRITE(RADEON_LAST_CLEAR_REG, dev_priv->sarea_priv->last_clear); + /* Set ring buffer size */ +#ifdef __BIG_ENDIAN + RADEON_WRITE(RADEON_CP_RB_CNTL, + dev_priv->ring.size_l2qw | RADEON_BUF_SWAP_32BIT); +#else + RADEON_WRITE(RADEON_CP_RB_CNTL, dev_priv->ring.size_l2qw); +#endif + radeon_do_wait_for_idle(dev_priv); + /* Turn on bus mastering */ + tmp = RADEON_READ(RADEON_BUS_CNTL) & ~RADEON_BUS_MASTER_DIS; + RADEON_WRITE(RADEON_BUS_CNTL, tmp); + /* Sync everything up */ RADEON_WRITE(RADEON_ISYNC_CNTL, (RADEON_ISYNC_ANY2D_IDLE3D | RADEON_ISYNC_ANY3D_IDLE2D | RADEON_ISYNC_WAIT_IDLEGUI | RADEON_ISYNC_CPSCRATCH_IDLEGUI)); - -} - -static void radeon_test_writeback(drm_radeon_private_t * dev_priv) -{ - u32 tmp; - - /* Writeback doesn't seem to work everywhere, test it here and possibly - * enable it if it appears to work - */ - DRM_WRITE32(dev_priv->ring_rptr, RADEON_SCRATCHOFF(1), 0); - RADEON_WRITE(RADEON_SCRATCH_REG1, 0xdeadbeef); - - for (tmp = 0; tmp < dev_priv->usec_timeout; tmp++) { - if (DRM_READ32(dev_priv->ring_rptr, RADEON_SCRATCHOFF(1)) == - 0xdeadbeef) - break; - DRM_UDELAY(1); - } - - if (tmp < dev_priv->usec_timeout) { - dev_priv->writeback_works = 1; - DRM_INFO("writeback test succeeded in %d usecs\n", tmp); - } else { - dev_priv->writeback_works = 0; - DRM_INFO("writeback test failed\n"); - } - if (radeon_no_wb == 1) { - dev_priv->writeback_works = 0; - DRM_INFO("writeback forced off\n"); - } } /* Enable or disable PCI-E GART on the chip */ @@ -1332,14 +1317,6 @@ static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init) DRM_DEBUG("\n"); - /* if we require new memory map but we don't have it fail */ - if ((dev_priv->flags & CHIP_NEW_MEMMAP) && !dev_priv->new_memmap) - { - DRM_ERROR("Cannot initialise DRM on this card\nThis card requires a new X.org DDX\n"); - radeon_do_cleanup_cp(dev); - return DRM_ERR(EINVAL); - } - if (init->is_pci && (dev_priv->flags & CHIP_IS_AGP)) { DRM_DEBUG("Forcing AGP card to PCI mode\n"); @@ -1519,9 +1496,6 @@ static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init) dev_priv->fb_location = (RADEON_READ(RADEON_MC_FB_LOCATION) & 0xffff) << 16; - dev_priv->fb_size = - ((RADEON_READ(RADEON_MC_FB_LOCATION) & 0xffff0000u) + 0x10000) - - dev_priv->fb_location; dev_priv->front_pitch_offset = (((dev_priv->front_pitch / 64) << 22) | ((dev_priv->front_offset @@ -1536,46 +1510,8 @@ static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init) + dev_priv->fb_location) >> 10)); dev_priv->gart_size = init->gart_size; - - /* New let's set the memory map ... */ - if (dev_priv->new_memmap) { - u32 base = 0; - - DRM_INFO("Setting GART location based on new memory map\n"); - - /* If using AGP, try to locate the AGP aperture at the same - * location in the card and on the bus, though we have to - * align it down. - */ -#if __OS_HAS_AGP - if (dev_priv->flags & CHIP_IS_AGP) { - base = dev->agp->base; - /* Check if valid */ - if ((base + dev_priv->gart_size) > dev_priv->fb_location && - base < (dev_priv->fb_location + dev_priv->fb_size)) { - DRM_INFO("Can't use AGP base @0x%08lx, won't fit\n", - dev->agp->base); - base = 0; - } - } -#endif - /* If not or if AGP is at 0 (Macs), try to put it elsewhere */ - if (base == 0) { - base = dev_priv->fb_location + dev_priv->fb_size; - if (((base + dev_priv->gart_size) & 0xfffffffful) - < base) - base = dev_priv->fb_location - - dev_priv->gart_size; - } - dev_priv->gart_vm_start = base & 0xffc00000u; - if (dev_priv->gart_vm_start != base) - DRM_INFO("GART aligned down from 0x%08x to 0x%08x\n", - base, dev_priv->gart_vm_start); - } else { - DRM_INFO("Setting GART location based on old memory map\n"); - dev_priv->gart_vm_start = dev_priv->fb_location + - RADEON_READ(RADEON_CONFIG_APER_SIZE); - } + dev_priv->gart_vm_start = dev_priv->fb_location + + RADEON_READ(RADEON_CONFIG_APER_SIZE); #if __OS_HAS_AGP if (dev_priv->flags & CHIP_IS_AGP) @@ -1660,7 +1596,6 @@ static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init) dev_priv->last_buf = 0; radeon_do_engine_reset(dev); - radeon_test_writeback(dev_priv); return 0; } diff --git a/trunk/drivers/char/drm/radeon_drm.h b/trunk/drivers/char/drm/radeon_drm.h index c8e279e89c2e..9c177a6b2a4c 100644 --- a/trunk/drivers/char/drm/radeon_drm.h +++ b/trunk/drivers/char/drm/radeon_drm.h @@ -222,7 +222,6 @@ typedef union { # define R300_WAIT_3D 0x2 # define R300_WAIT_2D_CLEAN 0x3 # define R300_WAIT_3D_CLEAN 0x4 -#define R300_CMD_SCRATCH 8 typedef union { unsigned int u; @@ -248,9 +247,6 @@ typedef union { struct { unsigned char cmd_type, flags, pad0, pad1; } wait; - struct { - unsigned char cmd_type, reg, n_bufs, flags; - } scratch; } drm_r300_cmd_header_t; #define RADEON_FRONT 0x1 @@ -701,7 +697,6 @@ typedef struct drm_radeon_setparam { #define RADEON_SETPARAM_FB_LOCATION 1 /* determined framebuffer location */ #define RADEON_SETPARAM_SWITCH_TILING 2 /* enable/disable color tiling */ #define RADEON_SETPARAM_PCIGART_LOCATION 3 /* PCI Gart Location */ -#define RADEON_SETPARAM_NEW_MEMMAP 4 /* Use new memory map */ /* 1.14: Clients can allocate/free a surface */ diff --git a/trunk/drivers/char/drm/radeon_drv.h b/trunk/drivers/char/drm/radeon_drv.h index 78345cee8f8e..1f7d2ab8c4fc 100644 --- a/trunk/drivers/char/drm/radeon_drv.h +++ b/trunk/drivers/char/drm/radeon_drv.h @@ -38,7 +38,7 @@ #define DRIVER_NAME "radeon" #define DRIVER_DESC "ATI Radeon" -#define DRIVER_DATE "20060225" +#define DRIVER_DATE "20051229" /* Interface history: * @@ -91,11 +91,9 @@ * 1.20- Add support for r300 texrect * 1.21- Add support for card type getparam * 1.22- Add support for texture cache flushes (R300_TX_CNTL) - * 1.23- Add new radeon memory map work from benh - * 1.24- Add general-purpose packet for manipulating scratch registers (r300) */ #define DRIVER_MAJOR 1 -#define DRIVER_MINOR 24 +#define DRIVER_MINOR 22 #define DRIVER_PATCHLEVEL 0 /* @@ -103,21 +101,20 @@ */ enum radeon_family { CHIP_R100, - CHIP_RV100, CHIP_RS100, + CHIP_RV100, CHIP_RV200, - CHIP_RS200, CHIP_R200, + CHIP_RS200, + CHIP_R250, + CHIP_RS250, CHIP_RV250, - CHIP_RS300, CHIP_RV280, CHIP_R300, + CHIP_RS300, CHIP_R350, CHIP_RV350, - CHIP_RV380, CHIP_R420, - CHIP_RV410, - CHIP_RS400, CHIP_LAST, }; @@ -139,11 +136,9 @@ enum radeon_chip_flags { CHIP_IS_AGP = 0x00080000UL, CHIP_HAS_HIERZ = 0x00100000UL, CHIP_IS_PCIE = 0x00200000UL, - CHIP_NEW_MEMMAP = 0x00400000UL, }; -#define GET_RING_HEAD(dev_priv) (dev_priv->writeback_works ? \ - DRM_READ32( (dev_priv)->ring_rptr, 0 ) : RADEON_READ(RADEON_CP_RB_RPTR)) +#define GET_RING_HEAD(dev_priv) DRM_READ32( (dev_priv)->ring_rptr, 0 ) #define SET_RING_HEAD(dev_priv,val) DRM_WRITE32( (dev_priv)->ring_rptr, 0, (val) ) typedef struct drm_radeon_freelist { @@ -204,8 +199,6 @@ typedef struct drm_radeon_private { drm_radeon_sarea_t *sarea_priv; u32 fb_location; - u32 fb_size; - int new_memmap; int gart_size; u32 gart_vm_start; @@ -279,8 +272,6 @@ typedef struct drm_radeon_private { unsigned long pcigart_offset; drm_ati_pcigart_info gart_info; - u32 scratch_ages[5]; - /* starting from here on, data is preserved accross an open */ uint32_t flags; /* see radeon_chip_flags */ } drm_radeon_private_t; diff --git a/trunk/drivers/char/drm/radeon_state.c b/trunk/drivers/char/drm/radeon_state.c index c5b8f774a599..7bc27516d425 100644 --- a/trunk/drivers/char/drm/radeon_state.c +++ b/trunk/drivers/char/drm/radeon_state.c @@ -45,53 +45,22 @@ static __inline__ int radeon_check_and_fixup_offset(drm_radeon_private_t * u32 off = *offset; struct drm_radeon_driver_file_fields *radeon_priv; - /* Hrm ... the story of the offset ... So this function converts - * the various ideas of what userland clients might have for an - * offset in the card address space into an offset into the card - * address space :) So with a sane client, it should just keep - * the value intact and just do some boundary checking. However, - * not all clients are sane. Some older clients pass us 0 based - * offsets relative to the start of the framebuffer and some may - * assume the AGP aperture it appended to the framebuffer, so we - * try to detect those cases and fix them up. - * - * Note: It might be a good idea here to make sure the offset lands - * in some "allowed" area to protect things like the PCIE GART... - */ - - /* First, the best case, the offset already lands in either the - * framebuffer or the GART mapped space - */ - if ((off >= dev_priv->fb_location && - off < (dev_priv->fb_location + dev_priv->fb_size)) || - (off >= dev_priv->gart_vm_start && - off < (dev_priv->gart_vm_start + dev_priv->gart_size))) + if (off >= dev_priv->fb_location && + off < (dev_priv->gart_vm_start + dev_priv->gart_size)) return 0; - /* Ok, that didn't happen... now check if we have a zero based - * offset that fits in the framebuffer + gart space, apply the - * magic offset we get from SETPARAM or calculated from fb_location - */ - if (off < (dev_priv->fb_size + dev_priv->gart_size)) { - radeon_priv = filp_priv->driver_priv; - off += radeon_priv->radeon_fb_delta; - } + radeon_priv = filp_priv->driver_priv; + off += radeon_priv->radeon_fb_delta; - /* Finally, assume we aimed at a GART offset if beyond the fb */ - if (off > (dev_priv->fb_location + dev_priv->fb_size)) - off = off - (dev_priv->fb_location + dev_priv->fb_size) + - dev_priv->gart_vm_start; + DRM_DEBUG("offset fixed up to 0x%x\n", off); - /* Now recheck and fail if out of bounds */ - if ((off >= dev_priv->fb_location && - off < (dev_priv->fb_location + dev_priv->fb_size)) || - (off >= dev_priv->gart_vm_start && - off < (dev_priv->gart_vm_start + dev_priv->gart_size))) { - DRM_DEBUG("offset fixed up to 0x%x\n", off); - *offset = off; - return 0; - } - return DRM_ERR(EINVAL); + if (off < dev_priv->fb_location || + off >= (dev_priv->gart_vm_start + dev_priv->gart_size)) + return DRM_ERR(EINVAL); + + *offset = off; + + return 0; } static __inline__ int radeon_check_and_fixup_packets(drm_radeon_private_t * @@ -1970,6 +1939,11 @@ static int radeon_surface_alloc(DRM_IOCTL_ARGS) drm_radeon_private_t *dev_priv = dev->dev_private; drm_radeon_surface_alloc_t alloc; + if (!dev_priv) { + DRM_ERROR("%s called with no initialization\n", __FUNCTION__); + return DRM_ERR(EINVAL); + } + DRM_COPY_FROM_USER_IOCTL(alloc, (drm_radeon_surface_alloc_t __user *) data, sizeof(alloc)); @@ -1986,7 +1960,12 @@ static int radeon_surface_free(DRM_IOCTL_ARGS) drm_radeon_private_t *dev_priv = dev->dev_private; drm_radeon_surface_free_t memfree; - DRM_COPY_FROM_USER_IOCTL(memfree, (drm_radeon_surface_free_t __user *) data, + if (!dev_priv) { + DRM_ERROR("%s called with no initialization\n", __FUNCTION__); + return DRM_ERR(EINVAL); + } + + DRM_COPY_FROM_USER_IOCTL(memfree, (drm_radeon_mem_free_t __user *) data, sizeof(memfree)); if (free_surface(filp, dev_priv, memfree.address)) @@ -2121,6 +2100,11 @@ static int radeon_cp_vertex(DRM_IOCTL_ARGS) LOCK_TEST_WITH_RETURN(dev, filp); + if (!dev_priv) { + DRM_ERROR("%s called with no initialization\n", __FUNCTION__); + return DRM_ERR(EINVAL); + } + DRM_GET_PRIV_WITH_RETURN(filp_priv, filp); DRM_COPY_FROM_USER_IOCTL(vertex, (drm_radeon_vertex_t __user *) data, @@ -2205,6 +2189,11 @@ static int radeon_cp_indices(DRM_IOCTL_ARGS) LOCK_TEST_WITH_RETURN(dev, filp); + if (!dev_priv) { + DRM_ERROR("%s called with no initialization\n", __FUNCTION__); + return DRM_ERR(EINVAL); + } + DRM_GET_PRIV_WITH_RETURN(filp_priv, filp); DRM_COPY_FROM_USER_IOCTL(elts, (drm_radeon_indices_t __user *) data, @@ -2351,6 +2340,11 @@ static int radeon_cp_indirect(DRM_IOCTL_ARGS) LOCK_TEST_WITH_RETURN(dev, filp); + if (!dev_priv) { + DRM_ERROR("%s called with no initialization\n", __FUNCTION__); + return DRM_ERR(EINVAL); + } + DRM_COPY_FROM_USER_IOCTL(indirect, (drm_radeon_indirect_t __user *) data, sizeof(indirect)); @@ -2423,6 +2417,11 @@ static int radeon_cp_vertex2(DRM_IOCTL_ARGS) LOCK_TEST_WITH_RETURN(dev, filp); + if (!dev_priv) { + DRM_ERROR("%s called with no initialization\n", __FUNCTION__); + return DRM_ERR(EINVAL); + } + DRM_GET_PRIV_WITH_RETURN(filp_priv, filp); DRM_COPY_FROM_USER_IOCTL(vertex, (drm_radeon_vertex2_t __user *) data, @@ -2739,6 +2738,11 @@ static int radeon_cp_cmdbuf(DRM_IOCTL_ARGS) LOCK_TEST_WITH_RETURN(dev, filp); + if (!dev_priv) { + DRM_ERROR("%s called with no initialization\n", __FUNCTION__); + return DRM_ERR(EINVAL); + } + DRM_GET_PRIV_WITH_RETURN(filp_priv, filp); DRM_COPY_FROM_USER_IOCTL(cmdbuf, @@ -2893,6 +2897,11 @@ static int radeon_cp_getparam(DRM_IOCTL_ARGS) drm_radeon_getparam_t param; int value; + if (!dev_priv) { + DRM_ERROR("%s called with no initialization\n", __FUNCTION__); + return DRM_ERR(EINVAL); + } + DRM_COPY_FROM_USER_IOCTL(param, (drm_radeon_getparam_t __user *) data, sizeof(param)); @@ -2972,6 +2981,11 @@ static int radeon_cp_setparam(DRM_IOCTL_ARGS) drm_radeon_setparam_t sp; struct drm_radeon_driver_file_fields *radeon_priv; + if (!dev_priv) { + DRM_ERROR("%s called with no initialization\n", __FUNCTION__); + return DRM_ERR(EINVAL); + } + DRM_GET_PRIV_WITH_RETURN(filp_priv, filp); DRM_COPY_FROM_USER_IOCTL(sp, (drm_radeon_setparam_t __user *) data, @@ -2998,9 +3012,6 @@ static int radeon_cp_setparam(DRM_IOCTL_ARGS) case RADEON_SETPARAM_PCIGART_LOCATION: dev_priv->pcigart_offset = sp.value; break; - case RADEON_SETPARAM_NEW_MEMMAP: - dev_priv->new_memmap = sp.value; - break; default: DRM_DEBUG("Invalid parameter %d\n", sp.param); return DRM_ERR(EINVAL); diff --git a/trunk/drivers/char/drm/sis_mm.c b/trunk/drivers/char/drm/sis_mm.c index 5e9936bc307f..6774d2fe3452 100644 --- a/trunk/drivers/char/drm/sis_mm.c +++ b/trunk/drivers/char/drm/sis_mm.c @@ -110,7 +110,7 @@ static int sis_fb_alloc(DRM_IOCTL_ARGS) DRM_COPY_TO_USER_IOCTL(argp, fb, sizeof(fb)); - DRM_DEBUG("alloc fb, size = %d, offset = %d\n", fb.size, req.offset); + DRM_DEBUG("alloc fb, size = %d, offset = %ld\n", fb.size, req.offset); return retval; } diff --git a/trunk/drivers/char/generic_nvram.c b/trunk/drivers/char/generic_nvram.c index 43ff59816511..1b5e01e6e129 100644 --- a/trunk/drivers/char/generic_nvram.c +++ b/trunk/drivers/char/generic_nvram.c @@ -22,9 +22,6 @@ #include #include #include -#ifdef CONFIG_PPC_PMAC -#include -#endif #define NVRAM_SIZE 8192 @@ -95,7 +92,7 @@ static int nvram_ioctl(struct inode *inode, struct file *file, case IOC_NVRAM_GET_OFFSET: { int part, offset; - if (!machine_is(powermac)) + if (_machine != _MACH_Pmac) return -EINVAL; if (copy_from_user(&part, (void __user*)arg, sizeof(part)) != 0) return -EFAULT; diff --git a/trunk/drivers/char/hvc_console.c b/trunk/drivers/char/hvc_console.c index 2b6a56b2bf35..f65b2e14a485 100644 --- a/trunk/drivers/char/hvc_console.c +++ b/trunk/drivers/char/hvc_console.c @@ -39,10 +39,8 @@ #include #include #include - #include - -#include "hvc_console.h" +#include #define HVC_MAJOR 229 #define HVC_MINOR 0 @@ -56,14 +54,17 @@ #define HVC_CLOSE_WAIT (HZ/100) /* 1/10 of a second */ /* - * These sizes are most efficient for vio, because they are the - * native transfer size. We could make them selectable in the - * future to better deal with backends that want other buffer sizes. + * The Linux TTY code does not support dynamic addition of tty derived devices + * so we need to know how many tty devices we might need when space is allocated + * for the tty device. Since this driver supports hotplug of vty adapters we + * need to make sure we have enough allocated. */ +#define HVC_ALLOC_TTY_ADAPTERS 8 + #define N_OUTBUF 16 #define N_INBUF 16 -#define __ALIGNED__ __attribute__((__aligned__(sizeof(long)))) +#define __ALIGNED__ __attribute__((__aligned__(8))) static struct tty_driver *hvc_driver; static struct task_struct *hvc_task; @@ -153,7 +154,7 @@ static uint32_t vtermnos[MAX_NR_HVC_CONSOLES] = void hvc_console_print(struct console *co, const char *b, unsigned count) { - char c[N_OUTBUF] __ALIGNED__; + char c[16] __ALIGNED__; unsigned i = 0, n = 0; int r, donecr = 0, index = co->index; @@ -472,10 +473,8 @@ static void hvc_push(struct hvc_struct *hp) n = hp->ops->put_chars(hp->vtermno, hp->outbuf, hp->n_outbuf); if (n <= 0) { - if (n == 0) { - hp->do_wakeup = 1; + if (n == 0) return; - } /* throw away output on error; this happens when there is no session connected to the vterm. */ hp->n_outbuf = 0; @@ -487,19 +486,12 @@ static void hvc_push(struct hvc_struct *hp) hp->do_wakeup = 1; } -static int hvc_write(struct tty_struct *tty, const unsigned char *buf, int count) +static inline int __hvc_write_kernel(struct hvc_struct *hp, + const unsigned char *buf, int count) { - struct hvc_struct *hp = tty->driver_data; unsigned long flags; int rsize, written = 0; - /* This write was probably executed during a tty close. */ - if (!hp) - return -EPIPE; - - if (hp->count <= 0) - return -EIO; - spin_lock_irqsave(&hp->lock, flags); /* Push pending writes */ @@ -518,8 +510,26 @@ static int hvc_write(struct tty_struct *tty, const unsigned char *buf, int count } spin_unlock_irqrestore(&hp->lock, flags); + return written; +} +static int hvc_write(struct tty_struct *tty, const unsigned char *buf, int count) +{ + struct hvc_struct *hp = tty->driver_data; + int written; + + /* This write was probably executed during a tty close. */ + if (!hp) + return -EPIPE; + + if (hp->count <= 0) + return -EIO; + + written = __hvc_write_kernel(hp, buf, count); + /* * Racy, but harmless, kick thread if there is still pending data. + * There really is nothing wrong with kicking the thread, even if there + * is no buffered data. */ if (hp->n_outbuf) hvc_kick(); @@ -604,13 +614,6 @@ static int hvc_poll(struct hvc_struct *hp) spin_unlock_irqrestore(&hp->lock, flags); tty_hangup(tty); spin_lock_irqsave(&hp->lock, flags); - } else if ( n == -EAGAIN ) { - /* - * Some back-ends can only ensure a certain min - * num of bytes read, which may be > 'count'. - * Let the tty clear the flip buff to make room. - */ - poll_mask |= HVC_POLL_READ; } break; } @@ -632,7 +635,16 @@ static int hvc_poll(struct hvc_struct *hp) tty_insert_flip_char(tty, buf[i], 0); } + /* + * Account for the total amount read in one loop, and if above + * 64 bytes, we do a quick schedule loop to let the tty grok + * the data and eventually throttle us. + */ read_total += n; + if (read_total >= 64) { + poll_mask |= HVC_POLL_QUICK; + break; + } } throttled: /* Wakeup write queue if necessary */ @@ -755,8 +767,7 @@ struct hvc_struct __devinit *hvc_alloc(uint32_t vtermno, int irq, * see if this vterm id matches one registered for console. */ for (i=0; i < MAX_NR_HVC_CONSOLES; i++) - if (vtermnos[i] == hp->vtermno && - cons_ops[i] == hp->ops) + if (vtermnos[i] == hp->vtermno) break; /* no matching slot, just use a counter */ @@ -812,38 +823,34 @@ EXPORT_SYMBOL(hvc_remove); * interfaces start to become available. */ int __init hvc_init(void) { - struct tty_driver *drv; - /* We need more than hvc_count adapters due to hotplug additions. */ - drv = alloc_tty_driver(HVC_ALLOC_TTY_ADAPTERS); - if (!drv) + hvc_driver = alloc_tty_driver(HVC_ALLOC_TTY_ADAPTERS); + if (!hvc_driver) return -ENOMEM; - drv->owner = THIS_MODULE; - drv->devfs_name = "hvc/"; - drv->driver_name = "hvc"; - drv->name = "hvc"; - drv->major = HVC_MAJOR; - drv->minor_start = HVC_MINOR; - drv->type = TTY_DRIVER_TYPE_SYSTEM; - drv->init_termios = tty_std_termios; - drv->flags = TTY_DRIVER_REAL_RAW; - tty_set_operations(drv, &hvc_ops); + hvc_driver->owner = THIS_MODULE; + hvc_driver->devfs_name = "hvc/"; + hvc_driver->driver_name = "hvc"; + hvc_driver->name = "hvc"; + hvc_driver->major = HVC_MAJOR; + hvc_driver->minor_start = HVC_MINOR; + hvc_driver->type = TTY_DRIVER_TYPE_SYSTEM; + hvc_driver->init_termios = tty_std_termios; + hvc_driver->flags = TTY_DRIVER_REAL_RAW; + tty_set_operations(hvc_driver, &hvc_ops); /* Always start the kthread because there can be hotplug vty adapters * added later. */ hvc_task = kthread_run(khvcd, NULL, "khvcd"); if (IS_ERR(hvc_task)) { panic("Couldn't create kthread for console.\n"); - put_tty_driver(drv); + put_tty_driver(hvc_driver); return -EIO; } - if (tty_register_driver(drv)) + if (tty_register_driver(hvc_driver)) panic("Couldn't register hvc console driver\n"); - mb(); - hvc_driver = drv; return 0; } module_init(hvc_init); diff --git a/trunk/drivers/char/hvc_console.h b/trunk/drivers/char/hvc_console.h deleted file mode 100644 index 96b7401319c1..000000000000 --- a/trunk/drivers/char/hvc_console.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - * hvc_console.h - * Copyright (C) 2005 IBM Corporation - * - * Author(s): - * Ryan S. Arnold - * - * hvc_console header information: - * moved here from include/asm-powerpc/hvconsole.h - * and drivers/char/hvc_console.c - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef HVC_CONSOLE_H -#define HVC_CONSOLE_H - -/* - * This is the max number of console adapters that can/will be found as - * console devices on first stage console init. Any number beyond this range - * can't be used as a console device but is still a valid tty device. - */ -#define MAX_NR_HVC_CONSOLES 16 - -/* - * The Linux TTY code does not support dynamic addition of tty derived devices - * so we need to know how many tty devices we might need when space is allocated - * for the tty device. Since this driver supports hotplug of vty adapters we - * need to make sure we have enough allocated. - */ -#define HVC_ALLOC_TTY_ADAPTERS 8 - - -/* implemented by a low level driver */ -struct hv_ops { - int (*get_chars)(uint32_t vtermno, char *buf, int count); - int (*put_chars)(uint32_t vtermno, const char *buf, int count); -}; - -struct hvc_struct; - -/* Register a vterm and a slot index for use as a console (console_init) */ -extern int hvc_instantiate(uint32_t vtermno, int index, struct hv_ops *ops); - -/* register a vterm for hvc tty operation (module_init or hotplug add) */ -extern struct hvc_struct * __devinit hvc_alloc(uint32_t vtermno, int irq, - struct hv_ops *ops); -/* remove a vterm from hvc tty operation (modele_exit or hotplug remove) */ -extern int __devexit hvc_remove(struct hvc_struct *hp); - -#endif // HVC_CONSOLE_H diff --git a/trunk/drivers/char/hvc_rtas.c b/trunk/drivers/char/hvc_rtas.c deleted file mode 100644 index 83364ea63cba..000000000000 --- a/trunk/drivers/char/hvc_rtas.c +++ /dev/null @@ -1,138 +0,0 @@ -/* - * IBM RTAS driver interface to hvc_console.c - * - * (C) Copyright IBM Corporation 2001-2005 - * (C) Copyright Red Hat, Inc. 2005 - * - * Author(s): Maximino Augilar - * : Ryan S. Arnold - * : Utz Bacher - * : David Woodhouse - * - * inspired by drivers/char/hvc_console.c - * written by Anton Blanchard and Paul Mackerras - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include -#include -#include -#include -#include - -#include -#include -#include "hvc_console.h" - -#define hvc_rtas_cookie 0x67781e15 -struct hvc_struct *hvc_rtas_dev; - -#define RTASCONS_PUT_ATTEMPTS 16 - -static int rtascons_put_char_token = RTAS_UNKNOWN_SERVICE; -static int rtascons_get_char_token = RTAS_UNKNOWN_SERVICE; -static int rtascons_put_delay = 100; -module_param_named(put_delay, rtascons_put_delay, int, 0644); - -static inline int hvc_rtas_write_console(uint32_t vtermno, const char *buf, int count) -{ - int done; - - /* if there is more than one character to be displayed, wait a bit */ - for (done = 0; done < count; done++) { - int result; - result = rtas_call(rtascons_put_char_token, 1, 1, NULL, buf[done]); - if (result) - break; - } - /* the calling routine expects to receive the number of bytes sent */ - return done; -} - -static int hvc_rtas_read_console(uint32_t vtermno, char *buf, int count) -{ - int i; - - for (i = 0; i < count; i++) { - int c, err; - - err = rtas_call(rtascons_get_char_token, 0, 2, &c); - if (err) - break; - - buf[i] = c; - } - - return i; -} - -static struct hv_ops hvc_rtas_get_put_ops = { - .get_chars = hvc_rtas_read_console, - .put_chars = hvc_rtas_write_console, -}; - -static int hvc_rtas_init(void) -{ - struct hvc_struct *hp; - - if (rtascons_put_char_token == RTAS_UNKNOWN_SERVICE) - rtascons_put_char_token = rtas_token("put-term-char"); - if (rtascons_put_char_token == RTAS_UNKNOWN_SERVICE) - return -EIO; - - if (rtascons_get_char_token == RTAS_UNKNOWN_SERVICE) - rtascons_get_char_token = rtas_token("get-term-char"); - if (rtascons_get_char_token == RTAS_UNKNOWN_SERVICE) - return -EIO; - - BUG_ON(hvc_rtas_dev); - - /* Allocate an hvc_struct for the console device we instantiated - * earlier. Save off hp so that we can return it on exit */ - hp = hvc_alloc(hvc_rtas_cookie, NO_IRQ, &hvc_rtas_get_put_ops); - if (IS_ERR(hp)) - return PTR_ERR(hp); - hvc_rtas_dev = hp; - return 0; -} -module_init(hvc_rtas_init); - -/* This will tear down the tty portion of the driver */ -static void __exit hvc_rtas_exit(void) -{ - /* Really the fun isn't over until the worker thread breaks down and the - * tty cleans up */ - if (hvc_rtas_dev) - hvc_remove(hvc_rtas_dev); -} -module_exit(hvc_rtas_exit); - -/* This will happen prior to module init. There is no tty at this time? */ -static int hvc_rtas_console_init(void) -{ - rtascons_put_char_token = rtas_token("put-term-char"); - if (rtascons_put_char_token == RTAS_UNKNOWN_SERVICE) - return -EIO; - rtascons_get_char_token = rtas_token("get-term-char"); - if (rtascons_get_char_token == RTAS_UNKNOWN_SERVICE) - return -EIO; - - hvc_instantiate(hvc_rtas_cookie, 0, &hvc_rtas_get_put_ops ); - add_preferred_console("hvc", 0, NULL); - return 0; -} -console_initcall(hvc_rtas_console_init); diff --git a/trunk/drivers/char/hvc_vio.c b/trunk/drivers/char/hvc_vio.c index 9add81ceb440..f5212eb2b41d 100644 --- a/trunk/drivers/char/hvc_vio.c +++ b/trunk/drivers/char/hvc_vio.c @@ -31,13 +31,10 @@ #include #include - #include #include #include -#include "hvc_console.h" - char hvc_driver_name[] = "hvc_console"; static struct vio_device_id hvc_driver_table[] __devinitdata = { @@ -51,14 +48,6 @@ static int filtered_get_chars(uint32_t vtermno, char *buf, int count) unsigned long got; int i; - /* - * Vio firmware will read up to SIZE_VIO_GET_CHARS at its own discretion - * so we play safe and avoid the situation where got > count which could - * overload the flip buffer. - */ - if (count < SIZE_VIO_GET_CHARS) - return -EAGAIN; - got = hvc_get_chars(vtermno, buf, count); /* diff --git a/trunk/drivers/char/hvcs.c b/trunk/drivers/char/hvcs.c index 327b00c3c45e..f7ac31856572 100644 --- a/trunk/drivers/char/hvcs.c +++ b/trunk/drivers/char/hvcs.c @@ -439,6 +439,7 @@ static int hvcs_io(struct hvcs_struct *hvcsd) char buf[HVCS_BUFF_LEN] __ALIGNED__; unsigned long flags; int got = 0; + int i; spin_lock_irqsave(&hvcsd->lock, flags); diff --git a/trunk/drivers/char/ipmi/ipmi_devintf.c b/trunk/drivers/char/ipmi/ipmi_devintf.c index e1c95374984c..932feedda262 100644 --- a/trunk/drivers/char/ipmi/ipmi_devintf.c +++ b/trunk/drivers/char/ipmi/ipmi_devintf.c @@ -42,7 +42,7 @@ #include #include #include -#include +#include #include #include #include @@ -55,7 +55,7 @@ struct ipmi_file_private struct file *file; struct fasync_struct *fasync_queue; wait_queue_head_t wait; - struct mutex recv_mutex; + struct semaphore recv_sem; int default_retries; unsigned int default_retry_time_ms; }; @@ -141,7 +141,7 @@ static int ipmi_open(struct inode *inode, struct file *file) INIT_LIST_HEAD(&(priv->recv_msgs)); init_waitqueue_head(&priv->wait); priv->fasync_queue = NULL; - mutex_init(&priv->recv_mutex); + sema_init(&(priv->recv_sem), 1); /* Use the low-level defaults. */ priv->default_retries = -1; @@ -285,15 +285,15 @@ static int ipmi_ioctl(struct inode *inode, break; } - /* We claim a mutex because we don't want two + /* We claim a semaphore because we don't want two users getting something from the queue at a time. Since we have to release the spinlock before we can copy the data to the user, it's possible another user will grab something from the queue, too. Then the messages might get out of order if something fails and the message gets put back onto the - queue. This mutex prevents that problem. */ - mutex_lock(&priv->recv_mutex); + queue. This semaphore prevents that problem. */ + down(&(priv->recv_sem)); /* Grab the message off the list. */ spin_lock_irqsave(&(priv->recv_msg_lock), flags); @@ -352,7 +352,7 @@ static int ipmi_ioctl(struct inode *inode, goto recv_putback_on_err; } - mutex_unlock(&priv->recv_mutex); + up(&(priv->recv_sem)); ipmi_free_recv_msg(msg); break; @@ -362,11 +362,11 @@ static int ipmi_ioctl(struct inode *inode, spin_lock_irqsave(&(priv->recv_msg_lock), flags); list_add(entry, &(priv->recv_msgs)); spin_unlock_irqrestore(&(priv->recv_msg_lock), flags); - mutex_unlock(&priv->recv_mutex); + up(&(priv->recv_sem)); break; recv_err: - mutex_unlock(&priv->recv_mutex); + up(&(priv->recv_sem)); break; } diff --git a/trunk/drivers/char/ipmi/ipmi_kcs_sm.c b/trunk/drivers/char/ipmi/ipmi_kcs_sm.c index 2062675f9e99..da1554194d3d 100644 --- a/trunk/drivers/char/ipmi/ipmi_kcs_sm.c +++ b/trunk/drivers/char/ipmi/ipmi_kcs_sm.c @@ -227,7 +227,7 @@ static inline int check_ibf(struct si_sm_data *kcs, unsigned char status, static inline int check_obf(struct si_sm_data *kcs, unsigned char status, long time) { - if (!GET_STATUS_OBF(status)) { + if (! GET_STATUS_OBF(status)) { kcs->obf_timeout -= time; if (kcs->obf_timeout < 0) { 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) } if (state == KCS_READ_STATE) { - if (!check_obf(kcs, status, time)) + if (! check_obf(kcs, status, time)) return SI_SM_CALL_WITH_DELAY; read_next_byte(kcs); } else { @@ -447,7 +447,7 @@ static enum si_sm_result kcs_event(struct si_sm_data *kcs, long time) "Not in read state for error2"); break; } - if (!check_obf(kcs, status, time)) + if (! check_obf(kcs, status, time)) return SI_SM_CALL_WITH_DELAY; clear_obf(kcs, status); @@ -462,7 +462,7 @@ static enum si_sm_result kcs_event(struct si_sm_data *kcs, long time) break; } - if (!check_obf(kcs, status, time)) + if (! check_obf(kcs, status, time)) return SI_SM_CALL_WITH_DELAY; clear_obf(kcs, status); diff --git a/trunk/drivers/char/ipmi/ipmi_msghandler.c b/trunk/drivers/char/ipmi/ipmi_msghandler.c index 0ded046d5aa8..40eb005b9d77 100644 --- a/trunk/drivers/char/ipmi/ipmi_msghandler.c +++ b/trunk/drivers/char/ipmi/ipmi_msghandler.c @@ -38,7 +38,6 @@ #include #include #include -#include #include #include #include @@ -235,7 +234,7 @@ struct ipmi_smi /* The list of command receivers that are registered for commands on this interface. */ - struct mutex cmd_rcvrs_mutex; + struct semaphore cmd_rcvrs_lock; struct list_head cmd_rcvrs; /* Events that were queues because no one was there to receive @@ -388,10 +387,10 @@ static void clean_up_interface_data(ipmi_smi_t intf) /* Wholesale remove all the entries from the list in the * interface and wait for RCU to know that none are in use. */ - mutex_lock(&intf->cmd_rcvrs_mutex); + down(&intf->cmd_rcvrs_lock); list_add_rcu(&list, &intf->cmd_rcvrs); list_del_rcu(&intf->cmd_rcvrs); - mutex_unlock(&intf->cmd_rcvrs_mutex); + up(&intf->cmd_rcvrs_lock); synchronize_rcu(); list_for_each_entry_safe(rcvr, rcvr2, &list, link) @@ -558,7 +557,7 @@ unsigned int ipmi_addr_length(int addr_type) static void deliver_response(struct ipmi_recv_msg *msg) { - if (!msg->user) { + if (! msg->user) { ipmi_smi_t intf = msg->user_msg_data; unsigned long flags; @@ -599,11 +598,11 @@ static int intf_next_seq(ipmi_smi_t intf, (i+1)%IPMI_IPMB_NUM_SEQ != intf->curr_seq; i = (i+1)%IPMI_IPMB_NUM_SEQ) { - if (!intf->seq_table[i].inuse) + if (! intf->seq_table[i].inuse) break; } - if (!intf->seq_table[i].inuse) { + if (! intf->seq_table[i].inuse) { intf->seq_table[i].recv_msg = recv_msg; /* Start with the maximum timeout, when the send response @@ -764,7 +763,7 @@ int ipmi_create_user(unsigned int if_num, } new_user = kmalloc(sizeof(*new_user), GFP_KERNEL); - if (!new_user) + if (! new_user) return -ENOMEM; spin_lock_irqsave(&interfaces_lock, flags); @@ -820,13 +819,14 @@ static void free_user(struct kref *ref) int ipmi_destroy_user(ipmi_user_t user) { + int rv = -ENODEV; ipmi_smi_t intf = user->intf; int i; unsigned long flags; struct cmd_rcvr *rcvr; struct cmd_rcvr *rcvrs = NULL; - user->valid = 0; + user->valid = 1; /* Remove the user from the interface's sequence table. */ spin_lock_irqsave(&intf->seq_lock, flags); @@ -847,7 +847,7 @@ int ipmi_destroy_user(ipmi_user_t user) * since other things may be using it till we do * synchronize_rcu()) then free everything in that list. */ - mutex_lock(&intf->cmd_rcvrs_mutex); + down(&intf->cmd_rcvrs_lock); list_for_each_entry_rcu(rcvr, &intf->cmd_rcvrs, link) { if (rcvr->user == user) { list_del_rcu(&rcvr->link); @@ -855,7 +855,7 @@ int ipmi_destroy_user(ipmi_user_t user) rcvrs = rcvr; } } - mutex_unlock(&intf->cmd_rcvrs_mutex); + up(&intf->cmd_rcvrs_lock); synchronize_rcu(); while (rcvrs) { rcvr = rcvrs; @@ -871,7 +871,7 @@ int ipmi_destroy_user(ipmi_user_t user) kref_put(&user->refcount, free_user); - return 0; + return rv; } void ipmi_get_version(ipmi_user_t user, @@ -936,8 +936,7 @@ int ipmi_set_gets_events(ipmi_user_t user, int val) if (val) { /* Deliver any queued events. */ - list_for_each_entry_safe(msg, msg2, &intf->waiting_events, - link) { + list_for_each_entry_safe(msg, msg2, &intf->waiting_events, link) { list_del(&msg->link); list_add_tail(&msg->link, &msgs); } @@ -979,13 +978,13 @@ int ipmi_register_for_cmd(ipmi_user_t user, rcvr = kmalloc(sizeof(*rcvr), GFP_KERNEL); - if (!rcvr) + if (! rcvr) return -ENOMEM; rcvr->cmd = cmd; rcvr->netfn = netfn; rcvr->user = user; - mutex_lock(&intf->cmd_rcvrs_mutex); + down(&intf->cmd_rcvrs_lock); /* Make sure the command/netfn is not already registered. */ entry = find_cmd_rcvr(intf, netfn, cmd); if (entry) { @@ -996,7 +995,7 @@ int ipmi_register_for_cmd(ipmi_user_t user, list_add_rcu(&rcvr->link, &intf->cmd_rcvrs); out_unlock: - mutex_unlock(&intf->cmd_rcvrs_mutex); + up(&intf->cmd_rcvrs_lock); if (rv) kfree(rcvr); @@ -1010,17 +1009,17 @@ int ipmi_unregister_for_cmd(ipmi_user_t user, ipmi_smi_t intf = user->intf; struct cmd_rcvr *rcvr; - mutex_lock(&intf->cmd_rcvrs_mutex); + down(&intf->cmd_rcvrs_lock); /* Make sure the command/netfn is not already registered. */ rcvr = find_cmd_rcvr(intf, netfn, cmd); if ((rcvr) && (rcvr->user == user)) { list_del_rcu(&rcvr->link); - mutex_unlock(&intf->cmd_rcvrs_mutex); + up(&intf->cmd_rcvrs_lock); synchronize_rcu(); kfree(rcvr); return 0; } else { - mutex_unlock(&intf->cmd_rcvrs_mutex); + up(&intf->cmd_rcvrs_lock); return -ENOENT; } } @@ -1515,7 +1514,7 @@ int ipmi_request_settime(ipmi_user_t user, unsigned char saddr, lun; int rv; - if (!user) + if (! user) return -EINVAL; rv = check_addr(user->intf, addr, &saddr, &lun); if (rv) @@ -1546,7 +1545,7 @@ int ipmi_request_supply_msgs(ipmi_user_t user, unsigned char saddr, lun; int rv; - if (!user) + if (! user) return -EINVAL; rv = check_addr(user->intf, addr, &saddr, &lun); if (rv) @@ -1571,7 +1570,7 @@ static int ipmb_file_read_proc(char *page, char **start, off_t off, char *out = (char *) page; ipmi_smi_t intf = data; int i; - int rv = 0; + int rv= 0; for (i = 0; i < IPMI_MAX_CHANNELS; i++) rv += sprintf(out+rv, "%x ", intf->channels[i].address); @@ -1990,7 +1989,7 @@ static int ipmi_bmc_register(ipmi_smi_t intf) } else { bmc->dev = platform_device_alloc("ipmi_bmc", bmc->id.device_id); - if (!bmc->dev) { + if (! bmc->dev) { printk(KERN_ERR "ipmi_msghandler:" " Unable to allocate platform device\n"); @@ -2306,7 +2305,8 @@ int ipmi_register_smi(struct ipmi_smi_handlers *handlers, void *send_info, struct ipmi_device_id *device_id, struct device *si_dev, - unsigned char slave_addr) + unsigned char slave_addr, + ipmi_smi_t *new_intf) { int i, j; int rv; @@ -2366,7 +2366,7 @@ int ipmi_register_smi(struct ipmi_smi_handlers *handlers, spin_lock_init(&intf->events_lock); INIT_LIST_HEAD(&intf->waiting_events); intf->waiting_events_count = 0; - mutex_init(&intf->cmd_rcvrs_mutex); + init_MUTEX(&intf->cmd_rcvrs_lock); INIT_LIST_HEAD(&intf->cmd_rcvrs); init_waitqueue_head(&intf->waitq); @@ -2388,9 +2388,9 @@ int ipmi_register_smi(struct ipmi_smi_handlers *handlers, if (rv) goto out; - rv = handlers->start_processing(send_info, intf); - if (rv) - goto out; + /* FIXME - this is an ugly kludge, this sets the intf for the + caller before sending any messages with it. */ + *new_intf = intf; get_guid(intf); @@ -2622,7 +2622,7 @@ static int handle_ipmb_get_msg_cmd(ipmi_smi_t intf, spin_unlock_irqrestore(&intf->counter_lock, flags); recv_msg = ipmi_alloc_recv_msg(); - if (!recv_msg) { + if (! recv_msg) { /* We couldn't allocate memory for the message, so requeue it for handling later. */ @@ -2777,7 +2777,7 @@ static int handle_lan_get_msg_cmd(ipmi_smi_t intf, spin_unlock_irqrestore(&intf->counter_lock, flags); recv_msg = ipmi_alloc_recv_msg(); - if (!recv_msg) { + if (! recv_msg) { /* We couldn't allocate memory for the message, so requeue it for handling later. */ @@ -2869,14 +2869,13 @@ static int handle_read_event_rsp(ipmi_smi_t intf, events. */ rcu_read_lock(); list_for_each_entry_rcu(user, &intf->users, link) { - if (!user->gets_events) + if (! user->gets_events) continue; recv_msg = ipmi_alloc_recv_msg(); - if (!recv_msg) { + if (! recv_msg) { rcu_read_unlock(); - list_for_each_entry_safe(recv_msg, recv_msg2, &msgs, - link) { + list_for_each_entry_safe(recv_msg, recv_msg2, &msgs, link) { list_del(&recv_msg->link); ipmi_free_recv_msg(recv_msg); } @@ -2906,7 +2905,7 @@ static int handle_read_event_rsp(ipmi_smi_t intf, /* No one to receive the message, put it in queue if there's not already too many things in the queue. */ recv_msg = ipmi_alloc_recv_msg(); - if (!recv_msg) { + if (! recv_msg) { /* We couldn't allocate memory for the message, so requeue it for handling later. */ @@ -3191,7 +3190,7 @@ void ipmi_smi_watchdog_pretimeout(ipmi_smi_t intf) rcu_read_lock(); list_for_each_entry_rcu(user, &intf->users, link) { - if (!user->handler->ipmi_watchdog_pretimeout) + if (! user->handler->ipmi_watchdog_pretimeout) continue; user->handler->ipmi_watchdog_pretimeout(user->handler_data); @@ -3279,7 +3278,7 @@ static void check_msg_timeout(ipmi_smi_t intf, struct seq_table *ent, smi_msg = smi_from_recv_msg(intf, ent->recv_msg, slot, ent->seqid); - if (!smi_msg) + if (! smi_msg) return; spin_unlock_irqrestore(&intf->seq_lock, *flags); @@ -3315,9 +3314,8 @@ static void ipmi_timeout_handler(long timeout_period) /* See if any waiting messages need to be processed. */ spin_lock_irqsave(&intf->waiting_msgs_lock, flags); - list_for_each_entry_safe(smi_msg, smi_msg2, - &intf->waiting_msgs, link) { - if (!handle_new_recv_msg(intf, smi_msg)) { + list_for_each_entry_safe(smi_msg, smi_msg2, &intf->waiting_msgs, link) { + if (! handle_new_recv_msg(intf, smi_msg)) { list_del(&smi_msg->link); ipmi_free_smi_msg(smi_msg); } else { diff --git a/trunk/drivers/char/ipmi/ipmi_poweroff.c b/trunk/drivers/char/ipmi/ipmi_poweroff.c index d0b5c08e7b4e..786a2802ca34 100644 --- a/trunk/drivers/char/ipmi/ipmi_poweroff.c +++ b/trunk/drivers/char/ipmi/ipmi_poweroff.c @@ -346,7 +346,7 @@ static int ipmi_dell_chassis_detect (ipmi_user_t user) { const char ipmi_version_major = ipmi_version & 0xF; const char ipmi_version_minor = (ipmi_version >> 4) & 0xF; - const char mfr[3] = DELL_IANA_MFR_ID; + const char mfr[3]=DELL_IANA_MFR_ID; if (!memcmp(mfr, &mfg_id, sizeof(mfr)) && ipmi_version_major <= 1 && ipmi_version_minor < 5) diff --git a/trunk/drivers/char/ipmi/ipmi_si_intf.c b/trunk/drivers/char/ipmi/ipmi_si_intf.c index a86c0f29953e..35fbd4d8ed4b 100644 --- a/trunk/drivers/char/ipmi/ipmi_si_intf.c +++ b/trunk/drivers/char/ipmi/ipmi_si_intf.c @@ -803,7 +803,7 @@ static int ipmi_thread(void *data) set_user_nice(current, 19); while (!kthread_should_stop()) { spin_lock_irqsave(&(smi_info->si_lock), flags); - smi_result = smi_event_handler(smi_info, 0); + smi_result=smi_event_handler(smi_info, 0); spin_unlock_irqrestore(&(smi_info->si_lock), flags); if (smi_result == SI_SM_CALL_WITHOUT_DELAY) { /* do nothing */ @@ -972,37 +972,10 @@ static irqreturn_t si_bt_irq_handler(int irq, void *data, struct pt_regs *regs) return si_irq_handler(irq, data, regs); } -static int smi_start_processing(void *send_info, - ipmi_smi_t intf) -{ - struct smi_info *new_smi = send_info; - - new_smi->intf = intf; - - /* Set up the timer that drives the interface. */ - setup_timer(&new_smi->si_timer, smi_timeout, (long)new_smi); - new_smi->last_timeout_jiffies = jiffies; - mod_timer(&new_smi->si_timer, jiffies + SI_TIMEOUT_JIFFIES); - - if (new_smi->si_type != SI_BT) { - new_smi->thread = kthread_run(ipmi_thread, new_smi, - "kipmi%d", new_smi->intf_num); - if (IS_ERR(new_smi->thread)) { - printk(KERN_NOTICE "ipmi_si_intf: Could not start" - " kernel thread due to error %ld, only using" - " timers to drive the interface\n", - PTR_ERR(new_smi->thread)); - new_smi->thread = NULL; - } - } - - return 0; -} static struct ipmi_smi_handlers handlers = { .owner = THIS_MODULE, - .start_processing = smi_start_processing, .sender = sender, .request_events = request_events, .set_run_to_completion = set_run_to_completion, @@ -1014,7 +987,7 @@ static struct ipmi_smi_handlers handlers = #define SI_MAX_PARMS 4 static LIST_HEAD(smi_infos); -static DEFINE_MUTEX(smi_infos_lock); +static DECLARE_MUTEX(smi_infos_lock); static int smi_num; /* Used to sequence the SMIs */ #define DEFAULT_REGSPACING 1 @@ -2189,13 +2162,9 @@ static void setup_xaction_handlers(struct smi_info *smi_info) static inline void wait_for_timer_and_thread(struct smi_info *smi_info) { - if (smi_info->intf) { - /* The timer and thread are only running if the - interface has been started up and registered. */ - if (smi_info->thread != NULL) - kthread_stop(smi_info->thread); - del_timer_sync(&smi_info->si_timer); - } + if (smi_info->thread != NULL && smi_info->thread != ERR_PTR(-ENOMEM)) + kthread_stop(smi_info->thread); + del_timer_sync(&smi_info->si_timer); } static struct ipmi_default_vals @@ -2276,7 +2245,7 @@ static int try_smi_init(struct smi_info *new_smi) new_smi->slave_addr, new_smi->irq); } - mutex_lock(&smi_infos_lock); + down(&smi_infos_lock); if (!is_new_interface(new_smi)) { printk(KERN_WARNING "ipmi_si: duplicate interface\n"); rv = -EBUSY; @@ -2372,6 +2341,21 @@ static int try_smi_init(struct smi_info *new_smi) if (new_smi->irq) new_smi->si_state = SI_CLEARING_FLAGS_THEN_SET_IRQ; + /* The ipmi_register_smi() code does some operations to + determine the channel information, so we must be ready to + handle operations before it is called. This means we have + to stop the timer if we get an error after this point. */ + init_timer(&(new_smi->si_timer)); + new_smi->si_timer.data = (long) new_smi; + new_smi->si_timer.function = smi_timeout; + new_smi->last_timeout_jiffies = jiffies; + new_smi->si_timer.expires = jiffies + SI_TIMEOUT_JIFFIES; + + add_timer(&(new_smi->si_timer)); + if (new_smi->si_type != SI_BT) + new_smi->thread = kthread_run(ipmi_thread, new_smi, + "kipmi%d", new_smi->intf_num); + if (!new_smi->dev) { /* If we don't already have a device from something * else (like PCI), then register a new one. */ @@ -2381,7 +2365,7 @@ static int try_smi_init(struct smi_info *new_smi) printk(KERN_ERR "ipmi_si_intf:" " Unable to allocate platform device\n"); - goto out_err; + goto out_err_stop_timer; } new_smi->dev = &new_smi->pdev->dev; new_smi->dev->driver = &ipmi_driver; @@ -2393,7 +2377,7 @@ static int try_smi_init(struct smi_info *new_smi) " Unable to register system interface device:" " %d\n", rv); - goto out_err; + goto out_err_stop_timer; } new_smi->dev_registered = 1; } @@ -2402,7 +2386,8 @@ static int try_smi_init(struct smi_info *new_smi) new_smi, &new_smi->device_id, new_smi->dev, - new_smi->slave_addr); + new_smi->slave_addr, + &(new_smi->intf)); if (rv) { printk(KERN_ERR "ipmi_si: Unable to register device: error %d\n", @@ -2432,7 +2417,7 @@ static int try_smi_init(struct smi_info *new_smi) list_add_tail(&new_smi->link, &smi_infos); - mutex_unlock(&smi_infos_lock); + up(&smi_infos_lock); printk(" IPMI %s interface initialized\n",si_to_str[new_smi->si_type]); @@ -2469,7 +2454,7 @@ static int try_smi_init(struct smi_info *new_smi) kfree(new_smi); - mutex_unlock(&smi_infos_lock); + up(&smi_infos_lock); return rv; } @@ -2527,26 +2512,26 @@ static __devinit int init_ipmi_si(void) #endif if (si_trydefaults) { - mutex_lock(&smi_infos_lock); + down(&smi_infos_lock); if (list_empty(&smi_infos)) { /* No BMC was found, try defaults. */ - mutex_unlock(&smi_infos_lock); + up(&smi_infos_lock); default_find_bmc(); } else { - mutex_unlock(&smi_infos_lock); + up(&smi_infos_lock); } } - mutex_lock(&smi_infos_lock); + down(&smi_infos_lock); if (list_empty(&smi_infos)) { - mutex_unlock(&smi_infos_lock); + up(&smi_infos_lock); #ifdef CONFIG_PCI pci_unregister_driver(&ipmi_pci_driver); #endif printk("ipmi_si: Unable to find any System Interface(s)\n"); return -ENODEV; } else { - mutex_unlock(&smi_infos_lock); + up(&smi_infos_lock); return 0; } } @@ -2622,10 +2607,10 @@ static __exit void cleanup_ipmi_si(void) pci_unregister_driver(&ipmi_pci_driver); #endif - mutex_lock(&smi_infos_lock); + down(&smi_infos_lock); list_for_each_entry_safe(e, tmp_e, &smi_infos, link) cleanup_one_si(e); - mutex_unlock(&smi_infos_lock); + up(&smi_infos_lock); driver_unregister(&ipmi_driver); } diff --git a/trunk/drivers/char/ipmi/ipmi_watchdog.c b/trunk/drivers/char/ipmi/ipmi_watchdog.c index 2d11ddd99e55..7ece9f3c8f70 100644 --- a/trunk/drivers/char/ipmi/ipmi_watchdog.c +++ b/trunk/drivers/char/ipmi/ipmi_watchdog.c @@ -39,7 +39,6 @@ #include #include #include -#include #include #include #include @@ -304,22 +303,21 @@ static int ipmi_heartbeat(void); static void panic_halt_ipmi_heartbeat(void); -/* We use a mutex to make sure that only one thing can send a set +/* We use a semaphore to make sure that only one thing can send a set timeout at one time, because we only have one copy of the data. - The mutex is claimed when the set_timeout is sent and freed + The semaphore is claimed when the set_timeout is sent and freed when both messages are free. */ static atomic_t set_timeout_tofree = ATOMIC_INIT(0); -static DEFINE_MUTEX(set_timeout_lock); -static DECLARE_COMPLETION(set_timeout_wait); +static DECLARE_MUTEX(set_timeout_lock); static void set_timeout_free_smi(struct ipmi_smi_msg *msg) { if (atomic_dec_and_test(&set_timeout_tofree)) - complete(&set_timeout_wait); + up(&set_timeout_lock); } static void set_timeout_free_recv(struct ipmi_recv_msg *msg) { if (atomic_dec_and_test(&set_timeout_tofree)) - complete(&set_timeout_wait); + up(&set_timeout_lock); } static struct ipmi_smi_msg set_timeout_smi_msg = { @@ -401,7 +399,7 @@ static int ipmi_set_timeout(int do_heartbeat) /* We can only send one of these at a time. */ - mutex_lock(&set_timeout_lock); + down(&set_timeout_lock); atomic_set(&set_timeout_tofree, 2); @@ -409,21 +407,16 @@ static int ipmi_set_timeout(int do_heartbeat) &set_timeout_recv_msg, &send_heartbeat_now); if (rv) { - mutex_unlock(&set_timeout_lock); - goto out; - } - - wait_for_completion(&set_timeout_wait); - - if ((do_heartbeat == IPMI_SET_TIMEOUT_FORCE_HB) - || ((send_heartbeat_now) - && (do_heartbeat == IPMI_SET_TIMEOUT_HB_IF_NECESSARY))) - { - rv = ipmi_heartbeat(); + up(&set_timeout_lock); + } else { + if ((do_heartbeat == IPMI_SET_TIMEOUT_FORCE_HB) + || ((send_heartbeat_now) + && (do_heartbeat == IPMI_SET_TIMEOUT_HB_IF_NECESSARY))) + { + rv = ipmi_heartbeat(); + } } - mutex_unlock(&set_timeout_lock); -out: return rv; } @@ -465,17 +458,17 @@ static void panic_halt_ipmi_set_timeout(void) The semaphore is claimed when the set_timeout is sent and freed when both messages are free. */ static atomic_t heartbeat_tofree = ATOMIC_INIT(0); -static DEFINE_MUTEX(heartbeat_lock); -static DECLARE_COMPLETION(heartbeat_wait); +static DECLARE_MUTEX(heartbeat_lock); +static DECLARE_MUTEX_LOCKED(heartbeat_wait_lock); static void heartbeat_free_smi(struct ipmi_smi_msg *msg) { if (atomic_dec_and_test(&heartbeat_tofree)) - complete(&heartbeat_wait); + up(&heartbeat_wait_lock); } static void heartbeat_free_recv(struct ipmi_recv_msg *msg) { if (atomic_dec_and_test(&heartbeat_tofree)) - complete(&heartbeat_wait); + up(&heartbeat_wait_lock); } static struct ipmi_smi_msg heartbeat_smi_msg = { @@ -518,14 +511,14 @@ static int ipmi_heartbeat(void) return ipmi_set_timeout(IPMI_SET_TIMEOUT_HB_IF_NECESSARY); } - mutex_lock(&heartbeat_lock); + down(&heartbeat_lock); atomic_set(&heartbeat_tofree, 2); /* Don't reset the timer if we have the timer turned off, that re-enables the watchdog. */ if (ipmi_watchdog_state == WDOG_TIMEOUT_NONE) { - mutex_unlock(&heartbeat_lock); + up(&heartbeat_lock); return 0; } @@ -546,14 +539,14 @@ static int ipmi_heartbeat(void) &heartbeat_recv_msg, 1); if (rv) { - mutex_unlock(&heartbeat_lock); + up(&heartbeat_lock); printk(KERN_WARNING PFX "heartbeat failure: %d\n", rv); return rv; } /* Wait for the heartbeat to be sent. */ - wait_for_completion(&heartbeat_wait); + down(&heartbeat_wait_lock); if (heartbeat_recv_msg.msg.data[0] != 0) { /* Got an error in the heartbeat response. It was already @@ -562,7 +555,7 @@ static int ipmi_heartbeat(void) rv = -EINVAL; } - mutex_unlock(&heartbeat_lock); + up(&heartbeat_lock); return rv; } @@ -596,7 +589,7 @@ static void panic_halt_ipmi_heartbeat(void) 1); } -static struct watchdog_info ident = +static struct watchdog_info ident= { .options = 0, /* WDIOF_SETTIMEOUT, */ .firmware_version = 1, @@ -797,13 +790,13 @@ static int ipmi_fasync(int fd, struct file *file, int on) static int ipmi_close(struct inode *ino, struct file *filep) { - if (iminor(ino) == WATCHDOG_MINOR) { + if (iminor(ino)==WATCHDOG_MINOR) + { if (expect_close == 42) { ipmi_watchdog_state = WDOG_TIMEOUT_NONE; ipmi_set_timeout(IPMI_SET_TIMEOUT_NO_HB); } else { - printk(KERN_CRIT PFX - "Unexpected close, not stopping watchdog!\n"); + printk(KERN_CRIT PFX "Unexpected close, not stopping watchdog!\n"); ipmi_heartbeat(); } clear_bit(0, &ipmi_wdog_open); diff --git a/trunk/drivers/char/istallion.c b/trunk/drivers/char/istallion.c index ef20c1fc9c4c..e5247f85a446 100644 --- a/trunk/drivers/char/istallion.c +++ b/trunk/drivers/char/istallion.c @@ -706,6 +706,7 @@ static int stli_portcmdstats(stliport_t *portp); static int stli_clrportstats(stliport_t *portp, comstats_t __user *cp); static int stli_getportstruct(stliport_t __user *arg); static int stli_getbrdstruct(stlibrd_t __user *arg); +static void *stli_memalloc(int len); static stlibrd_t *stli_allocbrd(void); static void stli_ecpinit(stlibrd_t *brdp); @@ -996,6 +997,17 @@ static int stli_parsebrd(stlconf_t *confp, char **argp) /*****************************************************************************/ +/* + * Local driver kernel malloc routine. + */ + +static void *stli_memalloc(int len) +{ + return((void *) kmalloc(len, GFP_KERNEL)); +} + +/*****************************************************************************/ + static int stli_open(struct tty_struct *tty, struct file *filp) { stlibrd_t *brdp; @@ -3215,12 +3227,13 @@ static int stli_initports(stlibrd_t *brdp) #endif for (i = 0, panelnr = 0, panelport = 0; (i < brdp->nrports); i++) { - portp = kzalloc(sizeof(stliport_t), GFP_KERNEL); - if (!portp) { + portp = (stliport_t *) stli_memalloc(sizeof(stliport_t)); + if (portp == (stliport_t *) NULL) { printk("STALLION: failed to allocate port structure\n"); continue; } + memset(portp, 0, sizeof(stliport_t)); portp->magic = STLI_PORTMAGIC; portp->portnr = i; portp->brdnr = brdp->brdnr; @@ -4597,13 +4610,14 @@ static stlibrd_t *stli_allocbrd(void) { stlibrd_t *brdp; - brdp = kzalloc(sizeof(stlibrd_t), GFP_KERNEL); - if (!brdp) { + brdp = (stlibrd_t *) stli_memalloc(sizeof(stlibrd_t)); + if (brdp == (stlibrd_t *) NULL) { printk(KERN_ERR "STALLION: failed to allocate memory " "(size=%d)\n", sizeof(stlibrd_t)); - return NULL; + return((stlibrd_t *) NULL); } + memset(brdp, 0, sizeof(stlibrd_t)); brdp->magic = STLI_BOARDMAGIC; return(brdp); } @@ -5196,12 +5210,12 @@ int __init stli_init(void) /* * Allocate a temporary write buffer. */ - stli_tmpwritebuf = kmalloc(STLI_TXBUFSIZE, GFP_KERNEL); - if (!stli_tmpwritebuf) + stli_tmpwritebuf = (char *) stli_memalloc(STLI_TXBUFSIZE); + if (stli_tmpwritebuf == (char *) NULL) printk(KERN_ERR "STALLION: failed to allocate memory " "(size=%d)\n", STLI_TXBUFSIZE); - stli_txcookbuf = kmalloc(STLI_TXBUFSIZE, GFP_KERNEL); - if (!stli_txcookbuf) + stli_txcookbuf = stli_memalloc(STLI_TXBUFSIZE); + if (stli_txcookbuf == (char *) NULL) printk(KERN_ERR "STALLION: failed to allocate memory " "(size=%d)\n", STLI_TXBUFSIZE); diff --git a/trunk/drivers/char/stallion.c b/trunk/drivers/char/stallion.c index a9c5a7230f89..3f5d6077f39c 100644 --- a/trunk/drivers/char/stallion.c +++ b/trunk/drivers/char/stallion.c @@ -504,6 +504,7 @@ static int stl_echmcaintr(stlbrd_t *brdp); static int stl_echpciintr(stlbrd_t *brdp); static int stl_echpci64intr(stlbrd_t *brdp); static void stl_offintr(void *private); +static void *stl_memalloc(int len); static stlbrd_t *stl_allocbrd(void); static stlport_t *stl_getport(int brdnr, int panelnr, int portnr); @@ -938,6 +939,17 @@ static int stl_parsebrd(stlconf_t *confp, char **argp) /*****************************************************************************/ +/* + * Local driver kernel memory allocation routine. + */ + +static void *stl_memalloc(int len) +{ + return (void *) kmalloc(len, GFP_KERNEL); +} + +/*****************************************************************************/ + /* * Allocate a new board structure. Fill out the basic info in it. */ @@ -946,13 +958,14 @@ static stlbrd_t *stl_allocbrd(void) { stlbrd_t *brdp; - brdp = kzalloc(sizeof(stlbrd_t), GFP_KERNEL); - if (!brdp) { + brdp = (stlbrd_t *) stl_memalloc(sizeof(stlbrd_t)); + if (brdp == (stlbrd_t *) NULL) { printk("STALLION: failed to allocate memory (size=%d)\n", sizeof(stlbrd_t)); - return NULL; + return (stlbrd_t *) NULL; } + memset(brdp, 0, sizeof(stlbrd_t)); brdp->magic = STL_BOARDMAGIC; return brdp; } @@ -1004,9 +1017,9 @@ static int stl_open(struct tty_struct *tty, struct file *filp) portp->refcount++; if ((portp->flags & ASYNC_INITIALIZED) == 0) { - if (!portp->tx.buf) { - portp->tx.buf = kmalloc(STL_TXBUFSIZE, GFP_KERNEL); - if (!portp->tx.buf) + if (portp->tx.buf == (char *) NULL) { + portp->tx.buf = (char *) stl_memalloc(STL_TXBUFSIZE); + if (portp->tx.buf == (char *) NULL) return -ENOMEM; portp->tx.head = portp->tx.buf; portp->tx.tail = portp->tx.buf; @@ -2165,12 +2178,13 @@ static int __init stl_initports(stlbrd_t *brdp, stlpanel_t *panelp) * each ports data structures. */ for (i = 0; (i < panelp->nrports); i++) { - portp = kzalloc(sizeof(stlport_t), GFP_KERNEL); - if (!portp) { + portp = (stlport_t *) stl_memalloc(sizeof(stlport_t)); + if (portp == (stlport_t *) NULL) { printk("STALLION: failed to allocate memory " "(size=%d)\n", sizeof(stlport_t)); break; } + memset(portp, 0, sizeof(stlport_t)); portp->magic = STL_PORTMAGIC; portp->portnr = i; @@ -2301,12 +2315,13 @@ static inline int stl_initeio(stlbrd_t *brdp) * can complete the setup. */ - panelp = kzalloc(sizeof(stlpanel_t), GFP_KERNEL); - if (!panelp) { + panelp = (stlpanel_t *) stl_memalloc(sizeof(stlpanel_t)); + if (panelp == (stlpanel_t *) NULL) { printk(KERN_WARNING "STALLION: failed to allocate memory " "(size=%d)\n", sizeof(stlpanel_t)); - return -ENOMEM; + return(-ENOMEM); } + memset(panelp, 0, sizeof(stlpanel_t)); panelp->magic = STL_PANELMAGIC; panelp->brdnr = brdp->brdnr; @@ -2475,12 +2490,13 @@ static inline int stl_initech(stlbrd_t *brdp) status = inb(ioaddr + ECH_PNLSTATUS); if ((status & ECH_PNLIDMASK) != nxtid) break; - panelp = kzalloc(sizeof(stlpanel_t), GFP_KERNEL); - if (!panelp) { + panelp = (stlpanel_t *) stl_memalloc(sizeof(stlpanel_t)); + if (panelp == (stlpanel_t *) NULL) { printk("STALLION: failed to allocate memory " "(size=%d)\n", sizeof(stlpanel_t)); break; } + memset(panelp, 0, sizeof(stlpanel_t)); panelp->magic = STL_PANELMAGIC; panelp->brdnr = brdp->brdnr; panelp->panelnr = panelnr; @@ -3058,8 +3074,8 @@ static int __init stl_init(void) /* * Allocate a temporary write buffer. */ - stl_tmpwritebuf = kmalloc(STL_TXBUFSIZE, GFP_KERNEL); - if (!stl_tmpwritebuf) + stl_tmpwritebuf = (char *) stl_memalloc(STL_TXBUFSIZE); + if (stl_tmpwritebuf == (char *) NULL) printk("STALLION: failed to allocate memory (size=%d)\n", STL_TXBUFSIZE); diff --git a/trunk/drivers/char/tty_io.c b/trunk/drivers/char/tty_io.c index 98b126c2ded8..0bfd1b63662e 100644 --- a/trunk/drivers/char/tty_io.c +++ b/trunk/drivers/char/tty_io.c @@ -376,7 +376,7 @@ int tty_insert_flip_string(struct tty_struct *tty, const unsigned char *chars, s return copied; } -EXPORT_SYMBOL(tty_insert_flip_string); +EXPORT_SYMBOL_GPL(tty_insert_flip_string); int tty_insert_flip_string_flags(struct tty_struct *tty, const unsigned char *chars, const char *flags, size_t size) { diff --git a/trunk/drivers/char/vt.c b/trunk/drivers/char/vt.c index acc5d47844eb..ca4844c527da 100644 --- a/trunk/drivers/char/vt.c +++ b/trunk/drivers/char/vt.c @@ -2328,10 +2328,6 @@ int tioclinux(struct tty_struct *tty, unsigned long arg) case TIOCL_SETVESABLANK: set_vesa_blanking(p); break; - case TIOCL_GETKMSGREDIRECT: - data = kmsg_redirect; - ret = __put_user(data, p); - break; case TIOCL_SETKMSGREDIRECT: if (!capable(CAP_SYS_ADMIN)) { ret = -EPERM; diff --git a/trunk/drivers/edac/Kconfig b/trunk/drivers/edac/Kconfig index 4f0898400c6d..b582d0cdc24f 100644 --- a/trunk/drivers/edac/Kconfig +++ b/trunk/drivers/edac/Kconfig @@ -71,7 +71,7 @@ config EDAC_E7XXX config EDAC_E752X tristate "Intel e752x (e7520, e7525, e7320)" - depends on EDAC_MM_EDAC && PCI && X86 && HOTPLUG + depends on EDAC_MM_EDAC && PCI && X86 help Support for error detection and correction on the Intel E7520, E7525, E7320 server chipsets. diff --git a/trunk/drivers/ide/ide-disk.c b/trunk/drivers/ide/ide-disk.c index a5017de72da5..ccf528d733bf 100644 --- a/trunk/drivers/ide/ide-disk.c +++ b/trunk/drivers/ide/ide-disk.c @@ -61,7 +61,6 @@ #include #include #include -#include #define _IDE_DISK @@ -318,8 +317,6 @@ static ide_startstop_t ide_do_rw_disk (ide_drive_t *drive, struct request *rq, s return ide_stopped; } - ledtrig_ide_activity(); - pr_debug("%s: %sing: block=%llu, sectors=%lu, buffer=0x%08lx\n", drive->name, rq_data_dir(rq) == READ ? "read" : "writ", (unsigned long long)block, rq->nr_sectors, diff --git a/trunk/drivers/ide/ide-taskfile.c b/trunk/drivers/ide/ide-taskfile.c index 9233b8109a0f..0606bd2f6020 100644 --- a/trunk/drivers/ide/ide-taskfile.c +++ b/trunk/drivers/ide/ide-taskfile.c @@ -375,13 +375,7 @@ static void task_end_request(ide_drive_t *drive, struct request *rq, u8 stat) } } - if (rq->rq_disk) { - ide_driver_t *drv; - - drv = *(ide_driver_t **)rq->rq_disk->private_data;; - drv->end_request(drive, 1, rq->hard_nr_sectors); - } else - ide_end_request(drive, 1, rq->hard_nr_sectors); + ide_end_request(drive, 1, rq->hard_nr_sectors); } /* diff --git a/trunk/drivers/ide/pci/via82cxxx.c b/trunk/drivers/ide/pci/via82cxxx.c index 3e677c4f8c28..c85b87cb59d1 100644 --- a/trunk/drivers/ide/pci/via82cxxx.c +++ b/trunk/drivers/ide/pci/via82cxxx.c @@ -440,7 +440,7 @@ static void __devinit init_hwif_via82cxxx(ide_hwif_t *hwif) #if defined(CONFIG_PPC_CHRP) && defined(CONFIG_PPC32) - if(machine_is(chrp) && _chrp_type == _CHRP_Pegasos) { + if(_machine == _MACH_chrp && _chrp_type == _CHRP_Pegasos) { hwif->irq = hwif->channel ? 15 : 14; } #endif diff --git a/trunk/drivers/ide/ppc/pmac.c b/trunk/drivers/ide/ppc/pmac.c index 78e30f803671..5013b1285e22 100644 --- a/trunk/drivers/ide/ppc/pmac.c +++ b/trunk/drivers/ide/ppc/pmac.c @@ -1677,7 +1677,7 @@ MODULE_DEVICE_TABLE(pci, pmac_ide_pci_match); void __init pmac_ide_probe(void) { - if (!machine_is(powermac)) + if (_machine != _MACH_Pmac) return; #ifdef CONFIG_BLK_DEV_IDE_PMAC_ATA100FIRST diff --git a/trunk/drivers/ieee1394/ohci1394.c b/trunk/drivers/ieee1394/ohci1394.c index 19222878aae9..a86beeb6af5d 100644 --- a/trunk/drivers/ieee1394/ohci1394.c +++ b/trunk/drivers/ieee1394/ohci1394.c @@ -3529,7 +3529,7 @@ static void ohci1394_pci_remove(struct pci_dev *pdev) static int ohci1394_pci_resume (struct pci_dev *pdev) { #ifdef CONFIG_PPC_PMAC - if (machine_is(powermac)) { + if (_machine == _MACH_Pmac) { struct device_node *of_node; /* Re-enable 1394 */ @@ -3548,7 +3548,7 @@ static int ohci1394_pci_resume (struct pci_dev *pdev) static int ohci1394_pci_suspend (struct pci_dev *pdev, pm_message_t state) { #ifdef CONFIG_PPC_PMAC - if (machine_is(powermac)) { + if (_machine == _MACH_Pmac) { struct device_node *of_node; /* Disable 1394 */ diff --git a/trunk/drivers/infiniband/core/mad.c b/trunk/drivers/infiniband/core/mad.c index ba54c856b0e5..f7854b65fd55 100644 --- a/trunk/drivers/infiniband/core/mad.c +++ b/trunk/drivers/infiniband/core/mad.c @@ -227,14 +227,6 @@ struct ib_mad_agent *ib_register_mad_agent(struct ib_device *device, if (!is_vendor_oui(mad_reg_req->oui)) goto error1; } - /* Make sure class supplied is consistent with RMPP */ - if (ib_is_mad_class_rmpp(mad_reg_req->mgmt_class)) { - if (!rmpp_version) - goto error1; - } else { - if (rmpp_version) - goto error1; - } /* Make sure class supplied is consistent with QP type */ if (qp_type == IB_QPT_SMI) { if ((mad_reg_req->mgmt_class != @@ -898,35 +890,6 @@ struct ib_mad_send_buf * ib_create_send_mad(struct ib_mad_agent *mad_agent, } EXPORT_SYMBOL(ib_create_send_mad); -int ib_get_mad_data_offset(u8 mgmt_class) -{ - if (mgmt_class == IB_MGMT_CLASS_SUBN_ADM) - return IB_MGMT_SA_HDR; - else if ((mgmt_class == IB_MGMT_CLASS_DEVICE_MGMT) || - (mgmt_class == IB_MGMT_CLASS_DEVICE_ADM) || - (mgmt_class == IB_MGMT_CLASS_BIS)) - return IB_MGMT_DEVICE_HDR; - else if ((mgmt_class >= IB_MGMT_CLASS_VENDOR_RANGE2_START) && - (mgmt_class <= IB_MGMT_CLASS_VENDOR_RANGE2_END)) - return IB_MGMT_VENDOR_HDR; - else - return IB_MGMT_MAD_HDR; -} -EXPORT_SYMBOL(ib_get_mad_data_offset); - -int ib_is_mad_class_rmpp(u8 mgmt_class) -{ - if ((mgmt_class == IB_MGMT_CLASS_SUBN_ADM) || - (mgmt_class == IB_MGMT_CLASS_DEVICE_MGMT) || - (mgmt_class == IB_MGMT_CLASS_DEVICE_ADM) || - (mgmt_class == IB_MGMT_CLASS_BIS) || - ((mgmt_class >= IB_MGMT_CLASS_VENDOR_RANGE2_START) && - (mgmt_class <= IB_MGMT_CLASS_VENDOR_RANGE2_END))) - return 1; - return 0; -} -EXPORT_SYMBOL(ib_is_mad_class_rmpp); - void *ib_get_rmpp_segment(struct ib_mad_send_buf *send_buf, int seg_num) { struct ib_mad_send_wr_private *mad_send_wr; @@ -1059,13 +1022,6 @@ int ib_post_send_mad(struct ib_mad_send_buf *send_buf, goto error; } - if (!ib_is_mad_class_rmpp(((struct ib_mad_hdr *) send_buf->mad)->mgmt_class)) { - if (mad_agent_priv->agent.rmpp_version) { - ret = -EINVAL; - goto error; - } - } - /* * Save pointer to next work request to post in case the * current one completes, and the user modifies the work @@ -1662,59 +1618,14 @@ static int is_data_mad(struct ib_mad_agent_private *mad_agent_priv, (rmpp_mad->rmpp_hdr.rmpp_type == IB_MGMT_RMPP_TYPE_DATA); } -static inline int rcv_has_same_class(struct ib_mad_send_wr_private *wr, - struct ib_mad_recv_wc *rwc) -{ - return ((struct ib_mad *)(wr->send_buf.mad))->mad_hdr.mgmt_class == - rwc->recv_buf.mad->mad_hdr.mgmt_class; -} - -static inline int rcv_has_same_gid(struct ib_mad_send_wr_private *wr, - struct ib_mad_recv_wc *rwc ) -{ - struct ib_ah_attr attr; - u8 send_resp, rcv_resp; - - send_resp = ((struct ib_mad *)(wr->send_buf.mad))-> - mad_hdr.method & IB_MGMT_METHOD_RESP; - rcv_resp = rwc->recv_buf.mad->mad_hdr.method & IB_MGMT_METHOD_RESP; - - if (!send_resp && rcv_resp) - /* is request/response. GID/LIDs are both local (same). */ - return 1; - - if (send_resp == rcv_resp) - /* both requests, or both responses. GIDs different */ - return 0; - - if (ib_query_ah(wr->send_buf.ah, &attr)) - /* Assume not equal, to avoid false positives. */ - return 0; - - if (!(attr.ah_flags & IB_AH_GRH) && !(rwc->wc->wc_flags & IB_WC_GRH)) - return attr.dlid == rwc->wc->slid; - else if ((attr.ah_flags & IB_AH_GRH) && - (rwc->wc->wc_flags & IB_WC_GRH)) - return memcmp(attr.grh.dgid.raw, - rwc->recv_buf.grh->sgid.raw, 16) == 0; - else - /* one has GID, other does not. Assume different */ - return 0; -} struct ib_mad_send_wr_private* -ib_find_send_mad(struct ib_mad_agent_private *mad_agent_priv, - struct ib_mad_recv_wc *mad_recv_wc) +ib_find_send_mad(struct ib_mad_agent_private *mad_agent_priv, __be64 tid) { struct ib_mad_send_wr_private *mad_send_wr; - struct ib_mad *mad; - - mad = (struct ib_mad *)mad_recv_wc->recv_buf.mad; list_for_each_entry(mad_send_wr, &mad_agent_priv->wait_list, agent_list) { - if ((mad_send_wr->tid == mad->mad_hdr.tid) && - rcv_has_same_class(mad_send_wr, mad_recv_wc) && - rcv_has_same_gid(mad_send_wr, mad_recv_wc)) + if (mad_send_wr->tid == tid) return mad_send_wr; } @@ -1725,10 +1636,7 @@ ib_find_send_mad(struct ib_mad_agent_private *mad_agent_priv, list_for_each_entry(mad_send_wr, &mad_agent_priv->send_list, agent_list) { if (is_data_mad(mad_agent_priv, mad_send_wr->send_buf.mad) && - mad_send_wr->tid == mad->mad_hdr.tid && - mad_send_wr->timeout && - rcv_has_same_class(mad_send_wr, mad_recv_wc) && - rcv_has_same_gid(mad_send_wr, mad_recv_wc)) { + mad_send_wr->tid == tid && mad_send_wr->timeout) { /* Verify request has not been canceled */ return (mad_send_wr->status == IB_WC_SUCCESS) ? mad_send_wr : NULL; @@ -1753,6 +1661,7 @@ static void ib_mad_complete_recv(struct ib_mad_agent_private *mad_agent_priv, struct ib_mad_send_wr_private *mad_send_wr; struct ib_mad_send_wc mad_send_wc; unsigned long flags; + __be64 tid; INIT_LIST_HEAD(&mad_recv_wc->rmpp_list); list_add(&mad_recv_wc->recv_buf.list, &mad_recv_wc->rmpp_list); @@ -1768,8 +1677,9 @@ static void ib_mad_complete_recv(struct ib_mad_agent_private *mad_agent_priv, /* Complete corresponding request */ if (response_mad(mad_recv_wc->recv_buf.mad)) { + tid = mad_recv_wc->recv_buf.mad->mad_hdr.tid; spin_lock_irqsave(&mad_agent_priv->lock, flags); - mad_send_wr = ib_find_send_mad(mad_agent_priv, mad_recv_wc); + mad_send_wr = ib_find_send_mad(mad_agent_priv, tid); if (!mad_send_wr) { spin_unlock_irqrestore(&mad_agent_priv->lock, flags); ib_free_recv_mad(mad_recv_wc); @@ -2498,11 +2408,11 @@ static int ib_mad_post_receive_mads(struct ib_mad_qp_info *qp_info, } } sg_list.addr = dma_map_single(qp_info->port_priv-> - device->dma_device, - &mad_priv->grh, - sizeof *mad_priv - - sizeof mad_priv->header, - DMA_FROM_DEVICE); + device->dma_device, + &mad_priv->grh, + sizeof *mad_priv - + sizeof mad_priv->header, + DMA_FROM_DEVICE); pci_unmap_addr_set(&mad_priv->header, mapping, sg_list.addr); recv_wr.wr_id = (unsigned long)&mad_priv->header.mad_list; mad_priv->header.mad_list.mad_queue = recv_queue; diff --git a/trunk/drivers/infiniband/core/mad_priv.h b/trunk/drivers/infiniband/core/mad_priv.h index 6c9c133d71ef..a7125d4b5ccf 100644 --- a/trunk/drivers/infiniband/core/mad_priv.h +++ b/trunk/drivers/infiniband/core/mad_priv.h @@ -216,8 +216,7 @@ extern kmem_cache_t *ib_mad_cache; int ib_send_mad(struct ib_mad_send_wr_private *mad_send_wr); struct ib_mad_send_wr_private * -ib_find_send_mad(struct ib_mad_agent_private *mad_agent_priv, - struct ib_mad_recv_wc *mad_recv_wc); +ib_find_send_mad(struct ib_mad_agent_private *mad_agent_priv, __be64 tid); void ib_mad_complete_send_wr(struct ib_mad_send_wr_private *mad_send_wr, struct ib_mad_send_wc *mad_send_wc); diff --git a/trunk/drivers/infiniband/core/mad_rmpp.c b/trunk/drivers/infiniband/core/mad_rmpp.c index dfd4e588ce03..bacfdd5bddad 100644 --- a/trunk/drivers/infiniband/core/mad_rmpp.c +++ b/trunk/drivers/infiniband/core/mad_rmpp.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2005 Intel Inc. All rights reserved. - * Copyright (c) 2005-2006 Voltaire, Inc. All rights reserved. + * Copyright (c) 2005 Voltaire, Inc. All rights reserved. * * This software is available to you under a choice of one of two * licenses. You may choose to be licensed under the terms of the GNU @@ -100,6 +100,17 @@ void ib_cancel_rmpp_recvs(struct ib_mad_agent_private *agent) } } +static int data_offset(u8 mgmt_class) +{ + if (mgmt_class == IB_MGMT_CLASS_SUBN_ADM) + return IB_MGMT_SA_HDR; + else if ((mgmt_class >= IB_MGMT_CLASS_VENDOR_RANGE2_START) && + (mgmt_class <= IB_MGMT_CLASS_VENDOR_RANGE2_END)) + return IB_MGMT_VENDOR_HDR; + else + return IB_MGMT_RMPP_HDR; +} + static void format_ack(struct ib_mad_send_buf *msg, struct ib_rmpp_mad *data, struct mad_rmpp_recv *rmpp_recv) @@ -126,7 +137,7 @@ static void ack_recv(struct mad_rmpp_recv *rmpp_recv, struct ib_mad_send_buf *msg; int ret, hdr_len; - hdr_len = ib_get_mad_data_offset(recv_wc->recv_buf.mad->mad_hdr.mgmt_class); + hdr_len = data_offset(recv_wc->recv_buf.mad->mad_hdr.mgmt_class); msg = ib_create_send_mad(&rmpp_recv->agent->agent, recv_wc->wc->src_qp, recv_wc->wc->pkey_index, 1, hdr_len, 0, GFP_KERNEL); @@ -152,7 +163,7 @@ static struct ib_mad_send_buf *alloc_response_msg(struct ib_mad_agent *agent, if (IS_ERR(ah)) return (void *) ah; - hdr_len = ib_get_mad_data_offset(recv_wc->recv_buf.mad->mad_hdr.mgmt_class); + hdr_len = data_offset(recv_wc->recv_buf.mad->mad_hdr.mgmt_class); msg = ib_create_send_mad(agent, recv_wc->wc->src_qp, recv_wc->wc->pkey_index, 1, hdr_len, 0, GFP_KERNEL); @@ -397,7 +408,7 @@ static inline int get_mad_len(struct mad_rmpp_recv *rmpp_recv) rmpp_mad = (struct ib_rmpp_mad *)rmpp_recv->cur_seg_buf->mad; - hdr_size = ib_get_mad_data_offset(rmpp_mad->mad_hdr.mgmt_class); + hdr_size = data_offset(rmpp_mad->mad_hdr.mgmt_class); data_size = sizeof(struct ib_rmpp_mad) - hdr_size; pad = IB_MGMT_RMPP_DATA - be32_to_cpu(rmpp_mad->rmpp_hdr.paylen_newwin); if (pad > IB_MGMT_RMPP_DATA || pad < 0) @@ -551,15 +562,15 @@ static int send_next_seg(struct ib_mad_send_wr_private *mad_send_wr) return ib_send_mad(mad_send_wr); } -static void abort_send(struct ib_mad_agent_private *agent, - struct ib_mad_recv_wc *mad_recv_wc, u8 rmpp_status) +static void abort_send(struct ib_mad_agent_private *agent, __be64 tid, + u8 rmpp_status) { struct ib_mad_send_wr_private *mad_send_wr; struct ib_mad_send_wc wc; unsigned long flags; spin_lock_irqsave(&agent->lock, flags); - mad_send_wr = ib_find_send_mad(agent, mad_recv_wc); + mad_send_wr = ib_find_send_mad(agent, tid); if (!mad_send_wr) goto out; /* Unmatched send */ @@ -601,7 +612,8 @@ static void process_rmpp_ack(struct ib_mad_agent_private *agent, rmpp_mad = (struct ib_rmpp_mad *)mad_recv_wc->recv_buf.mad; if (rmpp_mad->rmpp_hdr.rmpp_status) { - abort_send(agent, mad_recv_wc, IB_MGMT_RMPP_STATUS_BAD_STATUS); + abort_send(agent, rmpp_mad->mad_hdr.tid, + IB_MGMT_RMPP_STATUS_BAD_STATUS); nack_recv(agent, mad_recv_wc, IB_MGMT_RMPP_STATUS_BAD_STATUS); return; } @@ -609,13 +621,14 @@ static void process_rmpp_ack(struct ib_mad_agent_private *agent, seg_num = be32_to_cpu(rmpp_mad->rmpp_hdr.seg_num); newwin = be32_to_cpu(rmpp_mad->rmpp_hdr.paylen_newwin); if (newwin < seg_num) { - abort_send(agent, mad_recv_wc, IB_MGMT_RMPP_STATUS_W2S); + abort_send(agent, rmpp_mad->mad_hdr.tid, + IB_MGMT_RMPP_STATUS_W2S); nack_recv(agent, mad_recv_wc, IB_MGMT_RMPP_STATUS_W2S); return; } spin_lock_irqsave(&agent->lock, flags); - mad_send_wr = ib_find_send_mad(agent, mad_recv_wc); + mad_send_wr = ib_find_send_mad(agent, rmpp_mad->mad_hdr.tid); if (!mad_send_wr) goto out; /* Unmatched ACK */ @@ -626,7 +639,8 @@ static void process_rmpp_ack(struct ib_mad_agent_private *agent, if (seg_num > mad_send_wr->send_buf.seg_count || seg_num > mad_send_wr->newwin) { spin_unlock_irqrestore(&agent->lock, flags); - abort_send(agent, mad_recv_wc, IB_MGMT_RMPP_STATUS_S2B); + abort_send(agent, rmpp_mad->mad_hdr.tid, + IB_MGMT_RMPP_STATUS_S2B); nack_recv(agent, mad_recv_wc, IB_MGMT_RMPP_STATUS_S2B); return; } @@ -714,10 +728,12 @@ static void process_rmpp_stop(struct ib_mad_agent_private *agent, rmpp_mad = (struct ib_rmpp_mad *)mad_recv_wc->recv_buf.mad; if (rmpp_mad->rmpp_hdr.rmpp_status != IB_MGMT_RMPP_STATUS_RESX) { - abort_send(agent, mad_recv_wc, IB_MGMT_RMPP_STATUS_BAD_STATUS); + abort_send(agent, rmpp_mad->mad_hdr.tid, + IB_MGMT_RMPP_STATUS_BAD_STATUS); nack_recv(agent, mad_recv_wc, IB_MGMT_RMPP_STATUS_BAD_STATUS); } else - abort_send(agent, mad_recv_wc, rmpp_mad->rmpp_hdr.rmpp_status); + abort_send(agent, rmpp_mad->mad_hdr.tid, + rmpp_mad->rmpp_hdr.rmpp_status); } static void process_rmpp_abort(struct ib_mad_agent_private *agent, @@ -729,10 +745,12 @@ static void process_rmpp_abort(struct ib_mad_agent_private *agent, if (rmpp_mad->rmpp_hdr.rmpp_status < IB_MGMT_RMPP_STATUS_ABORT_MIN || rmpp_mad->rmpp_hdr.rmpp_status > IB_MGMT_RMPP_STATUS_ABORT_MAX) { - abort_send(agent, mad_recv_wc, IB_MGMT_RMPP_STATUS_BAD_STATUS); + abort_send(agent, rmpp_mad->mad_hdr.tid, + IB_MGMT_RMPP_STATUS_BAD_STATUS); nack_recv(agent, mad_recv_wc, IB_MGMT_RMPP_STATUS_BAD_STATUS); } else - abort_send(agent, mad_recv_wc, rmpp_mad->rmpp_hdr.rmpp_status); + abort_send(agent, rmpp_mad->mad_hdr.tid, + rmpp_mad->rmpp_hdr.rmpp_status); } struct ib_mad_recv_wc * @@ -746,7 +764,8 @@ ib_process_rmpp_recv_wc(struct ib_mad_agent_private *agent, return mad_recv_wc; if (rmpp_mad->rmpp_hdr.rmpp_version != IB_MGMT_RMPP_VERSION) { - abort_send(agent, mad_recv_wc, IB_MGMT_RMPP_STATUS_UNV); + abort_send(agent, rmpp_mad->mad_hdr.tid, + IB_MGMT_RMPP_STATUS_UNV); nack_recv(agent, mad_recv_wc, IB_MGMT_RMPP_STATUS_UNV); goto out; } @@ -764,7 +783,8 @@ ib_process_rmpp_recv_wc(struct ib_mad_agent_private *agent, process_rmpp_abort(agent, mad_recv_wc); break; default: - abort_send(agent, mad_recv_wc, IB_MGMT_RMPP_STATUS_BADT); + abort_send(agent, rmpp_mad->mad_hdr.tid, + IB_MGMT_RMPP_STATUS_BADT); nack_recv(agent, mad_recv_wc, IB_MGMT_RMPP_STATUS_BADT); break; } diff --git a/trunk/drivers/infiniband/core/user_mad.c b/trunk/drivers/infiniband/core/user_mad.c index afe70a549c2f..fb6cd42601f9 100644 --- a/trunk/drivers/infiniband/core/user_mad.c +++ b/trunk/drivers/infiniband/core/user_mad.c @@ -177,6 +177,17 @@ static int queue_packet(struct ib_umad_file *file, return ret; } +static int data_offset(u8 mgmt_class) +{ + if (mgmt_class == IB_MGMT_CLASS_SUBN_ADM) + return IB_MGMT_SA_HDR; + else if ((mgmt_class >= IB_MGMT_CLASS_VENDOR_RANGE2_START) && + (mgmt_class <= IB_MGMT_CLASS_VENDOR_RANGE2_END)) + return IB_MGMT_VENDOR_HDR; + else + return IB_MGMT_RMPP_HDR; +} + static void send_handler(struct ib_mad_agent *agent, struct ib_mad_send_wc *send_wc) { @@ -272,7 +283,7 @@ static ssize_t copy_recv_mad(char __user *buf, struct ib_umad_packet *packet, */ return -ENOSPC; } - offset = ib_get_mad_data_offset(recv_buf->mad->mad_hdr.mgmt_class); + offset = data_offset(recv_buf->mad->mad_hdr.mgmt_class); max_seg_payload = sizeof (struct ib_mad) - offset; for (left = packet->length - seg_payload, buf += seg_payload; @@ -430,14 +441,21 @@ static ssize_t ib_umad_write(struct file *filp, const char __user *buf, } rmpp_mad = (struct ib_rmpp_mad *) packet->mad.data; - hdr_len = ib_get_mad_data_offset(rmpp_mad->mad_hdr.mgmt_class); - if (!ib_is_mad_class_rmpp(rmpp_mad->mad_hdr.mgmt_class)) { - copy_offset = IB_MGMT_MAD_HDR; - rmpp_active = 0; - } else { + if (rmpp_mad->mad_hdr.mgmt_class == IB_MGMT_CLASS_SUBN_ADM) { + hdr_len = IB_MGMT_SA_HDR; copy_offset = IB_MGMT_RMPP_HDR; rmpp_active = ib_get_rmpp_flags(&rmpp_mad->rmpp_hdr) & IB_MGMT_RMPP_FLAG_ACTIVE; + } else if (rmpp_mad->mad_hdr.mgmt_class >= IB_MGMT_CLASS_VENDOR_RANGE2_START && + rmpp_mad->mad_hdr.mgmt_class <= IB_MGMT_CLASS_VENDOR_RANGE2_END) { + hdr_len = IB_MGMT_VENDOR_HDR; + copy_offset = IB_MGMT_RMPP_HDR; + rmpp_active = ib_get_rmpp_flags(&rmpp_mad->rmpp_hdr) & + IB_MGMT_RMPP_FLAG_ACTIVE; + } else { + hdr_len = IB_MGMT_MAD_HDR; + copy_offset = IB_MGMT_MAD_HDR; + rmpp_active = 0; } data_len = count - sizeof (struct ib_user_mad) - hdr_len; diff --git a/trunk/drivers/infiniband/hw/mthca/mthca_av.c b/trunk/drivers/infiniband/hw/mthca/mthca_av.c index bc5bdcbe51b5..f023d3936518 100644 --- a/trunk/drivers/infiniband/hw/mthca/mthca_av.c +++ b/trunk/drivers/infiniband/hw/mthca/mthca_av.c @@ -265,7 +265,7 @@ int __devinit mthca_init_av_table(struct mthca_dev *dev) return -ENOMEM; } -void mthca_cleanup_av_table(struct mthca_dev *dev) +void __devexit mthca_cleanup_av_table(struct mthca_dev *dev) { if (mthca_is_memfree(dev)) return; diff --git a/trunk/drivers/infiniband/hw/mthca/mthca_cq.c b/trunk/drivers/infiniband/hw/mthca/mthca_cq.c index 312cf90731ea..76aabc5bf371 100644 --- a/trunk/drivers/infiniband/hw/mthca/mthca_cq.c +++ b/trunk/drivers/infiniband/hw/mthca/mthca_cq.c @@ -973,7 +973,7 @@ int __devinit mthca_init_cq_table(struct mthca_dev *dev) return err; } -void mthca_cleanup_cq_table(struct mthca_dev *dev) +void __devexit mthca_cleanup_cq_table(struct mthca_dev *dev) { mthca_array_cleanup(&dev->cq_table.cq, dev->limits.num_cqs); mthca_alloc_cleanup(&dev->cq_table.alloc); diff --git a/trunk/drivers/infiniband/hw/mthca/mthca_eq.c b/trunk/drivers/infiniband/hw/mthca/mthca_eq.c index 99f109c3815d..cbdc348fb689 100644 --- a/trunk/drivers/infiniband/hw/mthca/mthca_eq.c +++ b/trunk/drivers/infiniband/hw/mthca/mthca_eq.c @@ -765,7 +765,7 @@ static int __devinit mthca_map_eq_regs(struct mthca_dev *dev) } -static void mthca_unmap_eq_regs(struct mthca_dev *dev) +static void __devexit mthca_unmap_eq_regs(struct mthca_dev *dev) { if (mthca_is_memfree(dev)) { 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) return ret; } -void mthca_unmap_eq_icm(struct mthca_dev *dev) +void __devexit mthca_unmap_eq_icm(struct mthca_dev *dev) { u8 status; @@ -954,7 +954,7 @@ int __devinit mthca_init_eq_table(struct mthca_dev *dev) return err; } -void mthca_cleanup_eq_table(struct mthca_dev *dev) +void __devexit mthca_cleanup_eq_table(struct mthca_dev *dev) { u8 status; int i; diff --git a/trunk/drivers/infiniband/hw/mthca/mthca_mad.c b/trunk/drivers/infiniband/hw/mthca/mthca_mad.c index dfb482eac9a2..4ace6a392f41 100644 --- a/trunk/drivers/infiniband/hw/mthca/mthca_mad.c +++ b/trunk/drivers/infiniband/hw/mthca/mthca_mad.c @@ -271,7 +271,7 @@ int mthca_create_agents(struct mthca_dev *dev) return PTR_ERR(agent); } -void __devexit mthca_free_agents(struct mthca_dev *dev) +void mthca_free_agents(struct mthca_dev *dev) { struct ib_mad_agent *agent; int p, q; diff --git a/trunk/drivers/infiniband/hw/mthca/mthca_mcg.c b/trunk/drivers/infiniband/hw/mthca/mthca_mcg.c index 47ca8a9b7247..9965bda9afed 100644 --- a/trunk/drivers/infiniband/hw/mthca/mthca_mcg.c +++ b/trunk/drivers/infiniband/hw/mthca/mthca_mcg.c @@ -388,7 +388,7 @@ int __devinit mthca_init_mcg_table(struct mthca_dev *dev) return 0; } -void mthca_cleanup_mcg_table(struct mthca_dev *dev) +void __devexit mthca_cleanup_mcg_table(struct mthca_dev *dev) { mthca_alloc_cleanup(&dev->mcg_table.alloc); } diff --git a/trunk/drivers/infiniband/hw/mthca/mthca_mr.c b/trunk/drivers/infiniband/hw/mthca/mthca_mr.c index 25e1c1db9a40..698b62125765 100644 --- a/trunk/drivers/infiniband/hw/mthca/mthca_mr.c +++ b/trunk/drivers/infiniband/hw/mthca/mthca_mr.c @@ -170,7 +170,7 @@ static int __devinit mthca_buddy_init(struct mthca_buddy *buddy, int max_order) return -ENOMEM; } -static void mthca_buddy_cleanup(struct mthca_buddy *buddy) +static void __devexit mthca_buddy_cleanup(struct mthca_buddy *buddy) { int i; @@ -866,7 +866,7 @@ int __devinit mthca_init_mr_table(struct mthca_dev *dev) return err; } -void mthca_cleanup_mr_table(struct mthca_dev *dev) +void __devexit mthca_cleanup_mr_table(struct mthca_dev *dev) { /* XXX check if any MRs are still allocated? */ if (dev->limits.fmr_reserved_mtts) diff --git a/trunk/drivers/infiniband/hw/mthca/mthca_pd.c b/trunk/drivers/infiniband/hw/mthca/mthca_pd.c index 59df51614c85..105fc5faaddf 100644 --- a/trunk/drivers/infiniband/hw/mthca/mthca_pd.c +++ b/trunk/drivers/infiniband/hw/mthca/mthca_pd.c @@ -77,7 +77,7 @@ int __devinit mthca_init_pd_table(struct mthca_dev *dev) dev->limits.reserved_pds); } -void mthca_cleanup_pd_table(struct mthca_dev *dev) +void __devexit mthca_cleanup_pd_table(struct mthca_dev *dev) { /* XXX check if any PDs are still allocated? */ mthca_alloc_cleanup(&dev->pd_table.alloc); diff --git a/trunk/drivers/infiniband/hw/mthca/mthca_qp.c b/trunk/drivers/infiniband/hw/mthca/mthca_qp.c index 057c8e6af87b..1bc2678c2fae 100644 --- a/trunk/drivers/infiniband/hw/mthca/mthca_qp.c +++ b/trunk/drivers/infiniband/hw/mthca/mthca_qp.c @@ -2204,7 +2204,7 @@ int __devinit mthca_init_qp_table(struct mthca_dev *dev) return err; } -void mthca_cleanup_qp_table(struct mthca_dev *dev) +void __devexit mthca_cleanup_qp_table(struct mthca_dev *dev) { int i; u8 status; diff --git a/trunk/drivers/infiniband/hw/mthca/mthca_srq.c b/trunk/drivers/infiniband/hw/mthca/mthca_srq.c index 2dd3aea05341..0cfd15802217 100644 --- a/trunk/drivers/infiniband/hw/mthca/mthca_srq.c +++ b/trunk/drivers/infiniband/hw/mthca/mthca_srq.c @@ -206,7 +206,7 @@ int mthca_alloc_srq(struct mthca_dev *dev, struct mthca_pd *pd, roundup_pow_of_two(sizeof (struct mthca_next_seg) + srq->max_gs * sizeof (struct mthca_data_seg))); - if (!mthca_is_memfree(dev) && (ds > dev->limits.max_desc_sz)) + if (ds > dev->limits.max_desc_sz) return -EINVAL; srq->wqe_shift = long_log2(ds); @@ -684,7 +684,7 @@ int __devinit mthca_init_srq_table(struct mthca_dev *dev) return err; } -void mthca_cleanup_srq_table(struct mthca_dev *dev) +void __devexit mthca_cleanup_srq_table(struct mthca_dev *dev) { if (!(dev->mthca_flags & MTHCA_FLAG_SRQ)) return; diff --git a/trunk/drivers/infiniband/ulp/ipoib/ipoib_main.c b/trunk/drivers/infiniband/ulp/ipoib/ipoib_main.c index 9b0bd7c746ca..53a32f65788d 100644 --- a/trunk/drivers/infiniband/ulp/ipoib/ipoib_main.c +++ b/trunk/drivers/infiniband/ulp/ipoib/ipoib_main.c @@ -723,7 +723,7 @@ static int ipoib_hard_header(struct sk_buff *skb, * destination address onto the front of the skb so we can * figure out where to send the packet later. */ - if ((!skb->dst || !skb->dst->neighbour) && daddr) { + if (!skb->dst || !skb->dst->neighbour) { struct ipoib_pseudoheader *phdr = (struct ipoib_pseudoheader *) skb_push(skb, sizeof *phdr); memcpy(phdr->hwaddr, daddr, INFINIBAND_ALEN); diff --git a/trunk/drivers/infiniband/ulp/srp/ib_srp.c b/trunk/drivers/infiniband/ulp/srp/ib_srp.c index fd8a95a9c5d3..61924cc30e55 100644 --- a/trunk/drivers/infiniband/ulp/srp/ib_srp.c +++ b/trunk/drivers/infiniband/ulp/srp/ib_srp.c @@ -607,10 +607,10 @@ static void srp_unmap_data(struct scsi_cmnd *scmnd, */ if (likely(scmnd->use_sg)) { nents = scmnd->use_sg; - scat = scmnd->request_buffer; + scat = (struct scatterlist *) scmnd->request_buffer; } else { nents = 1; - scat = &req->fake_sg; + scat = (struct scatterlist *) scmnd->request_buffer; } dma_unmap_sg(target->srp_host->dev->dma_device, scat, nents, diff --git a/trunk/drivers/input/keyboard/hil_kbd.c b/trunk/drivers/input/keyboard/hil_kbd.c index 63f387e4b783..0a90962c38e7 100644 --- a/trunk/drivers/input/keyboard/hil_kbd.c +++ b/trunk/drivers/input/keyboard/hil_kbd.c @@ -66,7 +66,7 @@ static unsigned int hil_kbd_set3[HIL_KEYCODES_SET3_TBLSIZE] = static char hil_language[][16] = { HIL_LOCALE_MAP }; struct hil_kbd { - struct input_dev *dev; + struct input_dev dev; struct serio *serio; /* Input buffer and index for packets from HIL bus. */ @@ -86,7 +86,7 @@ struct hil_kbd { /* Process a complete packet after transfer from the HIL */ static void hil_kbd_process_record(struct hil_kbd *kbd) { - struct input_dev *dev = kbd->dev; + struct input_dev *dev = &kbd->dev; hil_packet *data = kbd->data; hil_packet p; int idx, i, cnt; @@ -240,8 +240,8 @@ static void hil_kbd_disconnect(struct serio *serio) return; } + input_unregister_device(&kbd->dev); serio_close(serio); - input_unregister_device(kbd->dev); kfree(kbd); } @@ -251,18 +251,16 @@ static int hil_kbd_connect(struct serio *serio, struct serio_driver *drv) uint8_t did, *idd; int i; - kbd = kzalloc(sizeof(*kbd), GFP_KERNEL); + kbd = kmalloc(sizeof(*kbd), GFP_KERNEL); if (!kbd) return -ENOMEM; - - kbd->dev = input_allocate_device(); - if (!kbd->dev) goto bail1; - kbd->dev->private = kbd; + memset(kbd, 0, sizeof(struct hil_kbd)); if (serio_open(serio, drv)) goto bail0; serio_set_drvdata(serio, kbd); kbd->serio = serio; + kbd->dev.private = kbd; init_MUTEX_LOCKED(&(kbd->sem)); @@ -304,38 +302,38 @@ static int hil_kbd_connect(struct serio *serio, struct serio_driver *drv) did, hil_language[did & HIL_IDD_DID_TYPE_KB_LANG_MASK]); break; default: - goto bail2; + goto bail1; } if(HIL_IDD_NUM_BUTTONS(idd) || HIL_IDD_NUM_AXES_PER_SET(*idd)) { printk(KERN_INFO PREFIX "keyboards only, no combo devices supported.\n"); - goto bail2; + goto bail1; } - kbd->dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP); - kbd->dev->ledbit[0] = BIT(LED_NUML) | BIT(LED_CAPSL) | BIT(LED_SCROLLL); - kbd->dev->keycodemax = HIL_KEYCODES_SET1_TBLSIZE; - kbd->dev->keycodesize = sizeof(hil_kbd_set1[0]); - kbd->dev->keycode = hil_kbd_set1; - kbd->dev->name = strlen(kbd->rnm) ? kbd->rnm : HIL_GENERIC_NAME; - kbd->dev->phys = "hpkbd/input0"; /* XXX */ + kbd->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_REP); + kbd->dev.ledbit[0] = BIT(LED_NUML) | BIT(LED_CAPSL) | BIT(LED_SCROLLL); + kbd->dev.keycodemax = HIL_KEYCODES_SET1_TBLSIZE; + kbd->dev.keycodesize = sizeof(hil_kbd_set1[0]); + kbd->dev.keycode = hil_kbd_set1; + kbd->dev.name = strlen(kbd->rnm) ? kbd->rnm : HIL_GENERIC_NAME; + kbd->dev.phys = "hpkbd/input0"; /* XXX */ - kbd->dev->id.bustype = BUS_HIL; - kbd->dev->id.vendor = PCI_VENDOR_ID_HP; - kbd->dev->id.product = 0x0001; /* TODO: get from kbd->rsc */ - kbd->dev->id.version = 0x0100; /* TODO: get from kbd->rsc */ - kbd->dev->dev = &serio->dev; + kbd->dev.id.bustype = BUS_HIL; + kbd->dev.id.vendor = PCI_VENDOR_ID_HP; + kbd->dev.id.product = 0x0001; /* TODO: get from kbd->rsc */ + kbd->dev.id.version = 0x0100; /* TODO: get from kbd->rsc */ + kbd->dev.dev = &serio->dev; for (i = 0; i < 128; i++) { - set_bit(hil_kbd_set1[i], kbd->dev->keybit); - set_bit(hil_kbd_set3[i], kbd->dev->keybit); + set_bit(hil_kbd_set1[i], kbd->dev.keybit); + set_bit(hil_kbd_set3[i], kbd->dev.keybit); } - clear_bit(0, kbd->dev->keybit); + clear_bit(0, kbd->dev.keybit); - input_register_device(kbd->dev); + input_register_device(&kbd->dev); printk(KERN_INFO "input: %s, ID: %d\n", - kbd->dev->name, did); + kbd->dev.name, did); serio->write(serio, 0); serio->write(serio, 0); @@ -345,10 +343,8 @@ static int hil_kbd_connect(struct serio *serio, struct serio_driver *drv) up(&(kbd->sem)); return 0; - bail2: - serio_close(serio); bail1: - input_free_device(kbd->dev); + serio_close(serio); bail0: kfree(kbd); serio_set_drvdata(serio, NULL); diff --git a/trunk/drivers/input/keyboard/hilkbd.c b/trunk/drivers/input/keyboard/hilkbd.c index 33edd030aa75..e95bc052e32a 100644 --- a/trunk/drivers/input/keyboard/hilkbd.c +++ b/trunk/drivers/input/keyboard/hilkbd.c @@ -3,7 +3,7 @@ * * Copyright (C) 1998 Philip Blundell * Copyright (C) 1999 Matthew Wilcox - * Copyright (C) 1999-2006 Helge Deller + * Copyright (C) 1999-2003 Helge Deller * * Very basic HP Human Interface Loop (HIL) driver. * This driver handles the keyboard on HP300 (m68k) and on some @@ -90,7 +90,7 @@ static unsigned int hphilkeyb_keycode[HIL_KEYCODES_SET1_TBLSIZE] = /* HIL structure */ static struct { - struct input_dev *dev; + struct input_dev dev; unsigned int curdev; @@ -117,7 +117,7 @@ static void poll_finished(void) down = (hil_dev.data[1] & 1) == 0; scode = hil_dev.data[1] >> 1; key = hphilkeyb_keycode[scode]; - input_report_key(hil_dev.dev, key, down); + input_report_key(&hil_dev.dev, key, down); break; } hil_dev.curdev = 0; @@ -207,14 +207,9 @@ hil_keyb_init(void) unsigned int i, kbid; wait_queue_head_t hil_wait; - if (hil_dev.dev) { + if (hil_dev.dev.id.bustype) { return -ENODEV; /* already initialized */ } - - hil_dev.dev = input_allocate_device(); - if (!hil_dev.dev) - return -ENOMEM; - hil_dev.dev->private = &hil_dev; #if defined(CONFIG_HP300) if (!hwreg_present((void *)(HILBASE + HIL_DATA))) @@ -252,26 +247,28 @@ hil_keyb_init(void) c = 0; hil_do(HIL_WRITEKBDSADR, &c, 1); + init_input_dev(&hil_dev.dev); + for (i = 0; i < HIL_KEYCODES_SET1_TBLSIZE; i++) if (hphilkeyb_keycode[i] != KEY_RESERVED) - set_bit(hphilkeyb_keycode[i], hil_dev.dev->keybit); - - hil_dev.dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP); - hil_dev.dev->ledbit[0] = BIT(LED_NUML) | BIT(LED_CAPSL) | BIT(LED_SCROLLL); - hil_dev.dev->keycodemax = HIL_KEYCODES_SET1_TBLSIZE; - hil_dev.dev->keycodesize = sizeof(hphilkeyb_keycode[0]); - hil_dev.dev->keycode = hphilkeyb_keycode; - hil_dev.dev->name = "HIL keyboard"; - hil_dev.dev->phys = "hpkbd/input0"; - - hil_dev.dev->id.bustype = BUS_HIL; - hil_dev.dev->id.vendor = PCI_VENDOR_ID_HP; - hil_dev.dev->id.product = 0x0001; - hil_dev.dev->id.version = 0x0010; - - input_register_device(hil_dev.dev); + set_bit(hphilkeyb_keycode[i], hil_dev.dev.keybit); + + hil_dev.dev.evbit[0] = BIT(EV_KEY) | BIT(EV_REP); + hil_dev.dev.ledbit[0] = BIT(LED_NUML) | BIT(LED_CAPSL) | BIT(LED_SCROLLL); + hil_dev.dev.keycodemax = HIL_KEYCODES_SET1_TBLSIZE; + hil_dev.dev.keycodesize = sizeof(hphilkeyb_keycode[0]); + hil_dev.dev.keycode = hphilkeyb_keycode; + hil_dev.dev.name = "HIL keyboard"; + hil_dev.dev.phys = "hpkbd/input0"; + + hil_dev.dev.id.bustype = BUS_HIL; + hil_dev.dev.id.vendor = PCI_VENDOR_ID_HP; + hil_dev.dev.id.product = 0x0001; + hil_dev.dev.id.version = 0x0010; + + input_register_device(&hil_dev.dev); printk(KERN_INFO "input: %s, ID %d at 0x%08lx (irq %d) found and attached\n", - hil_dev.dev->name, kbid, HILBASE, HIL_IRQ); + hil_dev.dev.name, kbid, HILBASE, HIL_IRQ); return 0; } @@ -332,9 +329,7 @@ static void __exit hil_exit(void) /* Turn off interrupts */ hil_do(HIL_INTOFF, NULL, 0); - input_unregister_device(hil_dev.dev); - - hil_dev.dev = NULL; + input_unregister_device(&hil_dev.dev); #if defined(CONFIG_PARISC) unregister_parisc_driver(&hil_driver); diff --git a/trunk/drivers/input/mouse/hil_ptr.c b/trunk/drivers/input/mouse/hil_ptr.c index bfb564fd8fe2..c2bf2ed07dc6 100644 --- a/trunk/drivers/input/mouse/hil_ptr.c +++ b/trunk/drivers/input/mouse/hil_ptr.c @@ -55,7 +55,7 @@ MODULE_LICENSE("Dual BSD/GPL"); #define HIL_PTR_MAX_LENGTH 16 struct hil_ptr { - struct input_dev *dev; + struct input_dev dev; struct serio *serio; /* Input buffer and index for packets from HIL bus. */ @@ -79,7 +79,7 @@ struct hil_ptr { /* Process a complete packet after transfer from the HIL */ static void hil_ptr_process_record(struct hil_ptr *ptr) { - struct input_dev *dev = ptr->dev; + struct input_dev *dev = &ptr->dev; hil_packet *data = ptr->data; hil_packet p; int idx, i, cnt, laxis; @@ -148,12 +148,12 @@ static void hil_ptr_process_record(struct hil_ptr *ptr) if (absdev) { val = lo + (hi<<8); #ifdef TABLET_AUTOADJUST - if (val < dev->absmin[ABS_X + i]) - dev->absmin[ABS_X + i] = val; - if (val > dev->absmax[ABS_X + i]) - dev->absmax[ABS_X + i] = val; + if (val < ptr->dev.absmin[ABS_X + i]) + ptr->dev.absmin[ABS_X + i] = val; + if (val > ptr->dev.absmax[ABS_X + i]) + ptr->dev.absmax[ABS_X + i] = val; #endif - if (i%3) val = dev->absmax[ABS_X + i] - val; + if (i%3) val = ptr->dev.absmax[ABS_X + i] - val; input_report_abs(dev, ABS_X + i, val); } else { val = (int) (((int8_t)lo) | ((int8_t)hi<<8)); @@ -233,29 +233,26 @@ static void hil_ptr_disconnect(struct serio *serio) return; } + input_unregister_device(&ptr->dev); serio_close(serio); - input_unregister_device(ptr->dev); kfree(ptr); } static int hil_ptr_connect(struct serio *serio, struct serio_driver *driver) { - struct hil_ptr *ptr; - char *txt; - unsigned int i, naxsets, btntype; - uint8_t did, *idd; + struct hil_ptr *ptr; + char *txt; + unsigned int i, naxsets, btntype; + uint8_t did, *idd; - if (!(ptr = kzalloc(sizeof(struct hil_ptr), GFP_KERNEL))) - return -ENOMEM; + if (!(ptr = kmalloc(sizeof(struct hil_ptr), GFP_KERNEL))) return -ENOMEM; + memset(ptr, 0, sizeof(struct hil_ptr)); - ptr->dev = input_allocate_device(); - if (!ptr->dev) goto bail0; - ptr->dev->private = ptr; - - if (serio_open(serio, driver)) goto bail1; + if (serio_open(serio, driver)) goto bail0; serio_set_drvdata(serio, ptr); ptr->serio = serio; + ptr->dev.private = ptr; init_MUTEX_LOCKED(&(ptr->sem)); @@ -286,24 +283,25 @@ static int hil_ptr_connect(struct serio *serio, struct serio_driver *driver) up(&(ptr->sem)); + init_input_dev(&ptr->dev); did = ptr->idd[0]; idd = ptr->idd + 1; txt = "unknown"; if ((did & HIL_IDD_DID_TYPE_MASK) == HIL_IDD_DID_TYPE_REL) { - ptr->dev->evbit[0] = BIT(EV_REL); + ptr->dev.evbit[0] = BIT(EV_REL); txt = "relative"; } if ((did & HIL_IDD_DID_TYPE_MASK) == HIL_IDD_DID_TYPE_ABS) { - ptr->dev->evbit[0] = BIT(EV_ABS); + ptr->dev.evbit[0] = BIT(EV_ABS); txt = "absolute"; } - if (!ptr->dev->evbit[0]) { - goto bail2; + if (!ptr->dev.evbit[0]) { + goto bail1; } ptr->nbtn = HIL_IDD_NUM_BUTTONS(idd); - if (ptr->nbtn) ptr->dev->evbit[0] |= BIT(EV_KEY); + if (ptr->nbtn) ptr->dev.evbit[0] |= BIT(EV_KEY); naxsets = HIL_IDD_NUM_AXSETS(*idd); ptr->naxes = HIL_IDD_NUM_AXES_PER_SET(*idd); @@ -327,7 +325,7 @@ static int hil_ptr_connect(struct serio *serio, struct serio_driver *driver) btntype = BTN_MOUSE; for (i = 0; i < ptr->nbtn; i++) { - set_bit(btntype | i, ptr->dev->keybit); + set_bit(btntype | i, ptr->dev.keybit); ptr->btnmap[i] = btntype | i; } @@ -339,52 +337,50 @@ static int hil_ptr_connect(struct serio *serio, struct serio_driver *driver) if ((did & HIL_IDD_DID_TYPE_MASK) == HIL_IDD_DID_TYPE_REL) { for (i = 0; i < ptr->naxes; i++) { - set_bit(REL_X + i, ptr->dev->relbit); + set_bit(REL_X + i, ptr->dev.relbit); } for (i = 3; (i < ptr->naxes + 3) && (naxsets > 1); i++) { - set_bit(REL_X + i, ptr->dev->relbit); + set_bit(REL_X + i, ptr->dev.relbit); } } else { for (i = 0; i < ptr->naxes; i++) { - set_bit(ABS_X + i, ptr->dev->absbit); - ptr->dev->absmin[ABS_X + i] = 0; - ptr->dev->absmax[ABS_X + i] = + set_bit(ABS_X + i, ptr->dev.absbit); + ptr->dev.absmin[ABS_X + i] = 0; + ptr->dev.absmax[ABS_X + i] = HIL_IDD_AXIS_MAX((ptr->idd + 1), i); } for (i = 3; (i < ptr->naxes + 3) && (naxsets > 1); i++) { - set_bit(ABS_X + i, ptr->dev->absbit); - ptr->dev->absmin[ABS_X + i] = 0; - ptr->dev->absmax[ABS_X + i] = + set_bit(ABS_X + i, ptr->dev.absbit); + ptr->dev.absmin[ABS_X + i] = 0; + ptr->dev.absmax[ABS_X + i] = HIL_IDD_AXIS_MAX((ptr->idd + 1), (i - 3)); } #ifdef TABLET_AUTOADJUST for (i = 0; i < ABS_MAX; i++) { - int diff = ptr->dev->absmax[ABS_X + i] / 10; - ptr->dev->absmin[ABS_X + i] += diff; - ptr->dev->absmax[ABS_X + i] -= diff; + int diff = ptr->dev.absmax[ABS_X + i] / 10; + ptr->dev.absmin[ABS_X + i] += diff; + ptr->dev.absmax[ABS_X + i] -= diff; } #endif } - ptr->dev->name = strlen(ptr->rnm) ? ptr->rnm : HIL_GENERIC_NAME; + ptr->dev.name = strlen(ptr->rnm) ? ptr->rnm : HIL_GENERIC_NAME; - ptr->dev->id.bustype = BUS_HIL; - ptr->dev->id.vendor = PCI_VENDOR_ID_HP; - ptr->dev->id.product = 0x0001; /* TODO: get from ptr->rsc */ - ptr->dev->id.version = 0x0100; /* TODO: get from ptr->rsc */ - ptr->dev->dev = &serio->dev; + ptr->dev.id.bustype = BUS_HIL; + ptr->dev.id.vendor = PCI_VENDOR_ID_HP; + ptr->dev.id.product = 0x0001; /* TODO: get from ptr->rsc */ + ptr->dev.id.version = 0x0100; /* TODO: get from ptr->rsc */ + ptr->dev.dev = &serio->dev; - input_register_device(ptr->dev); + input_register_device(&ptr->dev); printk(KERN_INFO "input: %s (%s), ID: %d\n", - ptr->dev->name, + ptr->dev.name, (btntype == BTN_MOUSE) ? "HIL mouse":"HIL tablet or touchpad", did); return 0; - bail2: - serio_close(serio); bail1: - input_free_device(ptr->dev); + serio_close(serio); bail0: kfree(ptr); serio_set_drvdata(serio, NULL); diff --git a/trunk/drivers/input/serio/gscps2.c b/trunk/drivers/input/serio/gscps2.c index c0b1e4becad3..a7b0de0f92b2 100644 --- a/trunk/drivers/input/serio/gscps2.c +++ b/trunk/drivers/input/serio/gscps2.c @@ -1,7 +1,7 @@ /* * drivers/input/serio/gscps2.c * - * Copyright (c) 2004-2006 Helge Deller + * Copyright (c) 2004 Helge Deller * Copyright (c) 2002 Laurent Canet * Copyright (c) 2002 Thibaut Varene * @@ -354,7 +354,7 @@ static int __init gscps2_probe(struct parisc_device *dev) memset(serio, 0, sizeof(struct serio)); ps2port->port = serio; ps2port->padev = dev; - ps2port->addr = ioremap_nocache(hpa, GSC_STATUS + 4); + ps2port->addr = ioremap(hpa, GSC_STATUS + 4); spin_lock_init(&ps2port->lock); gscps2_reset(ps2port); diff --git a/trunk/drivers/isdn/sc/ioctl.c b/trunk/drivers/isdn/sc/ioctl.c index f4f71226a078..94c9afb7017c 100644 --- a/trunk/drivers/isdn/sc/ioctl.c +++ b/trunk/drivers/isdn/sc/ioctl.c @@ -46,8 +46,7 @@ int sc_ioctl(int card, scs_ioctl *data) pr_debug("%s: SCIOCRESET: ioctl received\n", sc_adapter[card]->devicename); sc_adapter[card]->StartOnReset = 0; - kfree(rcvmsg); - return reset(card); + return (reset(card)); } case SCIOCLOAD: @@ -184,7 +183,7 @@ int sc_ioctl(int card, scs_ioctl *data) sc_adapter[card]->devicename); spid = kmalloc(SCIOC_SPIDSIZE, GFP_KERNEL); - if (!spid) { + if(!spid) { kfree(rcvmsg); return -ENOMEM; } @@ -196,10 +195,10 @@ int sc_ioctl(int card, scs_ioctl *data) if (!status) { pr_debug("%s: SCIOCGETSPID: command successful\n", sc_adapter[card]->devicename); - } else { + } + else { pr_debug("%s: SCIOCGETSPID: command failed (status = %d)\n", sc_adapter[card]->devicename, status); - kfree(spid); kfree(rcvmsg); return status; } diff --git a/trunk/drivers/leds/Kconfig b/trunk/drivers/leds/Kconfig deleted file mode 100644 index 2c4f20b7f021..000000000000 --- a/trunk/drivers/leds/Kconfig +++ /dev/null @@ -1,77 +0,0 @@ - -menu "LED devices" - -config NEW_LEDS - bool "LED Support" - help - Say Y to enable Linux LED support. This is not related to standard - keyboard LEDs which are controlled via the input system. - -config LEDS_CLASS - tristate "LED Class Support" - depends NEW_LEDS - help - This option enables the led sysfs class in /sys/class/leds. You'll - need this to do anything useful with LEDs. If unsure, say N. - -config LEDS_TRIGGERS - bool "LED Trigger support" - depends NEW_LEDS - help - This option enables trigger support for the leds class. - These triggers allow kernel events to drive the LEDs and can - be configured via sysfs. If unsure, say Y. - -config LEDS_CORGI - tristate "LED Support for the Sharp SL-C7x0 series" - depends LEDS_CLASS && PXA_SHARP_C7xx - help - This option enables support for the LEDs on Sharp Zaurus - SL-C7x0 series (C700, C750, C760, C860). - -config LEDS_LOCOMO - tristate "LED Support for Locomo device" - depends LEDS_CLASS && SHARP_LOCOMO - help - This option enables support for the LEDs on Sharp Locomo. - Zaurus models SL-5500 and SL-5600. - -config LEDS_SPITZ - tristate "LED Support for the Sharp SL-Cxx00 series" - depends LEDS_CLASS && PXA_SHARP_Cxx00 - help - This option enables support for the LEDs on Sharp Zaurus - SL-Cxx00 series (C1000, C3000, C3100). - -config LEDS_IXP4XX - tristate "LED Support for GPIO connected LEDs on IXP4XX processors" - depends LEDS_CLASS && ARCH_IXP4XX - help - This option enables support for the LEDs connected to GPIO - outputs of the Intel IXP4XX processors. To be useful the - particular board must have LEDs and they must be connected - to the GPIO lines. If unsure, say Y. - -config LEDS_TOSA - tristate "LED Support for the Sharp SL-6000 series" - depends LEDS_CLASS && PXA_SHARPSL - help - This option enables support for the LEDs on Sharp Zaurus - SL-6000 series. - -config LEDS_TRIGGER_TIMER - tristate "LED Timer Trigger" - depends LEDS_TRIGGERS - help - This allows LEDs to be controlled by a programmable timer - via sysfs. If unsure, say Y. - -config LEDS_TRIGGER_IDE_DISK - bool "LED Timer Trigger" - depends LEDS_TRIGGERS && BLK_DEV_IDEDISK - help - This allows LEDs to be controlled by IDE disk activity. - If unsure, say Y. - -endmenu - diff --git a/trunk/drivers/leds/Makefile b/trunk/drivers/leds/Makefile deleted file mode 100644 index 40699d3cabbf..000000000000 --- a/trunk/drivers/leds/Makefile +++ /dev/null @@ -1,16 +0,0 @@ - -# LED Core -obj-$(CONFIG_NEW_LEDS) += led-core.o -obj-$(CONFIG_LEDS_CLASS) += led-class.o -obj-$(CONFIG_LEDS_TRIGGERS) += led-triggers.o - -# LED Platform Drivers -obj-$(CONFIG_LEDS_CORGI) += leds-corgi.o -obj-$(CONFIG_LEDS_LOCOMO) += leds-locomo.o -obj-$(CONFIG_LEDS_SPITZ) += leds-spitz.o -obj-$(CONFIG_LEDS_IXP4XX) += leds-ixp4xx-gpio.o -obj-$(CONFIG_LEDS_TOSA) += leds-tosa.o - -# LED Triggers -obj-$(CONFIG_LEDS_TRIGGER_TIMER) += ledtrig-timer.o -obj-$(CONFIG_LEDS_TRIGGER_IDE_DISK) += ledtrig-ide-disk.o diff --git a/trunk/drivers/leds/led-class.c b/trunk/drivers/leds/led-class.c deleted file mode 100644 index b0b5d05fadd6..000000000000 --- a/trunk/drivers/leds/led-class.c +++ /dev/null @@ -1,167 +0,0 @@ -/* - * LED Class Core - * - * Copyright (C) 2005 John Lenz - * Copyright (C) 2005-2006 Richard Purdie - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "leds.h" - -static struct class *leds_class; - -static ssize_t led_brightness_show(struct class_device *dev, char *buf) -{ - struct led_classdev *led_cdev = class_get_devdata(dev); - ssize_t ret = 0; - - /* no lock needed for this */ - sprintf(buf, "%u\n", led_cdev->brightness); - ret = strlen(buf) + 1; - - return ret; -} - -static ssize_t led_brightness_store(struct class_device *dev, - const char *buf, size_t size) -{ - struct led_classdev *led_cdev = class_get_devdata(dev); - ssize_t ret = -EINVAL; - char *after; - unsigned long state = simple_strtoul(buf, &after, 10); - - if (after - buf > 0) { - ret = after - buf; - led_set_brightness(led_cdev, state); - } - - return ret; -} - -static CLASS_DEVICE_ATTR(brightness, 0644, led_brightness_show, - led_brightness_store); -#ifdef CONFIG_LEDS_TRIGGERS -static CLASS_DEVICE_ATTR(trigger, 0644, led_trigger_show, led_trigger_store); -#endif - -/** - * led_classdev_suspend - suspend an led_classdev. - * @led_cdev: the led_classdev to suspend. - */ -void led_classdev_suspend(struct led_classdev *led_cdev) -{ - led_cdev->flags |= LED_SUSPENDED; - led_cdev->brightness_set(led_cdev, 0); -} -EXPORT_SYMBOL_GPL(led_classdev_suspend); - -/** - * led_classdev_resume - resume an led_classdev. - * @led_cdev: the led_classdev to resume. - */ -void led_classdev_resume(struct led_classdev *led_cdev) -{ - led_cdev->brightness_set(led_cdev, led_cdev->brightness); - led_cdev->flags &= ~LED_SUSPENDED; -} -EXPORT_SYMBOL_GPL(led_classdev_resume); - -/** - * led_classdev_register - register a new object of led_classdev class. - * @dev: The device to register. - * @led_cdev: the led_classdev structure for this device. - */ -int led_classdev_register(struct device *parent, struct led_classdev *led_cdev) -{ - led_cdev->class_dev = class_device_create(leds_class, NULL, 0, - parent, "%s", led_cdev->name); - if (unlikely(IS_ERR(led_cdev->class_dev))) - return PTR_ERR(led_cdev->class_dev); - - class_set_devdata(led_cdev->class_dev, led_cdev); - - /* register the attributes */ - class_device_create_file(led_cdev->class_dev, - &class_device_attr_brightness); - - /* add to the list of leds */ - write_lock(&leds_list_lock); - list_add_tail(&led_cdev->node, &leds_list); - write_unlock(&leds_list_lock); - -#ifdef CONFIG_LEDS_TRIGGERS - rwlock_init(&led_cdev->trigger_lock); - - led_trigger_set_default(led_cdev); - - class_device_create_file(led_cdev->class_dev, - &class_device_attr_trigger); -#endif - - printk(KERN_INFO "Registered led device: %s\n", - led_cdev->class_dev->class_id); - - return 0; -} -EXPORT_SYMBOL_GPL(led_classdev_register); - -/** - * led_classdev_unregister - unregisters a object of led_properties class. - * @led_cdev: the led device to unreigister - * - * Unregisters a previously registered via led_classdev_register object. - */ -void led_classdev_unregister(struct led_classdev *led_cdev) -{ - class_device_remove_file(led_cdev->class_dev, - &class_device_attr_brightness); -#ifdef CONFIG_LEDS_TRIGGERS - class_device_remove_file(led_cdev->class_dev, - &class_device_attr_trigger); - write_lock(&led_cdev->trigger_lock); - if (led_cdev->trigger) - led_trigger_set(led_cdev, NULL); - write_unlock(&led_cdev->trigger_lock); -#endif - - class_device_unregister(led_cdev->class_dev); - - write_lock(&leds_list_lock); - list_del(&led_cdev->node); - write_unlock(&leds_list_lock); -} -EXPORT_SYMBOL_GPL(led_classdev_unregister); - -static int __init leds_init(void) -{ - leds_class = class_create(THIS_MODULE, "leds"); - if (IS_ERR(leds_class)) - return PTR_ERR(leds_class); - return 0; -} - -static void __exit leds_exit(void) -{ - class_destroy(leds_class); -} - -subsys_initcall(leds_init); -module_exit(leds_exit); - -MODULE_AUTHOR("John Lenz, Richard Purdie"); -MODULE_LICENSE("GPL"); -MODULE_DESCRIPTION("LED Class Interface"); diff --git a/trunk/drivers/leds/led-core.c b/trunk/drivers/leds/led-core.c deleted file mode 100644 index fe6541326c71..000000000000 --- a/trunk/drivers/leds/led-core.c +++ /dev/null @@ -1,25 +0,0 @@ -/* - * LED Class Core - * - * Copyright 2005-2006 Openedhand Ltd. - * - * Author: Richard Purdie - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - */ - -#include -#include -#include -#include -#include -#include "leds.h" - -rwlock_t leds_list_lock = RW_LOCK_UNLOCKED; -LIST_HEAD(leds_list); - -EXPORT_SYMBOL_GPL(leds_list); -EXPORT_SYMBOL_GPL(leds_list_lock); diff --git a/trunk/drivers/leds/led-triggers.c b/trunk/drivers/leds/led-triggers.c deleted file mode 100644 index 5e2cd8be1191..000000000000 --- a/trunk/drivers/leds/led-triggers.c +++ /dev/null @@ -1,239 +0,0 @@ -/* - * LED Triggers Core - * - * Copyright 2005-2006 Openedhand Ltd. - * - * Author: Richard Purdie - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "leds.h" - -/* - * Nests outside led_cdev->trigger_lock - */ -static rwlock_t triggers_list_lock = RW_LOCK_UNLOCKED; -static LIST_HEAD(trigger_list); - -ssize_t led_trigger_store(struct class_device *dev, const char *buf, - size_t count) -{ - struct led_classdev *led_cdev = class_get_devdata(dev); - char trigger_name[TRIG_NAME_MAX]; - struct led_trigger *trig; - size_t len; - - trigger_name[sizeof(trigger_name) - 1] = '\0'; - strncpy(trigger_name, buf, sizeof(trigger_name) - 1); - len = strlen(trigger_name); - - if (len && trigger_name[len - 1] == '\n') - trigger_name[len - 1] = '\0'; - - if (!strcmp(trigger_name, "none")) { - write_lock(&led_cdev->trigger_lock); - led_trigger_set(led_cdev, NULL); - write_unlock(&led_cdev->trigger_lock); - return count; - } - - read_lock(&triggers_list_lock); - list_for_each_entry(trig, &trigger_list, next_trig) { - if (!strcmp(trigger_name, trig->name)) { - write_lock(&led_cdev->trigger_lock); - led_trigger_set(led_cdev, trig); - write_unlock(&led_cdev->trigger_lock); - - read_unlock(&triggers_list_lock); - return count; - } - } - read_unlock(&triggers_list_lock); - - return -EINVAL; -} - - -ssize_t led_trigger_show(struct class_device *dev, char *buf) -{ - struct led_classdev *led_cdev = class_get_devdata(dev); - struct led_trigger *trig; - int len = 0; - - read_lock(&triggers_list_lock); - read_lock(&led_cdev->trigger_lock); - - if (!led_cdev->trigger) - len += sprintf(buf+len, "[none] "); - else - len += sprintf(buf+len, "none "); - - list_for_each_entry(trig, &trigger_list, next_trig) { - if (led_cdev->trigger && !strcmp(led_cdev->trigger->name, - trig->name)) - len += sprintf(buf+len, "[%s] ", trig->name); - else - len += sprintf(buf+len, "%s ", trig->name); - } - read_unlock(&led_cdev->trigger_lock); - read_unlock(&triggers_list_lock); - - len += sprintf(len+buf, "\n"); - return len; -} - -void led_trigger_event(struct led_trigger *trigger, - enum led_brightness brightness) -{ - struct list_head *entry; - - if (!trigger) - return; - - read_lock(&trigger->leddev_list_lock); - list_for_each(entry, &trigger->led_cdevs) { - struct led_classdev *led_cdev; - - led_cdev = list_entry(entry, struct led_classdev, trig_list); - led_set_brightness(led_cdev, brightness); - } - read_unlock(&trigger->leddev_list_lock); -} - -/* Caller must ensure led_cdev->trigger_lock held */ -void led_trigger_set(struct led_classdev *led_cdev, struct led_trigger *trigger) -{ - unsigned long flags; - - /* Remove any existing trigger */ - if (led_cdev->trigger) { - write_lock_irqsave(&led_cdev->trigger->leddev_list_lock, flags); - list_del(&led_cdev->trig_list); - write_unlock_irqrestore(&led_cdev->trigger->leddev_list_lock, flags); - if (led_cdev->trigger->deactivate) - led_cdev->trigger->deactivate(led_cdev); - } - if (trigger) { - write_lock_irqsave(&trigger->leddev_list_lock, flags); - list_add_tail(&led_cdev->trig_list, &trigger->led_cdevs); - write_unlock_irqrestore(&trigger->leddev_list_lock, flags); - if (trigger->activate) - trigger->activate(led_cdev); - } - led_cdev->trigger = trigger; -} - -void led_trigger_set_default(struct led_classdev *led_cdev) -{ - struct led_trigger *trig; - - if (!led_cdev->default_trigger) - return; - - read_lock(&triggers_list_lock); - write_lock(&led_cdev->trigger_lock); - list_for_each_entry(trig, &trigger_list, next_trig) { - if (!strcmp(led_cdev->default_trigger, trig->name)) - led_trigger_set(led_cdev, trig); - } - write_unlock(&led_cdev->trigger_lock); - read_unlock(&triggers_list_lock); -} - -int led_trigger_register(struct led_trigger *trigger) -{ - struct led_classdev *led_cdev; - - rwlock_init(&trigger->leddev_list_lock); - INIT_LIST_HEAD(&trigger->led_cdevs); - - /* Add to the list of led triggers */ - write_lock(&triggers_list_lock); - list_add_tail(&trigger->next_trig, &trigger_list); - write_unlock(&triggers_list_lock); - - /* Register with any LEDs that have this as a default trigger */ - read_lock(&leds_list_lock); - list_for_each_entry(led_cdev, &leds_list, node) { - write_lock(&led_cdev->trigger_lock); - if (!led_cdev->trigger && led_cdev->default_trigger && - !strcmp(led_cdev->default_trigger, trigger->name)) - led_trigger_set(led_cdev, trigger); - write_unlock(&led_cdev->trigger_lock); - } - read_unlock(&leds_list_lock); - - return 0; -} - -void led_trigger_register_simple(const char *name, struct led_trigger **tp) -{ - struct led_trigger *trigger; - - trigger = kzalloc(sizeof(struct led_trigger), GFP_KERNEL); - - if (trigger) { - trigger->name = name; - led_trigger_register(trigger); - } - *tp = trigger; -} - -void led_trigger_unregister(struct led_trigger *trigger) -{ - struct led_classdev *led_cdev; - - /* Remove from the list of led triggers */ - write_lock(&triggers_list_lock); - list_del(&trigger->next_trig); - write_unlock(&triggers_list_lock); - - /* Remove anyone actively using this trigger */ - read_lock(&leds_list_lock); - list_for_each_entry(led_cdev, &leds_list, node) { - write_lock(&led_cdev->trigger_lock); - if (led_cdev->trigger == trigger) - led_trigger_set(led_cdev, NULL); - write_unlock(&led_cdev->trigger_lock); - } - read_unlock(&leds_list_lock); -} - -void led_trigger_unregister_simple(struct led_trigger *trigger) -{ - led_trigger_unregister(trigger); - kfree(trigger); -} - -/* Used by LED Class */ -EXPORT_SYMBOL_GPL(led_trigger_set); -EXPORT_SYMBOL_GPL(led_trigger_set_default); -EXPORT_SYMBOL_GPL(led_trigger_show); -EXPORT_SYMBOL_GPL(led_trigger_store); - -/* LED Trigger Interface */ -EXPORT_SYMBOL_GPL(led_trigger_register); -EXPORT_SYMBOL_GPL(led_trigger_unregister); - -/* Simple LED Tigger Interface */ -EXPORT_SYMBOL_GPL(led_trigger_register_simple); -EXPORT_SYMBOL_GPL(led_trigger_unregister_simple); -EXPORT_SYMBOL_GPL(led_trigger_event); - -MODULE_AUTHOR("Richard Purdie"); -MODULE_LICENSE("GPL"); -MODULE_DESCRIPTION("LED Triggers Core"); diff --git a/trunk/drivers/leds/leds-corgi.c b/trunk/drivers/leds/leds-corgi.c deleted file mode 100644 index bb7d84df0121..000000000000 --- a/trunk/drivers/leds/leds-corgi.c +++ /dev/null @@ -1,121 +0,0 @@ -/* - * LED Triggers Core - * - * Copyright 2005-2006 Openedhand Ltd. - * - * Author: Richard Purdie - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static void corgiled_amber_set(struct led_classdev *led_cdev, enum led_brightness value) -{ - if (value) - GPSR0 = GPIO_bit(CORGI_GPIO_LED_ORANGE); - else - GPCR0 = GPIO_bit(CORGI_GPIO_LED_ORANGE); -} - -static void corgiled_green_set(struct led_classdev *led_cdev, enum led_brightness value) -{ - if (value) - set_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_LED_GREEN); - else - reset_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_LED_GREEN); -} - -static struct led_classdev corgi_amber_led = { - .name = "corgi:amber", - .default_trigger = "sharpsl-charge", - .brightness_set = corgiled_amber_set, -}; - -static struct led_classdev corgi_green_led = { - .name = "corgi:green", - .default_trigger = "nand-disk", - .brightness_set = corgiled_green_set, -}; - -#ifdef CONFIG_PM -static int corgiled_suspend(struct platform_device *dev, pm_message_t state) -{ -#ifdef CONFIG_LEDS_TRIGGERS - if (corgi_amber_led.trigger && strcmp(corgi_amber_led.trigger->name, "sharpsl-charge")) -#endif - led_classdev_suspend(&corgi_amber_led); - led_classdev_suspend(&corgi_green_led); - return 0; -} - -static int corgiled_resume(struct platform_device *dev) -{ - led_classdev_resume(&corgi_amber_led); - led_classdev_resume(&corgi_green_led); - return 0; -} -#endif - -static int corgiled_probe(struct platform_device *pdev) -{ - int ret; - - ret = led_classdev_register(&pdev->dev, &corgi_amber_led); - if (ret < 0) - return ret; - - ret = led_classdev_register(&pdev->dev, &corgi_green_led); - if (ret < 0) - led_classdev_unregister(&corgi_amber_led); - - return ret; -} - -static int corgiled_remove(struct platform_device *pdev) -{ - led_classdev_unregister(&corgi_amber_led); - led_classdev_unregister(&corgi_green_led); - return 0; -} - -static struct platform_driver corgiled_driver = { - .probe = corgiled_probe, - .remove = corgiled_remove, -#ifdef CONFIG_PM - .suspend = corgiled_suspend, - .resume = corgiled_resume, -#endif - .driver = { - .name = "corgi-led", - }, -}; - -static int __init corgiled_init(void) -{ - return platform_driver_register(&corgiled_driver); -} - -static void __exit corgiled_exit(void) -{ - platform_driver_unregister(&corgiled_driver); -} - -module_init(corgiled_init); -module_exit(corgiled_exit); - -MODULE_AUTHOR("Richard Purdie "); -MODULE_DESCRIPTION("Corgi LED driver"); -MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/leds/leds-ixp4xx-gpio.c b/trunk/drivers/leds/leds-ixp4xx-gpio.c deleted file mode 100644 index 30ced150e4cf..000000000000 --- a/trunk/drivers/leds/leds-ixp4xx-gpio.c +++ /dev/null @@ -1,215 +0,0 @@ -/* - * IXP4XX GPIO driver LED driver - * - * Author: John Bowler - * - * Copyright (c) 2006 John Bowler - * - * Permission is hereby granted, free of charge, to any - * person obtaining a copy of this software and associated - * documentation files (the "Software"), to deal in the - * Software without restriction, including without - * limitation the rights to use, copy, modify, merge, - * publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the - * following conditions: - * - * The above copyright notice and this permission notice - * shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF - * ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED - * TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A - * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT - * SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - */ - -#include -#include -#include -#include -#include -#include -#include - -extern spinlock_t gpio_lock; - -/* Up to 16 gpio lines are possible. */ -#define GPIO_MAX 16 -static struct ixp4xxgpioled_device { - struct led_classdev ancestor; - int flags; -} ixp4xxgpioled_devices[GPIO_MAX]; - -void ixp4xxgpioled_brightness_set(struct led_classdev *pled, - enum led_brightness value) -{ - const struct ixp4xxgpioled_device *const ixp4xx_dev = - container_of(pled, struct ixp4xxgpioled_device, ancestor); - const u32 gpio_pin = ixp4xx_dev - ixp4xxgpioled_devices; - - if (gpio_pin < GPIO_MAX && ixp4xx_dev->ancestor.name != 0) { - /* Set or clear the 'gpio_pin' bit according to the style - * and the required setting (value > 0 == on) - */ - const int gpio_value = - (value > 0) == (ixp4xx_dev->flags != IXP4XX_GPIO_LOW) ? - IXP4XX_GPIO_HIGH : IXP4XX_GPIO_LOW; - - { - unsigned long flags; - spin_lock_irqsave(&gpio_lock, flags); - gpio_line_set(gpio_pin, gpio_value); - spin_unlock_irqrestore(&gpio_lock, flags); - } - } -} - -/* LEDs are described in resources, the following iterates over the valid - * LED resources. - */ -#define for_all_leds(i, pdev) \ - for (i=0; inum_resources; ++i) \ - if (pdev->resource[i].start < GPIO_MAX && \ - pdev->resource[i].name != 0) - -/* The following applies 'operation' to each LED from the given platform, - * the function always returns 0 to allow tail call elimination. - */ -static int apply_to_all_leds(struct platform_device *pdev, - void (*operation)(struct led_classdev *pled)) -{ - int i; - - for_all_leds(i, pdev) - operation(&ixp4xxgpioled_devices[pdev->resource[i].start].ancestor); - return 0; -} - -#ifdef CONFIG_PM -static int ixp4xxgpioled_suspend(struct platform_device *pdev, - pm_message_t state) -{ - return apply_to_all_leds(pdev, led_classdev_suspend); -} - -static int ixp4xxgpioled_resume(struct platform_device *pdev) -{ - return apply_to_all_leds(pdev, led_classdev_resume); -} -#endif - -static void ixp4xxgpioled_remove_one_led(struct led_classdev *pled) -{ - led_classdev_unregister(pled); - pled->name = 0; -} - -static int ixp4xxgpioled_remove(struct platform_device *pdev) -{ - return apply_to_all_leds(pdev, ixp4xxgpioled_remove_one_led); -} - -static int ixp4xxgpioled_probe(struct platform_device *pdev) -{ - /* The board level has to tell the driver where the - * LEDs are connected - there is no way to find out - * electrically. It must also say whether the GPIO - * lines are active high or active low. - * - * To do this read the num_resources (the number of - * LEDs) and the struct resource (the data for each - * LED). The name comes from the resource, and it - * isn't copied. - */ - int i; - - for_all_leds(i, pdev) { - const u8 gpio_pin = pdev->resource[i].start; - int rc; - - if (ixp4xxgpioled_devices[gpio_pin].ancestor.name == 0) { - unsigned long flags; - - spin_lock_irqsave(&gpio_lock, flags); - gpio_line_config(gpio_pin, IXP4XX_GPIO_OUT); - /* The config can, apparently, reset the state, - * I suspect the gpio line may be an input and - * the config may cause the line to be latched, - * so the setting depends on how the LED is - * connected to the line (which affects how it - * floats if not driven). - */ - gpio_line_set(gpio_pin, IXP4XX_GPIO_HIGH); - spin_unlock_irqrestore(&gpio_lock, flags); - - ixp4xxgpioled_devices[gpio_pin].flags = - pdev->resource[i].flags & IORESOURCE_BITS; - - ixp4xxgpioled_devices[gpio_pin].ancestor.name = - pdev->resource[i].name; - - /* This is how a board manufacturer makes the LED - * come on on reset - the GPIO line will be high, so - * make the LED light when the line is low... - */ - if (ixp4xxgpioled_devices[gpio_pin].flags != IXP4XX_GPIO_LOW) - ixp4xxgpioled_devices[gpio_pin].ancestor.brightness = 100; - else - ixp4xxgpioled_devices[gpio_pin].ancestor.brightness = 0; - - ixp4xxgpioled_devices[gpio_pin].ancestor.flags = 0; - - ixp4xxgpioled_devices[gpio_pin].ancestor.brightness_set = - ixp4xxgpioled_brightness_set; - - ixp4xxgpioled_devices[gpio_pin].ancestor.default_trigger = 0; - } - - rc = led_classdev_register(&pdev->dev, - &ixp4xxgpioled_devices[gpio_pin].ancestor); - if (rc < 0) { - ixp4xxgpioled_devices[gpio_pin].ancestor.name = 0; - ixp4xxgpioled_remove(pdev); - return rc; - } - } - - return 0; -} - -static struct platform_driver ixp4xxgpioled_driver = { - .probe = ixp4xxgpioled_probe, - .remove = ixp4xxgpioled_remove, -#ifdef CONFIG_PM - .suspend = ixp4xxgpioled_suspend, - .resume = ixp4xxgpioled_resume, -#endif - .driver = { - .name = "IXP4XX-GPIO-LED", - }, -}; - -static int __init ixp4xxgpioled_init(void) -{ - return platform_driver_register(&ixp4xxgpioled_driver); -} - -static void __exit ixp4xxgpioled_exit(void) -{ - platform_driver_unregister(&ixp4xxgpioled_driver); -} - -module_init(ixp4xxgpioled_init); -module_exit(ixp4xxgpioled_exit); - -MODULE_AUTHOR("John Bowler "); -MODULE_DESCRIPTION("IXP4XX GPIO LED driver"); -MODULE_LICENSE("Dual MIT/GPL"); diff --git a/trunk/drivers/leds/leds-locomo.c b/trunk/drivers/leds/leds-locomo.c deleted file mode 100644 index 749a86c2adb6..000000000000 --- a/trunk/drivers/leds/leds-locomo.c +++ /dev/null @@ -1,95 +0,0 @@ -/* - * linux/drivers/leds/locomo.c - * - * Copyright (C) 2005 John Lenz - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include -#include -#include -#include -#include - -#include -#include - -static void locomoled_brightness_set(struct led_classdev *led_cdev, - enum led_brightness value, int offset) -{ - struct locomo_dev *locomo_dev = LOCOMO_DEV(led_cdev->class_dev->dev); - unsigned long flags; - - local_irq_save(flags); - if (value) - locomo_writel(LOCOMO_LPT_TOFH, locomo_dev->mapbase + offset); - else - locomo_writel(LOCOMO_LPT_TOFL, locomo_dev->mapbase + offset); - local_irq_restore(flags); -} - -static void locomoled_brightness_set0(struct led_classdev *led_cdev, - enum led_brightness value) -{ - locomoled_brightness_set(led_cdev, value, LOCOMO_LPT0); -} - -static void locomoled_brightness_set1(struct led_classdev *led_cdev, - enum led_brightness value) -{ - locomoled_brightness_set(led_cdev, value, LOCOMO_LPT1); -} - -static struct led_classdev locomo_led0 = { - .name = "locomo:amber", - .brightness_set = locomoled_brightness_set0, -}; - -static struct led_classdev locomo_led1 = { - .name = "locomo:green", - .brightness_set = locomoled_brightness_set1, -}; - -static int locomoled_probe(struct locomo_dev *ldev) -{ - int ret; - - ret = led_classdev_register(&ldev->dev, &locomo_led0); - if (ret < 0) - return ret; - - ret = led_classdev_register(&ldev->dev, &locomo_led1); - if (ret < 0) - led_classdev_unregister(&locomo_led0); - - return ret; -} - -static int locomoled_remove(struct locomo_dev *dev) -{ - led_classdev_unregister(&locomo_led0); - led_classdev_unregister(&locomo_led1); - return 0; -} - -static struct locomo_driver locomoled_driver = { - .drv = { - .name = "locomoled" - }, - .devid = LOCOMO_DEVID_LED, - .probe = locomoled_probe, - .remove = locomoled_remove, -}; - -static int __init locomoled_init(void) -{ - return locomo_driver_register(&locomoled_driver); -} -module_init(locomoled_init); - -MODULE_AUTHOR("John Lenz "); -MODULE_DESCRIPTION("Locomo LED driver"); -MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/leds/leds-spitz.c b/trunk/drivers/leds/leds-spitz.c deleted file mode 100644 index 65bbef4a5e09..000000000000 --- a/trunk/drivers/leds/leds-spitz.c +++ /dev/null @@ -1,125 +0,0 @@ -/* - * LED Triggers Core - * - * Copyright 2005-2006 Openedhand Ltd. - * - * Author: Richard Purdie - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static void spitzled_amber_set(struct led_classdev *led_cdev, enum led_brightness value) -{ - if (value) - set_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_LED_ORANGE); - else - reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_LED_ORANGE); -} - -static void spitzled_green_set(struct led_classdev *led_cdev, enum led_brightness value) -{ - if (value) - set_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_LED_GREEN); - else - reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_LED_GREEN); -} - -static struct led_classdev spitz_amber_led = { - .name = "spitz:amber", - .default_trigger = "sharpsl-charge", - .brightness_set = spitzled_amber_set, -}; - -static struct led_classdev spitz_green_led = { - .name = "spitz:green", - .default_trigger = "ide-disk", - .brightness_set = spitzled_green_set, -}; - -#ifdef CONFIG_PM -static int spitzled_suspend(struct platform_device *dev, pm_message_t state) -{ -#ifdef CONFIG_LEDS_TRIGGERS - if (spitz_amber_led.trigger && strcmp(spitz_amber_led.trigger->name, "sharpsl-charge")) -#endif - led_classdev_suspend(&spitz_amber_led); - led_classdev_suspend(&spitz_green_led); - return 0; -} - -static int spitzled_resume(struct platform_device *dev) -{ - led_classdev_resume(&spitz_amber_led); - led_classdev_resume(&spitz_green_led); - return 0; -} -#endif - -static int spitzled_probe(struct platform_device *pdev) -{ - int ret; - - if (machine_is_akita()) - spitz_green_led.default_trigger = "nand-disk"; - - ret = led_classdev_register(&pdev->dev, &spitz_amber_led); - if (ret < 0) - return ret; - - ret = led_classdev_register(&pdev->dev, &spitz_green_led); - if (ret < 0) - led_classdev_unregister(&spitz_amber_led); - - return ret; -} - -static int spitzled_remove(struct platform_device *pdev) -{ - led_classdev_unregister(&spitz_amber_led); - led_classdev_unregister(&spitz_green_led); - - return 0; -} - -static struct platform_driver spitzled_driver = { - .probe = spitzled_probe, - .remove = spitzled_remove, -#ifdef CONFIG_PM - .suspend = spitzled_suspend, - .resume = spitzled_resume, -#endif - .driver = { - .name = "spitz-led", - }, -}; - -static int __init spitzled_init(void) -{ - return platform_driver_register(&spitzled_driver); -} - -static void __exit spitzled_exit(void) -{ - platform_driver_unregister(&spitzled_driver); -} - -module_init(spitzled_init); -module_exit(spitzled_exit); - -MODULE_AUTHOR("Richard Purdie "); -MODULE_DESCRIPTION("Spitz LED driver"); -MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/leds/leds-tosa.c b/trunk/drivers/leds/leds-tosa.c deleted file mode 100644 index c9e8cc1ec481..000000000000 --- a/trunk/drivers/leds/leds-tosa.c +++ /dev/null @@ -1,131 +0,0 @@ -/* - * LED Triggers Core - * - * Copyright 2005 Dirk Opfer - * - * Author: Dirk Opfer - * based on spitz.c - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static void tosaled_amber_set(struct led_classdev *led_cdev, - enum led_brightness value) -{ - if (value) - set_scoop_gpio(&tosascoop_jc_device.dev, - TOSA_SCOOP_JC_CHRG_ERR_LED); - else - reset_scoop_gpio(&tosascoop_jc_device.dev, - TOSA_SCOOP_JC_CHRG_ERR_LED); -} - -static void tosaled_green_set(struct led_classdev *led_cdev, - enum led_brightness value) -{ - if (value) - set_scoop_gpio(&tosascoop_jc_device.dev, - TOSA_SCOOP_JC_NOTE_LED); - else - reset_scoop_gpio(&tosascoop_jc_device.dev, - TOSA_SCOOP_JC_NOTE_LED); -} - -static struct led_classdev tosa_amber_led = { - .name = "tosa:amber", - .default_trigger = "sharpsl-charge", - .brightness_set = tosaled_amber_set, -}; - -static struct led_classdev tosa_green_led = { - .name = "tosa:green", - .default_trigger = "nand-disk", - .brightness_set = tosaled_green_set, -}; - -#ifdef CONFIG_PM -static int tosaled_suspend(struct platform_device *dev, pm_message_t state) -{ -#ifdef CONFIG_LEDS_TRIGGERS - if (tosa_amber_led.trigger && strcmp(tosa_amber_led.trigger->name, - "sharpsl-charge")) -#endif - led_classdev_suspend(&tosa_amber_led); - led_classdev_suspend(&tosa_green_led); - return 0; -} - -static int tosaled_resume(struct platform_device *dev) -{ - led_classdev_resume(&tosa_amber_led); - led_classdev_resume(&tosa_green_led); - return 0; -} -#else -#define tosaled_suspend NULL -#define tosaled_resume NULL -#endif - -static int tosaled_probe(struct platform_device *pdev) -{ - int ret; - - ret = led_classdev_register(&pdev->dev, &tosa_amber_led); - if (ret < 0) - return ret; - - ret = led_classdev_register(&pdev->dev, &tosa_green_led); - if (ret < 0) - led_classdev_unregister(&tosa_amber_led); - - return ret; -} - -static int tosaled_remove(struct platform_device *pdev) -{ - led_classdev_unregister(&tosa_amber_led); - led_classdev_unregister(&tosa_green_led); - - return 0; -} - -static struct platform_driver tosaled_driver = { - .probe = tosaled_probe, - .remove = tosaled_remove, - .suspend = tosaled_suspend, - .resume = tosaled_resume, - .driver = { - .name = "tosa-led", - }, -}; - -static int __init tosaled_init(void) -{ - return platform_driver_register(&tosaled_driver); -} - -static void __exit tosaled_exit(void) -{ - platform_driver_unregister(&tosaled_driver); -} - -module_init(tosaled_init); -module_exit(tosaled_exit); - -MODULE_AUTHOR("Dirk Opfer "); -MODULE_DESCRIPTION("Tosa LED driver"); -MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/leds/leds.h b/trunk/drivers/leds/leds.h deleted file mode 100644 index a715c4ed93ff..000000000000 --- a/trunk/drivers/leds/leds.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * LED Core - * - * Copyright 2005 Openedhand Ltd. - * - * Author: Richard Purdie - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - */ -#ifndef __LEDS_H_INCLUDED -#define __LEDS_H_INCLUDED - -#include - -static inline void led_set_brightness(struct led_classdev *led_cdev, - enum led_brightness value) -{ - if (value > LED_FULL) - value = LED_FULL; - led_cdev->brightness = value; - if (!(led_cdev->flags & LED_SUSPENDED)) - led_cdev->brightness_set(led_cdev, value); -} - -extern rwlock_t leds_list_lock; -extern struct list_head leds_list; - -#ifdef CONFIG_LEDS_TRIGGERS -void led_trigger_set_default(struct led_classdev *led_cdev); -void led_trigger_set(struct led_classdev *led_cdev, - struct led_trigger *trigger); -#else -#define led_trigger_set_default(x) do {} while(0) -#define led_trigger_set(x, y) do {} while(0) -#endif - -ssize_t led_trigger_store(struct class_device *dev, const char *buf, - size_t count); -ssize_t led_trigger_show(struct class_device *dev, char *buf); - -#endif /* __LEDS_H_INCLUDED */ diff --git a/trunk/drivers/leds/ledtrig-ide-disk.c b/trunk/drivers/leds/ledtrig-ide-disk.c deleted file mode 100644 index fa651886ab4f..000000000000 --- a/trunk/drivers/leds/ledtrig-ide-disk.c +++ /dev/null @@ -1,62 +0,0 @@ -/* - * LED IDE-Disk Activity Trigger - * - * Copyright 2006 Openedhand Ltd. - * - * Author: Richard Purdie - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - */ - -#include -#include -#include -#include -#include - -static void ledtrig_ide_timerfunc(unsigned long data); - -DEFINE_LED_TRIGGER(ledtrig_ide); -static DEFINE_TIMER(ledtrig_ide_timer, ledtrig_ide_timerfunc, 0, 0); -static int ide_activity; -static int ide_lastactivity; - -void ledtrig_ide_activity(void) -{ - ide_activity++; - if (!timer_pending(&ledtrig_ide_timer)) - mod_timer(&ledtrig_ide_timer, jiffies + msecs_to_jiffies(10)); -} -EXPORT_SYMBOL(ledtrig_ide_activity); - -static void ledtrig_ide_timerfunc(unsigned long data) -{ - if (ide_lastactivity != ide_activity) { - ide_lastactivity = ide_activity; - led_trigger_event(ledtrig_ide, LED_FULL); - mod_timer(&ledtrig_ide_timer, jiffies + msecs_to_jiffies(10)); - } else { - led_trigger_event(ledtrig_ide, LED_OFF); - } -} - -static int __init ledtrig_ide_init(void) -{ - led_trigger_register_simple("ide-disk", &ledtrig_ide); - return 0; -} - -static void __exit ledtrig_ide_exit(void) -{ - led_trigger_unregister_simple(ledtrig_ide); -} - -module_init(ledtrig_ide_init); -module_exit(ledtrig_ide_exit); - -MODULE_AUTHOR("Richard Purdie "); -MODULE_DESCRIPTION("LED IDE Disk Activity Trigger"); -MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/leds/ledtrig-timer.c b/trunk/drivers/leds/ledtrig-timer.c deleted file mode 100644 index f484b5d6dbf8..000000000000 --- a/trunk/drivers/leds/ledtrig-timer.c +++ /dev/null @@ -1,170 +0,0 @@ -/* - * LED Kernel Timer Trigger - * - * Copyright 2005-2006 Openedhand Ltd. - * - * Author: Richard Purdie - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "leds.h" - -struct timer_trig_data { - unsigned long delay_on; /* milliseconds on */ - unsigned long delay_off; /* milliseconds off */ - struct timer_list timer; -}; - -static void led_timer_function(unsigned long data) -{ - struct led_classdev *led_cdev = (struct led_classdev *) data; - struct timer_trig_data *timer_data = led_cdev->trigger_data; - unsigned long brightness = LED_OFF; - unsigned long delay = timer_data->delay_off; - - if (!timer_data->delay_on || !timer_data->delay_off) { - led_set_brightness(led_cdev, LED_OFF); - return; - } - - if (!led_cdev->brightness) { - brightness = LED_FULL; - delay = timer_data->delay_on; - } - - led_set_brightness(led_cdev, brightness); - - mod_timer(&timer_data->timer, jiffies + msecs_to_jiffies(delay)); -} - -static ssize_t led_delay_on_show(struct class_device *dev, char *buf) -{ - struct led_classdev *led_cdev = class_get_devdata(dev); - struct timer_trig_data *timer_data = led_cdev->trigger_data; - - sprintf(buf, "%lu\n", timer_data->delay_on); - - return strlen(buf) + 1; -} - -static ssize_t led_delay_on_store(struct class_device *dev, const char *buf, - size_t size) -{ - struct led_classdev *led_cdev = class_get_devdata(dev); - struct timer_trig_data *timer_data = led_cdev->trigger_data; - int ret = -EINVAL; - char *after; - unsigned long state = simple_strtoul(buf, &after, 10); - - if (after - buf > 0) { - timer_data->delay_on = state; - mod_timer(&timer_data->timer, jiffies + 1); - ret = after - buf; - } - - return ret; -} - -static ssize_t led_delay_off_show(struct class_device *dev, char *buf) -{ - struct led_classdev *led_cdev = class_get_devdata(dev); - struct timer_trig_data *timer_data = led_cdev->trigger_data; - - sprintf(buf, "%lu\n", timer_data->delay_off); - - return strlen(buf) + 1; -} - -static ssize_t led_delay_off_store(struct class_device *dev, const char *buf, - size_t size) -{ - struct led_classdev *led_cdev = class_get_devdata(dev); - struct timer_trig_data *timer_data = led_cdev->trigger_data; - int ret = -EINVAL; - char *after; - unsigned long state = simple_strtoul(buf, &after, 10); - - if (after - buf > 0) { - timer_data->delay_off = state; - mod_timer(&timer_data->timer, jiffies + 1); - ret = after - buf; - } - - return ret; -} - -static CLASS_DEVICE_ATTR(delay_on, 0644, led_delay_on_show, - led_delay_on_store); -static CLASS_DEVICE_ATTR(delay_off, 0644, led_delay_off_show, - led_delay_off_store); - -static void timer_trig_activate(struct led_classdev *led_cdev) -{ - struct timer_trig_data *timer_data; - - timer_data = kzalloc(sizeof(struct timer_trig_data), GFP_KERNEL); - if (!timer_data) - return; - - led_cdev->trigger_data = timer_data; - - init_timer(&timer_data->timer); - timer_data->timer.function = led_timer_function; - timer_data->timer.data = (unsigned long) led_cdev; - - class_device_create_file(led_cdev->class_dev, - &class_device_attr_delay_on); - class_device_create_file(led_cdev->class_dev, - &class_device_attr_delay_off); -} - -static void timer_trig_deactivate(struct led_classdev *led_cdev) -{ - struct timer_trig_data *timer_data = led_cdev->trigger_data; - - if (timer_data) { - class_device_remove_file(led_cdev->class_dev, - &class_device_attr_delay_on); - class_device_remove_file(led_cdev->class_dev, - &class_device_attr_delay_off); - del_timer_sync(&timer_data->timer); - kfree(timer_data); - } -} - -static struct led_trigger timer_led_trigger = { - .name = "timer", - .activate = timer_trig_activate, - .deactivate = timer_trig_deactivate, -}; - -static int __init timer_trig_init(void) -{ - return led_trigger_register(&timer_led_trigger); -} - -static void __exit timer_trig_exit(void) -{ - led_trigger_unregister(&timer_led_trigger); -} - -module_init(timer_trig_init); -module_exit(timer_trig_exit); - -MODULE_AUTHOR("Richard Purdie "); -MODULE_DESCRIPTION("Timer LED trigger"); -MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/macintosh/adb.c b/trunk/drivers/macintosh/adb.c index 259fd8973ce9..34fcabac5fdb 100644 --- a/trunk/drivers/macintosh/adb.c +++ b/trunk/drivers/macintosh/adb.c @@ -42,7 +42,6 @@ #include #ifdef CONFIG_PPC #include -#include #endif @@ -295,7 +294,7 @@ int __init adb_init(void) int i; #ifdef CONFIG_PPC32 - if (!machine_is(chrp) && !machine_is(powermac)) + if ( (_machine != _MACH_chrp) && (_machine != _MACH_Pmac) ) return 0; #endif #ifdef CONFIG_MAC diff --git a/trunk/drivers/macintosh/adbhid.c b/trunk/drivers/macintosh/adbhid.c index 394334ec5765..f5779a73184d 100644 --- a/trunk/drivers/macintosh/adbhid.c +++ b/trunk/drivers/macintosh/adbhid.c @@ -1206,8 +1206,8 @@ init_ms_a3(int id) static int __init adbhid_init(void) { #ifndef CONFIG_MAC - if (!machine_is(chrp) && !machine_is(powermac)) - return 0; + if ( (_machine != _MACH_chrp) && (_machine != _MACH_Pmac) ) + return 0; #endif led_request.complete = 1; diff --git a/trunk/drivers/macintosh/mediabay.c b/trunk/drivers/macintosh/mediabay.c index 53c1c7909413..8dbf2852bae0 100644 --- a/trunk/drivers/macintosh/mediabay.c +++ b/trunk/drivers/macintosh/mediabay.c @@ -839,8 +839,8 @@ static int __init media_bay_init(void) media_bays[i].cd_index = -1; #endif } - if (!machine_is(powermac)) - return 0; + if (_machine != _MACH_Pmac) + return -ENODEV; macio_register_driver(&media_bay_driver); diff --git a/trunk/drivers/md/md.c b/trunk/drivers/md/md.c index 1ed5152db450..039e071c1007 100644 --- a/trunk/drivers/md/md.c +++ b/trunk/drivers/md/md.c @@ -215,11 +215,13 @@ static void mddev_put(mddev_t *mddev) return; if (!mddev->raid_disks && list_empty(&mddev->disks)) { list_del(&mddev->all_mddevs); - spin_unlock(&all_mddevs_lock); + /* that blocks */ blk_cleanup_queue(mddev->queue); + /* that also blocks */ kobject_unregister(&mddev->kobj); - } else - spin_unlock(&all_mddevs_lock); + /* result blows... */ + } + spin_unlock(&all_mddevs_lock); } static mddev_t * mddev_find(dev_t unit) diff --git a/trunk/drivers/md/raid1.c b/trunk/drivers/md/raid1.c index 9b374c91db66..3cb0872a845d 100644 --- a/trunk/drivers/md/raid1.c +++ b/trunk/drivers/md/raid1.c @@ -1135,19 +1135,8 @@ static int end_sync_write(struct bio *bio, unsigned int bytes_done, int error) mirror = i; break; } - if (!uptodate) { - int sync_blocks = 0; - sector_t s = r1_bio->sector; - long sectors_to_go = r1_bio->sectors; - /* make sure these bits doesn't get cleared. */ - do { - bitmap_end_sync(mddev->bitmap, r1_bio->sector, - &sync_blocks, 1); - s += sync_blocks; - sectors_to_go -= sync_blocks; - } while (sectors_to_go > 0); + if (!uptodate) md_error(mddev, conf->mirrors[mirror].rdev); - } update_head_pos(mirror, r1_bio); diff --git a/trunk/drivers/md/raid6main.c b/trunk/drivers/md/raid6main.c index ab64b37e4996..6df4930fddec 100644 --- a/trunk/drivers/md/raid6main.c +++ b/trunk/drivers/md/raid6main.c @@ -2151,8 +2151,6 @@ static int run(mddev_t *mddev) } /* Ok, everything is just fine now */ - sysfs_create_group(&mddev->kobj, &raid6_attrs_group); - mddev->array_size = mddev->size * (mddev->raid_disks - 2); mddev->queue->unplug_fn = raid6_unplug_device; diff --git a/trunk/drivers/media/video/cpia_pp.c b/trunk/drivers/media/video/cpia_pp.c index 0b00e6027dfb..3021f21aae36 100644 --- a/trunk/drivers/media/video/cpia_pp.c +++ b/trunk/drivers/media/video/cpia_pp.c @@ -873,7 +873,7 @@ static int __init cpia_pp_setup(char *str) parport_nr[parport_ptr++] = PPCPIA_PARPORT_NONE; } - return 1; + return 0; } __setup("cpia_pp=", cpia_pp_setup); diff --git a/trunk/drivers/media/video/planb.c b/trunk/drivers/media/video/planb.c index d9e3cada52f4..522e9ddeb089 100644 --- a/trunk/drivers/media/video/planb.c +++ b/trunk/drivers/media/video/planb.c @@ -2156,7 +2156,7 @@ static int find_planb(void) struct pci_dev *pdev; int rc; - if (!machine_is(powermac)) + if (_machine != _MACH_Pmac) return 0; planb_devices = find_devices("planb"); diff --git a/trunk/drivers/mmc/Kconfig b/trunk/drivers/mmc/Kconfig index 7cc162e8978b..3f5d77f633fa 100644 --- a/trunk/drivers/mmc/Kconfig +++ b/trunk/drivers/mmc/Kconfig @@ -60,17 +60,6 @@ config MMC_SDHCI If unsure, say N. -config MMC_OMAP - tristate "TI OMAP Multimedia Card Interface support" - depends on ARCH_OMAP && MMC - select TPS65010 if MACH_OMAP_H2 - help - This selects the TI OMAP Multimedia card Interface. - If you have an OMAP board with a Multimedia Card slot, - say Y or M here. - - If unsure, say N. - config MMC_WBSD tristate "Winbond W83L51xD SD/MMC Card Interface support" depends on MMC && ISA_DMA_API diff --git a/trunk/drivers/mmc/Makefile b/trunk/drivers/mmc/Makefile index c7c34aadfc92..769d545284a4 100644 --- a/trunk/drivers/mmc/Makefile +++ b/trunk/drivers/mmc/Makefile @@ -20,10 +20,5 @@ obj-$(CONFIG_MMC_PXA) += pxamci.o obj-$(CONFIG_MMC_SDHCI) += sdhci.o obj-$(CONFIG_MMC_WBSD) += wbsd.o obj-$(CONFIG_MMC_AU1X) += au1xmmc.o -obj-$(CONFIG_MMC_OMAP) += omap.o mmc_core-y := mmc.o mmc_queue.o mmc_sysfs.o - -ifeq ($(CONFIG_MMC_DEBUG),y) -EXTRA_CFLAGS += -DDEBUG -endif diff --git a/trunk/drivers/mmc/au1xmmc.c b/trunk/drivers/mmc/au1xmmc.c index c0326bbc5f28..85e89c77bdea 100644 --- a/trunk/drivers/mmc/au1xmmc.c +++ b/trunk/drivers/mmc/au1xmmc.c @@ -56,11 +56,12 @@ #define DRIVER_NAME "au1xxx-mmc" /* Set this to enable special debugging macros */ +/* #define MMC_DEBUG */ -#ifdef DEBUG -#define DBG(fmt, idx, args...) printk("au1xx(%d): DEBUG: " fmt, idx, ##args) +#ifdef MMC_DEBUG +#define DEBUG(fmt, idx, args...) printk("au1xx(%d): DEBUG: " fmt, idx, ##args) #else -#define DBG(fmt, idx, args...) +#define DEBUG(fmt, idx, args...) #endif const struct { @@ -423,18 +424,18 @@ static void au1xmmc_receive_pio(struct au1xmmc_host *host) break; if (status & SD_STATUS_RC) { - DBG("RX CRC Error [%d + %d].\n", host->id, + DEBUG("RX CRC Error [%d + %d].\n", host->id, host->pio.len, count); break; } if (status & SD_STATUS_RO) { - DBG("RX Overrun [%d + %d]\n", host->id, + DEBUG("RX Overrun [%d + %d]\n", host->id, host->pio.len, count); break; } else if (status & SD_STATUS_RU) { - DBG("RX Underrun [%d + %d]\n", host->id, + DEBUG("RX Underrun [%d + %d]\n", host->id, host->pio.len, count); break; } @@ -720,7 +721,7 @@ static void au1xmmc_set_ios(struct mmc_host* mmc, struct mmc_ios* ios) { struct au1xmmc_host *host = mmc_priv(mmc); - DBG("set_ios (power=%u, clock=%uHz, vdd=%u, mode=%u)\n", + DEBUG("set_ios (power=%u, clock=%uHz, vdd=%u, mode=%u)\n", host->id, ios->power_mode, ios->clock, ios->vdd, ios->bus_mode); @@ -809,7 +810,7 @@ static irqreturn_t au1xmmc_irq(int irq, void *dev_id, struct pt_regs *regs) au1xmmc_receive_pio(host); } else if (status & 0x203FBC70) { - DBG("Unhandled status %8.8x\n", host->id, status); + DEBUG("Unhandled status %8.8x\n", host->id, status); handled = 0; } @@ -838,7 +839,7 @@ static void au1xmmc_poll_event(unsigned long arg) if (host->mrq != NULL) { u32 status = au_readl(HOST_STATUS(host)); - DBG("PENDING - %8.8x\n", host->id, status); + DEBUG("PENDING - %8.8x\n", host->id, status); } mod_timer(&host->timer, jiffies + AU1XMMC_DETECT_TIMEOUT); diff --git a/trunk/drivers/mmc/mmc.c b/trunk/drivers/mmc/mmc.c index da6ddd910fc5..1888060c5e0c 100644 --- a/trunk/drivers/mmc/mmc.c +++ b/trunk/drivers/mmc/mmc.c @@ -27,6 +27,12 @@ #include "mmc.h" +#ifdef CONFIG_MMC_DEBUG +#define DBG(x...) printk(KERN_DEBUG x) +#else +#define DBG(x...) do { } while (0) +#endif + #define CMD_RETRIES 3 /* @@ -71,9 +77,8 @@ void mmc_request_done(struct mmc_host *host, struct mmc_request *mrq) { struct mmc_command *cmd = mrq->cmd; int err = mrq->cmd->error; - pr_debug("MMC: req done (%02x): %d: %08x %08x %08x %08x\n", - cmd->opcode, err, cmd->resp[0], cmd->resp[1], - cmd->resp[2], cmd->resp[3]); + DBG("MMC: req done (%02x): %d: %08x %08x %08x %08x\n", cmd->opcode, + err, cmd->resp[0], cmd->resp[1], cmd->resp[2], cmd->resp[3]); if (err && cmd->retries) { cmd->retries--; @@ -97,8 +102,8 @@ EXPORT_SYMBOL(mmc_request_done); void mmc_start_request(struct mmc_host *host, struct mmc_request *mrq) { - pr_debug("MMC: starting cmd %02x arg %08x flags %08x\n", - mrq->cmd->opcode, mrq->cmd->arg, mrq->cmd->flags); + DBG("MMC: starting cmd %02x arg %08x flags %08x\n", + mrq->cmd->opcode, mrq->cmd->arg, mrq->cmd->flags); WARN_ON(host->card_busy == NULL); @@ -971,8 +976,8 @@ static unsigned int mmc_calculate_clock(struct mmc_host *host) if (!mmc_card_dead(card) && max_dtr > card->csd.max_dtr) max_dtr = card->csd.max_dtr; - pr_debug("MMC: selected %d.%03dMHz transfer rate\n", - max_dtr / 1000000, (max_dtr / 1000) % 1000); + DBG("MMC: selected %d.%03dMHz transfer rate\n", + max_dtr / 1000000, (max_dtr / 1000) % 1000); return max_dtr; } diff --git a/trunk/drivers/mmc/mmci.c b/trunk/drivers/mmc/mmci.c index df7e861e2fc7..9fef29d978b5 100644 --- a/trunk/drivers/mmc/mmci.c +++ b/trunk/drivers/mmc/mmci.c @@ -33,8 +33,12 @@ #define DRIVER_NAME "mmci-pl18x" +#ifdef CONFIG_MMC_DEBUG #define DBG(host,fmt,args...) \ pr_debug("%s: %s: " fmt, mmc_hostname(host->mmc), __func__ , args) +#else +#define DBG(host,fmt,args...) do { } while (0) +#endif static unsigned int fmax = 515633; diff --git a/trunk/drivers/mmc/omap.c b/trunk/drivers/mmc/omap.c deleted file mode 100644 index becb3c68c34d..000000000000 --- a/trunk/drivers/mmc/omap.c +++ /dev/null @@ -1,1226 +0,0 @@ -/* - * linux/drivers/media/mmc/omap.c - * - * Copyright (C) 2004 Nokia Corporation - * Written by Tuukka Tikkanen and Juha Yrjölä - * Misc hacks here and there by Tony Lindgren - * Other hacks (DMA, SD, etc) by David Brownell - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include "omap.h" - -#define DRIVER_NAME "mmci-omap" -#define RSP_TYPE(x) ((x) & ~(MMC_RSP_BUSY|MMC_RSP_OPCODE)) - -/* Specifies how often in millisecs to poll for card status changes - * when the cover switch is open */ -#define OMAP_MMC_SWITCH_POLL_DELAY 500 - -static int mmc_omap_enable_poll = 1; - -struct mmc_omap_host { - int initialized; - int suspended; - struct mmc_request * mrq; - struct mmc_command * cmd; - struct mmc_data * data; - struct mmc_host * mmc; - struct device * dev; - unsigned char id; /* 16xx chips have 2 MMC blocks */ - struct clk * iclk; - struct clk * fclk; - void __iomem *base; - int irq; - unsigned char bus_mode; - unsigned char hw_bus_mode; - - unsigned int sg_len; - int sg_idx; - u16 * buffer; - u32 buffer_bytes_left; - u32 total_bytes_left; - - unsigned use_dma:1; - unsigned brs_received:1, dma_done:1; - unsigned dma_is_read:1; - unsigned dma_in_use:1; - int dma_ch; - spinlock_t dma_lock; - struct timer_list dma_timer; - unsigned dma_len; - - short power_pin; - short wp_pin; - - int switch_pin; - struct work_struct switch_work; - struct timer_list switch_timer; - int switch_last_state; -}; - -static inline int -mmc_omap_cover_is_open(struct mmc_omap_host *host) -{ - if (host->switch_pin < 0) - return 0; - return omap_get_gpio_datain(host->switch_pin); -} - -static ssize_t -mmc_omap_show_cover_switch(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct mmc_omap_host *host = dev_get_drvdata(dev); - - return sprintf(buf, "%s\n", mmc_omap_cover_is_open(host) ? "open" : - "closed"); -} - -static DEVICE_ATTR(cover_switch, S_IRUGO, mmc_omap_show_cover_switch, NULL); - -static ssize_t -mmc_omap_show_enable_poll(struct device *dev, - struct device_attribute *attr, char *buf) -{ - return snprintf(buf, PAGE_SIZE, "%d\n", mmc_omap_enable_poll); -} - -static ssize_t -mmc_omap_store_enable_poll(struct device *dev, - struct device_attribute *attr, const char *buf, - size_t size) -{ - int enable_poll; - - if (sscanf(buf, "%10d", &enable_poll) != 1) - return -EINVAL; - - if (enable_poll != mmc_omap_enable_poll) { - struct mmc_omap_host *host = dev_get_drvdata(dev); - - mmc_omap_enable_poll = enable_poll; - if (enable_poll && host->switch_pin >= 0) - schedule_work(&host->switch_work); - } - return size; -} - -static DEVICE_ATTR(enable_poll, 0664, - mmc_omap_show_enable_poll, mmc_omap_store_enable_poll); - -static void -mmc_omap_start_command(struct mmc_omap_host *host, struct mmc_command *cmd) -{ - u32 cmdreg; - u32 resptype; - u32 cmdtype; - - host->cmd = cmd; - - resptype = 0; - cmdtype = 0; - - /* Our hardware needs to know exact type */ - switch (RSP_TYPE(mmc_resp_type(cmd))) { - case RSP_TYPE(MMC_RSP_R1): - /* resp 1, resp 1b */ - resptype = 1; - break; - case RSP_TYPE(MMC_RSP_R2): - resptype = 2; - break; - case RSP_TYPE(MMC_RSP_R3): - resptype = 3; - break; - default: - break; - } - - if (mmc_cmd_type(cmd) == MMC_CMD_ADTC) { - cmdtype = OMAP_MMC_CMDTYPE_ADTC; - } else if (mmc_cmd_type(cmd) == MMC_CMD_BC) { - cmdtype = OMAP_MMC_CMDTYPE_BC; - } else if (mmc_cmd_type(cmd) == MMC_CMD_BCR) { - cmdtype = OMAP_MMC_CMDTYPE_BCR; - } else { - cmdtype = OMAP_MMC_CMDTYPE_AC; - } - - cmdreg = cmd->opcode | (resptype << 8) | (cmdtype << 12); - - if (host->bus_mode == MMC_BUSMODE_OPENDRAIN) - cmdreg |= 1 << 6; - - if (cmd->flags & MMC_RSP_BUSY) - cmdreg |= 1 << 11; - - if (host->data && !(host->data->flags & MMC_DATA_WRITE)) - cmdreg |= 1 << 15; - - clk_enable(host->fclk); - - OMAP_MMC_WRITE(host->base, CTO, 200); - OMAP_MMC_WRITE(host->base, ARGL, cmd->arg & 0xffff); - OMAP_MMC_WRITE(host->base, ARGH, cmd->arg >> 16); - OMAP_MMC_WRITE(host->base, IE, - OMAP_MMC_STAT_A_EMPTY | OMAP_MMC_STAT_A_FULL | - OMAP_MMC_STAT_CMD_CRC | OMAP_MMC_STAT_CMD_TOUT | - OMAP_MMC_STAT_DATA_CRC | OMAP_MMC_STAT_DATA_TOUT | - OMAP_MMC_STAT_END_OF_CMD | OMAP_MMC_STAT_CARD_ERR | - OMAP_MMC_STAT_END_OF_DATA); - OMAP_MMC_WRITE(host->base, CMD, cmdreg); -} - -static void -mmc_omap_xfer_done(struct mmc_omap_host *host, struct mmc_data *data) -{ - if (host->dma_in_use) { - enum dma_data_direction dma_data_dir; - - BUG_ON(host->dma_ch < 0); - if (data->error != MMC_ERR_NONE) - omap_stop_dma(host->dma_ch); - /* Release DMA channel lazily */ - mod_timer(&host->dma_timer, jiffies + HZ); - if (data->flags & MMC_DATA_WRITE) - dma_data_dir = DMA_TO_DEVICE; - else - dma_data_dir = DMA_FROM_DEVICE; - dma_unmap_sg(mmc_dev(host->mmc), data->sg, host->sg_len, - dma_data_dir); - } - host->data = NULL; - host->sg_len = 0; - clk_disable(host->fclk); - - /* NOTE: MMC layer will sometimes poll-wait CMD13 next, issuing - * dozens of requests until the card finishes writing data. - * It'd be cheaper to just wait till an EOFB interrupt arrives... - */ - - if (!data->stop) { - host->mrq = NULL; - mmc_request_done(host->mmc, data->mrq); - return; - } - - mmc_omap_start_command(host, data->stop); -} - -static void -mmc_omap_end_of_data(struct mmc_omap_host *host, struct mmc_data *data) -{ - unsigned long flags; - int done; - - if (!host->dma_in_use) { - mmc_omap_xfer_done(host, data); - return; - } - done = 0; - spin_lock_irqsave(&host->dma_lock, flags); - if (host->dma_done) - done = 1; - else - host->brs_received = 1; - spin_unlock_irqrestore(&host->dma_lock, flags); - if (done) - mmc_omap_xfer_done(host, data); -} - -static void -mmc_omap_dma_timer(unsigned long data) -{ - struct mmc_omap_host *host = (struct mmc_omap_host *) data; - - BUG_ON(host->dma_ch < 0); - omap_free_dma(host->dma_ch); - host->dma_ch = -1; -} - -static void -mmc_omap_dma_done(struct mmc_omap_host *host, struct mmc_data *data) -{ - unsigned long flags; - int done; - - done = 0; - spin_lock_irqsave(&host->dma_lock, flags); - if (host->brs_received) - done = 1; - else - host->dma_done = 1; - spin_unlock_irqrestore(&host->dma_lock, flags); - if (done) - mmc_omap_xfer_done(host, data); -} - -static void -mmc_omap_cmd_done(struct mmc_omap_host *host, struct mmc_command *cmd) -{ - host->cmd = NULL; - - if (cmd->flags & MMC_RSP_PRESENT) { - if (cmd->flags & MMC_RSP_136) { - /* response type 2 */ - cmd->resp[3] = - OMAP_MMC_READ(host->base, RSP0) | - (OMAP_MMC_READ(host->base, RSP1) << 16); - cmd->resp[2] = - OMAP_MMC_READ(host->base, RSP2) | - (OMAP_MMC_READ(host->base, RSP3) << 16); - cmd->resp[1] = - OMAP_MMC_READ(host->base, RSP4) | - (OMAP_MMC_READ(host->base, RSP5) << 16); - cmd->resp[0] = - OMAP_MMC_READ(host->base, RSP6) | - (OMAP_MMC_READ(host->base, RSP7) << 16); - } else { - /* response types 1, 1b, 3, 4, 5, 6 */ - cmd->resp[0] = - OMAP_MMC_READ(host->base, RSP6) | - (OMAP_MMC_READ(host->base, RSP7) << 16); - } - } - - if (host->data == NULL || cmd->error != MMC_ERR_NONE) { - host->mrq = NULL; - clk_disable(host->fclk); - mmc_request_done(host->mmc, cmd->mrq); - } -} - -/* PIO only */ -static void -mmc_omap_sg_to_buf(struct mmc_omap_host *host) -{ - struct scatterlist *sg; - - sg = host->data->sg + host->sg_idx; - host->buffer_bytes_left = sg->length; - host->buffer = page_address(sg->page) + sg->offset; - if (host->buffer_bytes_left > host->total_bytes_left) - host->buffer_bytes_left = host->total_bytes_left; -} - -/* PIO only */ -static void -mmc_omap_xfer_data(struct mmc_omap_host *host, int write) -{ - int n; - void __iomem *reg; - u16 *p; - - if (host->buffer_bytes_left == 0) { - host->sg_idx++; - BUG_ON(host->sg_idx == host->sg_len); - mmc_omap_sg_to_buf(host); - } - n = 64; - if (n > host->buffer_bytes_left) - n = host->buffer_bytes_left; - host->buffer_bytes_left -= n; - host->total_bytes_left -= n; - host->data->bytes_xfered += n; - - if (write) { - __raw_writesw(host->base + OMAP_MMC_REG_DATA, host->buffer, n); - } else { - __raw_readsw(host->base + OMAP_MMC_REG_DATA, host->buffer, n); - } -} - -static inline void mmc_omap_report_irq(u16 status) -{ - static const char *mmc_omap_status_bits[] = { - "EOC", "CD", "CB", "BRS", "EOFB", "DTO", "DCRC", "CTO", - "CCRC", "CRW", "AF", "AE", "OCRB", "CIRQ", "CERR" - }; - int i, c = 0; - - for (i = 0; i < ARRAY_SIZE(mmc_omap_status_bits); i++) - if (status & (1 << i)) { - if (c) - printk(" "); - printk("%s", mmc_omap_status_bits[i]); - c++; - } -} - -static irqreturn_t mmc_omap_irq(int irq, void *dev_id, struct pt_regs *regs) -{ - struct mmc_omap_host * host = (struct mmc_omap_host *)dev_id; - u16 status; - int end_command; - int end_transfer; - int transfer_error; - - if (host->cmd == NULL && host->data == NULL) { - status = OMAP_MMC_READ(host->base, STAT); - dev_info(mmc_dev(host->mmc),"spurious irq 0x%04x\n", status); - if (status != 0) { - OMAP_MMC_WRITE(host->base, STAT, status); - OMAP_MMC_WRITE(host->base, IE, 0); - } - return IRQ_HANDLED; - } - - end_command = 0; - end_transfer = 0; - transfer_error = 0; - - while ((status = OMAP_MMC_READ(host->base, STAT)) != 0) { - OMAP_MMC_WRITE(host->base, STAT, status); -#ifdef CONFIG_MMC_DEBUG - dev_dbg(mmc_dev(host->mmc), "MMC IRQ %04x (CMD %d): ", - status, host->cmd != NULL ? host->cmd->opcode : -1); - mmc_omap_report_irq(status); - printk("\n"); -#endif - if (host->total_bytes_left) { - if ((status & OMAP_MMC_STAT_A_FULL) || - (status & OMAP_MMC_STAT_END_OF_DATA)) - mmc_omap_xfer_data(host, 0); - if (status & OMAP_MMC_STAT_A_EMPTY) - mmc_omap_xfer_data(host, 1); - } - - if (status & OMAP_MMC_STAT_END_OF_DATA) { - end_transfer = 1; - } - - if (status & OMAP_MMC_STAT_DATA_TOUT) { - dev_dbg(mmc_dev(host->mmc), "data timeout\n"); - if (host->data) { - host->data->error |= MMC_ERR_TIMEOUT; - transfer_error = 1; - } - } - - if (status & OMAP_MMC_STAT_DATA_CRC) { - if (host->data) { - host->data->error |= MMC_ERR_BADCRC; - dev_dbg(mmc_dev(host->mmc), - "data CRC error, bytes left %d\n", - host->total_bytes_left); - transfer_error = 1; - } else { - dev_dbg(mmc_dev(host->mmc), "data CRC error\n"); - } - } - - if (status & OMAP_MMC_STAT_CMD_TOUT) { - /* Timeouts are routine with some commands */ - if (host->cmd) { - if (host->cmd->opcode != MMC_ALL_SEND_CID && - host->cmd->opcode != - MMC_SEND_OP_COND && - host->cmd->opcode != - MMC_APP_CMD && - !mmc_omap_cover_is_open(host)) - dev_err(mmc_dev(host->mmc), - "command timeout, CMD %d\n", - host->cmd->opcode); - host->cmd->error = MMC_ERR_TIMEOUT; - end_command = 1; - } - } - - if (status & OMAP_MMC_STAT_CMD_CRC) { - if (host->cmd) { - dev_err(mmc_dev(host->mmc), - "command CRC error (CMD%d, arg 0x%08x)\n", - host->cmd->opcode, host->cmd->arg); - host->cmd->error = MMC_ERR_BADCRC; - end_command = 1; - } else - dev_err(mmc_dev(host->mmc), - "command CRC error without cmd?\n"); - } - - if (status & OMAP_MMC_STAT_CARD_ERR) { - if (host->cmd && host->cmd->opcode == MMC_STOP_TRANSMISSION) { - u32 response = OMAP_MMC_READ(host->base, RSP6) - | (OMAP_MMC_READ(host->base, RSP7) << 16); - /* STOP sometimes sets must-ignore bits */ - if (!(response & (R1_CC_ERROR - | R1_ILLEGAL_COMMAND - | R1_COM_CRC_ERROR))) { - end_command = 1; - continue; - } - } - - dev_dbg(mmc_dev(host->mmc), "card status error (CMD%d)\n", - host->cmd->opcode); - if (host->cmd) { - host->cmd->error = MMC_ERR_FAILED; - end_command = 1; - } - if (host->data) { - host->data->error = MMC_ERR_FAILED; - transfer_error = 1; - } - } - - /* - * NOTE: On 1610 the END_OF_CMD may come too early when - * starting a write - */ - if ((status & OMAP_MMC_STAT_END_OF_CMD) && - (!(status & OMAP_MMC_STAT_A_EMPTY))) { - end_command = 1; - } - } - - if (end_command) { - mmc_omap_cmd_done(host, host->cmd); - } - if (transfer_error) - mmc_omap_xfer_done(host, host->data); - else if (end_transfer) - mmc_omap_end_of_data(host, host->data); - - return IRQ_HANDLED; -} - -static irqreturn_t mmc_omap_switch_irq(int irq, void *dev_id, struct pt_regs *regs) -{ - struct mmc_omap_host *host = (struct mmc_omap_host *) dev_id; - - schedule_work(&host->switch_work); - - return IRQ_HANDLED; -} - -static void mmc_omap_switch_timer(unsigned long arg) -{ - struct mmc_omap_host *host = (struct mmc_omap_host *) arg; - - schedule_work(&host->switch_work); -} - -/* FIXME: Handle card insertion and removal properly. Maybe use a mask - * for MMC state? */ -static void mmc_omap_switch_callback(unsigned long data, u8 mmc_mask) -{ -} - -static void mmc_omap_switch_handler(void *data) -{ - struct mmc_omap_host *host = (struct mmc_omap_host *) data; - struct mmc_card *card; - static int complained = 0; - int cards = 0, cover_open; - - if (host->switch_pin == -1) - return; - cover_open = mmc_omap_cover_is_open(host); - if (cover_open != host->switch_last_state) { - kobject_uevent(&host->dev->kobj, KOBJ_CHANGE); - host->switch_last_state = cover_open; - } - mmc_detect_change(host->mmc, 0); - list_for_each_entry(card, &host->mmc->cards, node) { - if (mmc_card_present(card)) - cards++; - } - if (mmc_omap_cover_is_open(host)) { - if (!complained) { - dev_info(mmc_dev(host->mmc), "cover is open"); - complained = 1; - } - if (mmc_omap_enable_poll) - mod_timer(&host->switch_timer, jiffies + - msecs_to_jiffies(OMAP_MMC_SWITCH_POLL_DELAY)); - } else { - complained = 0; - } -} - -/* Prepare to transfer the next segment of a scatterlist */ -static void -mmc_omap_prepare_dma(struct mmc_omap_host *host, struct mmc_data *data) -{ - int dma_ch = host->dma_ch; - unsigned long data_addr; - u16 buf, frame; - u32 count; - struct scatterlist *sg = &data->sg[host->sg_idx]; - int src_port = 0; - int dst_port = 0; - int sync_dev = 0; - - data_addr = io_v2p((u32) host->base) + OMAP_MMC_REG_DATA; - frame = 1 << data->blksz_bits; - count = sg_dma_len(sg); - - if ((data->blocks == 1) && (count > (1 << data->blksz_bits))) - count = frame; - - host->dma_len = count; - - /* FIFO is 16x2 bytes on 15xx, and 32x2 bytes on 16xx and 24xx. - * Use 16 or 32 word frames when the blocksize is at least that large. - * Blocksize is usually 512 bytes; but not for some SD reads. - */ - if (cpu_is_omap15xx() && frame > 32) - frame = 32; - else if (frame > 64) - frame = 64; - count /= frame; - frame >>= 1; - - if (!(data->flags & MMC_DATA_WRITE)) { - buf = 0x800f | ((frame - 1) << 8); - - if (cpu_class_is_omap1()) { - src_port = OMAP_DMA_PORT_TIPB; - dst_port = OMAP_DMA_PORT_EMIFF; - } - if (cpu_is_omap24xx()) - sync_dev = OMAP24XX_DMA_MMC1_RX; - - omap_set_dma_src_params(dma_ch, src_port, - OMAP_DMA_AMODE_CONSTANT, - data_addr, 0, 0); - omap_set_dma_dest_params(dma_ch, dst_port, - OMAP_DMA_AMODE_POST_INC, - sg_dma_address(sg), 0, 0); - omap_set_dma_dest_data_pack(dma_ch, 1); - omap_set_dma_dest_burst_mode(dma_ch, OMAP_DMA_DATA_BURST_4); - } else { - buf = 0x0f80 | ((frame - 1) << 0); - - if (cpu_class_is_omap1()) { - src_port = OMAP_DMA_PORT_EMIFF; - dst_port = OMAP_DMA_PORT_TIPB; - } - if (cpu_is_omap24xx()) - sync_dev = OMAP24XX_DMA_MMC1_TX; - - omap_set_dma_dest_params(dma_ch, dst_port, - OMAP_DMA_AMODE_CONSTANT, - data_addr, 0, 0); - omap_set_dma_src_params(dma_ch, src_port, - OMAP_DMA_AMODE_POST_INC, - sg_dma_address(sg), 0, 0); - omap_set_dma_src_data_pack(dma_ch, 1); - omap_set_dma_src_burst_mode(dma_ch, OMAP_DMA_DATA_BURST_4); - } - - /* Max limit for DMA frame count is 0xffff */ - if (unlikely(count > 0xffff)) - BUG(); - - OMAP_MMC_WRITE(host->base, BUF, buf); - omap_set_dma_transfer_params(dma_ch, OMAP_DMA_DATA_TYPE_S16, - frame, count, OMAP_DMA_SYNC_FRAME, - sync_dev, 0); -} - -/* A scatterlist segment completed */ -static void mmc_omap_dma_cb(int lch, u16 ch_status, void *data) -{ - struct mmc_omap_host *host = (struct mmc_omap_host *) data; - struct mmc_data *mmcdat = host->data; - - if (unlikely(host->dma_ch < 0)) { - dev_err(mmc_dev(host->mmc), "DMA callback while DMA not - enabled\n"); - return; - } - /* FIXME: We really should do something to _handle_ the errors */ - if (ch_status & OMAP_DMA_TOUT_IRQ) { - dev_err(mmc_dev(host->mmc),"DMA timeout\n"); - return; - } - if (ch_status & OMAP_DMA_DROP_IRQ) { - dev_err(mmc_dev(host->mmc), "DMA sync error\n"); - return; - } - if (!(ch_status & OMAP_DMA_BLOCK_IRQ)) { - return; - } - mmcdat->bytes_xfered += host->dma_len; - host->sg_idx++; - if (host->sg_idx < host->sg_len) { - mmc_omap_prepare_dma(host, host->data); - omap_start_dma(host->dma_ch); - } else - mmc_omap_dma_done(host, host->data); -} - -static int mmc_omap_get_dma_channel(struct mmc_omap_host *host, struct mmc_data *data) -{ - const char *dev_name; - int sync_dev, dma_ch, is_read, r; - - is_read = !(data->flags & MMC_DATA_WRITE); - del_timer_sync(&host->dma_timer); - if (host->dma_ch >= 0) { - if (is_read == host->dma_is_read) - return 0; - omap_free_dma(host->dma_ch); - host->dma_ch = -1; - } - - if (is_read) { - if (host->id == 1) { - sync_dev = OMAP_DMA_MMC_RX; - dev_name = "MMC1 read"; - } else { - sync_dev = OMAP_DMA_MMC2_RX; - dev_name = "MMC2 read"; - } - } else { - if (host->id == 1) { - sync_dev = OMAP_DMA_MMC_TX; - dev_name = "MMC1 write"; - } else { - sync_dev = OMAP_DMA_MMC2_TX; - dev_name = "MMC2 write"; - } - } - r = omap_request_dma(sync_dev, dev_name, mmc_omap_dma_cb, - host, &dma_ch); - if (r != 0) { - dev_dbg(mmc_dev(host->mmc), "omap_request_dma() failed with %d\n", r); - return r; - } - host->dma_ch = dma_ch; - host->dma_is_read = is_read; - - return 0; -} - -static inline void set_cmd_timeout(struct mmc_omap_host *host, struct mmc_request *req) -{ - u16 reg; - - reg = OMAP_MMC_READ(host->base, SDIO); - reg &= ~(1 << 5); - OMAP_MMC_WRITE(host->base, SDIO, reg); - /* Set maximum timeout */ - OMAP_MMC_WRITE(host->base, CTO, 0xff); -} - -static inline void set_data_timeout(struct mmc_omap_host *host, struct mmc_request *req) -{ - int timeout; - u16 reg; - - /* Convert ns to clock cycles by assuming 20MHz frequency - * 1 cycle at 20MHz = 500 ns - */ - timeout = req->data->timeout_clks + req->data->timeout_ns / 500; - - /* Check if we need to use timeout multiplier register */ - reg = OMAP_MMC_READ(host->base, SDIO); - if (timeout > 0xffff) { - reg |= (1 << 5); - timeout /= 1024; - } else - reg &= ~(1 << 5); - OMAP_MMC_WRITE(host->base, SDIO, reg); - OMAP_MMC_WRITE(host->base, DTO, timeout); -} - -static void -mmc_omap_prepare_data(struct mmc_omap_host *host, struct mmc_request *req) -{ - struct mmc_data *data = req->data; - int i, use_dma, block_size; - unsigned sg_len; - - host->data = data; - if (data == NULL) { - OMAP_MMC_WRITE(host->base, BLEN, 0); - OMAP_MMC_WRITE(host->base, NBLK, 0); - OMAP_MMC_WRITE(host->base, BUF, 0); - host->dma_in_use = 0; - set_cmd_timeout(host, req); - return; - } - - - block_size = 1 << data->blksz_bits; - - OMAP_MMC_WRITE(host->base, NBLK, data->blocks - 1); - OMAP_MMC_WRITE(host->base, BLEN, block_size - 1); - set_data_timeout(host, req); - - /* cope with calling layer confusion; it issues "single - * block" writes using multi-block scatterlists. - */ - sg_len = (data->blocks == 1) ? 1 : data->sg_len; - - /* Only do DMA for entire blocks */ - use_dma = host->use_dma; - if (use_dma) { - for (i = 0; i < sg_len; i++) { - if ((data->sg[i].length % block_size) != 0) { - use_dma = 0; - break; - } - } - } - - host->sg_idx = 0; - if (use_dma) { - if (mmc_omap_get_dma_channel(host, data) == 0) { - enum dma_data_direction dma_data_dir; - - if (data->flags & MMC_DATA_WRITE) - dma_data_dir = DMA_TO_DEVICE; - else - dma_data_dir = DMA_FROM_DEVICE; - - host->sg_len = dma_map_sg(mmc_dev(host->mmc), data->sg, - sg_len, dma_data_dir); - host->total_bytes_left = 0; - mmc_omap_prepare_dma(host, req->data); - host->brs_received = 0; - host->dma_done = 0; - host->dma_in_use = 1; - } else - use_dma = 0; - } - - /* Revert to PIO? */ - if (!use_dma) { - OMAP_MMC_WRITE(host->base, BUF, 0x1f1f); - host->total_bytes_left = data->blocks * block_size; - host->sg_len = sg_len; - mmc_omap_sg_to_buf(host); - host->dma_in_use = 0; - } -} - -static void mmc_omap_request(struct mmc_host *mmc, struct mmc_request *req) -{ - struct mmc_omap_host *host = mmc_priv(mmc); - - WARN_ON(host->mrq != NULL); - - host->mrq = req; - - /* only touch fifo AFTER the controller readies it */ - mmc_omap_prepare_data(host, req); - mmc_omap_start_command(host, req->cmd); - if (host->dma_in_use) - omap_start_dma(host->dma_ch); -} - -static void innovator_fpga_socket_power(int on) -{ -#if defined(CONFIG_MACH_OMAP_INNOVATOR) && defined(CONFIG_ARCH_OMAP15XX) - - if (on) { - fpga_write(fpga_read(OMAP1510_FPGA_POWER) | (1 << 3), - OMAP1510_FPGA_POWER); - } else { - fpga_write(fpga_read(OMAP1510_FPGA_POWER) & ~(1 << 3), - OMAP1510_FPGA_POWER); - } -#endif -} - -/* - * Turn the socket power on/off. Innovator uses FPGA, most boards - * probably use GPIO. - */ -static void mmc_omap_power(struct mmc_omap_host *host, int on) -{ - if (on) { - if (machine_is_omap_innovator()) - innovator_fpga_socket_power(1); - else if (machine_is_omap_h2()) - tps65010_set_gpio_out_value(GPIO3, HIGH); - else if (machine_is_omap_h3()) - /* GPIO 4 of TPS65010 sends SD_EN signal */ - tps65010_set_gpio_out_value(GPIO4, HIGH); - else if (cpu_is_omap24xx()) { - u16 reg = OMAP_MMC_READ(host->base, CON); - OMAP_MMC_WRITE(host->base, CON, reg | (1 << 11)); - } else - if (host->power_pin >= 0) - omap_set_gpio_dataout(host->power_pin, 1); - } else { - if (machine_is_omap_innovator()) - innovator_fpga_socket_power(0); - else if (machine_is_omap_h2()) - tps65010_set_gpio_out_value(GPIO3, LOW); - else if (machine_is_omap_h3()) - tps65010_set_gpio_out_value(GPIO4, LOW); - else if (cpu_is_omap24xx()) { - u16 reg = OMAP_MMC_READ(host->base, CON); - OMAP_MMC_WRITE(host->base, CON, reg & ~(1 << 11)); - } else - if (host->power_pin >= 0) - omap_set_gpio_dataout(host->power_pin, 0); - } -} - -static void mmc_omap_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) -{ - struct mmc_omap_host *host = mmc_priv(mmc); - int dsor; - int realclock, i; - - realclock = ios->clock; - - if (ios->clock == 0) - dsor = 0; - else { - int func_clk_rate = clk_get_rate(host->fclk); - - dsor = func_clk_rate / realclock; - if (dsor < 1) - dsor = 1; - - if (func_clk_rate / dsor > realclock) - dsor++; - - if (dsor > 250) - dsor = 250; - dsor++; - - if (ios->bus_width == MMC_BUS_WIDTH_4) - dsor |= 1 << 15; - } - - switch (ios->power_mode) { - case MMC_POWER_OFF: - mmc_omap_power(host, 0); - break; - case MMC_POWER_UP: - case MMC_POWER_ON: - mmc_omap_power(host, 1); - dsor |= 1<<11; - break; - } - - host->bus_mode = ios->bus_mode; - host->hw_bus_mode = host->bus_mode; - - clk_enable(host->fclk); - - /* On insanely high arm_per frequencies something sometimes - * goes somehow out of sync, and the POW bit is not being set, - * which results in the while loop below getting stuck. - * Writing to the CON register twice seems to do the trick. */ - for (i = 0; i < 2; i++) - OMAP_MMC_WRITE(host->base, CON, dsor); - if (ios->power_mode == MMC_POWER_UP) { - /* Send clock cycles, poll completion */ - OMAP_MMC_WRITE(host->base, IE, 0); - OMAP_MMC_WRITE(host->base, STAT, 0xffff); - OMAP_MMC_WRITE(host->base, CMD, 1<<7); - while (0 == (OMAP_MMC_READ(host->base, STAT) & 1)); - OMAP_MMC_WRITE(host->base, STAT, 1); - } - clk_disable(host->fclk); -} - -static int mmc_omap_get_ro(struct mmc_host *mmc) -{ - struct mmc_omap_host *host = mmc_priv(mmc); - - return host->wp_pin && omap_get_gpio_datain(host->wp_pin); -} - -static struct mmc_host_ops mmc_omap_ops = { - .request = mmc_omap_request, - .set_ios = mmc_omap_set_ios, - .get_ro = mmc_omap_get_ro, -}; - -static int __init mmc_omap_probe(struct platform_device *pdev) -{ - struct omap_mmc_conf *minfo = pdev->dev.platform_data; - struct mmc_host *mmc; - struct mmc_omap_host *host = NULL; - int ret = 0; - - if (platform_get_resource(pdev, IORESOURCE_MEM, 0) || - platform_get_irq(pdev, IORESOURCE_IRQ, 0)) { - dev_err(&pdev->dev, "mmc_omap_probe: invalid resource type\n"); - return -ENODEV; - } - - if (!request_mem_region(pdev->resource[0].start, - pdev->resource[0].end - pdev->resource[0].start + 1, - pdev->name)) { - dev_dbg(&pdev->dev, "request_mem_region failed\n"); - return -EBUSY; - } - - mmc = mmc_alloc_host(sizeof(struct mmc_omap_host), &pdev->dev); - if (!mmc) { - ret = -ENOMEM; - goto out; - } - - host = mmc_priv(mmc); - host->mmc = mmc; - - spin_lock_init(&host->dma_lock); - init_timer(&host->dma_timer); - host->dma_timer.function = mmc_omap_dma_timer; - host->dma_timer.data = (unsigned long) host; - - host->id = pdev->id; - - if (cpu_is_omap24xx()) { - host->iclk = clk_get(&pdev->dev, "mmc_ick"); - if (IS_ERR(host->iclk)) - goto out; - clk_enable(host->iclk); - } - - if (!cpu_is_omap24xx()) - host->fclk = clk_get(&pdev->dev, "mmc_ck"); - else - host->fclk = clk_get(&pdev->dev, "mmc_fck"); - - if (IS_ERR(host->fclk)) { - ret = PTR_ERR(host->fclk); - goto out; - } - - /* REVISIT: - * Also, use minfo->cover to decide how to manage - * the card detect sensing. - */ - host->power_pin = minfo->power_pin; - host->switch_pin = minfo->switch_pin; - host->wp_pin = minfo->wp_pin; - host->use_dma = 1; - host->dma_ch = -1; - - host->irq = pdev->resource[1].start; - host->base = ioremap(pdev->res.start, SZ_4K); - if (!host->base) { - ret = -ENOMEM; - goto out; - } - - if (minfo->wire4) - mmc->caps |= MMC_CAP_4_BIT_DATA; - - mmc->ops = &mmc_omap_ops; - mmc->f_min = 400000; - mmc->f_max = 24000000; - mmc->ocr_avail = MMC_VDD_32_33|MMC_VDD_33_34; - - /* Use scatterlist DMA to reduce per-transfer costs. - * NOTE max_seg_size assumption that small blocks aren't - * normally used (except e.g. for reading SD registers). - */ - mmc->max_phys_segs = 32; - mmc->max_hw_segs = 32; - mmc->max_sectors = 256; /* NBLK max 11-bits, OMAP also limited by DMA */ - mmc->max_seg_size = mmc->max_sectors * 512; - - if (host->power_pin >= 0) { - if ((ret = omap_request_gpio(host->power_pin)) != 0) { - dev_err(mmc_dev(host->mmc), "Unable to get GPIO - pin for MMC power\n"); - goto out; - } - omap_set_gpio_direction(host->power_pin, 0); - } - - ret = request_irq(host->irq, mmc_omap_irq, 0, DRIVER_NAME, host); - if (ret) - goto out; - - host->dev = &pdev->dev; - platform_set_drvdata(pdev, host); - - mmc_add_host(mmc); - - if (host->switch_pin >= 0) { - INIT_WORK(&host->switch_work, mmc_omap_switch_handler, host); - init_timer(&host->switch_timer); - host->switch_timer.function = mmc_omap_switch_timer; - host->switch_timer.data = (unsigned long) host; - if (omap_request_gpio(host->switch_pin) != 0) { - dev_warn(mmc_dev(host->mmc), "Unable to get GPIO pin for MMC cover switch\n"); - host->switch_pin = -1; - goto no_switch; - } - - omap_set_gpio_direction(host->switch_pin, 1); - ret = request_irq(OMAP_GPIO_IRQ(host->switch_pin), - mmc_omap_switch_irq, SA_TRIGGER_RISING, DRIVER_NAME, host); - if (ret) { - dev_warn(mmc_dev(host->mmc), "Unable to get IRQ for MMC cover switch\n"); - omap_free_gpio(host->switch_pin); - host->switch_pin = -1; - goto no_switch; - } - ret = device_create_file(&pdev->dev, &dev_attr_cover_switch); - if (ret == 0) { - ret = device_create_file(&pdev->dev, &dev_attr_enable_poll); - if (ret != 0) - device_remove_file(&pdev->dev, &dev_attr_cover_switch); - } - if (ret) { - dev_wan(mmc_dev(host->mmc), "Unable to create sysfs attributes\n"); - free_irq(OMAP_GPIO_IRQ(host->switch_pin), host); - omap_free_gpio(host->switch_pin); - host->switch_pin = -1; - goto no_switch; - } - if (mmc_omap_enable_poll && mmc_omap_cover_is_open(host)) - schedule_work(&host->switch_work); - } - -no_switch: - return 0; - -out: - /* FIXME: Free other resources too. */ - if (host) { - if (host->iclk && !IS_ERR(host->iclk)) - clk_put(host->iclk); - if (host->fclk && !IS_ERR(host->fclk)) - clk_put(host->fclk); - mmc_free_host(host->mmc); - } - return ret; -} - -static int mmc_omap_remove(struct platform_device *pdev) -{ - struct mmc_omap_host *host = platform_get_drvdata(pdev); - - platform_set_drvdata(pdev, NULL); - - if (host) { - mmc_remove_host(host->mmc); - free_irq(host->irq, host); - - if (host->power_pin >= 0) - omap_free_gpio(host->power_pin); - if (host->switch_pin >= 0) { - device_remove_file(&pdev->dev, &dev_attr_enable_poll); - device_remove_file(&pdev->dev, &dev_attr_cover_switch); - free_irq(OMAP_GPIO_IRQ(host->switch_pin), host); - omap_free_gpio(host->switch_pin); - host->switch_pin = -1; - del_timer_sync(&host->switch_timer); - flush_scheduled_work(); - } - if (host->iclk && !IS_ERR(host->iclk)) - clk_put(host->iclk); - if (host->fclk && !IS_ERR(host->fclk)) - clk_put(host->fclk); - mmc_free_host(host->mmc); - } - - release_mem_region(pdev->resource[0].start, - pdev->resource[0].end - pdev->resource[0].start + 1); - - return 0; -} - -#ifdef CONFIG_PM -static int mmc_omap_suspend(struct platform_device *pdev, pm_message_t mesg) -{ - int ret = 0; - struct mmc_omap_host *host = platform_get_drvdata(pdev); - - if (host && host->suspended) - return 0; - - if (host) { - ret = mmc_suspend_host(host->mmc, mesg); - if (ret == 0) - host->suspended = 1; - } - return ret; -} - -static int mmc_omap_resume(struct platform_device *pdev) -{ - int ret = 0; - struct mmc_omap_host *host = platform_get_drvdata(pdev); - - if (host && !host->suspended) - return 0; - - if (host) { - ret = mmc_resume_host(host->mmc); - if (ret == 0) - host->suspended = 0; - } - - return ret; -} -#else -#define mmc_omap_suspend NULL -#define mmc_omap_resume NULL -#endif - -static struct platform_driver mmc_omap_driver = { - .probe = mmc_omap_probe, - .remove = mmc_omap_remove, - .suspend = mmc_omap_suspend, - .resume = mmc_omap_resume, - .driver = { - .name = DRIVER_NAME, - }, -}; - -static int __init mmc_omap_init(void) -{ - return platform_driver_register(&mmc_omap_driver); -} - -static void __exit mmc_omap_exit(void) -{ - platform_driver_unregister(&mmc_omap_driver); -} - -module_init(mmc_omap_init); -module_exit(mmc_omap_exit); - -MODULE_DESCRIPTION("OMAP Multimedia Card driver"); -MODULE_LICENSE("GPL"); -MODULE_ALIAS(DRIVER_NAME); -MODULE_AUTHOR("Juha Yrjölä"); diff --git a/trunk/drivers/mmc/omap.h b/trunk/drivers/mmc/omap.h deleted file mode 100644 index c954d355a5e3..000000000000 --- a/trunk/drivers/mmc/omap.h +++ /dev/null @@ -1,55 +0,0 @@ -#ifndef DRIVERS_MEDIA_MMC_OMAP_H -#define DRIVERS_MEDIA_MMC_OMAP_H - -#define OMAP_MMC_REG_CMD 0x00 -#define OMAP_MMC_REG_ARGL 0x04 -#define OMAP_MMC_REG_ARGH 0x08 -#define OMAP_MMC_REG_CON 0x0c -#define OMAP_MMC_REG_STAT 0x10 -#define OMAP_MMC_REG_IE 0x14 -#define OMAP_MMC_REG_CTO 0x18 -#define OMAP_MMC_REG_DTO 0x1c -#define OMAP_MMC_REG_DATA 0x20 -#define OMAP_MMC_REG_BLEN 0x24 -#define OMAP_MMC_REG_NBLK 0x28 -#define OMAP_MMC_REG_BUF 0x2c -#define OMAP_MMC_REG_SDIO 0x34 -#define OMAP_MMC_REG_REV 0x3c -#define OMAP_MMC_REG_RSP0 0x40 -#define OMAP_MMC_REG_RSP1 0x44 -#define OMAP_MMC_REG_RSP2 0x48 -#define OMAP_MMC_REG_RSP3 0x4c -#define OMAP_MMC_REG_RSP4 0x50 -#define OMAP_MMC_REG_RSP5 0x54 -#define OMAP_MMC_REG_RSP6 0x58 -#define OMAP_MMC_REG_RSP7 0x5c -#define OMAP_MMC_REG_IOSR 0x60 -#define OMAP_MMC_REG_SYSC 0x64 -#define OMAP_MMC_REG_SYSS 0x68 - -#define OMAP_MMC_STAT_CARD_ERR (1 << 14) -#define OMAP_MMC_STAT_CARD_IRQ (1 << 13) -#define OMAP_MMC_STAT_OCR_BUSY (1 << 12) -#define OMAP_MMC_STAT_A_EMPTY (1 << 11) -#define OMAP_MMC_STAT_A_FULL (1 << 10) -#define OMAP_MMC_STAT_CMD_CRC (1 << 8) -#define OMAP_MMC_STAT_CMD_TOUT (1 << 7) -#define OMAP_MMC_STAT_DATA_CRC (1 << 6) -#define OMAP_MMC_STAT_DATA_TOUT (1 << 5) -#define OMAP_MMC_STAT_END_BUSY (1 << 4) -#define OMAP_MMC_STAT_END_OF_DATA (1 << 3) -#define OMAP_MMC_STAT_CARD_BUSY (1 << 2) -#define OMAP_MMC_STAT_END_OF_CMD (1 << 0) - -#define OMAP_MMC_READ(base, reg) __raw_readw((base) + OMAP_MMC_REG_##reg) -#define OMAP_MMC_WRITE(base, reg, val) __raw_writew((val), (base) + OMAP_MMC_REG_##reg) - -/* - * Command types - */ -#define OMAP_MMC_CMDTYPE_BC 0 -#define OMAP_MMC_CMDTYPE_BCR 1 -#define OMAP_MMC_CMDTYPE_AC 2 -#define OMAP_MMC_CMDTYPE_ADTC 3 - -#endif diff --git a/trunk/drivers/mmc/pxamci.c b/trunk/drivers/mmc/pxamci.c index eb9a8826e9b5..c32fad1ce51c 100644 --- a/trunk/drivers/mmc/pxamci.c +++ b/trunk/drivers/mmc/pxamci.c @@ -37,6 +37,12 @@ #include "pxamci.h" +#ifdef CONFIG_MMC_DEBUG +#define DBG(x...) printk(KERN_DEBUG x) +#else +#define DBG(x...) do { } while (0) +#endif + #define DRIVER_NAME "pxa2xx-mci" #define NR_SG 1 @@ -200,7 +206,7 @@ static void pxamci_start_cmd(struct pxamci_host *host, struct mmc_command *cmd, static void pxamci_finish_request(struct pxamci_host *host, struct mmc_request *mrq) { - pr_debug("PXAMCI: request done\n"); + DBG("PXAMCI: request done\n"); host->mrq = NULL; host->cmd = NULL; host->data = NULL; @@ -246,7 +252,7 @@ static int pxamci_cmd_done(struct pxamci_host *host, unsigned int stat) if ((cmd->resp[0] & 0x80000000) == 0) cmd->error = MMC_ERR_BADCRC; } else { - pr_debug("ignoring CRC from command %d - *risky*\n",cmd->opcode); + DBG("ignoring CRC from command %d - *risky*\n",cmd->opcode); } #else cmd->error = MMC_ERR_BADCRC; @@ -311,12 +317,12 @@ static irqreturn_t pxamci_irq(int irq, void *devid, struct pt_regs *regs) ireg = readl(host->base + MMC_I_REG); - pr_debug("PXAMCI: irq %08x\n", ireg); + DBG("PXAMCI: irq %08x\n", ireg); if (ireg) { unsigned stat = readl(host->base + MMC_STAT); - pr_debug("PXAMCI: stat %08x\n", stat); + DBG("PXAMCI: stat %08x\n", stat); if (ireg & END_CMD_RES) handled |= pxamci_cmd_done(host, stat); @@ -370,9 +376,9 @@ static void pxamci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) { struct pxamci_host *host = mmc_priv(mmc); - pr_debug("pxamci_set_ios: clock %u power %u vdd %u.%02u\n", - ios->clock, ios->power_mode, ios->vdd / 100, - ios->vdd % 100); + DBG("pxamci_set_ios: clock %u power %u vdd %u.%02u\n", + ios->clock, ios->power_mode, ios->vdd / 100, + ios->vdd % 100); if (ios->clock) { unsigned int clk = CLOCKRATE / ios->clock; @@ -399,8 +405,8 @@ static void pxamci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) host->cmdat |= CMDAT_INIT; } - pr_debug("pxamci_set_ios: clkrt = %x cmdat = %x\n", - host->clkrt, host->cmdat); + DBG("pxamci_set_ios: clkrt = %x cmdat = %x\n", + host->clkrt, host->cmdat); } static struct mmc_host_ops pxamci_ops = { diff --git a/trunk/drivers/mmc/sdhci.c b/trunk/drivers/mmc/sdhci.c index bdbfca050029..8b811d94371c 100644 --- a/trunk/drivers/mmc/sdhci.c +++ b/trunk/drivers/mmc/sdhci.c @@ -31,8 +31,12 @@ #define BUGMAIL "" +#ifdef CONFIG_MMC_DEBUG #define DBG(f, x...) \ - pr_debug(DRIVER_NAME " [%s()]: " f, __func__,## x) + printk(KERN_DEBUG DRIVER_NAME " [%s()]: " f, __func__,## x) +#else +#define DBG(f, x...) do { } while (0) +#endif static const struct pci_device_id pci_ids[] __devinitdata = { /* handle any SD host controller */ diff --git a/trunk/drivers/mmc/wbsd.c b/trunk/drivers/mmc/wbsd.c index 511f7b0b31d2..3be397d436fa 100644 --- a/trunk/drivers/mmc/wbsd.c +++ b/trunk/drivers/mmc/wbsd.c @@ -44,10 +44,15 @@ #define DRIVER_NAME "wbsd" #define DRIVER_VERSION "1.5" +#ifdef CONFIG_MMC_DEBUG #define DBG(x...) \ - pr_debug(DRIVER_NAME ": " x) + printk(KERN_DEBUG DRIVER_NAME ": " x) #define DBGF(f, x...) \ - pr_debug(DRIVER_NAME " [%s()]: " f, __func__ , ##x) + printk(KERN_DEBUG DRIVER_NAME " [%s()]: " f, __func__ , ##x) +#else +#define DBG(x...) do { } while (0) +#define DBGF(x...) do { } while (0) +#endif /* * Device resources diff --git a/trunk/drivers/mtd/chips/amd_flash.c b/trunk/drivers/mtd/chips/amd_flash.c index 57115618c496..fdb91b6f1d97 100644 --- a/trunk/drivers/mtd/chips/amd_flash.c +++ b/trunk/drivers/mtd/chips/amd_flash.c @@ -664,7 +664,7 @@ static struct mtd_info *amd_flash_probe(struct map_info *map) printk("%s: Probing for AMD compatible flash...\n", map->name); if ((table_pos[0] = probe_new_chip(mtd, 0, NULL, &temp, table, - ARRAY_SIZE(table))) + sizeof(table)/sizeof(table[0]))) == -1) { printk(KERN_WARNING "%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) base += (1 << temp.chipshift)) { int numchips = temp.numchips; table_pos[numchips] = probe_new_chip(mtd, base, chips, - &temp, table, ARRAY_SIZE(table)); + &temp, table, sizeof(table)/sizeof(table[0])); } mtd->eraseregions = kmalloc(sizeof(struct mtd_erase_region_info) * diff --git a/trunk/drivers/mtd/chips/jedec_probe.c b/trunk/drivers/mtd/chips/jedec_probe.c index 517ea33e7260..edb306c03c0a 100644 --- a/trunk/drivers/mtd/chips/jedec_probe.c +++ b/trunk/drivers/mtd/chips/jedec_probe.c @@ -34,7 +34,6 @@ #define MANUFACTURER_MACRONIX 0x00C2 #define MANUFACTURER_NEC 0x0010 #define MANUFACTURER_PMC 0x009D -#define MANUFACTURER_SHARP 0x00b0 #define MANUFACTURER_SST 0x00BF #define MANUFACTURER_ST 0x0020 #define MANUFACTURER_TOSHIBA 0x0098 @@ -125,9 +124,6 @@ #define PM49FL004 0x006E #define PM49FL008 0x006A -/* Sharp */ -#define LH28F640BF 0x00b0 - /* ST - www.st.com */ #define M29W800DT 0x00D7 #define M29W800DB 0x005B @@ -1271,19 +1267,6 @@ static const struct amd_flash_info jedec_table[] = { .regions = { ERASEINFO( 0x01000, 256 ) } - }, { - .mfr_id = MANUFACTURER_SHARP, - .dev_id = LH28F640BF, - .name = "LH28F640BF", - .uaddr = { - [0] = MTD_UADDR_UNNECESSARY, /* x8 */ - }, - .DevSize = SIZE_4MiB, - .CmdSet = P_ID_INTEL_STD, - .NumEraseRegions= 1, - .regions = { - ERASEINFO(0x40000,16), - } }, { .mfr_id = MANUFACTURER_SST, .dev_id = SST39LF512, @@ -2052,7 +2035,7 @@ static int jedec_probe_chip(struct map_info *map, __u32 base, DEBUG(MTD_DEBUG_LEVEL3, "Search for id:(%02x %02x) interleave(%d) type(%d)\n", cfi->mfr, cfi->id, cfi_interleave(cfi), cfi->device_type); - for (i = 0; i < ARRAY_SIZE(jedec_table); i++) { + for (i=0; i\n"); diff --git a/trunk/drivers/mtd/cmdlinepart.c b/trunk/drivers/mtd/cmdlinepart.c index a7a7bfe33879..6b8bb2e4dcfd 100644 --- a/trunk/drivers/mtd/cmdlinepart.c +++ b/trunk/drivers/mtd/cmdlinepart.c @@ -42,8 +42,7 @@ /* special size referring to all the remaining space in a partition */ -#define SIZE_REMAINING UINT_MAX -#define OFFSET_CONTINUOUS UINT_MAX +#define SIZE_REMAINING 0xffffffff struct cmdline_mtd_partition { struct cmdline_mtd_partition *next; @@ -76,7 +75,7 @@ static struct mtd_partition * newpart(char *s, { struct mtd_partition *parts; unsigned long size; - unsigned long offset = OFFSET_CONTINUOUS; + unsigned long offset = 0; char *name; int name_len; unsigned char *extra_mem; @@ -315,7 +314,7 @@ static int parse_cmdline_partitions(struct mtd_info *master, { for(i = 0, offset = 0; i < part->num_parts; i++) { - if (part->parts[i].offset == OFFSET_CONTINUOUS) + if (!part->parts[i].offset) part->parts[i].offset = offset; else offset = part->parts[i].offset; diff --git a/trunk/drivers/mtd/devices/blkmtd.c b/trunk/drivers/mtd/devices/blkmtd.c index 79f2e1f23ebd..04f864d238db 100644 --- a/trunk/drivers/mtd/devices/blkmtd.c +++ b/trunk/drivers/mtd/devices/blkmtd.c @@ -28,9 +28,8 @@ #include #include #include -#include #include -#include + #define err(format, arg...) printk(KERN_ERR "blkmtd: " format "\n" , ## arg) #define info(format, arg...) printk(KERN_INFO "blkmtd: " format "\n" , ## arg) @@ -47,7 +46,7 @@ struct blkmtd_dev { struct list_head list; struct block_device *blkdev; struct mtd_info mtd_info; - struct mutex wrbuf_mutex; + struct semaphore wrbuf_mutex; }; @@ -269,7 +268,7 @@ static int write_pages(struct blkmtd_dev *dev, const u_char *buf, loff_t to, if(end_len) pagecnt++; - mutex_lock(&dev->wrbuf_mutex); + down(&dev->wrbuf_mutex); DEBUG(3, "blkmtd: write: start_len = %zd len = %zd end_len = %zd pagecnt = %d\n", start_len, len, end_len, pagecnt); @@ -377,7 +376,7 @@ static int write_pages(struct blkmtd_dev *dev, const u_char *buf, loff_t to, blkmtd_write_out(bio); DEBUG(2, "blkmtd: write: end, retlen = %zd, err = %d\n", *retlen, err); - mutex_unlock(&dev->wrbuf_mutex); + up(&dev->wrbuf_mutex); if(retlen) *retlen = thislen; @@ -615,6 +614,8 @@ static struct mtd_erase_region_info *calc_erase_regions( } +extern dev_t __init name_to_dev_t(const char *line); + static struct blkmtd_dev *add_device(char *devname, int readonly, int erase_size) { struct block_device *bdev; @@ -658,7 +659,7 @@ static struct blkmtd_dev *add_device(char *devname, int readonly, int erase_size memset(dev, 0, sizeof(struct blkmtd_dev)); dev->blkdev = bdev; if(!readonly) { - mutex_init(&dev->wrbuf_mutex); + init_MUTEX(&dev->wrbuf_mutex); } dev->mtd_info.size = dev->blkdev->bd_inode->i_size & PAGE_MASK; diff --git a/trunk/drivers/mtd/devices/block2mtd.c b/trunk/drivers/mtd/devices/block2mtd.c index 4160b8334c53..7ff403b2a0a0 100644 --- a/trunk/drivers/mtd/devices/block2mtd.c +++ b/trunk/drivers/mtd/devices/block2mtd.c @@ -18,7 +18,6 @@ #include #include #include -#include #define VERSION "$Revision: 1.30 $" @@ -32,7 +31,7 @@ struct block2mtd_dev { struct list_head list; struct block_device *blkdev; struct mtd_info mtd; - struct mutex write_mutex; + struct semaphore write_mutex; }; @@ -135,9 +134,9 @@ static int block2mtd_erase(struct mtd_info *mtd, struct erase_info *instr) int err; instr->state = MTD_ERASING; - mutex_lock(&dev->write_mutex); + down(&dev->write_mutex); err = _block2mtd_erase(dev, from, len); - mutex_unlock(&dev->write_mutex); + up(&dev->write_mutex); if (err) { ERROR("erase failed err = %d", err); instr->state = MTD_ERASE_FAILED; @@ -250,9 +249,9 @@ static int block2mtd_write(struct mtd_info *mtd, loff_t to, size_t len, if (to + len > mtd->size) len = mtd->size - to; - mutex_lock(&dev->write_mutex); + down(&dev->write_mutex); err = _block2mtd_write(dev, buf, to, len, retlen); - mutex_unlock(&dev->write_mutex); + up(&dev->write_mutex); if (err > 0) err = 0; return err; @@ -311,7 +310,7 @@ static struct block2mtd_dev *add_device(char *devname, int erase_size) goto devinit_err; } - mutex_init(&dev->write_mutex); + init_MUTEX(&dev->write_mutex); /* Setup the MTD structure */ /* make the name contain the block device in */ diff --git a/trunk/drivers/mtd/devices/doc2000.c b/trunk/drivers/mtd/devices/doc2000.c index 23e7a5c7d2c1..e4345cf744a2 100644 --- a/trunk/drivers/mtd/devices/doc2000.c +++ b/trunk/drivers/mtd/devices/doc2000.c @@ -20,7 +20,6 @@ #include #include #include -#include #include #include @@ -606,7 +605,7 @@ static void DoC2k_init(struct mtd_info *mtd) this->curfloor = -1; this->curchip = -1; - mutex_init(&this->lock); + init_MUTEX(&this->lock); /* Ident all the chips present. */ DoC_ScanChips(this, maxchips); @@ -646,7 +645,7 @@ static int doc_read_ecc(struct mtd_info *mtd, loff_t from, size_t len, if (from >= this->totlen) return -EINVAL; - mutex_lock(&this->lock); + down(&this->lock); *retlen = 0; while (left) { @@ -775,7 +774,7 @@ static int doc_read_ecc(struct mtd_info *mtd, loff_t from, size_t len, buf += len; } - mutex_unlock(&this->lock); + up(&this->lock); return ret; } @@ -804,7 +803,7 @@ static int doc_write_ecc(struct mtd_info *mtd, loff_t to, size_t len, if (to >= this->totlen) return -EINVAL; - mutex_lock(&this->lock); + down(&this->lock); *retlen = 0; while (left) { @@ -874,7 +873,7 @@ static int doc_write_ecc(struct mtd_info *mtd, loff_t to, size_t len, printk(KERN_ERR "Error programming flash\n"); /* Error in programming */ *retlen = 0; - mutex_unlock(&this->lock); + up(&this->lock); return -EIO; } @@ -936,7 +935,7 @@ static int doc_write_ecc(struct mtd_info *mtd, loff_t to, size_t len, printk(KERN_ERR "Error programming flash\n"); /* Error in programming */ *retlen = 0; - mutex_unlock(&this->lock); + up(&this->lock); return -EIO; } @@ -957,7 +956,7 @@ static int doc_write_ecc(struct mtd_info *mtd, loff_t to, size_t len, ret = doc_write_oob_nolock(mtd, to, 8, &dummy, x); if (ret) { - mutex_unlock(&this->lock); + up(&this->lock); return ret; } } @@ -967,7 +966,7 @@ static int doc_write_ecc(struct mtd_info *mtd, loff_t to, size_t len, buf += len; } - mutex_unlock(&this->lock); + up(&this->lock); return 0; } @@ -976,13 +975,13 @@ static int doc_writev_ecc(struct mtd_info *mtd, const struct kvec *vecs, u_char *eccbuf, struct nand_oobinfo *oobsel) { static char static_buf[512]; - static DEFINE_MUTEX(writev_buf_mutex); + static DECLARE_MUTEX(writev_buf_sem); size_t totretlen = 0; size_t thisvecofs = 0; int ret= 0; - mutex_lock(&writev_buf_mutex); + down(&writev_buf_sem); while(count) { size_t thislen, thisretlen; @@ -1025,7 +1024,7 @@ static int doc_writev_ecc(struct mtd_info *mtd, const struct kvec *vecs, to += thislen; } - mutex_unlock(&writev_buf_mutex); + up(&writev_buf_sem); *retlen = totretlen; return ret; } @@ -1038,7 +1037,7 @@ static int doc_read_oob(struct mtd_info *mtd, loff_t ofs, size_t len, int len256 = 0, ret; struct Nand *mychip; - mutex_lock(&this->lock); + down(&this->lock); mychip = &this->chips[ofs >> this->chipshift]; @@ -1084,7 +1083,7 @@ static int doc_read_oob(struct mtd_info *mtd, loff_t ofs, size_t len, ret = DoC_WaitReady(this); - mutex_unlock(&this->lock); + up(&this->lock); return ret; } @@ -1198,10 +1197,10 @@ static int doc_write_oob(struct mtd_info *mtd, loff_t ofs, size_t len, struct DiskOnChip *this = mtd->priv; int ret; - mutex_lock(&this->lock); + down(&this->lock); ret = doc_write_oob_nolock(mtd, ofs, len, retlen, buf); - mutex_unlock(&this->lock); + up(&this->lock); return ret; } @@ -1215,10 +1214,10 @@ static int doc_erase(struct mtd_info *mtd, struct erase_info *instr) struct Nand *mychip; int status; - mutex_lock(&this->lock); + down(&this->lock); if (ofs & (mtd->erasesize-1) || len & (mtd->erasesize-1)) { - mutex_unlock(&this->lock); + up(&this->lock); return -EINVAL; } @@ -1266,7 +1265,7 @@ static int doc_erase(struct mtd_info *mtd, struct erase_info *instr) callback: mtd_erase_callback(instr); - mutex_unlock(&this->lock); + up(&this->lock); return 0; } diff --git a/trunk/drivers/mtd/devices/lart.c b/trunk/drivers/mtd/devices/lart.c index 29b0ddaa324e..1e876fcb0408 100644 --- a/trunk/drivers/mtd/devices/lart.c +++ b/trunk/drivers/mtd/devices/lart.c @@ -581,6 +581,8 @@ static int flash_write (struct mtd_info *mtd,loff_t to,size_t len,size_t *retlen /***************************************************************************************************/ +#define NB_OF(x) (sizeof (x) / sizeof (x[0])) + static struct mtd_info mtd; static struct mtd_erase_region_info erase_regions[] = { @@ -638,7 +640,7 @@ int __init lart_flash_init (void) mtd.flags = MTD_CAP_NORFLASH; mtd.size = FLASH_BLOCKSIZE_PARAM * FLASH_NUMBLOCKS_16m_PARAM + FLASH_BLOCKSIZE_MAIN * FLASH_NUMBLOCKS_16m_MAIN; mtd.erasesize = FLASH_BLOCKSIZE_MAIN; - mtd.numeraseregions = ARRAY_SIZE(erase_regions); + mtd.numeraseregions = NB_OF (erase_regions); mtd.eraseregions = erase_regions; mtd.erase = flash_erase; mtd.read = flash_read; @@ -668,9 +670,9 @@ int __init lart_flash_init (void) result,mtd.eraseregions[result].numblocks); #ifdef HAVE_PARTITIONS - printk ("\npartitions = %d\n", ARRAY_SIZE(lart_partitions)); + printk ("\npartitions = %d\n",NB_OF (lart_partitions)); - for (result = 0; result < ARRAY_SIZE(lart_partitions); result++) + for (result = 0; result < NB_OF (lart_partitions); result++) printk (KERN_DEBUG "\n\n" "lart_partitions[%d].name = %s\n" @@ -685,7 +687,7 @@ int __init lart_flash_init (void) #ifndef HAVE_PARTITIONS result = add_mtd_device (&mtd); #else - result = add_mtd_partitions (&mtd,lart_partitions, ARRAY_SIZE(lart_partitions)); + result = add_mtd_partitions (&mtd,lart_partitions,NB_OF (lart_partitions)); #endif return (result); diff --git a/trunk/drivers/mtd/devices/m25p80.c b/trunk/drivers/mtd/devices/m25p80.c index 04e65d5dae00..d5f24089be71 100644 --- a/trunk/drivers/mtd/devices/m25p80.c +++ b/trunk/drivers/mtd/devices/m25p80.c @@ -186,7 +186,7 @@ static int m25p80_erase(struct mtd_info *mtd, struct erase_info *instr) struct m25p *flash = mtd_to_m25p(mtd); u32 addr,len; - DEBUG(MTD_DEBUG_LEVEL2, "%s: %s %s 0x%08x, len %d\n", + DEBUG(MTD_DEBUG_LEVEL2, "%s: %s %s 0x%08x, len %zd\n", flash->spi->dev.bus_id, __FUNCTION__, "at", (u32)instr->addr, instr->len); diff --git a/trunk/drivers/mtd/devices/ms02-nv.c b/trunk/drivers/mtd/devices/ms02-nv.c index 485f663493d2..0ff2e4378244 100644 --- a/trunk/drivers/mtd/devices/ms02-nv.c +++ b/trunk/drivers/mtd/devices/ms02-nv.c @@ -308,7 +308,7 @@ static int __init ms02nv_init(void) break; } - for (i = 0; i < ARRAY_SIZE(ms02nv_addrs); i++) + for (i = 0; i < (sizeof(ms02nv_addrs) / sizeof(*ms02nv_addrs)); i++) if (!ms02nv_init_one(ms02nv_addrs[i] << stride)) count++; diff --git a/trunk/drivers/mtd/inftlcore.c b/trunk/drivers/mtd/inftlcore.c index a3b92479719d..8a544890173d 100644 --- a/trunk/drivers/mtd/inftlcore.c +++ b/trunk/drivers/mtd/inftlcore.c @@ -47,6 +47,9 @@ */ #define MAX_LOOPS 10000 +extern void INFTL_dumptables(struct INFTLrecord *inftl); +extern void INFTL_dumpVUchains(struct INFTLrecord *inftl); + static void inftl_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd) { struct INFTLrecord *inftl; @@ -129,7 +132,7 @@ static void inftl_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd) return; } #ifdef PSYCHO_DEBUG - printk(KERN_INFO "INFTL: Found new inftl%c\n", inftl->mbd.devnum + 'a'); + printk(KERN_INFO "INFTL: Found new nftl%c\n", nftl->mbd.devnum + 'a'); #endif return; } @@ -882,6 +885,8 @@ static struct mtd_blktrans_ops inftl_tr = { .owner = THIS_MODULE, }; +extern char inftlmountrev[]; + static int __init init_inftl(void) { printk(KERN_INFO "INFTL: inftlcore.c $Revision: 1.19 $, " diff --git a/trunk/drivers/mtd/maps/alchemy-flash.c b/trunk/drivers/mtd/maps/alchemy-flash.c index b933a2a27b18..a57791a6ce40 100644 --- a/trunk/drivers/mtd/maps/alchemy-flash.c +++ b/trunk/drivers/mtd/maps/alchemy-flash.c @@ -126,6 +126,8 @@ static struct mtd_partition alchemy_partitions[] = { } }; +#define NB_OF(x) (sizeof(x)/sizeof(x[0])) + static struct mtd_info *mymtd; int __init alchemy_mtd_init(void) @@ -152,7 +154,7 @@ int __init alchemy_mtd_init(void) * Static partition definition selection */ parts = alchemy_partitions; - nb_parts = ARRAY_SIZE(alchemy_partitions); + nb_parts = NB_OF(alchemy_partitions); alchemy_map.size = window_size; /* diff --git a/trunk/drivers/mtd/maps/cfi_flagadm.c b/trunk/drivers/mtd/maps/cfi_flagadm.c index fd0f0d3187de..6a8c0415bde8 100644 --- a/trunk/drivers/mtd/maps/cfi_flagadm.c +++ b/trunk/drivers/mtd/maps/cfi_flagadm.c @@ -86,7 +86,7 @@ struct mtd_partition flagadm_parts[] = { } }; -#define PARTITION_COUNT ARRAY_SIZE(flagadm_parts) +#define PARTITION_COUNT (sizeof(flagadm_parts)/sizeof(struct mtd_partition)) static struct mtd_info *mymtd; diff --git a/trunk/drivers/mtd/maps/dbox2-flash.c b/trunk/drivers/mtd/maps/dbox2-flash.c index 652813cd6c2d..49d90542fc75 100644 --- a/trunk/drivers/mtd/maps/dbox2-flash.c +++ b/trunk/drivers/mtd/maps/dbox2-flash.c @@ -57,7 +57,7 @@ static struct mtd_partition partition_info[]= { } }; -#define NUM_PARTITIONS ARRAY_SIZE(partition_info) +#define NUM_PARTITIONS (sizeof(partition_info) / sizeof(partition_info[0])) #define WINDOW_ADDR 0x10000000 #define WINDOW_SIZE 0x800000 diff --git a/trunk/drivers/mtd/maps/dilnetpc.c b/trunk/drivers/mtd/maps/dilnetpc.c index c299d10b33e6..efb221692641 100644 --- a/trunk/drivers/mtd/maps/dilnetpc.c +++ b/trunk/drivers/mtd/maps/dilnetpc.c @@ -300,7 +300,7 @@ static struct mtd_partition partition_info[]= }, }; -#define NUM_PARTITIONS ARRAY_SIZE(partition_info) +#define NUM_PARTITIONS (sizeof(partition_info)/sizeof(partition_info[0])) static struct mtd_info *mymtd; static struct mtd_info *lowlvl_parts[NUM_PARTITIONS]; @@ -345,7 +345,7 @@ static struct mtd_partition higlvl_partition_info[]= }, }; -#define NUM_HIGHLVL_PARTITIONS ARRAY_SIZE(higlvl_partition_info) +#define NUM_HIGHLVL_PARTITIONS (sizeof(higlvl_partition_info)/sizeof(partition_info[0])) static int dnp_adnp_probe(void) diff --git a/trunk/drivers/mtd/maps/dmv182.c b/trunk/drivers/mtd/maps/dmv182.c index 2bb3c0f0f970..b993ac01a9a5 100644 --- a/trunk/drivers/mtd/maps/dmv182.c +++ b/trunk/drivers/mtd/maps/dmv182.c @@ -99,7 +99,7 @@ static struct mtd_info *this_mtd; static int __init init_svme182(void) { struct mtd_partition *partitions; - int num_parts = ARRAY_SIZE(svme182_partitions); + int num_parts = sizeof(svme182_partitions) / sizeof(struct mtd_partition); partitions = svme182_partitions; diff --git a/trunk/drivers/mtd/maps/h720x-flash.c b/trunk/drivers/mtd/maps/h720x-flash.c index 0667101ccbe1..319094821101 100644 --- a/trunk/drivers/mtd/maps/h720x-flash.c +++ b/trunk/drivers/mtd/maps/h720x-flash.c @@ -59,7 +59,7 @@ static struct mtd_partition h720x_partitions[] = { } }; -#define NUM_PARTITIONS ARRAY_SIZE(h720x_partitions) +#define NUM_PARTITIONS (sizeof(h720x_partitions)/sizeof(h720x_partitions[0])) static int nr_mtd_parts; static struct mtd_partition *mtd_parts; diff --git a/trunk/drivers/mtd/maps/netsc520.c b/trunk/drivers/mtd/maps/netsc520.c index ed215470158b..33060a315722 100644 --- a/trunk/drivers/mtd/maps/netsc520.c +++ b/trunk/drivers/mtd/maps/netsc520.c @@ -76,7 +76,7 @@ static struct mtd_partition partition_info[]={ .size = 0x80000 }, }; -#define NUM_PARTITIONS ARRAY_SIZE(partition_info) +#define NUM_PARTITIONS (sizeof(partition_info)/sizeof(partition_info[0])) #define WINDOW_SIZE 0x00100000 #define WINDOW_ADDR 0x00200000 @@ -88,7 +88,7 @@ static struct map_info netsc520_map = { .phys = WINDOW_ADDR, }; -#define NUM_FLASH_BANKS ARRAY_SIZE(netsc520_map) +#define NUM_FLASH_BANKS (sizeof(netsc520_map)/sizeof(struct map_info)) static struct mtd_info *mymtd; diff --git a/trunk/drivers/mtd/maps/nettel.c b/trunk/drivers/mtd/maps/nettel.c index 54a3102ab19a..632eb2aa968f 100644 --- a/trunk/drivers/mtd/maps/nettel.c +++ b/trunk/drivers/mtd/maps/nettel.c @@ -128,7 +128,8 @@ static struct mtd_partition nettel_amd_partitions[] = { } }; -#define NUM_AMD_PARTITIONS ARRAY_SIZE(nettel_amd_partitions) +#define NUM_AMD_PARTITIONS \ + (sizeof(nettel_amd_partitions)/sizeof(nettel_amd_partitions[0])) /****************************************************************************/ diff --git a/trunk/drivers/mtd/maps/ocotea.c b/trunk/drivers/mtd/maps/ocotea.c index a21fcd195ab4..c223514ca2eb 100644 --- a/trunk/drivers/mtd/maps/ocotea.c +++ b/trunk/drivers/mtd/maps/ocotea.c @@ -58,6 +58,8 @@ static struct mtd_partition ocotea_large_partitions[] = { } }; +#define NB_OF(x) (sizeof(x)/sizeof(x[0])) + int __init init_ocotea(void) { u8 fpga0_reg; @@ -95,7 +97,7 @@ int __init init_ocotea(void) if (flash) { flash->owner = THIS_MODULE; add_mtd_partitions(flash, ocotea_small_partitions, - ARRAY_SIZE(ocotea_small_partitions)); + NB_OF(ocotea_small_partitions)); } else { printk("map probe failed for flash\n"); return -ENXIO; @@ -116,7 +118,7 @@ int __init init_ocotea(void) if (flash) { flash->owner = THIS_MODULE; add_mtd_partitions(flash, ocotea_large_partitions, - ARRAY_SIZE(ocotea_large_partitions)); + NB_OF(ocotea_large_partitions)); } else { printk("map probe failed for flash\n"); return -ENXIO; diff --git a/trunk/drivers/mtd/maps/pci.c b/trunk/drivers/mtd/maps/pci.c index d2ab1bae9c34..21822c2edbe4 100644 --- a/trunk/drivers/mtd/maps/pci.c +++ b/trunk/drivers/mtd/maps/pci.c @@ -334,6 +334,9 @@ mtd_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) return 0; release: + if (mtd) + map_destroy(mtd); + if (map) { map->exit(dev, map); kfree(map); diff --git a/trunk/drivers/mtd/maps/pcmciamtd.c b/trunk/drivers/mtd/maps/pcmciamtd.c index 8bbc751a6021..f988c817e196 100644 --- a/trunk/drivers/mtd/maps/pcmciamtd.c +++ b/trunk/drivers/mtd/maps/pcmciamtd.c @@ -616,7 +616,7 @@ static void pcmciamtd_config(dev_link_t *link) } else if(mem_type == 2) { mtd = do_map_probe("map_rom", &dev->pcmcia_map); } else { - for(i = 0; i < ARRAY_SIZE(probes); i++) { + for(i = 0; i < sizeof(probes) / sizeof(char *); i++) { DEBUG(1, "Trying %s", probes[i]); mtd = do_map_probe(probes[i], &dev->pcmcia_map); if(mtd) diff --git a/trunk/drivers/mtd/maps/redwood.c b/trunk/drivers/mtd/maps/redwood.c index 50b14033613f..5b76ed886185 100644 --- a/trunk/drivers/mtd/maps/redwood.c +++ b/trunk/drivers/mtd/maps/redwood.c @@ -121,7 +121,8 @@ struct map_info redwood_flash_map = { }; -#define NUM_REDWOOD_FLASH_PARTITIONS ARRAY_SIZE(redwood_flash_partitions) +#define NUM_REDWOOD_FLASH_PARTITIONS \ + (sizeof(redwood_flash_partitions)/sizeof(redwood_flash_partitions[0])) static struct mtd_info *redwood_mtd; diff --git a/trunk/drivers/mtd/maps/sbc8240.c b/trunk/drivers/mtd/maps/sbc8240.c index 350286dc1d2e..225cdd9ba5b2 100644 --- a/trunk/drivers/mtd/maps/sbc8240.c +++ b/trunk/drivers/mtd/maps/sbc8240.c @@ -66,7 +66,7 @@ static struct map_info sbc8240_map[2] = { } }; -#define NUM_FLASH_BANKS ARRAY_SIZE(sbc8240_map) +#define NUM_FLASH_BANKS (sizeof(sbc8240_map) / sizeof(struct map_info)) /* * The following defines the partition layout of SBC8240 boards. @@ -125,6 +125,8 @@ static struct mtd_partition sbc8240_fs_partitions [] = { } }; +#define NB_OF(x) (sizeof (x) / sizeof (x[0])) + /* trivial struct to describe partition information */ struct mtd_part_def { @@ -188,10 +190,10 @@ int __init init_sbc8240_mtd (void) #ifdef CONFIG_MTD_PARTITIONS sbc8240_part_banks[0].mtd_part = sbc8240_uboot_partitions; sbc8240_part_banks[0].type = "static image"; - sbc8240_part_banks[0].nums = ARRAY_SIZE(sbc8240_uboot_partitions); + sbc8240_part_banks[0].nums = NB_OF(sbc8240_uboot_partitions); sbc8240_part_banks[1].mtd_part = sbc8240_fs_partitions; sbc8240_part_banks[1].type = "static file system"; - sbc8240_part_banks[1].nums = ARRAY_SIZE(sbc8240_fs_partitions); + sbc8240_part_banks[1].nums = NB_OF(sbc8240_fs_partitions); for (i = 0; i < NUM_FLASH_BANKS; i++) { diff --git a/trunk/drivers/mtd/maps/sc520cdp.c b/trunk/drivers/mtd/maps/sc520cdp.c index e8c130e1efd3..ed92afadd8a9 100644 --- a/trunk/drivers/mtd/maps/sc520cdp.c +++ b/trunk/drivers/mtd/maps/sc520cdp.c @@ -107,7 +107,7 @@ static struct map_info sc520cdp_map[] = { }, }; -#define NUM_FLASH_BANKS ARRAY_SIZE(sc520cdp_map) +#define NUM_FLASH_BANKS (sizeof(sc520cdp_map)/sizeof(struct map_info)) static struct mtd_info *mymtd[NUM_FLASH_BANKS]; static struct mtd_info *merged_mtd; diff --git a/trunk/drivers/mtd/maps/scx200_docflash.c b/trunk/drivers/mtd/maps/scx200_docflash.c index 28b8a571a91a..2c91dff8bb60 100644 --- a/trunk/drivers/mtd/maps/scx200_docflash.c +++ b/trunk/drivers/mtd/maps/scx200_docflash.c @@ -70,7 +70,7 @@ static struct mtd_partition partition_info[] = { .size = 0x80000 }, }; -#define NUM_PARTITIONS ARRAY_SIZE(partition_info) +#define NUM_PARTITIONS (sizeof(partition_info)/sizeof(partition_info[0])) #endif diff --git a/trunk/drivers/mtd/maps/sharpsl-flash.c b/trunk/drivers/mtd/maps/sharpsl-flash.c index 12fe53c0d2fc..999f4bb3d845 100644 --- a/trunk/drivers/mtd/maps/sharpsl-flash.c +++ b/trunk/drivers/mtd/maps/sharpsl-flash.c @@ -49,6 +49,8 @@ static struct mtd_partition sharpsl_partitions[1] = { } }; +#define NB_OF(x) (sizeof(x)/sizeof(x[0])) + int __init init_sharpsl(void) { struct mtd_partition *parts; @@ -90,7 +92,7 @@ int __init init_sharpsl(void) } parts = sharpsl_partitions; - nb_parts = ARRAY_SIZE(sharpsl_partitions); + nb_parts = NB_OF(sharpsl_partitions); printk(KERN_NOTICE "Using %s partision definition\n", part_type); add_mtd_partitions(mymtd, parts, nb_parts); diff --git a/trunk/drivers/mtd/maps/ts5500_flash.c b/trunk/drivers/mtd/maps/ts5500_flash.c index a7422c200567..4b372bcb17f1 100644 --- a/trunk/drivers/mtd/maps/ts5500_flash.c +++ b/trunk/drivers/mtd/maps/ts5500_flash.c @@ -64,7 +64,7 @@ static struct mtd_partition ts5500_partitions[] = { } }; -#define NUM_PARTITIONS ARRAY_SIZE(ts5500_partitions) +#define NUM_PARTITIONS (sizeof(ts5500_partitions)/sizeof(struct mtd_partition)) static struct mtd_info *mymtd; diff --git a/trunk/drivers/mtd/maps/uclinux.c b/trunk/drivers/mtd/maps/uclinux.c index f7264dc2ac9b..79d92808b766 100644 --- a/trunk/drivers/mtd/maps/uclinux.c +++ b/trunk/drivers/mtd/maps/uclinux.c @@ -37,7 +37,7 @@ struct mtd_partition uclinux_romfs[] = { { .name = "ROMfs" } }; -#define NUM_PARTITIONS ARRAY_SIZE(uclinux_romfs) +#define NUM_PARTITIONS (sizeof(uclinux_romfs) / sizeof(uclinux_romfs[0])) /****************************************************************************/ diff --git a/trunk/drivers/mtd/maps/vmax301.c b/trunk/drivers/mtd/maps/vmax301.c index b3e487395435..e0063941c0df 100644 --- a/trunk/drivers/mtd/maps/vmax301.c +++ b/trunk/drivers/mtd/maps/vmax301.c @@ -182,7 +182,7 @@ int __init init_vmax301(void) } } - if (!vmax_mtd[0] && !vmax_mtd[1]) { + if (!vmax_mtd[1] && !vmax_mtd[2]) { iounmap((void *)iomapadr); return -ENXIO; } diff --git a/trunk/drivers/mtd/mtd_blkdevs.c b/trunk/drivers/mtd/mtd_blkdevs.c index 458d3c8ae1ee..840dd66ce2dc 100644 --- a/trunk/drivers/mtd/mtd_blkdevs.c +++ b/trunk/drivers/mtd/mtd_blkdevs.c @@ -19,12 +19,12 @@ #include #include #include -#include +#include #include static LIST_HEAD(blktrans_majors); -extern struct mutex mtd_table_mutex; +extern struct semaphore mtd_table_mutex; extern struct mtd_info *mtd_table[]; struct mtd_blkcore_priv { @@ -122,9 +122,9 @@ static int mtd_blktrans_thread(void *arg) spin_unlock_irq(rq->queue_lock); - mutex_lock(&dev->lock); + down(&dev->sem); res = do_blktrans_request(tr, dev, req); - mutex_unlock(&dev->lock); + up(&dev->sem); spin_lock_irq(rq->queue_lock); @@ -235,8 +235,8 @@ int add_mtd_blktrans_dev(struct mtd_blktrans_dev *new) int last_devnum = -1; struct gendisk *gd; - if (!!mutex_trylock(&mtd_table_mutex)) { - mutex_unlock(&mtd_table_mutex); + if (!down_trylock(&mtd_table_mutex)) { + up(&mtd_table_mutex); BUG(); } @@ -267,7 +267,7 @@ int add_mtd_blktrans_dev(struct mtd_blktrans_dev *new) return -EBUSY; } - mutex_init(&new->lock); + init_MUTEX(&new->sem); list_add_tail(&new->list, &tr->devs); added: if (!tr->writesect) @@ -313,8 +313,8 @@ int add_mtd_blktrans_dev(struct mtd_blktrans_dev *new) int del_mtd_blktrans_dev(struct mtd_blktrans_dev *old) { - if (!!mutex_trylock(&mtd_table_mutex)) { - mutex_unlock(&mtd_table_mutex); + if (!down_trylock(&mtd_table_mutex)) { + up(&mtd_table_mutex); BUG(); } @@ -378,14 +378,14 @@ int register_mtd_blktrans(struct mtd_blktrans_ops *tr) memset(tr->blkcore_priv, 0, sizeof(*tr->blkcore_priv)); - mutex_lock(&mtd_table_mutex); + down(&mtd_table_mutex); ret = register_blkdev(tr->major, tr->name); if (ret) { printk(KERN_WARNING "Unable to register %s block device on major %d: %d\n", tr->name, tr->major, ret); kfree(tr->blkcore_priv); - mutex_unlock(&mtd_table_mutex); + up(&mtd_table_mutex); return ret; } spin_lock_init(&tr->blkcore_priv->queue_lock); @@ -396,7 +396,7 @@ int register_mtd_blktrans(struct mtd_blktrans_ops *tr) if (!tr->blkcore_priv->rq) { unregister_blkdev(tr->major, tr->name); kfree(tr->blkcore_priv); - mutex_unlock(&mtd_table_mutex); + up(&mtd_table_mutex); return -ENOMEM; } @@ -407,7 +407,7 @@ int register_mtd_blktrans(struct mtd_blktrans_ops *tr) blk_cleanup_queue(tr->blkcore_priv->rq); unregister_blkdev(tr->major, tr->name); kfree(tr->blkcore_priv); - mutex_unlock(&mtd_table_mutex); + up(&mtd_table_mutex); return ret; } @@ -419,7 +419,7 @@ int register_mtd_blktrans(struct mtd_blktrans_ops *tr) tr->add_mtd(tr, mtd_table[i]); } - mutex_unlock(&mtd_table_mutex); + up(&mtd_table_mutex); return 0; } @@ -428,7 +428,7 @@ int deregister_mtd_blktrans(struct mtd_blktrans_ops *tr) { struct list_head *this, *next; - mutex_lock(&mtd_table_mutex); + down(&mtd_table_mutex); /* Clean up the kernel thread */ tr->blkcore_priv->exiting = 1; @@ -446,7 +446,7 @@ int deregister_mtd_blktrans(struct mtd_blktrans_ops *tr) blk_cleanup_queue(tr->blkcore_priv->rq); unregister_blkdev(tr->major, tr->name); - mutex_unlock(&mtd_table_mutex); + up(&mtd_table_mutex); kfree(tr->blkcore_priv); diff --git a/trunk/drivers/mtd/mtdblock.c b/trunk/drivers/mtd/mtdblock.c index 2cef280e388c..e84756644fd1 100644 --- a/trunk/drivers/mtd/mtdblock.c +++ b/trunk/drivers/mtd/mtdblock.c @@ -19,13 +19,11 @@ #include #include -#include - static struct mtdblk_dev { struct mtd_info *mtd; int count; - struct mutex cache_mutex; + struct semaphore cache_sem; unsigned char *cache_data; unsigned long cache_offset; unsigned int cache_size; @@ -286,7 +284,7 @@ static int mtdblock_open(struct mtd_blktrans_dev *mbd) mtdblk->count = 1; mtdblk->mtd = mtd; - mutex_init(&mtdblk->cache_mutex); + init_MUTEX (&mtdblk->cache_sem); mtdblk->cache_state = STATE_EMPTY; if ((mtdblk->mtd->flags & MTD_CAP_RAM) != MTD_CAP_RAM && mtdblk->mtd->erasesize) { @@ -308,9 +306,9 @@ static int mtdblock_release(struct mtd_blktrans_dev *mbd) DEBUG(MTD_DEBUG_LEVEL1, "mtdblock_release\n"); - mutex_lock(&mtdblk->cache_mutex); + down(&mtdblk->cache_sem); write_cached_data(mtdblk); - mutex_unlock(&mtdblk->cache_mutex); + up(&mtdblk->cache_sem); if (!--mtdblk->count) { /* It was the last usage. Free the device */ @@ -329,9 +327,9 @@ static int mtdblock_flush(struct mtd_blktrans_dev *dev) { struct mtdblk_dev *mtdblk = mtdblks[dev->devnum]; - mutex_lock(&mtdblk->cache_mutex); + down(&mtdblk->cache_sem); write_cached_data(mtdblk); - mutex_unlock(&mtdblk->cache_mutex); + up(&mtdblk->cache_sem); if (mtdblk->mtd->sync) mtdblk->mtd->sync(mtdblk->mtd); diff --git a/trunk/drivers/mtd/mtdcore.c b/trunk/drivers/mtd/mtdcore.c index 9905870f56e5..dade02ab0687 100644 --- a/trunk/drivers/mtd/mtdcore.c +++ b/trunk/drivers/mtd/mtdcore.c @@ -19,13 +19,15 @@ #include #include #include +#ifdef CONFIG_PROC_FS #include +#endif #include /* These are exported solely for the purpose of mtd_blkdevs.c. You should not use them for _anything_ else */ -DEFINE_MUTEX(mtd_table_mutex); +DECLARE_MUTEX(mtd_table_mutex); struct mtd_info *mtd_table[MAX_MTD_DEVICES]; EXPORT_SYMBOL_GPL(mtd_table_mutex); @@ -47,7 +49,7 @@ int add_mtd_device(struct mtd_info *mtd) { int i; - mutex_lock(&mtd_table_mutex); + down(&mtd_table_mutex); for (i=0; i < MAX_MTD_DEVICES; i++) if (!mtd_table[i]) { @@ -65,7 +67,7 @@ int add_mtd_device(struct mtd_info *mtd) not->add(mtd); } - mutex_unlock(&mtd_table_mutex); + up(&mtd_table_mutex); /* We _know_ we aren't being removed, because our caller is still holding us here. So none of this try_ nonsense, and no bitching about it @@ -74,7 +76,7 @@ int add_mtd_device(struct mtd_info *mtd) return 0; } - mutex_unlock(&mtd_table_mutex); + up(&mtd_table_mutex); return 1; } @@ -92,7 +94,7 @@ int del_mtd_device (struct mtd_info *mtd) { int ret; - mutex_lock(&mtd_table_mutex); + down(&mtd_table_mutex); if (mtd_table[mtd->index] != mtd) { ret = -ENODEV; @@ -116,7 +118,7 @@ int del_mtd_device (struct mtd_info *mtd) ret = 0; } - mutex_unlock(&mtd_table_mutex); + up(&mtd_table_mutex); return ret; } @@ -133,7 +135,7 @@ void register_mtd_user (struct mtd_notifier *new) { int i; - mutex_lock(&mtd_table_mutex); + down(&mtd_table_mutex); list_add(&new->list, &mtd_notifiers); @@ -143,7 +145,7 @@ void register_mtd_user (struct mtd_notifier *new) if (mtd_table[i]) new->add(mtd_table[i]); - mutex_unlock(&mtd_table_mutex); + up(&mtd_table_mutex); } /** @@ -160,7 +162,7 @@ int unregister_mtd_user (struct mtd_notifier *old) { int i; - mutex_lock(&mtd_table_mutex); + down(&mtd_table_mutex); module_put(THIS_MODULE); @@ -169,7 +171,7 @@ int unregister_mtd_user (struct mtd_notifier *old) old->remove(mtd_table[i]); list_del(&old->list); - mutex_unlock(&mtd_table_mutex); + up(&mtd_table_mutex); return 0; } @@ -191,7 +193,7 @@ struct mtd_info *get_mtd_device(struct mtd_info *mtd, int num) struct mtd_info *ret = NULL; int i; - mutex_lock(&mtd_table_mutex); + down(&mtd_table_mutex); if (num == -1) { for (i=0; i< MAX_MTD_DEVICES; i++) @@ -209,7 +211,7 @@ struct mtd_info *get_mtd_device(struct mtd_info *mtd, int num) if (ret) ret->usecount++; - mutex_unlock(&mtd_table_mutex); + up(&mtd_table_mutex); return ret; } @@ -217,9 +219,9 @@ void put_mtd_device(struct mtd_info *mtd) { int c; - mutex_lock(&mtd_table_mutex); + down(&mtd_table_mutex); c = --mtd->usecount; - mutex_unlock(&mtd_table_mutex); + up(&mtd_table_mutex); BUG_ON(c < 0); module_put(mtd->owner); @@ -294,11 +296,10 @@ EXPORT_SYMBOL(unregister_mtd_user); EXPORT_SYMBOL(default_mtd_writev); EXPORT_SYMBOL(default_mtd_readv); -#ifdef CONFIG_PROC_FS - /*====================================================================*/ /* Support for /proc/mtd */ +#ifdef CONFIG_PROC_FS static struct proc_dir_entry *proc_mtd; static inline int mtd_proc_info (char *buf, int i) @@ -318,7 +319,7 @@ static int mtd_read_proc (char *page, char **start, off_t off, int count, int len, l, i; off_t begin = 0; - mutex_lock(&mtd_table_mutex); + down(&mtd_table_mutex); len = sprintf(page, "dev: size erasesize name\n"); for (i=0; i< MAX_MTD_DEVICES; i++) { @@ -336,34 +337,38 @@ static int mtd_read_proc (char *page, char **start, off_t off, int count, *eof = 1; done: - mutex_unlock(&mtd_table_mutex); + up(&mtd_table_mutex); if (off >= len+begin) return 0; *start = page + (off-begin); return ((count < begin+len-off) ? count : begin+len-off); } +#endif /* CONFIG_PROC_FS */ + /*====================================================================*/ /* Init code */ static int __init init_mtd(void) { +#ifdef CONFIG_PROC_FS if ((proc_mtd = create_proc_entry( "mtd", 0, NULL ))) proc_mtd->read_proc = mtd_read_proc; +#endif return 0; } static void __exit cleanup_mtd(void) { +#ifdef CONFIG_PROC_FS if (proc_mtd) remove_proc_entry( "mtd", NULL); +#endif } module_init(init_mtd); module_exit(cleanup_mtd); -#endif /* CONFIG_PROC_FS */ - MODULE_LICENSE("GPL"); MODULE_AUTHOR("David Woodhouse "); diff --git a/trunk/drivers/mtd/nand/Kconfig b/trunk/drivers/mtd/nand/Kconfig index cfe288a6e853..1fc4c134d939 100644 --- a/trunk/drivers/mtd/nand/Kconfig +++ b/trunk/drivers/mtd/nand/Kconfig @@ -178,16 +178,17 @@ config MTD_NAND_DISKONCHIP_BBTWRITE Even if you leave this disabled, you can enable BBT writes at module load time (assuming you build diskonchip as a module) with the module parameter "inftl_bbt_write=1". + + config MTD_NAND_SHARPSL + bool "Support for NAND Flash on Sharp SL Series (C7xx + others)" + depends on MTD_NAND && ARCH_PXA + + config MTD_NAND_NANDSIM + bool "Support for NAND Flash Simulator" + depends on MTD_NAND && MTD_PARTITIONS -config MTD_NAND_SHARPSL - tristate "Support for NAND Flash on Sharp SL Series (C7xx + others)" - depends on MTD_NAND && ARCH_PXA - -config MTD_NAND_NANDSIM - tristate "Support for NAND Flash Simulator" - depends on MTD_NAND && MTD_PARTITIONS help The simulator may simulate verious NAND flash chips for the MTD nand layer. - + endmenu diff --git a/trunk/drivers/mtd/nand/au1550nd.c b/trunk/drivers/mtd/nand/au1550nd.c index bde3550910a2..201e1362da14 100644 --- a/trunk/drivers/mtd/nand/au1550nd.c +++ b/trunk/drivers/mtd/nand/au1550nd.c @@ -55,6 +55,8 @@ static const struct mtd_partition partition_info[] = { .size = MTDPART_SIZ_FULL } }; +#define NB_OF(x) (sizeof(x)/sizeof(x[0])) + /** * au_read_byte - read one byte from the chip @@ -460,7 +462,7 @@ int __init au1xxx_nand_init (void) } /* Register the partitions */ - add_mtd_partitions(au1550_mtd, partition_info, ARRAY_SIZE(partition_info)); + add_mtd_partitions(au1550_mtd, partition_info, NB_OF(partition_info)); return 0; diff --git a/trunk/drivers/mtd/nand/nand_base.c b/trunk/drivers/mtd/nand/nand_base.c index 95e96fa1fceb..5d222460b42a 100644 --- a/trunk/drivers/mtd/nand/nand_base.c +++ b/trunk/drivers/mtd/nand/nand_base.c @@ -80,7 +80,6 @@ #include #include #include -#include #include #ifdef CONFIG_MTD_PARTITIONS @@ -516,8 +515,6 @@ static int nand_block_checkbad (struct mtd_info *mtd, loff_t ofs, int getchip, i return nand_isbad_bbt (mtd, ofs, allowbbt); } -DEFINE_LED_TRIGGER(nand_led_trigger); - /* * Wait for the ready pin, after a command * The timeout is catched later. @@ -527,14 +524,12 @@ static void nand_wait_ready(struct mtd_info *mtd) struct nand_chip *this = mtd->priv; unsigned long timeo = jiffies + 2; - led_trigger_event(nand_led_trigger, LED_FULL); /* wait until command is processed or timeout occures */ do { if (this->dev_ready(mtd)) - break; + return; touch_softlockup_watchdog(); } while (time_before(jiffies, timeo)); - led_trigger_event(nand_led_trigger, LED_OFF); } /** @@ -822,8 +817,6 @@ static int nand_wait(struct mtd_info *mtd, struct nand_chip *this, int state) else timeo += (HZ * 20) / 1000; - led_trigger_event(nand_led_trigger, LED_FULL); - /* Apply this short delay always to ensure that we do wait tWB in * any case on any machine. */ ndelay (100); @@ -847,8 +840,6 @@ static int nand_wait(struct mtd_info *mtd, struct nand_chip *this, int state) } cond_resched(); } - led_trigger_event(nand_led_trigger, LED_OFF); - status = (int) this->read_byte(mtd); return status; } @@ -2733,21 +2724,6 @@ void nand_release (struct mtd_info *mtd) EXPORT_SYMBOL_GPL (nand_scan); EXPORT_SYMBOL_GPL (nand_release); - -static int __init nand_base_init(void) -{ - led_trigger_register_simple("nand-disk", &nand_led_trigger); - return 0; -} - -static void __exit nand_base_exit(void) -{ - led_trigger_unregister_simple(nand_led_trigger); -} - -module_init(nand_base_init); -module_exit(nand_base_exit); - MODULE_LICENSE ("GPL"); MODULE_AUTHOR ("Steven J. Hill , Thomas Gleixner "); MODULE_DESCRIPTION ("Generic NAND flash driver code"); diff --git a/trunk/drivers/mtd/redboot.c b/trunk/drivers/mtd/redboot.c index c077d2ec9cdd..8815c8dbef2d 100644 --- a/trunk/drivers/mtd/redboot.c +++ b/trunk/drivers/mtd/redboot.c @@ -85,6 +85,10 @@ static int parse_redboot_partitions(struct mtd_info *master, numslots = (master->erasesize / sizeof(struct fis_image_desc)); for (i = 0; i < numslots; i++) { + if (buf[i].name[0] == 0xff) { + i = numslots; + break; + } if (!memcmp(buf[i].name, "FIS directory", 14)) { /* This is apparently the FIS directory entry for the * FIS directory itself. The FIS directory size is @@ -124,7 +128,7 @@ static int parse_redboot_partitions(struct mtd_info *master, struct fis_list *new_fl, **prev; if (buf[i].name[0] == 0xff) - continue; + break; if (!redboot_checksum(&buf[i])) break; diff --git a/trunk/drivers/net/3c59x.c b/trunk/drivers/net/3c59x.c index 274b0138d442..70f63891b19c 100644 --- a/trunk/drivers/net/3c59x.c +++ b/trunk/drivers/net/3c59x.c @@ -788,7 +788,7 @@ struct vortex_private { int options; /* User-settable misc. driver options. */ unsigned int media_override:4, /* Passed-in media type. */ default_media:4, /* Read from the EEPROM/Wn3_Config. */ - full_duplex:1, autoselect:1, + full_duplex:1, force_fd:1, autoselect:1, bus_master:1, /* Vortex can only do a fragment bus-m. */ full_bus_master_tx:1, full_bus_master_rx:2, /* Boomerang */ flow_ctrl:1, /* Use 802.3x flow control (PAUSE only) */ @@ -1633,6 +1633,12 @@ vortex_set_duplex(struct net_device *dev) ((vp->full_duplex && vp->flow_ctrl && vp->partner_flow_ctrl) ? 0x100 : 0), ioaddr + Wn3_MAC_Ctrl); + + issue_and_wait(dev, TxReset); + /* + * Don't reset the PHY - that upsets autonegotiation during DHCP operations. + */ + issue_and_wait(dev, RxReset|0x04); } static void vortex_check_media(struct net_device *dev, unsigned int init) @@ -1657,7 +1663,7 @@ vortex_up(struct net_device *dev) struct vortex_private *vp = netdev_priv(dev); void __iomem *ioaddr = vp->ioaddr; unsigned int config; - int i, mii_reg1, mii_reg5; + int i; if (VORTEX_PCI(vp)) { pci_set_power_state(VORTEX_PCI(vp), PCI_D0); /* Go active */ @@ -1717,23 +1723,14 @@ vortex_up(struct net_device *dev) printk(KERN_DEBUG "vortex_up(): writing 0x%x to InternalConfig\n", config); iowrite32(config, ioaddr + Wn3_Config); + netif_carrier_off(dev); if (dev->if_port == XCVR_MII || dev->if_port == XCVR_NWAY) { EL3WINDOW(4); - mii_reg1 = mdio_read(dev, vp->phys[0], MII_BMSR); - mii_reg5 = mdio_read(dev, vp->phys[0], MII_LPA); - vp->partner_flow_ctrl = ((mii_reg5 & 0x0400) != 0); - vortex_check_media(dev, 1); } else vortex_set_duplex(dev); - issue_and_wait(dev, TxReset); - /* - * Don't reset the PHY - that upsets autonegotiation during DHCP operations. - */ - issue_and_wait(dev, RxReset|0x04); - iowrite16(SetStatusEnb | 0x00, ioaddr + EL3_CMD); @@ -2086,14 +2083,16 @@ vortex_error(struct net_device *dev, int status) } if (tx_status & 0x14) vp->stats.tx_fifo_errors++; if (tx_status & 0x38) vp->stats.tx_aborted_errors++; - if (tx_status & 0x08) vp->xstats.tx_max_collisions++; iowrite8(0, ioaddr + TxStatus); if (tx_status & 0x30) { /* txJabber or txUnderrun */ do_tx_reset = 1; - } else if ((tx_status & 0x08) && (vp->drv_flags & MAX_COLLISION_RESET)) { /* maxCollisions */ - do_tx_reset = 1; - reset_mask = 0x0108; /* Reset interface logic, but not download logic */ - } else { /* Merely re-enable the transmitter. */ + } else if (tx_status & 0x08) { /* maxCollisions */ + vp->xstats.tx_max_collisions++; + if (vp->drv_flags & MAX_COLLISION_RESET) { + do_tx_reset = 1; + reset_mask = 0x0108; /* Reset interface logic, but not download logic */ + } + } else { /* Merely re-enable the transmitter. */ iowrite16(TxEnable, ioaddr + EL3_CMD); } } diff --git a/trunk/drivers/net/8390.h b/trunk/drivers/net/8390.h index 51e39dcd0603..599b68d8c45f 100644 --- a/trunk/drivers/net/8390.h +++ b/trunk/drivers/net/8390.h @@ -134,7 +134,7 @@ struct ei_device { #define inb_p(_p) inb(_p) #define outb_p(_v,_p) outb(_v,_p) -#elif defined(CONFIG_NE_H8300) || defined(CONFIG_NE_H8300_MODULE) +#elif defined(CONFIG_NET_CBUS) || defined(CONFIG_NE_H8300) || defined(CONFIG_NE_H8300_MODULE) #define EI_SHIFT(x) (ei_local->reg_offset[x]) #else #define EI_SHIFT(x) (x) diff --git a/trunk/drivers/net/Kconfig b/trunk/drivers/net/Kconfig index bdaaad8f2123..e20b849a22e8 100644 --- a/trunk/drivers/net/Kconfig +++ b/trunk/drivers/net/Kconfig @@ -2313,11 +2313,13 @@ config S2IO_NAPI endmenu +if !UML source "drivers/net/tokenring/Kconfig" source "drivers/net/wireless/Kconfig" source "drivers/net/pcmcia/Kconfig" +endif source "drivers/net/wan/Kconfig" diff --git a/trunk/drivers/net/acenic_firmware.h b/trunk/drivers/net/acenic_firmware.h index d7882dd783c8..6d625d595622 100644 --- a/trunk/drivers/net/acenic_firmware.h +++ b/trunk/drivers/net/acenic_firmware.h @@ -4397,7 +4397,7 @@ static u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __devinitdata = { 0x3c010001, 0x220821, 0xac317e30, 0x8fbf0024, 0x8fb40020, 0x8fb3001c, 0x8fb20018, 0x8fb10014, 0x8fb00010, 0x3e00008, 0x27bd0028, 0x0 }; -static u32 tigonFwRodata[(MAX_RODATA_LEN/4) + 1] __devinitdata = { +static u32 tigonFwRodata[(MAX_RODATA_LEN/4) + 1] __initdata = { 0x24486561, 0x6465723a, 0x202f7072, 0x6f6a6563, 0x74732f72, 0x63732f73, 0x772f6765, 0x2f2e2f6e, 0x69632f66, 0x772f636f, 0x6d6d6f6e, @@ -4571,7 +4571,7 @@ static u32 tigonFwRodata[(MAX_RODATA_LEN/4) + 1] __devinitdata = { 0x0, 0x14c38, 0x14c38, 0x14b80, 0x14bc4, 0x14c38, 0x14c38, 0x0, 0x0, 0x0 }; -static u32 tigonFwData[(MAX_DATA_LEN/4) + 1] __devinitdata = { +static u32 tigonFwData[(MAX_DATA_LEN/4) + 1] __initdata = { 0x416c7465, 0x6f6e2041, 0x63654e49, 0x43205600, 0x416c7465, 0x6f6e2041, 0x63654e49, 0x43205600, 0x42424242, @@ -4612,7 +4612,7 @@ static u32 tigonFwData[(MAX_DATA_LEN/4) + 1] __devinitdata = { #define tigon2FwSbssLen 0xcc #define tigon2FwBssAddr 0x00016f50 #define tigon2FwBssLen 0x20c0 -static u32 tigon2FwText[(MAX_TEXT_LEN/4) + 1] __devinitdata = { +static u32 tigon2FwText[(MAX_TEXT_LEN/4) + 1] __initdata = { 0x0, 0x10000003, 0x0, 0xd, 0xd, 0x3c1d0001, 0x8fbd6d20, 0x3a0f021, 0x3c100000, @@ -9154,7 +9154,7 @@ static u32 tigon2FwText[(MAX_TEXT_LEN/4) + 1] __devinitdata = { 0x24020001, 0x8f430328, 0x1021, 0x24630001, 0x3e00008, 0xaf430328, 0x3e00008, 0x0, 0x0, 0x0, 0x0, 0x0 }; -static u32 tigon2FwRodata[(MAX_RODATA_LEN/4) + 1] __devinitdata = { +static u32 tigon2FwRodata[(MAX_RODATA_LEN/4) + 1] __initdata = { 0x24486561, 0x6465723a, 0x202f7072, 0x6f6a6563, 0x74732f72, 0x63732f73, 0x772f6765, 0x2f2e2f6e, 0x69632f66, 0x77322f63, 0x6f6d6d6f, @@ -9425,7 +9425,7 @@ static u32 tigon2FwRodata[(MAX_RODATA_LEN/4) + 1] __devinitdata = { 0x14ed8, 0x14b8c, 0x14bd8, 0x14c24, 0x14ed8, 0x7365746d, 0x61636163, 0x74000000, 0x0, 0x0 }; -static u32 tigon2FwData[(MAX_DATA_LEN/4) + 1] __devinitdata = { +static u32 tigon2FwData[(MAX_DATA_LEN/4) + 1] __initdata = { 0x1, 0x1, 0x1, 0xc001fc, 0x3ffc, 0xc00000, 0x416c7465, 0x6f6e2041, 0x63654e49, diff --git a/trunk/drivers/net/b44.c b/trunk/drivers/net/b44.c index 15032f2c7817..c3267e4e1bb0 100644 --- a/trunk/drivers/net/b44.c +++ b/trunk/drivers/net/b44.c @@ -1339,9 +1339,6 @@ static int b44_set_mac_addr(struct net_device *dev, void *p) if (netif_running(dev)) return -EBUSY; - if (!is_valid_ether_addr(addr->sa_data)) - return -EINVAL; - memcpy(dev->dev_addr, addr->sa_data, dev->addr_len); spin_lock_irq(&bp->lock); @@ -1879,12 +1876,6 @@ static int __devinit b44_get_invariants(struct b44 *bp) bp->dev->dev_addr[3] = eeprom[80]; bp->dev->dev_addr[4] = eeprom[83]; bp->dev->dev_addr[5] = eeprom[82]; - - if (!is_valid_ether_addr(&bp->dev->dev_addr[0])){ - printk(KERN_ERR PFX "Invalid MAC address found in EEPROM\n"); - return -EINVAL; - } - memcpy(bp->dev->perm_addr, bp->dev->dev_addr, bp->dev->addr_len); bp->phy_addr = eeprom[90] & 0x1f; @@ -2042,11 +2033,6 @@ static int __devinit b44_init_one(struct pci_dev *pdev, pci_save_state(bp->pdev); - /* Chip reset provides power to the b44 MAC & PCI cores, which - * is necessary for MAC register access. - */ - b44_chip_reset(bp); - printk(KERN_INFO "%s: Broadcom 4400 10/100BaseT Ethernet ", dev->name); for (i = 0; i < 6; i++) printk("%2.2x%c", dev->dev_addr[i], diff --git a/trunk/drivers/net/bonding/bond_3ad.c b/trunk/drivers/net/bonding/bond_3ad.c index 6a407070c2e8..f3f5825469d6 100644 --- a/trunk/drivers/net/bonding/bond_3ad.c +++ b/trunk/drivers/net/bonding/bond_3ad.c @@ -2294,34 +2294,6 @@ void bond_3ad_handle_link_change(struct slave *slave, char link) port->sm_vars |= AD_PORT_BEGIN; } -/* - * set link state for bonding master: if we have an active partnered - * aggregator, we're up, if not, we're down. Presumes that we cannot - * have an active aggregator if there are no slaves with link up. - * - * Called by bond_set_carrier(). Return zero if carrier state does not - * change, nonzero if it does. - */ -int bond_3ad_set_carrier(struct bonding *bond) -{ - struct aggregator *agg; - - agg = __get_active_agg(&(SLAVE_AD_INFO(bond->first_slave).aggregator)); - if (agg && MAC_ADDRESS_COMPARE(&agg->partner_system, &null_mac_addr)) { - if (!netif_carrier_ok(bond->dev)) { - netif_carrier_on(bond->dev); - return 1; - } - return 0; - } - - if (netif_carrier_ok(bond->dev)) { - netif_carrier_off(bond->dev); - return 1; - } - return 0; -} - /** * bond_3ad_get_active_agg_info - get information of the active aggregator * @bond: bonding struct to work on diff --git a/trunk/drivers/net/bonding/bond_3ad.h b/trunk/drivers/net/bonding/bond_3ad.h index 6ad5ad6e65d5..5ee2cef5b037 100644 --- a/trunk/drivers/net/bonding/bond_3ad.h +++ b/trunk/drivers/net/bonding/bond_3ad.h @@ -283,6 +283,5 @@ void bond_3ad_handle_link_change(struct slave *slave, char link); int bond_3ad_get_active_agg_info(struct bonding *bond, struct ad_info *ad_info); int bond_3ad_xmit_xor(struct sk_buff *skb, struct net_device *dev); int bond_3ad_lacpdu_recv(struct sk_buff *skb, struct net_device *dev, struct packet_type* ptype, struct net_device *orig_dev); -int bond_3ad_set_carrier(struct bonding *bond); #endif //__BOND_3AD_H__ diff --git a/trunk/drivers/net/bonding/bond_main.c b/trunk/drivers/net/bonding/bond_main.c index 55d236726d11..f13a539dc169 100644 --- a/trunk/drivers/net/bonding/bond_main.c +++ b/trunk/drivers/net/bonding/bond_main.c @@ -558,42 +558,6 @@ static void bond_del_vlans_from_slave(struct bonding *bond, struct net_device *s /*------------------------------- Link status -------------------------------*/ -/* - * Set the carrier state for the master according to the state of its - * slaves. If any slaves are up, the master is up. In 802.3ad mode, - * do special 802.3ad magic. - * - * Returns zero if carrier state does not change, nonzero if it does. - */ -static int bond_set_carrier(struct bonding *bond) -{ - struct slave *slave; - int i; - - if (bond->slave_cnt == 0) - goto down; - - if (bond->params.mode == BOND_MODE_8023AD) - return bond_3ad_set_carrier(bond); - - bond_for_each_slave(bond, slave, i) { - if (slave->link == BOND_LINK_UP) { - if (!netif_carrier_ok(bond->dev)) { - netif_carrier_on(bond->dev); - return 1; - } - return 0; - } - } - -down: - if (netif_carrier_ok(bond->dev)) { - netif_carrier_off(bond->dev); - return 1; - } - return 0; -} - /* * Get link speed and duplex from the slave's base driver * using ethtool. If for some reason the call fails or the @@ -1110,24 +1074,10 @@ void bond_change_active_slave(struct bonding *bond, struct slave *new_active) void bond_select_active_slave(struct bonding *bond) { struct slave *best_slave; - int rv; best_slave = bond_find_best_slave(bond); if (best_slave != bond->curr_active_slave) { bond_change_active_slave(bond, best_slave); - rv = bond_set_carrier(bond); - if (!rv) - return; - - if (netif_carrier_ok(bond->dev)) { - printk(KERN_INFO DRV_NAME - ": %s: first active interface up!\n", - bond->dev->name); - } else { - printk(KERN_INFO DRV_NAME ": %s: " - "now running without any active interface !\n", - bond->dev->name); - } } } @@ -1508,14 +1458,10 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) if (((!bond->curr_active_slave) || (bond->curr_active_slave->dev->priv_flags & IFF_SLAVE_INACTIVE)) && (new_slave->link != BOND_LINK_DOWN)) { + dprintk("This is the first active slave\n"); /* first slave or no active slave yet, and this link is OK, so make this interface the active one */ bond_change_active_slave(bond, new_slave); - printk(KERN_INFO DRV_NAME - ": %s: first active interface up!\n", - bond->dev->name); - netif_carrier_on(bond->dev); - } else { dprintk("This is just a backup slave\n"); bond_set_slave_inactive_flags(new_slave); @@ -1571,8 +1517,6 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) break; } /* switch(bond_mode) */ - bond_set_carrier(bond); - write_unlock_bh(&bond->lock); res = bond_create_slave_symlinks(bond_dev, slave_dev); @@ -1712,12 +1656,18 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev) bond_alb_deinit_slave(bond, slave); } - if (oldcurrent == slave) + if (oldcurrent == slave) { bond_select_active_slave(bond); - if (bond->slave_cnt == 0) { - bond_set_carrier(bond); + if (!bond->curr_active_slave) { + printk(KERN_INFO DRV_NAME + ": %s: now running without any active " + "interface !\n", + bond_dev->name); + } + } + if (bond->slave_cnt == 0) { /* if the last slave was removed, zero the mac address * of the master so it will be set by the application * to the mac address of the first slave @@ -1801,8 +1751,6 @@ static int bond_release_all(struct net_device *bond_dev) write_lock_bh(&bond->lock); - netif_carrier_off(bond_dev); - if (bond->slave_cnt == 0) { goto out; } @@ -2239,9 +2187,15 @@ void bond_mii_monitor(struct net_device *bond_dev) bond_select_active_slave(bond); + if (oldcurrent && !bond->curr_active_slave) { + printk(KERN_INFO DRV_NAME + ": %s: now running without any active " + "interface !\n", + bond_dev->name); + } + write_unlock(&bond->curr_slave_lock); - } else - bond_set_carrier(bond); + } re_arm: if (bond->params.miimon) { @@ -2545,6 +2499,13 @@ void bond_loadbalance_arp_mon(struct net_device *bond_dev) bond_select_active_slave(bond); + if (oldcurrent && !bond->curr_active_slave) { + printk(KERN_INFO DRV_NAME + ": %s: now running without any active " + "interface !\n", + bond_dev->name); + } + write_unlock(&bond->curr_slave_lock); } @@ -2618,15 +2579,12 @@ void bond_activebackup_arp_mon(struct net_device *bond_dev) bond->current_arp_slave = NULL; } - bond_set_carrier(bond); - if (slave == bond->curr_active_slave) { printk(KERN_INFO DRV_NAME ": %s: %s is up and now the " "active interface\n", bond_dev->name, slave->dev->name); - netif_carrier_on(bond->dev); } else { printk(KERN_INFO DRV_NAME ": %s: backup interface %s is " @@ -2886,8 +2844,7 @@ static void bond_info_show_master(struct seq_file *seq) (curr) ? curr->dev->name : "None"); } - seq_printf(seq, "MII Status: %s\n", netif_carrier_ok(bond->dev) ? - "up" : "down"); + seq_printf(seq, "MII Status: %s\n", (curr) ? "up" : "down"); seq_printf(seq, "MII Polling Interval (ms): %d\n", bond->params.miimon); seq_printf(seq, "Up Delay (ms): %d\n", bond->params.updelay * bond->params.miimon); @@ -4574,8 +4531,6 @@ int bond_create(char *name, struct bond_params *params, struct bonding **newbond if (newbond) *newbond = bond_dev->priv; - netif_carrier_off(bond_dev); - rtnl_unlock(); /* allows sysfs registration of net device */ res = bond_create_sysfs_entry(bond_dev->priv); goto done; diff --git a/trunk/drivers/net/bonding/bonding.h b/trunk/drivers/net/bonding/bonding.h index 0bdfe2c71453..ce9dc9b4e2dc 100644 --- a/trunk/drivers/net/bonding/bonding.h +++ b/trunk/drivers/net/bonding/bonding.h @@ -22,8 +22,8 @@ #include "bond_3ad.h" #include "bond_alb.h" -#define DRV_VERSION "3.0.3" -#define DRV_RELDATE "March 23, 2006" +#define DRV_VERSION "3.0.2" +#define DRV_RELDATE "February 21, 2006" #define DRV_NAME "bonding" #define DRV_DESCRIPTION "Ethernet Channel Bonding Driver" diff --git a/trunk/drivers/net/ixp2000/ixpdev.c b/trunk/drivers/net/ixp2000/ixpdev.c index fbc2d21020f4..77f104a005f3 100644 --- a/trunk/drivers/net/ixp2000/ixpdev.c +++ b/trunk/drivers/net/ixp2000/ixpdev.c @@ -299,7 +299,10 @@ int ixpdev_init(int __nds_count, struct net_device **__nds, int i; int err; - BUILD_BUG_ON(RX_BUF_COUNT > 192 || TX_BUF_COUNT > 192); + if (RX_BUF_COUNT > 192 || TX_BUF_COUNT > 192) { + static void __too_many_rx_or_tx_buffers(void); + __too_many_rx_or_tx_buffers(); + } printk(KERN_INFO "IXP2000 MSF ethernet driver %s\n", DRV_MODULE_VERSION); diff --git a/trunk/drivers/net/natsemi.c b/trunk/drivers/net/natsemi.c index 7826afbb9db9..8d4999837b65 100644 --- a/trunk/drivers/net/natsemi.c +++ b/trunk/drivers/net/natsemi.c @@ -226,7 +226,7 @@ static int full_duplex[MAX_UNITS]; NATSEMI_PG1_NREGS) #define NATSEMI_REGS_VER 1 /* v1 added RFDR registers */ #define NATSEMI_REGS_SIZE (NATSEMI_NREGS * sizeof(u32)) -#define NATSEMI_DEF_EEPROM_SIZE 24 /* 12 16-bit values */ +#define NATSEMI_EEPROM_SIZE 24 /* 12 16-bit values */ /* Buffer sizes: * The nic writes 32-bit values, even if the upper bytes of @@ -714,8 +714,6 @@ struct netdev_private { unsigned int iosize; spinlock_t lock; u32 msg_enable; - /* EEPROM data */ - int eeprom_size; }; static void move_int_phy(struct net_device *dev, int addr); @@ -892,7 +890,6 @@ static int __devinit natsemi_probe1 (struct pci_dev *pdev, np->msg_enable = (debug >= 0) ? (1<hands_off = 0; np->intr_status = 0; - np->eeprom_size = NATSEMI_DEF_EEPROM_SIZE; /* Initial port: * - If the nic was configured to use an external phy and if find_mii @@ -2585,8 +2582,7 @@ static int get_regs_len(struct net_device *dev) static int get_eeprom_len(struct net_device *dev) { - struct netdev_private *np = netdev_priv(dev); - return np->eeprom_size; + return NATSEMI_EEPROM_SIZE; } static int get_settings(struct net_device *dev, struct ethtool_cmd *ecmd) @@ -2673,20 +2669,15 @@ static u32 get_link(struct net_device *dev) static int get_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom, u8 *data) { struct netdev_private *np = netdev_priv(dev); - u8 *eebuf; + u8 eebuf[NATSEMI_EEPROM_SIZE]; int res; - eebuf = kmalloc(np->eeprom_size, GFP_KERNEL); - if (!eebuf) - return -ENOMEM; - eeprom->magic = PCI_VENDOR_ID_NS | (PCI_DEVICE_ID_NS_83815<<16); spin_lock_irq(&np->lock); res = netdev_get_eeprom(dev, eebuf); spin_unlock_irq(&np->lock); if (!res) memcpy(data, eebuf+eeprom->offset, eeprom->len); - kfree(eebuf); return res; } @@ -3042,10 +3033,9 @@ static int netdev_get_eeprom(struct net_device *dev, u8 *buf) int i; u16 *ebuf = (u16 *)buf; void __iomem * ioaddr = ns_ioaddr(dev); - struct netdev_private *np = netdev_priv(dev); /* eeprom_read reads 16 bits, and indexes by 16 bits */ - for (i = 0; i < np->eeprom_size/2; i++) { + for (i = 0; i < NATSEMI_EEPROM_SIZE/2; i++) { ebuf[i] = eeprom_read(ioaddr, i); /* The EEPROM itself stores data bit-swapped, but eeprom_read * reads it back "sanely". So we swap it back here in order to diff --git a/trunk/drivers/net/netconsole.c b/trunk/drivers/net/netconsole.c index 75b35ad760de..edd1b5306b16 100644 --- a/trunk/drivers/net/netconsole.c +++ b/trunk/drivers/net/netconsole.c @@ -94,7 +94,7 @@ static struct console netconsole = { static int option_setup(char *opt) { configured = !netpoll_parse_options(&np, opt); - return 1; + return 0; } __setup("netconsole=", option_setup); diff --git a/trunk/drivers/net/pcmcia/axnet_cs.c b/trunk/drivers/net/pcmcia/axnet_cs.c index 1cc94b2d76c1..aa5581369399 100644 --- a/trunk/drivers/net/pcmcia/axnet_cs.c +++ b/trunk/drivers/net/pcmcia/axnet_cs.c @@ -35,7 +35,6 @@ #include #include #include -#include #include "../8390.h" #include @@ -1683,67 +1682,17 @@ static struct net_device_stats *get_stats(struct net_device *dev) return &ei_local->stat; } -/* - * Form the 64 bit 8390 multicast table from the linked list of addresses - * associated with this dev structure. - */ - -static inline void make_mc_bits(u8 *bits, struct net_device *dev) -{ - struct dev_mc_list *dmi; - u32 crc; - - for (dmi=dev->mc_list; dmi; dmi=dmi->next) { - - crc = ether_crc(ETH_ALEN, dmi->dmi_addr); - /* - * The 8390 uses the 6 most significant bits of the - * CRC to index the multicast table. - */ - bits[crc>>29] |= (1<<((crc>>26)&7)); - } -} - /** * do_set_multicast_list - set/clear multicast filter * @dev: net device for which multicast filter is adjusted * - * Set or clear the multicast filter for this adaptor. - * Must be called with lock held. + * Set or clear the multicast filter for this adaptor. May be called + * from a BH in 2.1.x. Must be called with lock held. */ static void do_set_multicast_list(struct net_device *dev) { long e8390_base = dev->base_addr; - int i; - struct ei_device *ei_local = (struct ei_device*)netdev_priv(dev); - - if (!(dev->flags&(IFF_PROMISC|IFF_ALLMULTI))) { - memset(ei_local->mcfilter, 0, 8); - if (dev->mc_list) - make_mc_bits(ei_local->mcfilter, dev); - } else { - /* set to accept-all */ - memset(ei_local->mcfilter, 0xFF, 8); - } - - /* - * DP8390 manuals don't specify any magic sequence for altering - * the multicast regs on an already running card. To be safe, we - * ensure multicast mode is off prior to loading up the new hash - * table. If this proves to be not enough, we can always resort - * to stopping the NIC, loading the table and then restarting. - */ - - if (netif_running(dev)) - outb_p(E8390_RXCONFIG, e8390_base + EN0_RXCR); - - outb_p(E8390_NODMA + E8390_PAGE1, e8390_base + E8390_CMD); - for(i = 0; i < 8; i++) - { - outb_p(ei_local->mcfilter[i], e8390_base + EN1_MULT_SHIFT(i)); - } - outb_p(E8390_NODMA + E8390_PAGE0, e8390_base + E8390_CMD); if(dev->flags&IFF_PROMISC) outb_p(E8390_RXCONFIG | 0x58, e8390_base + EN0_RXCR); @@ -1845,6 +1794,12 @@ static void AX88190_init(struct net_device *dev, int startp) if(inb_p(e8390_base + EN1_PHYS_SHIFT(i))!=dev->dev_addr[i]) printk(KERN_ERR "Hw. address read/write mismap %d\n",i); } + /* + * Initialize the multicast list to accept-all. If we enable multicast + * the higher levels can do the filtering. + */ + for (i = 0; i < 8; i++) + outb_p(0xff, e8390_base + EN1_MULT + i); outb_p(ei_local->rx_start_page, e8390_base + EN1_CURPAG); outb_p(E8390_NODMA+E8390_PAGE0+E8390_STOP, e8390_base+E8390_CMD); diff --git a/trunk/drivers/net/pcmcia/xirc2ps_cs.c b/trunk/drivers/net/pcmcia/xirc2ps_cs.c index e8f849e12976..eed496803fe4 100644 --- a/trunk/drivers/net/pcmcia/xirc2ps_cs.c +++ b/trunk/drivers/net/pcmcia/xirc2ps_cs.c @@ -1973,7 +1973,7 @@ static int __init setup_xirc2ps_cs(char *str) MAYBE_SET(lockup_hack, 6); #undef MAYBE_SET - return 1; + return 0; } __setup("xirc2ps_cs=", setup_xirc2ps_cs); diff --git a/trunk/drivers/net/pcnet32.c b/trunk/drivers/net/pcnet32.c index 07c31f19c6ba..9595f74da93f 100644 --- a/trunk/drivers/net/pcnet32.c +++ b/trunk/drivers/net/pcnet32.c @@ -1167,8 +1167,8 @@ pcnet32_probe1(unsigned long ioaddr, int shared, struct pci_dev *pdev) * station address PROM at the base address and programmed into the * "Physical Address Registers" CSR12-14. * As a precautionary measure, we read the PROM values and complain if - * they disagree with the CSRs. If they miscompare, and the PROM addr - * is valid, then the PROM addr is used. + * they disagree with the CSRs. Either way, we use the CSR values, and + * double check that they are valid. */ for (i = 0; i < 3; i++) { unsigned int val; diff --git a/trunk/drivers/net/spider_net.c b/trunk/drivers/net/spider_net.c index 43f5e86fc559..1f5975a61e1f 100644 --- a/trunk/drivers/net/spider_net.c +++ b/trunk/drivers/net/spider_net.c @@ -1442,7 +1442,7 @@ spider_net_handle_error_irq(struct spider_net_card *card, u32 status_reg) case SPIDER_NET_GRFAFLLINT: /* fallthrough */ case SPIDER_NET_GRMFLLINT: if (netif_msg_intr(card) && net_ratelimit()) - pr_debug("Spider RX RAM full, incoming packets " + pr_err("Spider RX RAM full, incoming packets " "might be discarded!\n"); spider_net_rx_irq_off(card); tasklet_schedule(&card->rxram_full_tl); @@ -2086,7 +2086,7 @@ spider_net_setup_netdev(struct spider_net_card *card) spider_net_setup_netdev_ops(netdev); - netdev->features = NETIF_F_HW_CSUM; + netdev->features = 0; /* some time: NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX | * NETIF_F_HW_VLAN_FILTER */ diff --git a/trunk/drivers/net/tg3.c b/trunk/drivers/net/tg3.c index 964c09644832..b5473325bff4 100644 --- a/trunk/drivers/net/tg3.c +++ b/trunk/drivers/net/tg3.c @@ -69,8 +69,8 @@ #define DRV_MODULE_NAME "tg3" #define PFX DRV_MODULE_NAME ": " -#define DRV_MODULE_VERSION "3.55" -#define DRV_MODULE_RELDATE "Mar 27, 2006" +#define DRV_MODULE_VERSION "3.54" +#define DRV_MODULE_RELDATE "Mar 23, 2006" #define TG3_DEF_MAC_MODE 0 #define TG3_DEF_RX_MODE 0 @@ -497,40 +497,33 @@ static void tg3_write_mem(struct tg3 *tp, u32 off, u32 val) unsigned long flags; spin_lock_irqsave(&tp->indirect_lock, flags); - if (tp->write32 != tg3_write_indirect_reg32) { - tw32_f(TG3PCI_MEM_WIN_BASE_ADDR, off); - tw32_f(TG3PCI_MEM_WIN_DATA, val); + pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, off); + pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_DATA, val); - /* Always leave this as zero. */ - tw32_f(TG3PCI_MEM_WIN_BASE_ADDR, 0); - } else { - pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, off); - pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_DATA, val); - - /* Always leave this as zero. */ - pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, 0); - } + /* Always leave this as zero. */ + pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, 0); spin_unlock_irqrestore(&tp->indirect_lock, flags); } +static void tg3_write_mem_fast(struct tg3 *tp, u32 off, u32 val) +{ + /* If no workaround is needed, write to mem space directly */ + if (tp->write32 != tg3_write_indirect_reg32) + tw32(NIC_SRAM_WIN_BASE + off, val); + else + tg3_write_mem(tp, off, val); +} + static void tg3_read_mem(struct tg3 *tp, u32 off, u32 *val) { unsigned long flags; spin_lock_irqsave(&tp->indirect_lock, flags); - if (tp->write32 != tg3_write_indirect_reg32) { - tw32_f(TG3PCI_MEM_WIN_BASE_ADDR, off); - *val = tr32(TG3PCI_MEM_WIN_DATA); - - /* Always leave this as zero. */ - tw32_f(TG3PCI_MEM_WIN_BASE_ADDR, 0); - } else { - pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, off); - pci_read_config_dword(tp->pdev, TG3PCI_MEM_WIN_DATA, val); + pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, off); + pci_read_config_dword(tp->pdev, TG3PCI_MEM_WIN_DATA, val); - /* Always leave this as zero. */ - pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, 0); - } + /* Always leave this as zero. */ + pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, 0); spin_unlock_irqrestore(&tp->indirect_lock, flags); } @@ -1374,12 +1367,12 @@ static int tg3_set_power_state(struct tg3 *tp, pci_power_t state) } } - tg3_write_sig_post_reset(tp, RESET_KIND_SHUTDOWN); - /* Finally, set the new power state. */ pci_write_config_word(tp->pdev, pm + PCI_PM_CTRL, power_control); udelay(100); /* Delay after power state change */ + tg3_write_sig_post_reset(tp, RESET_KIND_SHUTDOWN); + return 0; } @@ -3607,7 +3600,7 @@ static inline int tg3_40bit_overflow_test(struct tg3 *tp, dma_addr_t mapping, int len) { #if defined(CONFIG_HIGHMEM) && (BITS_PER_LONG == 64) - if (tp->tg3_flags & TG3_FLAG_40BIT_DMA_BUG) + if (tp->tg3_flags2 & TG3_FLG2_5780_CLASS) return (((u64) mapping + len) > DMA_40BIT_MASK); return 0; #else @@ -6468,9 +6461,6 @@ static void tg3_timer(unsigned long __opaque) { struct tg3 *tp = (struct tg3 *) __opaque; - if (tp->irq_sync) - goto restart_timer; - spin_lock(&tp->lock); if (!(tp->tg3_flags & TG3_FLAG_TAGGED_STATUS)) { @@ -6547,11 +6537,11 @@ static void tg3_timer(unsigned long __opaque) if (tp->tg3_flags & TG3_FLAG_ENABLE_ASF) { u32 val; - tg3_write_mem(tp, NIC_SRAM_FW_CMD_MBOX, - FWCMD_NICDRV_ALIVE2); - tg3_write_mem(tp, NIC_SRAM_FW_CMD_LEN_MBOX, 4); + tg3_write_mem_fast(tp, NIC_SRAM_FW_CMD_MBOX, + FWCMD_NICDRV_ALIVE2); + tg3_write_mem_fast(tp, NIC_SRAM_FW_CMD_LEN_MBOX, 4); /* 5 seconds timeout */ - tg3_write_mem(tp, NIC_SRAM_FW_CMD_DATA_MBOX, 5); + tg3_write_mem_fast(tp, NIC_SRAM_FW_CMD_DATA_MBOX, 5); val = tr32(GRC_RX_CPU_EVENT); val |= (1 << 14); tw32(GRC_RX_CPU_EVENT, val); @@ -6561,7 +6551,6 @@ static void tg3_timer(unsigned long __opaque) spin_unlock(&tp->lock); -restart_timer: tp->timer.expires = jiffies + tp->timer_offset; add_timer(&tp->timer); } @@ -8410,11 +8399,8 @@ static int tg3_run_loopback(struct tg3 *tp, int loopback_mode) } mac_mode = (tp->mac_mode & ~MAC_MODE_PORT_MODE_MASK) | MAC_MODE_LINK_POLARITY | MAC_MODE_PORT_MODE_GMII; - if ((tp->phy_id & PHY_ID_MASK) == PHY_ID_BCM5401) { + if ((tp->phy_id & PHY_ID_MASK) == PHY_ID_BCM5401) mac_mode &= ~MAC_MODE_LINK_POLARITY; - tg3_writephy(tp, MII_TG3_EXT_CTRL, - MII_TG3_EXT_CTRL_LNK3_LED_MODE); - } tw32(MAC_MODE, mac_mode); } else @@ -10545,7 +10531,6 @@ static int __devinit tg3_get_device_address(struct tg3 *tp) { struct net_device *dev = tp->dev; u32 hi, lo, mac_offset; - int addr_ok = 0; #ifdef CONFIG_SPARC64 if (!tg3_get_macaddr_sparc(tp)) @@ -10575,34 +10560,29 @@ static int __devinit tg3_get_device_address(struct tg3 *tp) dev->dev_addr[3] = (lo >> 16) & 0xff; dev->dev_addr[4] = (lo >> 8) & 0xff; dev->dev_addr[5] = (lo >> 0) & 0xff; + } + /* Next, try NVRAM. */ + else if (!(tp->tg3_flags & TG3_FLG2_SUN_570X) && + !tg3_nvram_read(tp, mac_offset + 0, &hi) && + !tg3_nvram_read(tp, mac_offset + 4, &lo)) { + dev->dev_addr[0] = ((hi >> 16) & 0xff); + dev->dev_addr[1] = ((hi >> 24) & 0xff); + dev->dev_addr[2] = ((lo >> 0) & 0xff); + dev->dev_addr[3] = ((lo >> 8) & 0xff); + dev->dev_addr[4] = ((lo >> 16) & 0xff); + dev->dev_addr[5] = ((lo >> 24) & 0xff); + } + /* Finally just fetch it out of the MAC control regs. */ + else { + hi = tr32(MAC_ADDR_0_HIGH); + lo = tr32(MAC_ADDR_0_LOW); - /* Some old bootcode may report a 0 MAC address in SRAM */ - addr_ok = is_valid_ether_addr(&dev->dev_addr[0]); - } - if (!addr_ok) { - /* Next, try NVRAM. */ - if (!(tp->tg3_flags & TG3_FLG2_SUN_570X) && - !tg3_nvram_read(tp, mac_offset + 0, &hi) && - !tg3_nvram_read(tp, mac_offset + 4, &lo)) { - dev->dev_addr[0] = ((hi >> 16) & 0xff); - dev->dev_addr[1] = ((hi >> 24) & 0xff); - dev->dev_addr[2] = ((lo >> 0) & 0xff); - dev->dev_addr[3] = ((lo >> 8) & 0xff); - dev->dev_addr[4] = ((lo >> 16) & 0xff); - dev->dev_addr[5] = ((lo >> 24) & 0xff); - } - /* Finally just fetch it out of the MAC control regs. */ - else { - hi = tr32(MAC_ADDR_0_HIGH); - lo = tr32(MAC_ADDR_0_LOW); - - dev->dev_addr[5] = lo & 0xff; - dev->dev_addr[4] = (lo >> 8) & 0xff; - dev->dev_addr[3] = (lo >> 16) & 0xff; - dev->dev_addr[2] = (lo >> 24) & 0xff; - dev->dev_addr[1] = hi & 0xff; - dev->dev_addr[0] = (hi >> 8) & 0xff; - } + dev->dev_addr[5] = lo & 0xff; + dev->dev_addr[4] = (lo >> 8) & 0xff; + dev->dev_addr[3] = (lo >> 16) & 0xff; + dev->dev_addr[2] = (lo >> 24) & 0xff; + dev->dev_addr[1] = hi & 0xff; + dev->dev_addr[0] = (hi >> 8) & 0xff; } if (!is_valid_ether_addr(&dev->dev_addr[0])) { diff --git a/trunk/drivers/net/tokenring/Kconfig b/trunk/drivers/net/tokenring/Kconfig index 99c4c1922f19..e4cfc80b283b 100644 --- a/trunk/drivers/net/tokenring/Kconfig +++ b/trunk/drivers/net/tokenring/Kconfig @@ -3,7 +3,7 @@ # menu "Token Ring devices" - depends on NETDEVICES && !UML + depends on NETDEVICES # So far, we only have PCI, ISA, and MCA token ring devices config TR diff --git a/trunk/drivers/net/tulip/de4x5.c b/trunk/drivers/net/tulip/de4x5.c index f56094102042..d1a86a080a65 100644 --- a/trunk/drivers/net/tulip/de4x5.c +++ b/trunk/drivers/net/tulip/de4x5.c @@ -4160,7 +4160,7 @@ get_hw_addr(struct net_device *dev) ** If the address starts with 00 a0, we have to bit-reverse ** each byte of the address. */ - if ( machine_is(powermac) && + if ( (_machine & _MACH_Pmac) && (dev->dev_addr[0] == 0) && (dev->dev_addr[1] == 0xa0) ) { diff --git a/trunk/drivers/net/via-rhine.c b/trunk/drivers/net/via-rhine.c index a9b2150909d6..241871589283 100644 --- a/trunk/drivers/net/via-rhine.c +++ b/trunk/drivers/net/via-rhine.c @@ -1085,25 +1085,6 @@ static void rhine_check_media(struct net_device *dev, unsigned int init_media) else iowrite8(ioread8(ioaddr + ChipCmd1) & ~Cmd1FDuplex, ioaddr + ChipCmd1); - if (debug > 1) - printk(KERN_INFO "%s: force_media %d, carrier %d\n", dev->name, - rp->mii_if.force_media, netif_carrier_ok(dev)); -} - -/* Called after status of force_media possibly changed */ -void rhine_set_carrier(struct mii_if_info *mii) -{ - if (mii->force_media) { - /* autoneg is off: Link is always assumed to be up */ - if (!netif_carrier_ok(mii->dev)) - netif_carrier_on(mii->dev); - } - else /* Let MMI library update carrier status */ - rhine_check_media(mii->dev, 0); - if (debug > 1) - printk(KERN_INFO "%s: force_media %d, carrier %d\n", - mii->dev->name, mii->force_media, - netif_carrier_ok(mii->dev)); } static void rhine_check_media_task(struct net_device *dev) @@ -1801,7 +1782,6 @@ static int netdev_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) spin_lock_irq(&rp->lock); rc = mii_ethtool_sset(&rp->mii_if, cmd); spin_unlock_irq(&rp->lock); - rhine_set_carrier(&rp->mii_if); return rc; } @@ -1889,7 +1869,6 @@ static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) spin_lock_irq(&rp->lock); rc = generic_mii_ioctl(&rp->mii_if, if_mii(rq), cmd, NULL); spin_unlock_irq(&rp->lock); - rhine_set_carrier(&rp->mii_if); return rc; } diff --git a/trunk/drivers/net/wireless/Kconfig b/trunk/drivers/net/wireless/Kconfig index bad09ebdb50b..fd17aa8491b6 100644 --- a/trunk/drivers/net/wireless/Kconfig +++ b/trunk/drivers/net/wireless/Kconfig @@ -309,10 +309,7 @@ config APPLE_AIRPORT Say Y here to support the Airport 802.11b wireless Ethernet hardware built into the Macintosh iBook and other recent PowerPC-based Macintosh machines. This is essentially a Lucent Orinoco card with - a non-standard interface. - - This driver does not support the Airport Extreme (802.11b/g). Use - the BCM43xx driver for Airport Extreme cards. + a non-standard interface config PLX_HERMES tristate "Hermes in PLX9052 based PCI adaptor support (Netgear MA301 etc.)" @@ -356,7 +353,7 @@ config PCI_HERMES config ATMEL tristate "Atmel at76c50x chipset 802.11b support" - depends on NET_RADIO && (PCI || PCMCIA) + depends on NET_RADIO select FW_LOADER select CRC32 ---help--- @@ -404,7 +401,6 @@ config PCMCIA_HERMES config PCMCIA_SPECTRUM tristate "Symbol Spectrum24 Trilogy PCMCIA card support" depends on NET_RADIO && PCMCIA && HERMES - select FW_LOADER ---help--- This is a driver for 802.11b cards using RAM-loadable Symbol @@ -504,7 +500,6 @@ config PRISM54 will be called prism54.ko. source "drivers/net/wireless/hostap/Kconfig" -source "drivers/net/wireless/bcm43xx/Kconfig" # yes, this works even when no drivers are selected config NET_WIRELESS diff --git a/trunk/drivers/net/wireless/Makefile b/trunk/drivers/net/wireless/Makefile index c86779879361..3a6f7ba326ca 100644 --- a/trunk/drivers/net/wireless/Makefile +++ b/trunk/drivers/net/wireless/Makefile @@ -35,7 +35,6 @@ obj-$(CONFIG_PCMCIA_ATMEL) += atmel_cs.o obj-$(CONFIG_PRISM54) += prism54/ obj-$(CONFIG_HOSTAP) += hostap/ -obj-$(CONFIG_BCM43XX) += bcm43xx/ # 16-bit wireless PCMCIA client drivers obj-$(CONFIG_PCMCIA_RAYCS) += ray_cs.o diff --git a/trunk/drivers/net/wireless/bcm43xx/Kconfig b/trunk/drivers/net/wireless/bcm43xx/Kconfig deleted file mode 100644 index 418465600a77..000000000000 --- a/trunk/drivers/net/wireless/bcm43xx/Kconfig +++ /dev/null @@ -1,62 +0,0 @@ -config BCM43XX - tristate "Broadcom BCM43xx wireless support" - depends on PCI && IEEE80211 && IEEE80211_SOFTMAC && NET_RADIO && EXPERIMENTAL - select FW_LOADER - ---help--- - This is an experimental driver for the Broadcom 43xx wireless chip, - found in the Apple Airport Extreme and various other devices. - -config BCM43XX_DEBUG - bool "Broadcom BCM43xx debugging (RECOMMENDED)" - depends on BCM43XX - default y - ---help--- - Broadcom 43xx debugging messages. - Say Y, because the driver is still very experimental and - this will help you get it running. - -config BCM43XX_DMA - bool -config BCM43XX_PIO - bool - -choice - prompt "BCM43xx data transfer mode" - depends on BCM43XX - default BCM43XX_DMA_AND_PIO_MODE - -config BCM43XX_DMA_AND_PIO_MODE - bool "DMA + PIO" - select BCM43XX_DMA - select BCM43XX_PIO - ---help--- - Include both, Direct Memory Access (DMA) and Programmed I/O (PIO) - data transfer modes. - The actually used mode is selectable through the module - parameter "pio". If the module parameter is pio=0, DMA is used. - Otherwise PIO is used. DMA is default. - - If unsure, choose this option. - -config BCM43XX_DMA_MODE - bool "DMA (Direct Memory Access) only" - select BCM43XX_DMA - ---help--- - Only include Direct Memory Access (DMA). - This reduces the size of the driver module, by omitting the PIO code. - -config BCM43XX_PIO_MODE - bool "PIO (Programmed I/O) only" - select BCM43XX_PIO - ---help--- - Only include Programmed I/O (PIO). - This reduces the size of the driver module, by omitting the DMA code. - Please note that PIO transfers are slow (compared to DMA). - - Also note that not all devices of the 43xx series support PIO. - The 4306 (Apple Airport Extreme and others) supports PIO, while - the 4318 is known to _not_ support PIO. - - Only use PIO, if DMA does not work for you. - -endchoice diff --git a/trunk/drivers/net/wireless/bcm43xx/Makefile b/trunk/drivers/net/wireless/bcm43xx/Makefile deleted file mode 100644 index bb5220c629d2..000000000000 --- a/trunk/drivers/net/wireless/bcm43xx/Makefile +++ /dev/null @@ -1,12 +0,0 @@ -obj-$(CONFIG_BCM43XX) += bcm43xx.o -bcm43xx-obj-$(CONFIG_BCM43XX_DEBUG) += bcm43xx_debugfs.o - -bcm43xx-obj-$(CONFIG_BCM43XX_DMA) += bcm43xx_dma.o -bcm43xx-obj-$(CONFIG_BCM43XX_PIO) += bcm43xx_pio.o - -bcm43xx-objs := bcm43xx_main.o bcm43xx_ilt.o \ - bcm43xx_radio.o bcm43xx_phy.o \ - bcm43xx_power.o bcm43xx_wx.o \ - bcm43xx_leds.o bcm43xx_ethtool.o \ - bcm43xx_xmit.o bcm43xx_sysfs.o \ - $(bcm43xx-obj-y) diff --git a/trunk/drivers/net/wireless/bcm43xx/bcm43xx.h b/trunk/drivers/net/wireless/bcm43xx/bcm43xx.h deleted file mode 100644 index dcadd295de4f..000000000000 --- a/trunk/drivers/net/wireless/bcm43xx/bcm43xx.h +++ /dev/null @@ -1,926 +0,0 @@ -#ifndef BCM43xx_H_ -#define BCM43xx_H_ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -#include "bcm43xx_debugfs.h" -#include "bcm43xx_leds.h" -#include "bcm43xx_sysfs.h" - - -#define PFX KBUILD_MODNAME ": " - -#define BCM43xx_SWITCH_CORE_MAX_RETRIES 50 -#define BCM43xx_IRQWAIT_MAX_RETRIES 50 - -#define BCM43xx_IO_SIZE 8192 - -/* Active Core PCI Configuration Register. */ -#define BCM43xx_PCICFG_ACTIVE_CORE 0x80 -/* SPROM control register. */ -#define BCM43xx_PCICFG_SPROMCTL 0x88 -/* Interrupt Control PCI Configuration Register. (Only on PCI cores with rev >= 6) */ -#define BCM43xx_PCICFG_ICR 0x94 - -/* MMIO offsets */ -#define BCM43xx_MMIO_DMA1_REASON 0x20 -#define BCM43xx_MMIO_DMA1_IRQ_MASK 0x24 -#define BCM43xx_MMIO_DMA2_REASON 0x28 -#define BCM43xx_MMIO_DMA2_IRQ_MASK 0x2C -#define BCM43xx_MMIO_DMA3_REASON 0x30 -#define BCM43xx_MMIO_DMA3_IRQ_MASK 0x34 -#define BCM43xx_MMIO_DMA4_REASON 0x38 -#define BCM43xx_MMIO_DMA4_IRQ_MASK 0x3C -#define BCM43xx_MMIO_STATUS_BITFIELD 0x120 -#define BCM43xx_MMIO_STATUS2_BITFIELD 0x124 -#define BCM43xx_MMIO_GEN_IRQ_REASON 0x128 -#define BCM43xx_MMIO_GEN_IRQ_MASK 0x12C -#define BCM43xx_MMIO_RAM_CONTROL 0x130 -#define BCM43xx_MMIO_RAM_DATA 0x134 -#define BCM43xx_MMIO_PS_STATUS 0x140 -#define BCM43xx_MMIO_RADIO_HWENABLED_HI 0x158 -#define BCM43xx_MMIO_SHM_CONTROL 0x160 -#define BCM43xx_MMIO_SHM_DATA 0x164 -#define BCM43xx_MMIO_SHM_DATA_UNALIGNED 0x166 -#define BCM43xx_MMIO_XMITSTAT_0 0x170 -#define BCM43xx_MMIO_XMITSTAT_1 0x174 -#define BCM43xx_MMIO_REV3PLUS_TSF_LOW 0x180 /* core rev >= 3 only */ -#define BCM43xx_MMIO_REV3PLUS_TSF_HIGH 0x184 /* core rev >= 3 only */ -#define BCM43xx_MMIO_DMA1_BASE 0x200 -#define BCM43xx_MMIO_DMA2_BASE 0x220 -#define BCM43xx_MMIO_DMA3_BASE 0x240 -#define BCM43xx_MMIO_DMA4_BASE 0x260 -#define BCM43xx_MMIO_PIO1_BASE 0x300 -#define BCM43xx_MMIO_PIO2_BASE 0x310 -#define BCM43xx_MMIO_PIO3_BASE 0x320 -#define BCM43xx_MMIO_PIO4_BASE 0x330 -#define BCM43xx_MMIO_PHY_VER 0x3E0 -#define BCM43xx_MMIO_PHY_RADIO 0x3E2 -#define BCM43xx_MMIO_ANTENNA 0x3E8 -#define BCM43xx_MMIO_CHANNEL 0x3F0 -#define BCM43xx_MMIO_CHANNEL_EXT 0x3F4 -#define BCM43xx_MMIO_RADIO_CONTROL 0x3F6 -#define BCM43xx_MMIO_RADIO_DATA_HIGH 0x3F8 -#define BCM43xx_MMIO_RADIO_DATA_LOW 0x3FA -#define BCM43xx_MMIO_PHY_CONTROL 0x3FC -#define BCM43xx_MMIO_PHY_DATA 0x3FE -#define BCM43xx_MMIO_MACFILTER_CONTROL 0x420 -#define BCM43xx_MMIO_MACFILTER_DATA 0x422 -#define BCM43xx_MMIO_RADIO_HWENABLED_LO 0x49A -#define BCM43xx_MMIO_GPIO_CONTROL 0x49C -#define BCM43xx_MMIO_GPIO_MASK 0x49E -#define BCM43xx_MMIO_TSF_0 0x632 /* core rev < 3 only */ -#define BCM43xx_MMIO_TSF_1 0x634 /* core rev < 3 only */ -#define BCM43xx_MMIO_TSF_2 0x636 /* core rev < 3 only */ -#define BCM43xx_MMIO_TSF_3 0x638 /* core rev < 3 only */ -#define BCM43xx_MMIO_POWERUP_DELAY 0x6A8 - -/* SPROM offsets. */ -#define BCM43xx_SPROM_BASE 0x1000 -#define BCM43xx_SPROM_BOARDFLAGS2 0x1c -#define BCM43xx_SPROM_IL0MACADDR 0x24 -#define BCM43xx_SPROM_ET0MACADDR 0x27 -#define BCM43xx_SPROM_ET1MACADDR 0x2a -#define BCM43xx_SPROM_ETHPHY 0x2d -#define BCM43xx_SPROM_BOARDREV 0x2e -#define BCM43xx_SPROM_PA0B0 0x2f -#define BCM43xx_SPROM_PA0B1 0x30 -#define BCM43xx_SPROM_PA0B2 0x31 -#define BCM43xx_SPROM_WL0GPIO0 0x32 -#define BCM43xx_SPROM_WL0GPIO2 0x33 -#define BCM43xx_SPROM_MAXPWR 0x34 -#define BCM43xx_SPROM_PA1B0 0x35 -#define BCM43xx_SPROM_PA1B1 0x36 -#define BCM43xx_SPROM_PA1B2 0x37 -#define BCM43xx_SPROM_IDL_TSSI_TGT 0x38 -#define BCM43xx_SPROM_BOARDFLAGS 0x39 -#define BCM43xx_SPROM_ANTENNA_GAIN 0x3a -#define BCM43xx_SPROM_VERSION 0x3f - -/* BCM43xx_SPROM_BOARDFLAGS values */ -#define BCM43xx_BFL_BTCOEXIST 0x0001 /* implements Bluetooth coexistance */ -#define BCM43xx_BFL_PACTRL 0x0002 /* GPIO 9 controlling the PA */ -#define BCM43xx_BFL_AIRLINEMODE 0x0004 /* implements GPIO 13 radio disable indication */ -#define BCM43xx_BFL_RSSI 0x0008 /* software calculates nrssi slope. */ -#define BCM43xx_BFL_ENETSPI 0x0010 /* has ephy roboswitch spi */ -#define BCM43xx_BFL_XTAL_NOSLOW 0x0020 /* no slow clock available */ -#define BCM43xx_BFL_CCKHIPWR 0x0040 /* can do high power CCK transmission */ -#define BCM43xx_BFL_ENETADM 0x0080 /* has ADMtek switch */ -#define BCM43xx_BFL_ENETVLAN 0x0100 /* can do vlan */ -#define BCM43xx_BFL_AFTERBURNER 0x0200 /* supports Afterburner mode */ -#define BCM43xx_BFL_NOPCI 0x0400 /* leaves PCI floating */ -#define BCM43xx_BFL_FEM 0x0800 /* supports the Front End Module */ -#define BCM43xx_BFL_EXTLNA 0x1000 /* has an external LNA */ -#define BCM43xx_BFL_HGPA 0x2000 /* had high gain PA */ -#define BCM43xx_BFL_BTCMOD 0x4000 /* BFL_BTCOEXIST is given in alternate GPIOs */ -#define BCM43xx_BFL_ALTIQ 0x8000 /* alternate I/Q settings */ - -/* GPIO register offset, in both ChipCommon and PCI core. */ -#define BCM43xx_GPIO_CONTROL 0x6c - -/* SHM Routing */ -#define BCM43xx_SHM_SHARED 0x0001 -#define BCM43xx_SHM_WIRELESS 0x0002 -#define BCM43xx_SHM_PCM 0x0003 -#define BCM43xx_SHM_HWMAC 0x0004 -#define BCM43xx_SHM_UCODE 0x0300 - -/* MacFilter offsets. */ -#define BCM43xx_MACFILTER_SELF 0x0000 -#define BCM43xx_MACFILTER_ASSOC 0x0003 - -/* Chipcommon registers. */ -#define BCM43xx_CHIPCOMMON_CAPABILITIES 0x04 -#define BCM43xx_CHIPCOMMON_PLLONDELAY 0xB0 -#define BCM43xx_CHIPCOMMON_FREFSELDELAY 0xB4 -#define BCM43xx_CHIPCOMMON_SLOWCLKCTL 0xB8 -#define BCM43xx_CHIPCOMMON_SYSCLKCTL 0xC0 - -/* PCI core specific registers. */ -#define BCM43xx_PCICORE_BCAST_ADDR 0x50 -#define BCM43xx_PCICORE_BCAST_DATA 0x54 -#define BCM43xx_PCICORE_SBTOPCI2 0x108 - -/* SBTOPCI2 values. */ -#define BCM43xx_SBTOPCI2_PREFETCH 0x4 -#define BCM43xx_SBTOPCI2_BURST 0x8 - -/* Chipcommon capabilities. */ -#define BCM43xx_CAPABILITIES_PCTL 0x00040000 -#define BCM43xx_CAPABILITIES_PLLMASK 0x00030000 -#define BCM43xx_CAPABILITIES_PLLSHIFT 16 -#define BCM43xx_CAPABILITIES_FLASHMASK 0x00000700 -#define BCM43xx_CAPABILITIES_FLASHSHIFT 8 -#define BCM43xx_CAPABILITIES_EXTBUSPRESENT 0x00000040 -#define BCM43xx_CAPABILITIES_UARTGPIO 0x00000020 -#define BCM43xx_CAPABILITIES_UARTCLOCKMASK 0x00000018 -#define BCM43xx_CAPABILITIES_UARTCLOCKSHIFT 3 -#define BCM43xx_CAPABILITIES_MIPSBIGENDIAN 0x00000004 -#define BCM43xx_CAPABILITIES_NRUARTSMASK 0x00000003 - -/* PowerControl */ -#define BCM43xx_PCTL_IN 0xB0 -#define BCM43xx_PCTL_OUT 0xB4 -#define BCM43xx_PCTL_OUTENABLE 0xB8 -#define BCM43xx_PCTL_XTAL_POWERUP 0x40 -#define BCM43xx_PCTL_PLL_POWERDOWN 0x80 - -/* PowerControl Clock Modes */ -#define BCM43xx_PCTL_CLK_FAST 0x00 -#define BCM43xx_PCTL_CLK_SLOW 0x01 -#define BCM43xx_PCTL_CLK_DYNAMIC 0x02 - -#define BCM43xx_PCTL_FORCE_SLOW 0x0800 -#define BCM43xx_PCTL_FORCE_PLL 0x1000 -#define BCM43xx_PCTL_DYN_XTAL 0x2000 - -/* COREIDs */ -#define BCM43xx_COREID_CHIPCOMMON 0x800 -#define BCM43xx_COREID_ILINE20 0x801 -#define BCM43xx_COREID_SDRAM 0x803 -#define BCM43xx_COREID_PCI 0x804 -#define BCM43xx_COREID_MIPS 0x805 -#define BCM43xx_COREID_ETHERNET 0x806 -#define BCM43xx_COREID_V90 0x807 -#define BCM43xx_COREID_USB11_HOSTDEV 0x80a -#define BCM43xx_COREID_IPSEC 0x80b -#define BCM43xx_COREID_PCMCIA 0x80d -#define BCM43xx_COREID_EXT_IF 0x80f -#define BCM43xx_COREID_80211 0x812 -#define BCM43xx_COREID_MIPS_3302 0x816 -#define BCM43xx_COREID_USB11_HOST 0x817 -#define BCM43xx_COREID_USB11_DEV 0x818 -#define BCM43xx_COREID_USB20_HOST 0x819 -#define BCM43xx_COREID_USB20_DEV 0x81a -#define BCM43xx_COREID_SDIO_HOST 0x81b - -/* Core Information Registers */ -#define BCM43xx_CIR_BASE 0xf00 -#define BCM43xx_CIR_SBTPSFLAG (BCM43xx_CIR_BASE + 0x18) -#define BCM43xx_CIR_SBIMSTATE (BCM43xx_CIR_BASE + 0x90) -#define BCM43xx_CIR_SBINTVEC (BCM43xx_CIR_BASE + 0x94) -#define BCM43xx_CIR_SBTMSTATELOW (BCM43xx_CIR_BASE + 0x98) -#define BCM43xx_CIR_SBTMSTATEHIGH (BCM43xx_CIR_BASE + 0x9c) -#define BCM43xx_CIR_SBIMCONFIGLOW (BCM43xx_CIR_BASE + 0xa8) -#define BCM43xx_CIR_SB_ID_HI (BCM43xx_CIR_BASE + 0xfc) - -/* Mask to get the Backplane Flag Number from SBTPSFLAG. */ -#define BCM43xx_BACKPLANE_FLAG_NR_MASK 0x3f - -/* SBIMCONFIGLOW values/masks. */ -#define BCM43xx_SBIMCONFIGLOW_SERVICE_TOUT_MASK 0x00000007 -#define BCM43xx_SBIMCONFIGLOW_SERVICE_TOUT_SHIFT 0 -#define BCM43xx_SBIMCONFIGLOW_REQUEST_TOUT_MASK 0x00000070 -#define BCM43xx_SBIMCONFIGLOW_REQUEST_TOUT_SHIFT 4 -#define BCM43xx_SBIMCONFIGLOW_CONNID_MASK 0x00ff0000 -#define BCM43xx_SBIMCONFIGLOW_CONNID_SHIFT 16 - -/* sbtmstatelow state flags */ -#define BCM43xx_SBTMSTATELOW_RESET 0x01 -#define BCM43xx_SBTMSTATELOW_REJECT 0x02 -#define BCM43xx_SBTMSTATELOW_CLOCK 0x10000 -#define BCM43xx_SBTMSTATELOW_FORCE_GATE_CLOCK 0x20000 - -/* sbtmstatehigh state flags */ -#define BCM43xx_SBTMSTATEHIGH_SERROR 0x1 -#define BCM43xx_SBTMSTATEHIGH_BUSY 0x4 - -/* sbimstate flags */ -#define BCM43xx_SBIMSTATE_IB_ERROR 0x20000 -#define BCM43xx_SBIMSTATE_TIMEOUT 0x40000 - -/* PHYVersioning */ -#define BCM43xx_PHYTYPE_A 0x00 -#define BCM43xx_PHYTYPE_B 0x01 -#define BCM43xx_PHYTYPE_G 0x02 - -/* PHYRegisters */ -#define BCM43xx_PHY_ILT_A_CTRL 0x0072 -#define BCM43xx_PHY_ILT_A_DATA1 0x0073 -#define BCM43xx_PHY_ILT_A_DATA2 0x0074 -#define BCM43xx_PHY_G_LO_CONTROL 0x0810 -#define BCM43xx_PHY_ILT_G_CTRL 0x0472 -#define BCM43xx_PHY_ILT_G_DATA1 0x0473 -#define BCM43xx_PHY_ILT_G_DATA2 0x0474 -#define BCM43xx_PHY_A_PCTL 0x007B -#define BCM43xx_PHY_G_PCTL 0x0029 -#define BCM43xx_PHY_A_CRS 0x0029 -#define BCM43xx_PHY_RADIO_BITFIELD 0x0401 -#define BCM43xx_PHY_G_CRS 0x0429 -#define BCM43xx_PHY_NRSSILT_CTRL 0x0803 -#define BCM43xx_PHY_NRSSILT_DATA 0x0804 - -/* RadioRegisters */ -#define BCM43xx_RADIOCTL_ID 0x01 - -/* StatusBitField */ -#define BCM43xx_SBF_MAC_ENABLED 0x00000001 -#define BCM43xx_SBF_2 0x00000002 /*FIXME: fix name*/ -#define BCM43xx_SBF_CORE_READY 0x00000004 -#define BCM43xx_SBF_400 0x00000400 /*FIXME: fix name*/ -#define BCM43xx_SBF_4000 0x00004000 /*FIXME: fix name*/ -#define BCM43xx_SBF_8000 0x00008000 /*FIXME: fix name*/ -#define BCM43xx_SBF_XFER_REG_BYTESWAP 0x00010000 -#define BCM43xx_SBF_MODE_NOTADHOC 0x00020000 -#define BCM43xx_SBF_MODE_AP 0x00040000 -#define BCM43xx_SBF_RADIOREG_LOCK 0x00080000 -#define BCM43xx_SBF_MODE_MONITOR 0x00400000 -#define BCM43xx_SBF_MODE_PROMISC 0x01000000 -#define BCM43xx_SBF_PS1 0x02000000 -#define BCM43xx_SBF_PS2 0x04000000 -#define BCM43xx_SBF_NO_SSID_BCAST 0x08000000 -#define BCM43xx_SBF_TIME_UPDATE 0x10000000 -#define BCM43xx_SBF_80000000 0x80000000 /*FIXME: fix name*/ - -/* MicrocodeFlagsBitfield (addr + lo-word values?)*/ -#define BCM43xx_UCODEFLAGS_OFFSET 0x005E - -#define BCM43xx_UCODEFLAG_AUTODIV 0x0001 -#define BCM43xx_UCODEFLAG_UNKBGPHY 0x0002 -#define BCM43xx_UCODEFLAG_UNKBPHY 0x0004 -#define BCM43xx_UCODEFLAG_UNKGPHY 0x0020 -#define BCM43xx_UCODEFLAG_UNKPACTRL 0x0040 -#define BCM43xx_UCODEFLAG_JAPAN 0x0080 - -/* Generic-Interrupt reasons. */ -#define BCM43xx_IRQ_READY (1 << 0) -#define BCM43xx_IRQ_BEACON (1 << 1) -#define BCM43xx_IRQ_PS (1 << 2) -#define BCM43xx_IRQ_REG124 (1 << 5) -#define BCM43xx_IRQ_PMQ (1 << 6) -#define BCM43xx_IRQ_PIO_WORKAROUND (1 << 8) -#define BCM43xx_IRQ_XMIT_ERROR (1 << 11) -#define BCM43xx_IRQ_RX (1 << 15) -#define BCM43xx_IRQ_SCAN (1 << 16) -#define BCM43xx_IRQ_NOISE (1 << 18) -#define BCM43xx_IRQ_XMIT_STATUS (1 << 29) - -#define BCM43xx_IRQ_ALL 0xffffffff -#define BCM43xx_IRQ_INITIAL (BCM43xx_IRQ_PS | \ - BCM43xx_IRQ_REG124 | \ - BCM43xx_IRQ_PMQ | \ - BCM43xx_IRQ_XMIT_ERROR | \ - BCM43xx_IRQ_RX | \ - BCM43xx_IRQ_SCAN | \ - BCM43xx_IRQ_NOISE | \ - BCM43xx_IRQ_XMIT_STATUS) - - -/* Initial default iw_mode */ -#define BCM43xx_INITIAL_IWMODE IW_MODE_INFRA - -/* Bus type PCI. */ -#define BCM43xx_BUSTYPE_PCI 0 -/* Bus type Silicone Backplane Bus. */ -#define BCM43xx_BUSTYPE_SB 1 -/* Bus type PCMCIA. */ -#define BCM43xx_BUSTYPE_PCMCIA 2 - -/* Threshold values. */ -#define BCM43xx_MIN_RTS_THRESHOLD 1U -#define BCM43xx_MAX_RTS_THRESHOLD 2304U -#define BCM43xx_DEFAULT_RTS_THRESHOLD BCM43xx_MAX_RTS_THRESHOLD - -#define BCM43xx_DEFAULT_SHORT_RETRY_LIMIT 7 -#define BCM43xx_DEFAULT_LONG_RETRY_LIMIT 4 - -/* Max size of a security key */ -#define BCM43xx_SEC_KEYSIZE 16 -/* Security algorithms. */ -enum { - BCM43xx_SEC_ALGO_NONE = 0, /* unencrypted, as of TX header. */ - BCM43xx_SEC_ALGO_WEP, - BCM43xx_SEC_ALGO_UNKNOWN, - BCM43xx_SEC_ALGO_AES, - BCM43xx_SEC_ALGO_WEP104, - BCM43xx_SEC_ALGO_TKIP, -}; - -#ifdef assert -# undef assert -#endif -#ifdef CONFIG_BCM43XX_DEBUG -#define assert(expr) \ - do { \ - if (unlikely(!(expr))) { \ - printk(KERN_ERR PFX "ASSERTION FAILED (%s) at: %s:%d:%s()\n", \ - #expr, __FILE__, __LINE__, __FUNCTION__); \ - } \ - } while (0) -#else -#define assert(expr) do { /* nothing */ } while (0) -#endif - -/* rate limited printk(). */ -#ifdef printkl -# undef printkl -#endif -#define printkl(f, x...) do { if (printk_ratelimit()) printk(f ,##x); } while (0) -/* rate limited printk() for debugging */ -#ifdef dprintkl -# undef dprintkl -#endif -#ifdef CONFIG_BCM43XX_DEBUG -# define dprintkl printkl -#else -# define dprintkl(f, x...) do { /* nothing */ } while (0) -#endif - -/* Helper macro for if branches. - * An if branch marked with this macro is only taken in DEBUG mode. - * Example: - * if (DEBUG_ONLY(foo == bar)) { - * do something - * } - * In DEBUG mode, the branch will be taken if (foo == bar). - * In non-DEBUG mode, the branch will never be taken. - */ -#ifdef DEBUG_ONLY -# undef DEBUG_ONLY -#endif -#ifdef CONFIG_BCM43XX_DEBUG -# define DEBUG_ONLY(x) (x) -#else -# define DEBUG_ONLY(x) 0 -#endif - -/* debugging printk() */ -#ifdef dprintk -# undef dprintk -#endif -#ifdef CONFIG_BCM43XX_DEBUG -# define dprintk(f, x...) do { printk(f ,##x); } while (0) -#else -# define dprintk(f, x...) do { /* nothing */ } while (0) -#endif - - -struct net_device; -struct pci_dev; -struct bcm43xx_dmaring; -struct bcm43xx_pioqueue; - -struct bcm43xx_initval { - u16 offset; - u16 size; - u32 value; -} __attribute__((__packed__)); - -/* Values for bcm430x_sprominfo.locale */ -enum { - BCM43xx_LOCALE_WORLD = 0, - BCM43xx_LOCALE_THAILAND, - BCM43xx_LOCALE_ISRAEL, - BCM43xx_LOCALE_JORDAN, - BCM43xx_LOCALE_CHINA, - BCM43xx_LOCALE_JAPAN, - BCM43xx_LOCALE_USA_CANADA_ANZ, - BCM43xx_LOCALE_EUROPE, - BCM43xx_LOCALE_USA_LOW, - BCM43xx_LOCALE_JAPAN_HIGH, - BCM43xx_LOCALE_ALL, - BCM43xx_LOCALE_NONE, -}; - -#define BCM43xx_SPROM_SIZE 64 /* in 16-bit words. */ -struct bcm43xx_sprominfo { - u16 boardflags2; - u8 il0macaddr[6]; - u8 et0macaddr[6]; - u8 et1macaddr[6]; - u8 et0phyaddr:5; - u8 et1phyaddr:5; - u8 et0mdcport:1; - u8 et1mdcport:1; - u8 boardrev; - u8 locale:4; - u8 antennas_aphy:2; - u8 antennas_bgphy:2; - u16 pa0b0; - u16 pa0b1; - u16 pa0b2; - u8 wl0gpio0; - u8 wl0gpio1; - u8 wl0gpio2; - u8 wl0gpio3; - u8 maxpower_aphy; - u8 maxpower_bgphy; - u16 pa1b0; - u16 pa1b1; - u16 pa1b2; - u8 idle_tssi_tgt_aphy; - u8 idle_tssi_tgt_bgphy; - u16 boardflags; - u16 antennagain_aphy; - u16 antennagain_bgphy; -}; - -/* Value pair to measure the LocalOscillator. */ -struct bcm43xx_lopair { - s8 low; - s8 high; - u8 used:1; -}; -#define BCM43xx_LO_COUNT (14*4) - -struct bcm43xx_phyinfo { - /* Hardware Data */ - u8 version; - u8 type; - u8 rev; - u16 antenna_diversity; - u16 savedpctlreg; - u16 minlowsig[2]; - u16 minlowsigpos[2]; - u8 connected:1, - calibrated:1, - is_locked:1, /* used in bcm43xx_phy_{un}lock() */ - dyn_tssi_tbl:1; /* used in bcm43xx_phy_init_tssi2dbm_table() */ - /* LO Measurement Data. - * Use bcm43xx_get_lopair() to get a value. - */ - struct bcm43xx_lopair *_lo_pairs; - - /* TSSI to dBm table in use */ - const s8 *tssi2dbm; - /* idle TSSI value */ - s8 idle_tssi; - - /* Values from bcm43xx_calc_loopback_gain() */ - u16 loopback_gain[2]; - - /* PHY lock for core.rev < 3 - * This lock is only used by bcm43xx_phy_{un}lock() - */ - spinlock_t lock; -}; - - -struct bcm43xx_radioinfo { - u16 manufact; - u16 version; - u8 revision; - - /* Desired TX power in dBm Q5.2 */ - u16 txpower_desired; - /* TX Power control values. */ - union { - /* B/G PHY */ - struct { - u16 baseband_atten; - u16 radio_atten; - u16 txctl1; - u16 txctl2; - }; - /* A PHY */ - struct { - u16 txpwr_offset; - }; - }; - - /* Current Interference Mitigation mode */ - int interfmode; - /* Stack of saved values from the Interference Mitigation code. - * Each value in the stack is layed out as follows: - * bit 0-11: offset - * bit 12-15: register ID - * bit 16-32: value - * register ID is: 0x1 PHY, 0x2 Radio, 0x3 ILT - */ -#define BCM43xx_INTERFSTACK_SIZE 26 - u32 interfstack[BCM43xx_INTERFSTACK_SIZE]; - - /* Saved values from the NRSSI Slope calculation */ - s16 nrssi[2]; - s32 nrssislope; - /* In memory nrssi lookup table. */ - s8 nrssi_lt[64]; - - /* current channel */ - u8 channel; - u8 initial_channel; - - u16 lofcal; - - u16 initval; - - u8 enabled:1; - /* ACI (adjacent channel interference) flags. */ - u8 aci_enable:1, - aci_wlan_automatic:1, - aci_hw_rssi:1; -}; - -/* Data structures for DMA transmission, per 80211 core. */ -struct bcm43xx_dma { - struct bcm43xx_dmaring *tx_ring0; - struct bcm43xx_dmaring *tx_ring1; - struct bcm43xx_dmaring *tx_ring2; - struct bcm43xx_dmaring *tx_ring3; - struct bcm43xx_dmaring *rx_ring0; - struct bcm43xx_dmaring *rx_ring1; /* only available on core.rev < 5 */ -}; - -/* Data structures for PIO transmission, per 80211 core. */ -struct bcm43xx_pio { - struct bcm43xx_pioqueue *queue0; - struct bcm43xx_pioqueue *queue1; - struct bcm43xx_pioqueue *queue2; - struct bcm43xx_pioqueue *queue3; -}; - -#define BCM43xx_MAX_80211_CORES 2 - -#ifdef CONFIG_BCM947XX -#define core_offset(bcm) (bcm)->current_core_offset -#else -#define core_offset(bcm) 0 -#endif - -/* Generic information about a core. */ -struct bcm43xx_coreinfo { - u8 available:1, - enabled:1, - initialized:1; - /** core_id ID number */ - u16 id; - /** core_rev revision number */ - u8 rev; - /** Index number for _switch_core() */ - u8 index; -}; - -/* Additional information for each 80211 core. */ -struct bcm43xx_coreinfo_80211 { - /* PHY device. */ - struct bcm43xx_phyinfo phy; - /* Radio device. */ - struct bcm43xx_radioinfo radio; - union { - /* DMA context. */ - struct bcm43xx_dma dma; - /* PIO context. */ - struct bcm43xx_pio pio; - }; -}; - -/* Context information for a noise calculation (Link Quality). */ -struct bcm43xx_noise_calculation { - struct bcm43xx_coreinfo *core_at_start; - u8 channel_at_start; - u8 calculation_running:1; - u8 nr_samples; - s8 samples[8][4]; -}; - -struct bcm43xx_stats { - u8 link_quality; - u8 noise; - struct iw_statistics wstats; - /* Store the last TX/RX times here for updating the leds. */ - unsigned long last_tx; - unsigned long last_rx; -}; - -struct bcm43xx_key { - u8 enabled:1; - u8 algorithm; -}; - -struct bcm43xx_private { - struct bcm43xx_sysfs sysfs; - - struct ieee80211_device *ieee; - struct ieee80211softmac_device *softmac; - - struct net_device *net_dev; - struct pci_dev *pci_dev; - unsigned int irq; - - void __iomem *mmio_addr; - unsigned int mmio_len; - - /* Do not use the lock directly. Use the bcm43xx_lock* helper - * functions, to be MMIO-safe. */ - spinlock_t _lock; - - /* Driver status flags. */ - u32 initialized:1, /* init_board() succeed */ - was_initialized:1, /* for PCI suspend/resume. */ - shutting_down:1, /* free_board() in progress */ - __using_pio:1, /* Internal, use bcm43xx_using_pio(). */ - bad_frames_preempt:1, /* Use "Bad Frames Preemption" (default off) */ - reg124_set_0x4:1, /* Some variable to keep track of IRQ stuff. */ - powersaving:1, /* TRUE if we are in PowerSaving mode. FALSE otherwise. */ - short_preamble:1, /* TRUE, if short preamble is enabled. */ - firmware_norelease:1; /* Do not release the firmware. Used on suspend. */ - - struct bcm43xx_stats stats; - - /* Bus type we are connected to. - * This is currently always BCM43xx_BUSTYPE_PCI - */ - u8 bustype; - - u16 board_vendor; - u16 board_type; - u16 board_revision; - - u16 chip_id; - u8 chip_rev; - u8 chip_package; - - struct bcm43xx_sprominfo sprom; -#define BCM43xx_NR_LEDS 4 - struct bcm43xx_led leds[BCM43xx_NR_LEDS]; - - /* The currently active core. */ - struct bcm43xx_coreinfo *current_core; -#ifdef CONFIG_BCM947XX - /** current core memory offset */ - u32 current_core_offset; -#endif - struct bcm43xx_coreinfo *active_80211_core; - /* coreinfo structs for all possible cores follow. - * Note that a core might not exist. - * So check the coreinfo flags before using it. - */ - struct bcm43xx_coreinfo core_chipcommon; - struct bcm43xx_coreinfo core_pci; - struct bcm43xx_coreinfo core_80211[ BCM43xx_MAX_80211_CORES ]; - /* Additional information, specific to the 80211 cores. */ - struct bcm43xx_coreinfo_80211 core_80211_ext[ BCM43xx_MAX_80211_CORES ]; - /* Index of the current 80211 core. If current_core is not - * an 80211 core, this is -1. - */ - int current_80211_core_idx; - /* Number of available 80211 cores. */ - int nr_80211_available; - - u32 chipcommon_capabilities; - - /* Reason code of the last interrupt. */ - u32 irq_reason; - u32 dma_reason[4]; - /* saved irq enable/disable state bitfield. */ - u32 irq_savedstate; - /* Link Quality calculation context. */ - struct bcm43xx_noise_calculation noisecalc; - - /* Threshold values. */ - //TODO: The RTS thr has to be _used_. Currently, it is only set via WX. - u32 rts_threshold; - - /* Interrupt Service Routine tasklet (bottom-half) */ - struct tasklet_struct isr_tasklet; - - /* Periodic tasks */ - struct timer_list periodic_tasks; - unsigned int periodic_state; - - struct work_struct restart_work; - - /* Informational stuff. */ - char nick[IW_ESSID_MAX_SIZE + 1]; - - /* encryption/decryption */ - u16 security_offset; - struct bcm43xx_key key[54]; - u8 default_key_idx; - - /* Firmware. */ - const struct firmware *ucode; - const struct firmware *pcm; - const struct firmware *initvals0; - const struct firmware *initvals1; - - /* Debugging stuff follows. */ -#ifdef CONFIG_BCM43XX_DEBUG - struct bcm43xx_dfsentry *dfsentry; -#endif -}; - -/* bcm43xx_(un)lock() protect struct bcm43xx_private. - * Note that _NO_ MMIO writes are allowed. If you want to - * write to the device through MMIO in the critical section, use - * the *_mmio lock functions. - * MMIO read-access is allowed, though. - */ -#define bcm43xx_lock(bcm, flags) spin_lock_irqsave(&(bcm)->_lock, flags) -#define bcm43xx_unlock(bcm, flags) spin_unlock_irqrestore(&(bcm)->_lock, flags) -/* bcm43xx_(un)lock_mmio() protect struct bcm43xx_private and MMIO. - * MMIO write-access to the device is allowed. - * All MMIO writes are flushed on unlock, so it is guaranteed to not - * interfere with other threads writing MMIO registers. - */ -#define bcm43xx_lock_mmio(bcm, flags) bcm43xx_lock(bcm, flags) -#define bcm43xx_unlock_mmio(bcm, flags) do { mmiowb(); bcm43xx_unlock(bcm, flags); } while (0) - -static inline -struct bcm43xx_private * bcm43xx_priv(struct net_device *dev) -{ - return ieee80211softmac_priv(dev); -} - - -/* Helper function, which returns a boolean. - * TRUE, if PIO is used; FALSE, if DMA is used. - */ -#if defined(CONFIG_BCM43XX_DMA) && defined(CONFIG_BCM43XX_PIO) -static inline -int bcm43xx_using_pio(struct bcm43xx_private *bcm) -{ - return bcm->__using_pio; -} -#elif defined(CONFIG_BCM43XX_DMA) -static inline -int bcm43xx_using_pio(struct bcm43xx_private *bcm) -{ - return 0; -} -#elif defined(CONFIG_BCM43XX_PIO) -static inline -int bcm43xx_using_pio(struct bcm43xx_private *bcm) -{ - return 1; -} -#else -# error "Using neither DMA nor PIO? Confused..." -#endif - -/* Helper functions to access data structures private to the 80211 cores. - * Note that we _must_ have an 80211 core mapped when calling - * any of these functions. - */ -static inline -struct bcm43xx_pio * bcm43xx_current_pio(struct bcm43xx_private *bcm) -{ - assert(bcm43xx_using_pio(bcm)); - assert(bcm->current_80211_core_idx >= 0); - assert(bcm->current_80211_core_idx < BCM43xx_MAX_80211_CORES); - return &(bcm->core_80211_ext[bcm->current_80211_core_idx].pio); -} -static inline -struct bcm43xx_dma * bcm43xx_current_dma(struct bcm43xx_private *bcm) -{ - assert(!bcm43xx_using_pio(bcm)); - assert(bcm->current_80211_core_idx >= 0); - assert(bcm->current_80211_core_idx < BCM43xx_MAX_80211_CORES); - return &(bcm->core_80211_ext[bcm->current_80211_core_idx].dma); -} -static inline -struct bcm43xx_phyinfo * bcm43xx_current_phy(struct bcm43xx_private *bcm) -{ - assert(bcm->current_80211_core_idx >= 0); - assert(bcm->current_80211_core_idx < BCM43xx_MAX_80211_CORES); - return &(bcm->core_80211_ext[bcm->current_80211_core_idx].phy); -} -static inline -struct bcm43xx_radioinfo * bcm43xx_current_radio(struct bcm43xx_private *bcm) -{ - assert(bcm->current_80211_core_idx >= 0); - assert(bcm->current_80211_core_idx < BCM43xx_MAX_80211_CORES); - return &(bcm->core_80211_ext[bcm->current_80211_core_idx].radio); -} - -/* Are we running in init_board() context? */ -static inline -int bcm43xx_is_initializing(struct bcm43xx_private *bcm) -{ - if (bcm->initialized) - return 0; - if (bcm->shutting_down) - return 0; - return 1; -} - -static inline -struct bcm43xx_lopair * bcm43xx_get_lopair(struct bcm43xx_phyinfo *phy, - u16 radio_attenuation, - u16 baseband_attenuation) -{ - return phy->_lo_pairs + (radio_attenuation + 14 * (baseband_attenuation / 2)); -} - - -static inline -u16 bcm43xx_read16(struct bcm43xx_private *bcm, u16 offset) -{ - return ioread16(bcm->mmio_addr + core_offset(bcm) + offset); -} - -static inline -void bcm43xx_write16(struct bcm43xx_private *bcm, u16 offset, u16 value) -{ - iowrite16(value, bcm->mmio_addr + core_offset(bcm) + offset); -} - -static inline -u32 bcm43xx_read32(struct bcm43xx_private *bcm, u16 offset) -{ - return ioread32(bcm->mmio_addr + core_offset(bcm) + offset); -} - -static inline -void bcm43xx_write32(struct bcm43xx_private *bcm, u16 offset, u32 value) -{ - iowrite32(value, bcm->mmio_addr + core_offset(bcm) + offset); -} - -static inline -int bcm43xx_pci_read_config16(struct bcm43xx_private *bcm, int offset, u16 *value) -{ - return pci_read_config_word(bcm->pci_dev, offset, value); -} - -static inline -int bcm43xx_pci_read_config32(struct bcm43xx_private *bcm, int offset, u32 *value) -{ - return pci_read_config_dword(bcm->pci_dev, offset, value); -} - -static inline -int bcm43xx_pci_write_config16(struct bcm43xx_private *bcm, int offset, u16 value) -{ - return pci_write_config_word(bcm->pci_dev, offset, value); -} - -static inline -int bcm43xx_pci_write_config32(struct bcm43xx_private *bcm, int offset, u32 value) -{ - return pci_write_config_dword(bcm->pci_dev, offset, value); -} - -/** Limit a value between two limits */ -#ifdef limit_value -# undef limit_value -#endif -#define limit_value(value, min, max) \ - ({ \ - typeof(value) __value = (value); \ - typeof(value) __min = (min); \ - typeof(value) __max = (max); \ - if (__value < __min) \ - __value = __min; \ - else if (__value > __max) \ - __value = __max; \ - __value; \ - }) - -/** Helpers to print MAC addresses. */ -#define BCM43xx_MACFMT "%02x:%02x:%02x:%02x:%02x:%02x" -#define BCM43xx_MACARG(x) ((u8*)(x))[0], ((u8*)(x))[1], \ - ((u8*)(x))[2], ((u8*)(x))[3], \ - ((u8*)(x))[4], ((u8*)(x))[5] - -#endif /* BCM43xx_H_ */ diff --git a/trunk/drivers/net/wireless/bcm43xx/bcm43xx_debugfs.c b/trunk/drivers/net/wireless/bcm43xx/bcm43xx_debugfs.c deleted file mode 100644 index d2c3401e9b70..000000000000 --- a/trunk/drivers/net/wireless/bcm43xx/bcm43xx_debugfs.c +++ /dev/null @@ -1,499 +0,0 @@ -/* - - Broadcom BCM43xx wireless driver - - debugfs driver debugging code - - Copyright (c) 2005 Michael Buesch - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; see the file COPYING. If not, write to - the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor, - Boston, MA 02110-1301, USA. - -*/ - - - -#include -#include -#include -#include -#include -#include - -#include "bcm43xx.h" -#include "bcm43xx_main.h" -#include "bcm43xx_debugfs.h" -#include "bcm43xx_dma.h" -#include "bcm43xx_pio.h" -#include "bcm43xx_xmit.h" - -#define REALLY_BIG_BUFFER_SIZE (1024*256) - -static struct bcm43xx_debugfs fs; -static char really_big_buffer[REALLY_BIG_BUFFER_SIZE]; -static DECLARE_MUTEX(big_buffer_sem); - - -static ssize_t write_file_dummy(struct file *file, const char __user *buf, - size_t count, loff_t *ppos) -{ - return count; -} - -static int open_file_generic(struct inode *inode, struct file *file) -{ - file->private_data = inode->u.generic_ip; - return 0; -} - -#define fappend(fmt, x...) pos += snprintf(buf + pos, len - pos, fmt , ##x) - -static ssize_t devinfo_read_file(struct file *file, char __user *userbuf, - size_t count, loff_t *ppos) -{ - const size_t len = REALLY_BIG_BUFFER_SIZE; - - struct bcm43xx_private *bcm = file->private_data; - char *buf = really_big_buffer; - size_t pos = 0; - ssize_t res; - struct net_device *net_dev; - struct pci_dev *pci_dev; - unsigned long flags; - u16 tmp16; - int i; - - down(&big_buffer_sem); - - bcm43xx_lock_mmio(bcm, flags); - if (!bcm->initialized) { - fappend("Board not initialized.\n"); - goto out; - } - net_dev = bcm->net_dev; - pci_dev = bcm->pci_dev; - - /* This is where the information is written to the "devinfo" file */ - fappend("*** %s devinfo ***\n", net_dev->name); - fappend("vendor: 0x%04x device: 0x%04x\n", - pci_dev->vendor, pci_dev->device); - fappend("subsystem_vendor: 0x%04x subsystem_device: 0x%04x\n", - pci_dev->subsystem_vendor, pci_dev->subsystem_device); - fappend("IRQ: %d\n", bcm->irq); - fappend("mmio_addr: 0x%p mmio_len: %u\n", bcm->mmio_addr, bcm->mmio_len); - fappend("chip_id: 0x%04x chip_rev: 0x%02x\n", bcm->chip_id, bcm->chip_rev); - if ((bcm->core_80211[0].rev >= 3) && (bcm43xx_read32(bcm, 0x0158) & (1 << 16))) - fappend("Radio disabled by hardware!\n"); - if ((bcm->core_80211[0].rev < 3) && !(bcm43xx_read16(bcm, 0x049A) & (1 << 4))) - fappend("Radio disabled by hardware!\n"); - fappend("board_vendor: 0x%04x board_type: 0x%04x\n", bcm->board_vendor, - bcm->board_type); - - fappend("\nCores:\n"); -#define fappend_core(name, info) fappend("core \"" name "\" %s, %s, id: 0x%04x, " \ - "rev: 0x%02x, index: 0x%02x\n", \ - (info).available \ - ? "available" : "nonavailable", \ - (info).enabled \ - ? "enabled" : "disabled", \ - (info).id, (info).rev, (info).index) - fappend_core("CHIPCOMMON", bcm->core_chipcommon); - fappend_core("PCI", bcm->core_pci); - fappend_core("first 80211", bcm->core_80211[0]); - fappend_core("second 80211", bcm->core_80211[1]); -#undef fappend_core - tmp16 = bcm43xx_read16(bcm, BCM43xx_MMIO_GPIO_CONTROL); - fappend("LEDs: "); - for (i = 0; i < BCM43xx_NR_LEDS; i++) - fappend("%d ", !!(tmp16 & (1 << i))); - fappend("\n"); - -out: - bcm43xx_unlock_mmio(bcm, flags); - res = simple_read_from_buffer(userbuf, count, ppos, buf, pos); - up(&big_buffer_sem); - return res; -} - -static ssize_t drvinfo_read_file(struct file *file, char __user *userbuf, - size_t count, loff_t *ppos) -{ - const size_t len = REALLY_BIG_BUFFER_SIZE; - - char *buf = really_big_buffer; - size_t pos = 0; - ssize_t res; - - down(&big_buffer_sem); - - /* This is where the information is written to the "driver" file */ - fappend(KBUILD_MODNAME " driver\n"); - fappend("Compiled at: %s %s\n", __DATE__, __TIME__); - - res = simple_read_from_buffer(userbuf, count, ppos, buf, pos); - up(&big_buffer_sem); - return res; -} - -static ssize_t spromdump_read_file(struct file *file, char __user *userbuf, - size_t count, loff_t *ppos) -{ - const size_t len = REALLY_BIG_BUFFER_SIZE; - - struct bcm43xx_private *bcm = file->private_data; - char *buf = really_big_buffer; - size_t pos = 0; - ssize_t res; - unsigned long flags; - - down(&big_buffer_sem); - bcm43xx_lock_mmio(bcm, flags); - if (!bcm->initialized) { - fappend("Board not initialized.\n"); - goto out; - } - - /* This is where the information is written to the "sprom_dump" file */ - fappend("boardflags: 0x%04x\n", bcm->sprom.boardflags); - -out: - bcm43xx_unlock_mmio(bcm, flags); - res = simple_read_from_buffer(userbuf, count, ppos, buf, pos); - up(&big_buffer_sem); - return res; -} - -static ssize_t tsf_read_file(struct file *file, char __user *userbuf, - size_t count, loff_t *ppos) -{ - const size_t len = REALLY_BIG_BUFFER_SIZE; - - struct bcm43xx_private *bcm = file->private_data; - char *buf = really_big_buffer; - size_t pos = 0; - ssize_t res; - unsigned long flags; - u64 tsf; - - down(&big_buffer_sem); - bcm43xx_lock_mmio(bcm, flags); - if (!bcm->initialized) { - fappend("Board not initialized.\n"); - goto out; - } - bcm43xx_tsf_read(bcm, &tsf); - fappend("0x%08x%08x\n", - (unsigned int)((tsf & 0xFFFFFFFF00000000ULL) >> 32), - (unsigned int)(tsf & 0xFFFFFFFFULL)); - -out: - bcm43xx_unlock_mmio(bcm, flags); - res = simple_read_from_buffer(userbuf, count, ppos, buf, pos); - up(&big_buffer_sem); - return res; -} - -static ssize_t tsf_write_file(struct file *file, const char __user *user_buf, - size_t count, loff_t *ppos) -{ - struct bcm43xx_private *bcm = file->private_data; - char *buf = really_big_buffer; - ssize_t buf_size; - ssize_t res; - unsigned long flags; - u64 tsf; - - buf_size = min(count, sizeof (really_big_buffer) - 1); - down(&big_buffer_sem); - if (copy_from_user(buf, user_buf, buf_size)) { - res = -EFAULT; - goto out_up; - } - bcm43xx_lock_mmio(bcm, flags); - if (!bcm->initialized) { - printk(KERN_INFO PFX "debugfs: Board not initialized.\n"); - res = -EFAULT; - goto out_unlock; - } - if (sscanf(buf, "%lli", &tsf) != 1) { - printk(KERN_INFO PFX "debugfs: invalid values for \"tsf\"\n"); - res = -EINVAL; - goto out_unlock; - } - bcm43xx_tsf_write(bcm, tsf); - res = buf_size; - -out_unlock: - bcm43xx_unlock_mmio(bcm, flags); -out_up: - up(&big_buffer_sem); - return res; -} - -static ssize_t txstat_read_file(struct file *file, char __user *userbuf, - size_t count, loff_t *ppos) -{ - const size_t len = REALLY_BIG_BUFFER_SIZE; - - struct bcm43xx_private *bcm = file->private_data; - char *buf = really_big_buffer; - size_t pos = 0; - ssize_t res; - unsigned long flags; - struct bcm43xx_dfsentry *e; - struct bcm43xx_xmitstatus *status; - int i, cnt, j = 0; - - down(&big_buffer_sem); - bcm43xx_lock(bcm, flags); - - fappend("Last %d logged xmitstatus blobs (Latest first):\n\n", - BCM43xx_NR_LOGGED_XMITSTATUS); - e = bcm->dfsentry; - if (e->xmitstatus_printing == 0) { - /* At the beginning, make a copy of all data to avoid - * concurrency, as this function is called multiple - * times for big logs. Without copying, the data might - * change between reads. This would result in total trash. - */ - e->xmitstatus_printing = 1; - e->saved_xmitstatus_ptr = e->xmitstatus_ptr; - e->saved_xmitstatus_cnt = e->xmitstatus_cnt; - memcpy(e->xmitstatus_print_buffer, e->xmitstatus_buffer, - BCM43xx_NR_LOGGED_XMITSTATUS * sizeof(*(e->xmitstatus_buffer))); - } - i = e->saved_xmitstatus_ptr - 1; - if (i < 0) - i = BCM43xx_NR_LOGGED_XMITSTATUS - 1; - cnt = e->saved_xmitstatus_cnt; - while (cnt) { - status = e->xmitstatus_print_buffer + i; - fappend("0x%02x: cookie: 0x%04x, flags: 0x%02x, " - "cnt1: 0x%02x, cnt2: 0x%02x, seq: 0x%04x, " - "unk: 0x%04x\n", j, - status->cookie, status->flags, - status->cnt1, status->cnt2, status->seq, - status->unknown); - j++; - cnt--; - i--; - if (i < 0) - i = BCM43xx_NR_LOGGED_XMITSTATUS - 1; - } - - bcm43xx_unlock(bcm, flags); - res = simple_read_from_buffer(userbuf, count, ppos, buf, pos); - bcm43xx_lock(bcm, flags); - if (*ppos == pos) { - /* Done. Drop the copied data. */ - e->xmitstatus_printing = 0; - } - bcm43xx_unlock(bcm, flags); - up(&big_buffer_sem); - return res; -} - -#undef fappend - - -static struct file_operations devinfo_fops = { - .read = devinfo_read_file, - .write = write_file_dummy, - .open = open_file_generic, -}; - -static struct file_operations spromdump_fops = { - .read = spromdump_read_file, - .write = write_file_dummy, - .open = open_file_generic, -}; - -static struct file_operations drvinfo_fops = { - .read = drvinfo_read_file, - .write = write_file_dummy, - .open = open_file_generic, -}; - -static struct file_operations tsf_fops = { - .read = tsf_read_file, - .write = tsf_write_file, - .open = open_file_generic, -}; - -static struct file_operations txstat_fops = { - .read = txstat_read_file, - .write = write_file_dummy, - .open = open_file_generic, -}; - - -void bcm43xx_debugfs_add_device(struct bcm43xx_private *bcm) -{ - struct bcm43xx_dfsentry *e; - char devdir[IFNAMSIZ]; - - assert(bcm); - e = kzalloc(sizeof(*e), GFP_KERNEL); - if (!e) { - printk(KERN_ERR PFX "out of memory\n"); - return; - } - e->bcm = bcm; - e->xmitstatus_buffer = kzalloc(BCM43xx_NR_LOGGED_XMITSTATUS - * sizeof(*(e->xmitstatus_buffer)), - GFP_KERNEL); - if (!e->xmitstatus_buffer) { - printk(KERN_ERR PFX "out of memory\n"); - kfree(e); - return; - } - e->xmitstatus_print_buffer = kzalloc(BCM43xx_NR_LOGGED_XMITSTATUS - * sizeof(*(e->xmitstatus_buffer)), - GFP_KERNEL); - if (!e->xmitstatus_print_buffer) { - printk(KERN_ERR PFX "out of memory\n"); - kfree(e); - return; - } - - - bcm->dfsentry = e; - - strncpy(devdir, bcm->net_dev->name, ARRAY_SIZE(devdir)); - e->subdir = debugfs_create_dir(devdir, fs.root); - e->dentry_devinfo = debugfs_create_file("devinfo", 0444, e->subdir, - bcm, &devinfo_fops); - if (!e->dentry_devinfo) - printk(KERN_ERR PFX "debugfs: creating \"devinfo\" for \"%s\" failed!\n", devdir); - e->dentry_spromdump = debugfs_create_file("sprom_dump", 0444, e->subdir, - bcm, &spromdump_fops); - if (!e->dentry_spromdump) - printk(KERN_ERR PFX "debugfs: creating \"sprom_dump\" for \"%s\" failed!\n", devdir); - e->dentry_tsf = debugfs_create_file("tsf", 0666, e->subdir, - bcm, &tsf_fops); - if (!e->dentry_tsf) - printk(KERN_ERR PFX "debugfs: creating \"tsf\" for \"%s\" failed!\n", devdir); - e->dentry_txstat = debugfs_create_file("tx_status", 0444, e->subdir, - bcm, &txstat_fops); - if (!e->dentry_txstat) - printk(KERN_ERR PFX "debugfs: creating \"tx_status\" for \"%s\" failed!\n", devdir); -} - -void bcm43xx_debugfs_remove_device(struct bcm43xx_private *bcm) -{ - struct bcm43xx_dfsentry *e; - - if (!bcm) - return; - - e = bcm->dfsentry; - assert(e); - debugfs_remove(e->dentry_spromdump); - debugfs_remove(e->dentry_devinfo); - debugfs_remove(e->dentry_tsf); - debugfs_remove(e->dentry_txstat); - debugfs_remove(e->subdir); - kfree(e->xmitstatus_buffer); - kfree(e->xmitstatus_print_buffer); - kfree(e); -} - -void bcm43xx_debugfs_log_txstat(struct bcm43xx_private *bcm, - struct bcm43xx_xmitstatus *status) -{ - struct bcm43xx_dfsentry *e; - struct bcm43xx_xmitstatus *savedstatus; - - /* This is protected by bcm->_lock */ - e = bcm->dfsentry; - assert(e); - savedstatus = e->xmitstatus_buffer + e->xmitstatus_ptr; - memcpy(savedstatus, status, sizeof(*status)); - e->xmitstatus_ptr++; - if (e->xmitstatus_ptr >= BCM43xx_NR_LOGGED_XMITSTATUS) - e->xmitstatus_ptr = 0; - if (e->xmitstatus_cnt < BCM43xx_NR_LOGGED_XMITSTATUS) - e->xmitstatus_cnt++; -} - -void bcm43xx_debugfs_init(void) -{ - memset(&fs, 0, sizeof(fs)); - fs.root = debugfs_create_dir(KBUILD_MODNAME, NULL); - if (!fs.root) - printk(KERN_ERR PFX "debugfs: creating \"" KBUILD_MODNAME "\" subdir failed!\n"); - fs.dentry_driverinfo = debugfs_create_file("driver", 0444, fs.root, NULL, &drvinfo_fops); - if (!fs.dentry_driverinfo) - printk(KERN_ERR PFX "debugfs: creating \"" KBUILD_MODNAME "/driver\" failed!\n"); -} - -void bcm43xx_debugfs_exit(void) -{ - debugfs_remove(fs.dentry_driverinfo); - debugfs_remove(fs.root); -} - -void bcm43xx_printk_dump(const char *data, - size_t size, - const char *description) -{ - size_t i; - char c; - - printk(KERN_INFO PFX "Data dump (%s, %u bytes):", - description, size); - for (i = 0; i < size; i++) { - c = data[i]; - if (i % 8 == 0) - printk("\n" KERN_INFO PFX "0x%08x: 0x%02x, ", i, c & 0xff); - else - printk("0x%02x, ", c & 0xff); - } - printk("\n"); -} - -void bcm43xx_printk_bitdump(const unsigned char *data, - size_t bytes, int msb_to_lsb, - const char *description) -{ - size_t i; - int j; - const unsigned char *d; - - printk(KERN_INFO PFX "*** Bitdump (%s, %u bytes, %s) ***", - description, bytes, msb_to_lsb ? "MSB to LSB" : "LSB to MSB"); - for (i = 0; i < bytes; i++) { - d = data + i; - if (i % 8 == 0) - printk("\n" KERN_INFO PFX "0x%08x: ", i); - if (msb_to_lsb) { - for (j = 7; j >= 0; j--) { - if (*d & (1 << j)) - printk("1"); - else - printk("0"); - } - } else { - for (j = 0; j < 8; j++) { - if (*d & (1 << j)) - printk("1"); - else - printk("0"); - } - } - printk(" "); - } - printk("\n"); -} diff --git a/trunk/drivers/net/wireless/bcm43xx/bcm43xx_debugfs.h b/trunk/drivers/net/wireless/bcm43xx/bcm43xx_debugfs.h deleted file mode 100644 index 50ce267f794d..000000000000 --- a/trunk/drivers/net/wireless/bcm43xx/bcm43xx_debugfs.h +++ /dev/null @@ -1,117 +0,0 @@ -#ifndef BCM43xx_DEBUGFS_H_ -#define BCM43xx_DEBUGFS_H_ - -struct bcm43xx_private; -struct bcm43xx_xmitstatus; - -#ifdef CONFIG_BCM43XX_DEBUG - -#include -#include - -struct dentry; - -/* limited by the size of the "really_big_buffer" */ -#define BCM43xx_NR_LOGGED_XMITSTATUS 100 - -struct bcm43xx_dfsentry { - struct dentry *subdir; - struct dentry *dentry_devinfo; - struct dentry *dentry_spromdump; - struct dentry *dentry_tsf; - struct dentry *dentry_txstat; - - struct bcm43xx_private *bcm; - - /* saved xmitstatus. */ - struct bcm43xx_xmitstatus *xmitstatus_buffer; - int xmitstatus_ptr; - int xmitstatus_cnt; - /* We need a seperate buffer while printing to avoid - * concurrency issues. (New xmitstatus can arrive - * while we are printing). - */ - struct bcm43xx_xmitstatus *xmitstatus_print_buffer; - int saved_xmitstatus_ptr; - int saved_xmitstatus_cnt; - int xmitstatus_printing; -}; - -struct bcm43xx_debugfs { - struct dentry *root; - struct dentry *dentry_driverinfo; -}; - -void bcm43xx_debugfs_init(void); -void bcm43xx_debugfs_exit(void); -void bcm43xx_debugfs_add_device(struct bcm43xx_private *bcm); -void bcm43xx_debugfs_remove_device(struct bcm43xx_private *bcm); -void bcm43xx_debugfs_log_txstat(struct bcm43xx_private *bcm, - struct bcm43xx_xmitstatus *status); - -/* Debug helper: Dump binary data through printk. */ -void bcm43xx_printk_dump(const char *data, - size_t size, - const char *description); -/* Debug helper: Dump bitwise binary data through printk. */ -void bcm43xx_printk_bitdump(const unsigned char *data, - size_t bytes, int msb_to_lsb, - const char *description); -#define bcm43xx_printk_bitdumpt(pointer, msb_to_lsb, description) \ - do { \ - bcm43xx_printk_bitdump((const unsigned char *)(pointer), \ - sizeof(*(pointer)), \ - (msb_to_lsb), \ - (description)); \ - } while (0) - -#else /* CONFIG_BCM43XX_DEBUG*/ - -static inline -void bcm43xx_debugfs_init(void) { } -static inline -void bcm43xx_debugfs_exit(void) { } -static inline -void bcm43xx_debugfs_add_device(struct bcm43xx_private *bcm) { } -static inline -void bcm43xx_debugfs_remove_device(struct bcm43xx_private *bcm) { } -static inline -void bcm43xx_debugfs_log_txstat(struct bcm43xx_private *bcm, - struct bcm43xx_xmitstatus *status) { } - -static inline -void bcm43xx_printk_dump(const char *data, - size_t size, - const char *description) -{ -} -static inline -void bcm43xx_printk_bitdump(const unsigned char *data, - size_t bytes, int msb_to_lsb, - const char *description) -{ -} -#define bcm43xx_printk_bitdumpt(pointer, msb_to_lsb, description) do { /* nothing */ } while (0) - -#endif /* CONFIG_BCM43XX_DEBUG*/ - -/* Ugly helper macros to make incomplete code more verbose on runtime */ -#ifdef TODO -# undef TODO -#endif -#define TODO() \ - do { \ - printk(KERN_INFO PFX "TODO: Incomplete code in %s() at %s:%d\n", \ - __FUNCTION__, __FILE__, __LINE__); \ - } while (0) - -#ifdef FIXME -# undef FIXME -#endif -#define FIXME() \ - do { \ - printk(KERN_INFO PFX "FIXME: Possibly broken code in %s() at %s:%d\n", \ - __FUNCTION__, __FILE__, __LINE__); \ - } while (0) - -#endif /* BCM43xx_DEBUGFS_H_ */ diff --git a/trunk/drivers/net/wireless/bcm43xx/bcm43xx_dma.c b/trunk/drivers/net/wireless/bcm43xx/bcm43xx_dma.c deleted file mode 100644 index c3681b8f09b4..000000000000 --- a/trunk/drivers/net/wireless/bcm43xx/bcm43xx_dma.c +++ /dev/null @@ -1,968 +0,0 @@ -/* - - Broadcom BCM43xx wireless driver - - DMA ringbuffer and descriptor allocation/management - - Copyright (c) 2005 Michael Buesch - - Some code in this file is derived from the b44.c driver - Copyright (C) 2002 David S. Miller - Copyright (C) Pekka Pietikainen - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; see the file COPYING. If not, write to - the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor, - Boston, MA 02110-1301, USA. - -*/ - -#include "bcm43xx.h" -#include "bcm43xx_dma.h" -#include "bcm43xx_main.h" -#include "bcm43xx_debugfs.h" -#include "bcm43xx_power.h" -#include "bcm43xx_xmit.h" - -#include -#include -#include -#include - - -static inline int free_slots(struct bcm43xx_dmaring *ring) -{ - return (ring->nr_slots - ring->used_slots); -} - -static inline int next_slot(struct bcm43xx_dmaring *ring, int slot) -{ - assert(slot >= -1 && slot <= ring->nr_slots - 1); - if (slot == ring->nr_slots - 1) - return 0; - return slot + 1; -} - -static inline int prev_slot(struct bcm43xx_dmaring *ring, int slot) -{ - assert(slot >= 0 && slot <= ring->nr_slots - 1); - if (slot == 0) - return ring->nr_slots - 1; - return slot - 1; -} - -/* Request a slot for usage. */ -static inline -int request_slot(struct bcm43xx_dmaring *ring) -{ - int slot; - - assert(ring->tx); - assert(!ring->suspended); - assert(free_slots(ring) != 0); - - slot = next_slot(ring, ring->current_slot); - ring->current_slot = slot; - ring->used_slots++; - - /* Check the number of available slots and suspend TX, - * if we are running low on free slots. - */ - if (unlikely(free_slots(ring) < ring->suspend_mark)) { - netif_stop_queue(ring->bcm->net_dev); - ring->suspended = 1; - } -#ifdef CONFIG_BCM43XX_DEBUG - if (ring->used_slots > ring->max_used_slots) - ring->max_used_slots = ring->used_slots; -#endif /* CONFIG_BCM43XX_DEBUG*/ - - return slot; -} - -/* Return a slot to the free slots. */ -static inline -void return_slot(struct bcm43xx_dmaring *ring, int slot) -{ - assert(ring->tx); - - ring->used_slots--; - - /* Check if TX is suspended and check if we have - * enough free slots to resume it again. - */ - if (unlikely(ring->suspended)) { - if (free_slots(ring) >= ring->resume_mark) { - ring->suspended = 0; - netif_wake_queue(ring->bcm->net_dev); - } - } -} - -static inline -dma_addr_t map_descbuffer(struct bcm43xx_dmaring *ring, - unsigned char *buf, - size_t len, - int tx) -{ - dma_addr_t dmaaddr; - - if (tx) { - dmaaddr = dma_map_single(&ring->bcm->pci_dev->dev, - buf, len, - DMA_TO_DEVICE); - } else { - dmaaddr = dma_map_single(&ring->bcm->pci_dev->dev, - buf, len, - DMA_FROM_DEVICE); - } - - return dmaaddr; -} - -static inline -void unmap_descbuffer(struct bcm43xx_dmaring *ring, - dma_addr_t addr, - size_t len, - int tx) -{ - if (tx) { - dma_unmap_single(&ring->bcm->pci_dev->dev, - addr, len, - DMA_TO_DEVICE); - } else { - dma_unmap_single(&ring->bcm->pci_dev->dev, - addr, len, - DMA_FROM_DEVICE); - } -} - -static inline -void sync_descbuffer_for_cpu(struct bcm43xx_dmaring *ring, - dma_addr_t addr, - size_t len) -{ - assert(!ring->tx); - - dma_sync_single_for_cpu(&ring->bcm->pci_dev->dev, - addr, len, DMA_FROM_DEVICE); -} - -static inline -void sync_descbuffer_for_device(struct bcm43xx_dmaring *ring, - dma_addr_t addr, - size_t len) -{ - assert(!ring->tx); - - dma_sync_single_for_device(&ring->bcm->pci_dev->dev, - addr, len, DMA_FROM_DEVICE); -} - -/* Unmap and free a descriptor buffer. */ -static inline -void free_descriptor_buffer(struct bcm43xx_dmaring *ring, - struct bcm43xx_dmadesc *desc, - struct bcm43xx_dmadesc_meta *meta, - int irq_context) -{ - assert(meta->skb); - if (irq_context) - dev_kfree_skb_irq(meta->skb); - else - dev_kfree_skb(meta->skb); - meta->skb = NULL; -} - -static int alloc_ringmemory(struct bcm43xx_dmaring *ring) -{ - struct device *dev = &(ring->bcm->pci_dev->dev); - - ring->vbase = dma_alloc_coherent(dev, BCM43xx_DMA_RINGMEMSIZE, - &(ring->dmabase), GFP_KERNEL); - if (!ring->vbase) { - printk(KERN_ERR PFX "DMA ringmemory allocation failed\n"); - return -ENOMEM; - } - if (ring->dmabase + BCM43xx_DMA_RINGMEMSIZE > BCM43xx_DMA_BUSADDRMAX) { - printk(KERN_ERR PFX ">>>FATAL ERROR<<< DMA RINGMEMORY >1G " - "(0x%08x, len: %lu)\n", - ring->dmabase, BCM43xx_DMA_RINGMEMSIZE); - dma_free_coherent(dev, BCM43xx_DMA_RINGMEMSIZE, - ring->vbase, ring->dmabase); - return -ENOMEM; - } - assert(!(ring->dmabase & 0x000003FF)); - memset(ring->vbase, 0, BCM43xx_DMA_RINGMEMSIZE); - - return 0; -} - -static void free_ringmemory(struct bcm43xx_dmaring *ring) -{ - struct device *dev = &(ring->bcm->pci_dev->dev); - - dma_free_coherent(dev, BCM43xx_DMA_RINGMEMSIZE, - ring->vbase, ring->dmabase); -} - -/* Reset the RX DMA channel */ -int bcm43xx_dmacontroller_rx_reset(struct bcm43xx_private *bcm, - u16 mmio_base) -{ - int i; - u32 value; - - bcm43xx_write32(bcm, - mmio_base + BCM43xx_DMA_RX_CONTROL, - 0x00000000); - for (i = 0; i < 1000; i++) { - value = bcm43xx_read32(bcm, - mmio_base + BCM43xx_DMA_RX_STATUS); - value &= BCM43xx_DMA_RXSTAT_STAT_MASK; - if (value == BCM43xx_DMA_RXSTAT_STAT_DISABLED) { - i = -1; - break; - } - udelay(10); - } - if (i != -1) { - printk(KERN_ERR PFX "Error: Wait on DMA RX status timed out.\n"); - return -ENODEV; - } - - return 0; -} - -/* Reset the RX DMA channel */ -int bcm43xx_dmacontroller_tx_reset(struct bcm43xx_private *bcm, - u16 mmio_base) -{ - int i; - u32 value; - - for (i = 0; i < 1000; i++) { - value = bcm43xx_read32(bcm, - mmio_base + BCM43xx_DMA_TX_STATUS); - value &= BCM43xx_DMA_TXSTAT_STAT_MASK; - if (value == BCM43xx_DMA_TXSTAT_STAT_DISABLED || - value == BCM43xx_DMA_TXSTAT_STAT_IDLEWAIT || - value == BCM43xx_DMA_TXSTAT_STAT_STOPPED) - break; - udelay(10); - } - bcm43xx_write32(bcm, - mmio_base + BCM43xx_DMA_TX_CONTROL, - 0x00000000); - for (i = 0; i < 1000; i++) { - value = bcm43xx_read32(bcm, - mmio_base + BCM43xx_DMA_TX_STATUS); - value &= BCM43xx_DMA_TXSTAT_STAT_MASK; - if (value == BCM43xx_DMA_TXSTAT_STAT_DISABLED) { - i = -1; - break; - } - udelay(10); - } - if (i != -1) { - printk(KERN_ERR PFX "Error: Wait on DMA TX status timed out.\n"); - return -ENODEV; - } - /* ensure the reset is completed. */ - udelay(300); - - return 0; -} - -static int setup_rx_descbuffer(struct bcm43xx_dmaring *ring, - struct bcm43xx_dmadesc *desc, - struct bcm43xx_dmadesc_meta *meta, - gfp_t gfp_flags) -{ - struct bcm43xx_rxhdr *rxhdr; - dma_addr_t dmaaddr; - u32 desc_addr; - u32 desc_ctl; - const int slot = (int)(desc - ring->vbase); - struct sk_buff *skb; - - assert(slot >= 0 && slot < ring->nr_slots); - assert(!ring->tx); - - skb = __dev_alloc_skb(ring->rx_buffersize, gfp_flags); - if (unlikely(!skb)) - return -ENOMEM; - dmaaddr = map_descbuffer(ring, skb->data, ring->rx_buffersize, 0); - if (unlikely(dmaaddr + ring->rx_buffersize > BCM43xx_DMA_BUSADDRMAX)) { - unmap_descbuffer(ring, dmaaddr, ring->rx_buffersize, 0); - dev_kfree_skb_any(skb); - printk(KERN_ERR PFX ">>>FATAL ERROR<<< DMA RX SKB >1G " - "(0x%08x, len: %u)\n", - dmaaddr, ring->rx_buffersize); - return -ENOMEM; - } - meta->skb = skb; - meta->dmaaddr = dmaaddr; - skb->dev = ring->bcm->net_dev; - desc_addr = (u32)(dmaaddr + ring->memoffset); - desc_ctl = (BCM43xx_DMADTOR_BYTECNT_MASK & - (u32)(ring->rx_buffersize - ring->frameoffset)); - if (slot == ring->nr_slots - 1) - desc_ctl |= BCM43xx_DMADTOR_DTABLEEND; - set_desc_addr(desc, desc_addr); - set_desc_ctl(desc, desc_ctl); - - rxhdr = (struct bcm43xx_rxhdr *)(skb->data); - rxhdr->frame_length = 0; - rxhdr->flags1 = 0; - - return 0; -} - -/* Allocate the initial descbuffers. - * This is used for an RX ring only. - */ -static int alloc_initial_descbuffers(struct bcm43xx_dmaring *ring) -{ - int i, err = -ENOMEM; - struct bcm43xx_dmadesc *desc; - struct bcm43xx_dmadesc_meta *meta; - - for (i = 0; i < ring->nr_slots; i++) { - desc = ring->vbase + i; - meta = ring->meta + i; - - err = setup_rx_descbuffer(ring, desc, meta, GFP_KERNEL); - if (err) - goto err_unwind; - } - ring->used_slots = ring->nr_slots; - err = 0; -out: - return err; - -err_unwind: - for (i--; i >= 0; i--) { - desc = ring->vbase + i; - meta = ring->meta + i; - - unmap_descbuffer(ring, meta->dmaaddr, ring->rx_buffersize, 0); - dev_kfree_skb(meta->skb); - } - goto out; -} - -/* Do initial setup of the DMA controller. - * Reset the controller, write the ring busaddress - * and switch the "enable" bit on. - */ -static int dmacontroller_setup(struct bcm43xx_dmaring *ring) -{ - int err = 0; - u32 value; - - if (ring->tx) { - /* Set Transmit Control register to "transmit enable" */ - bcm43xx_dma_write(ring, BCM43xx_DMA_TX_CONTROL, - BCM43xx_DMA_TXCTRL_ENABLE); - /* Set Transmit Descriptor ring address. */ - bcm43xx_dma_write(ring, BCM43xx_DMA_TX_DESC_RING, - ring->dmabase + ring->memoffset); - } else { - err = alloc_initial_descbuffers(ring); - if (err) - goto out; - /* Set Receive Control "receive enable" and frame offset */ - value = (ring->frameoffset << BCM43xx_DMA_RXCTRL_FRAMEOFF_SHIFT); - value |= BCM43xx_DMA_RXCTRL_ENABLE; - bcm43xx_dma_write(ring, BCM43xx_DMA_RX_CONTROL, value); - /* Set Receive Descriptor ring address. */ - bcm43xx_dma_write(ring, BCM43xx_DMA_RX_DESC_RING, - ring->dmabase + ring->memoffset); - /* Init the descriptor pointer. */ - bcm43xx_dma_write(ring, BCM43xx_DMA_RX_DESC_INDEX, 200); - } - -out: - return err; -} - -/* Shutdown the DMA controller. */ -static void dmacontroller_cleanup(struct bcm43xx_dmaring *ring) -{ - if (ring->tx) { - bcm43xx_dmacontroller_tx_reset(ring->bcm, ring->mmio_base); - /* Zero out Transmit Descriptor ring address. */ - bcm43xx_dma_write(ring, BCM43xx_DMA_TX_DESC_RING, 0); - } else { - bcm43xx_dmacontroller_rx_reset(ring->bcm, ring->mmio_base); - /* Zero out Receive Descriptor ring address. */ - bcm43xx_dma_write(ring, BCM43xx_DMA_RX_DESC_RING, 0); - } -} - -static void free_all_descbuffers(struct bcm43xx_dmaring *ring) -{ - struct bcm43xx_dmadesc *desc; - struct bcm43xx_dmadesc_meta *meta; - int i; - - if (!ring->used_slots) - return; - for (i = 0; i < ring->nr_slots; i++) { - desc = ring->vbase + i; - meta = ring->meta + i; - - if (!meta->skb) { - assert(ring->tx); - continue; - } - if (ring->tx) { - unmap_descbuffer(ring, meta->dmaaddr, - meta->skb->len, 1); - } else { - unmap_descbuffer(ring, meta->dmaaddr, - ring->rx_buffersize, 0); - } - free_descriptor_buffer(ring, desc, meta, 0); - } -} - -/* Main initialization function. */ -static -struct bcm43xx_dmaring * bcm43xx_setup_dmaring(struct bcm43xx_private *bcm, - u16 dma_controller_base, - int nr_descriptor_slots, - int tx) -{ - struct bcm43xx_dmaring *ring; - int err; - - ring = kzalloc(sizeof(*ring), GFP_KERNEL); - if (!ring) - goto out; - - ring->meta = kzalloc(sizeof(*ring->meta) * nr_descriptor_slots, - GFP_KERNEL); - if (!ring->meta) - goto err_kfree_ring; - - ring->memoffset = BCM43xx_DMA_DMABUSADDROFFSET; -#ifdef CONFIG_BCM947XX - if (bcm->pci_dev->bus->number == 0) - ring->memoffset = 0; -#endif - - ring->bcm = bcm; - ring->nr_slots = nr_descriptor_slots; - ring->suspend_mark = ring->nr_slots * BCM43xx_TXSUSPEND_PERCENT / 100; - ring->resume_mark = ring->nr_slots * BCM43xx_TXRESUME_PERCENT / 100; - assert(ring->suspend_mark < ring->resume_mark); - ring->mmio_base = dma_controller_base; - if (tx) { - ring->tx = 1; - ring->current_slot = -1; - } else { - switch (dma_controller_base) { - case BCM43xx_MMIO_DMA1_BASE: - ring->rx_buffersize = BCM43xx_DMA1_RXBUFFERSIZE; - ring->frameoffset = BCM43xx_DMA1_RX_FRAMEOFFSET; - break; - case BCM43xx_MMIO_DMA4_BASE: - ring->rx_buffersize = BCM43xx_DMA4_RXBUFFERSIZE; - ring->frameoffset = BCM43xx_DMA4_RX_FRAMEOFFSET; - break; - default: - assert(0); - } - } - - err = alloc_ringmemory(ring); - if (err) - goto err_kfree_meta; - err = dmacontroller_setup(ring); - if (err) - goto err_free_ringmemory; - -out: - return ring; - -err_free_ringmemory: - free_ringmemory(ring); -err_kfree_meta: - kfree(ring->meta); -err_kfree_ring: - kfree(ring); - ring = NULL; - goto out; -} - -/* Main cleanup function. */ -static void bcm43xx_destroy_dmaring(struct bcm43xx_dmaring *ring) -{ - if (!ring) - return; - - dprintk(KERN_INFO PFX "DMA 0x%04x (%s) max used slots: %d/%d\n", - ring->mmio_base, - (ring->tx) ? "TX" : "RX", - ring->max_used_slots, ring->nr_slots); - /* Device IRQs are disabled prior entering this function, - * so no need to take care of concurrency with rx handler stuff. - */ - dmacontroller_cleanup(ring); - free_all_descbuffers(ring); - free_ringmemory(ring); - - kfree(ring->meta); - kfree(ring); -} - -void bcm43xx_dma_free(struct bcm43xx_private *bcm) -{ - struct bcm43xx_dma *dma; - - if (bcm43xx_using_pio(bcm)) - return; - dma = bcm43xx_current_dma(bcm); - - bcm43xx_destroy_dmaring(dma->rx_ring1); - dma->rx_ring1 = NULL; - bcm43xx_destroy_dmaring(dma->rx_ring0); - dma->rx_ring0 = NULL; - bcm43xx_destroy_dmaring(dma->tx_ring3); - dma->tx_ring3 = NULL; - bcm43xx_destroy_dmaring(dma->tx_ring2); - dma->tx_ring2 = NULL; - bcm43xx_destroy_dmaring(dma->tx_ring1); - dma->tx_ring1 = NULL; - bcm43xx_destroy_dmaring(dma->tx_ring0); - dma->tx_ring0 = NULL; -} - -int bcm43xx_dma_init(struct bcm43xx_private *bcm) -{ - struct bcm43xx_dma *dma = bcm43xx_current_dma(bcm); - struct bcm43xx_dmaring *ring; - int err = -ENOMEM; - - /* setup TX DMA channels. */ - ring = bcm43xx_setup_dmaring(bcm, BCM43xx_MMIO_DMA1_BASE, - BCM43xx_TXRING_SLOTS, 1); - if (!ring) - goto out; - dma->tx_ring0 = ring; - - ring = bcm43xx_setup_dmaring(bcm, BCM43xx_MMIO_DMA2_BASE, - BCM43xx_TXRING_SLOTS, 1); - if (!ring) - goto err_destroy_tx0; - dma->tx_ring1 = ring; - - ring = bcm43xx_setup_dmaring(bcm, BCM43xx_MMIO_DMA3_BASE, - BCM43xx_TXRING_SLOTS, 1); - if (!ring) - goto err_destroy_tx1; - dma->tx_ring2 = ring; - - ring = bcm43xx_setup_dmaring(bcm, BCM43xx_MMIO_DMA4_BASE, - BCM43xx_TXRING_SLOTS, 1); - if (!ring) - goto err_destroy_tx2; - dma->tx_ring3 = ring; - - /* setup RX DMA channels. */ - ring = bcm43xx_setup_dmaring(bcm, BCM43xx_MMIO_DMA1_BASE, - BCM43xx_RXRING_SLOTS, 0); - if (!ring) - goto err_destroy_tx3; - dma->rx_ring0 = ring; - - if (bcm->current_core->rev < 5) { - ring = bcm43xx_setup_dmaring(bcm, BCM43xx_MMIO_DMA4_BASE, - BCM43xx_RXRING_SLOTS, 0); - if (!ring) - goto err_destroy_rx0; - dma->rx_ring1 = ring; - } - - dprintk(KERN_INFO PFX "DMA initialized\n"); - err = 0; -out: - return err; - -err_destroy_rx0: - bcm43xx_destroy_dmaring(dma->rx_ring0); - dma->rx_ring0 = NULL; -err_destroy_tx3: - bcm43xx_destroy_dmaring(dma->tx_ring3); - dma->tx_ring3 = NULL; -err_destroy_tx2: - bcm43xx_destroy_dmaring(dma->tx_ring2); - dma->tx_ring2 = NULL; -err_destroy_tx1: - bcm43xx_destroy_dmaring(dma->tx_ring1); - dma->tx_ring1 = NULL; -err_destroy_tx0: - bcm43xx_destroy_dmaring(dma->tx_ring0); - dma->tx_ring0 = NULL; - goto out; -} - -/* Generate a cookie for the TX header. */ -static u16 generate_cookie(struct bcm43xx_dmaring *ring, - int slot) -{ - u16 cookie = 0x0000; - - /* Use the upper 4 bits of the cookie as - * DMA controller ID and store the slot number - * in the lower 12 bits - */ - switch (ring->mmio_base) { - default: - assert(0); - case BCM43xx_MMIO_DMA1_BASE: - break; - case BCM43xx_MMIO_DMA2_BASE: - cookie = 0x1000; - break; - case BCM43xx_MMIO_DMA3_BASE: - cookie = 0x2000; - break; - case BCM43xx_MMIO_DMA4_BASE: - cookie = 0x3000; - break; - } - assert(((u16)slot & 0xF000) == 0x0000); - cookie |= (u16)slot; - - return cookie; -} - -/* Inspect a cookie and find out to which controller/slot it belongs. */ -static -struct bcm43xx_dmaring * parse_cookie(struct bcm43xx_private *bcm, - u16 cookie, int *slot) -{ - struct bcm43xx_dma *dma = bcm43xx_current_dma(bcm); - struct bcm43xx_dmaring *ring = NULL; - - switch (cookie & 0xF000) { - case 0x0000: - ring = dma->tx_ring0; - break; - case 0x1000: - ring = dma->tx_ring1; - break; - case 0x2000: - ring = dma->tx_ring2; - break; - case 0x3000: - ring = dma->tx_ring3; - break; - default: - assert(0); - } - *slot = (cookie & 0x0FFF); - assert(*slot >= 0 && *slot < ring->nr_slots); - - return ring; -} - -static void dmacontroller_poke_tx(struct bcm43xx_dmaring *ring, - int slot) -{ - /* Everything is ready to start. Buffers are DMA mapped and - * associated with slots. - * "slot" is the last slot of the new frame we want to transmit. - * Close your seat belts now, please. - */ - wmb(); - slot = next_slot(ring, slot); - bcm43xx_dma_write(ring, BCM43xx_DMA_TX_DESC_INDEX, - (u32)(slot * sizeof(struct bcm43xx_dmadesc))); -} - -static int dma_tx_fragment(struct bcm43xx_dmaring *ring, - struct sk_buff *skb, - u8 cur_frag) -{ - int slot; - struct bcm43xx_dmadesc *desc; - struct bcm43xx_dmadesc_meta *meta; - u32 desc_ctl; - u32 desc_addr; - - assert(skb_shinfo(skb)->nr_frags == 0); - - slot = request_slot(ring); - desc = ring->vbase + slot; - meta = ring->meta + slot; - - /* Add a device specific TX header. */ - assert(skb_headroom(skb) >= sizeof(struct bcm43xx_txhdr)); - /* Reserve enough headroom for the device tx header. */ - __skb_push(skb, sizeof(struct bcm43xx_txhdr)); - /* Now calculate and add the tx header. - * The tx header includes the PLCP header. - */ - bcm43xx_generate_txhdr(ring->bcm, - (struct bcm43xx_txhdr *)skb->data, - skb->data + sizeof(struct bcm43xx_txhdr), - skb->len - sizeof(struct bcm43xx_txhdr), - (cur_frag == 0), - generate_cookie(ring, slot)); - - meta->skb = skb; - meta->dmaaddr = map_descbuffer(ring, skb->data, skb->len, 1); - if (unlikely(meta->dmaaddr + skb->len > BCM43xx_DMA_BUSADDRMAX)) { - return_slot(ring, slot); - printk(KERN_ERR PFX ">>>FATAL ERROR<<< DMA TX SKB >1G " - "(0x%08x, len: %u)\n", - meta->dmaaddr, skb->len); - return -ENOMEM; - } - - desc_addr = (u32)(meta->dmaaddr + ring->memoffset); - desc_ctl = BCM43xx_DMADTOR_FRAMESTART | BCM43xx_DMADTOR_FRAMEEND; - desc_ctl |= BCM43xx_DMADTOR_COMPIRQ; - desc_ctl |= (BCM43xx_DMADTOR_BYTECNT_MASK & - (u32)(meta->skb->len - ring->frameoffset)); - if (slot == ring->nr_slots - 1) - desc_ctl |= BCM43xx_DMADTOR_DTABLEEND; - - set_desc_ctl(desc, desc_ctl); - set_desc_addr(desc, desc_addr); - /* Now transfer the whole frame. */ - dmacontroller_poke_tx(ring, slot); - - return 0; -} - -int bcm43xx_dma_tx(struct bcm43xx_private *bcm, - struct ieee80211_txb *txb) -{ - /* We just received a packet from the kernel network subsystem. - * Add headers and DMA map the memory. Poke - * the device to send the stuff. - * Note that this is called from atomic context. - */ - struct bcm43xx_dmaring *ring = bcm43xx_current_dma(bcm)->tx_ring1; - u8 i; - struct sk_buff *skb; - - assert(ring->tx); - if (unlikely(free_slots(ring) < txb->nr_frags)) { - /* The queue should be stopped, - * if we are low on free slots. - * If this ever triggers, we have to lower the suspend_mark. - */ - dprintkl(KERN_ERR PFX "Out of DMA descriptor slots!\n"); - return -ENOMEM; - } - - for (i = 0; i < txb->nr_frags; i++) { - skb = txb->fragments[i]; - /* Take skb from ieee80211_txb_free */ - txb->fragments[i] = NULL; - dma_tx_fragment(ring, skb, i); - //TODO: handle failure of dma_tx_fragment - } - ieee80211_txb_free(txb); - - return 0; -} - -void bcm43xx_dma_handle_xmitstatus(struct bcm43xx_private *bcm, - struct bcm43xx_xmitstatus *status) -{ - struct bcm43xx_dmaring *ring; - struct bcm43xx_dmadesc *desc; - struct bcm43xx_dmadesc_meta *meta; - int is_last_fragment; - int slot; - - ring = parse_cookie(bcm, status->cookie, &slot); - assert(ring); - assert(ring->tx); - assert(get_desc_ctl(ring->vbase + slot) & BCM43xx_DMADTOR_FRAMESTART); - while (1) { - assert(slot >= 0 && slot < ring->nr_slots); - desc = ring->vbase + slot; - meta = ring->meta + slot; - - is_last_fragment = !!(get_desc_ctl(desc) & BCM43xx_DMADTOR_FRAMEEND); - unmap_descbuffer(ring, meta->dmaaddr, meta->skb->len, 1); - free_descriptor_buffer(ring, desc, meta, 1); - /* Everything belonging to the slot is unmapped - * and freed, so we can return it. - */ - return_slot(ring, slot); - - if (is_last_fragment) - break; - slot = next_slot(ring, slot); - } - bcm->stats.last_tx = jiffies; -} - -static void dma_rx(struct bcm43xx_dmaring *ring, - int *slot) -{ - struct bcm43xx_dmadesc *desc; - struct bcm43xx_dmadesc_meta *meta; - struct bcm43xx_rxhdr *rxhdr; - struct sk_buff *skb; - u16 len; - int err; - dma_addr_t dmaaddr; - - desc = ring->vbase + *slot; - meta = ring->meta + *slot; - - sync_descbuffer_for_cpu(ring, meta->dmaaddr, ring->rx_buffersize); - skb = meta->skb; - - if (ring->mmio_base == BCM43xx_MMIO_DMA4_BASE) { - /* We received an xmit status. */ - struct bcm43xx_hwxmitstatus *hw = (struct bcm43xx_hwxmitstatus *)skb->data; - struct bcm43xx_xmitstatus stat; - - stat.cookie = le16_to_cpu(hw->cookie); - stat.flags = hw->flags; - stat.cnt1 = hw->cnt1; - stat.cnt2 = hw->cnt2; - stat.seq = le16_to_cpu(hw->seq); - stat.unknown = le16_to_cpu(hw->unknown); - - bcm43xx_debugfs_log_txstat(ring->bcm, &stat); - bcm43xx_dma_handle_xmitstatus(ring->bcm, &stat); - /* recycle the descriptor buffer. */ - sync_descbuffer_for_device(ring, meta->dmaaddr, ring->rx_buffersize); - - return; - } - rxhdr = (struct bcm43xx_rxhdr *)skb->data; - len = le16_to_cpu(rxhdr->frame_length); - if (len == 0) { - int i = 0; - - do { - udelay(2); - barrier(); - len = le16_to_cpu(rxhdr->frame_length); - } while (len == 0 && i++ < 5); - if (unlikely(len == 0)) { - /* recycle the descriptor buffer. */ - sync_descbuffer_for_device(ring, meta->dmaaddr, - ring->rx_buffersize); - goto drop; - } - } - if (unlikely(len > ring->rx_buffersize)) { - /* The data did not fit into one descriptor buffer - * and is split over multiple buffers. - * This should never happen, as we try to allocate buffers - * big enough. So simply ignore this packet. - */ - int cnt = 0; - s32 tmp = len; - - while (1) { - desc = ring->vbase + *slot; - meta = ring->meta + *slot; - /* recycle the descriptor buffer. */ - sync_descbuffer_for_device(ring, meta->dmaaddr, - ring->rx_buffersize); - *slot = next_slot(ring, *slot); - cnt++; - tmp -= ring->rx_buffersize; - if (tmp <= 0) - break; - } - printkl(KERN_ERR PFX "DMA RX buffer too small " - "(len: %u, buffer: %u, nr-dropped: %d)\n", - len, ring->rx_buffersize, cnt); - goto drop; - } - len -= IEEE80211_FCS_LEN; - - dmaaddr = meta->dmaaddr; - err = setup_rx_descbuffer(ring, desc, meta, GFP_ATOMIC); - if (unlikely(err)) { - dprintkl(KERN_ERR PFX "DMA RX: setup_rx_descbuffer() failed\n"); - sync_descbuffer_for_device(ring, dmaaddr, - ring->rx_buffersize); - goto drop; - } - - unmap_descbuffer(ring, dmaaddr, ring->rx_buffersize, 0); - skb_put(skb, len + ring->frameoffset); - skb_pull(skb, ring->frameoffset); - - err = bcm43xx_rx(ring->bcm, skb, rxhdr); - if (err) { - dev_kfree_skb_irq(skb); - goto drop; - } - -drop: - return; -} - -void bcm43xx_dma_rx(struct bcm43xx_dmaring *ring) -{ - u32 status; - u16 descptr; - int slot, current_slot; -#ifdef CONFIG_BCM43XX_DEBUG - int used_slots = 0; -#endif - - assert(!ring->tx); - status = bcm43xx_dma_read(ring, BCM43xx_DMA_RX_STATUS); - descptr = (status & BCM43xx_DMA_RXSTAT_DPTR_MASK); - current_slot = descptr / sizeof(struct bcm43xx_dmadesc); - assert(current_slot >= 0 && current_slot < ring->nr_slots); - - slot = ring->current_slot; - for ( ; slot != current_slot; slot = next_slot(ring, slot)) { - dma_rx(ring, &slot); -#ifdef CONFIG_BCM43XX_DEBUG - if (++used_slots > ring->max_used_slots) - ring->max_used_slots = used_slots; -#endif - } - bcm43xx_dma_write(ring, BCM43xx_DMA_RX_DESC_INDEX, - (u32)(slot * sizeof(struct bcm43xx_dmadesc))); - ring->current_slot = slot; -} - -void bcm43xx_dma_tx_suspend(struct bcm43xx_dmaring *ring) -{ - assert(ring->tx); - bcm43xx_power_saving_ctl_bits(ring->bcm, -1, 1); - bcm43xx_dma_write(ring, BCM43xx_DMA_TX_CONTROL, - bcm43xx_dma_read(ring, BCM43xx_DMA_TX_CONTROL) - | BCM43xx_DMA_TXCTRL_SUSPEND); -} - -void bcm43xx_dma_tx_resume(struct bcm43xx_dmaring *ring) -{ - assert(ring->tx); - bcm43xx_dma_write(ring, BCM43xx_DMA_TX_CONTROL, - bcm43xx_dma_read(ring, BCM43xx_DMA_TX_CONTROL) - & ~BCM43xx_DMA_TXCTRL_SUSPEND); - bcm43xx_power_saving_ctl_bits(ring->bcm, -1, -1); -} diff --git a/trunk/drivers/net/wireless/bcm43xx/bcm43xx_dma.h b/trunk/drivers/net/wireless/bcm43xx/bcm43xx_dma.h deleted file mode 100644 index 2d520e4b0276..000000000000 --- a/trunk/drivers/net/wireless/bcm43xx/bcm43xx_dma.h +++ /dev/null @@ -1,218 +0,0 @@ -#ifndef BCM43xx_DMA_H_ -#define BCM43xx_DMA_H_ - -#include -#include -#include -#include -#include - - -/* DMA-Interrupt reasons. */ -#define BCM43xx_DMAIRQ_FATALMASK ((1 << 10) | (1 << 11) | (1 << 12) \ - | (1 << 14) | (1 << 15)) -#define BCM43xx_DMAIRQ_NONFATALMASK (1 << 13) -#define BCM43xx_DMAIRQ_RX_DONE (1 << 16) - -/* DMA controller register offsets. (relative to BCM43xx_DMA#_BASE) */ -#define BCM43xx_DMA_TX_CONTROL 0x00 -#define BCM43xx_DMA_TX_DESC_RING 0x04 -#define BCM43xx_DMA_TX_DESC_INDEX 0x08 -#define BCM43xx_DMA_TX_STATUS 0x0c -#define BCM43xx_DMA_RX_CONTROL 0x10 -#define BCM43xx_DMA_RX_DESC_RING 0x14 -#define BCM43xx_DMA_RX_DESC_INDEX 0x18 -#define BCM43xx_DMA_RX_STATUS 0x1c - -/* DMA controller channel control word values. */ -#define BCM43xx_DMA_TXCTRL_ENABLE (1 << 0) -#define BCM43xx_DMA_TXCTRL_SUSPEND (1 << 1) -#define BCM43xx_DMA_TXCTRL_LOOPBACK (1 << 2) -#define BCM43xx_DMA_TXCTRL_FLUSH (1 << 4) -#define BCM43xx_DMA_RXCTRL_ENABLE (1 << 0) -#define BCM43xx_DMA_RXCTRL_FRAMEOFF_MASK 0x000000fe -#define BCM43xx_DMA_RXCTRL_FRAMEOFF_SHIFT 1 -#define BCM43xx_DMA_RXCTRL_PIO (1 << 8) -/* DMA controller channel status word values. */ -#define BCM43xx_DMA_TXSTAT_DPTR_MASK 0x00000fff -#define BCM43xx_DMA_TXSTAT_STAT_MASK 0x0000f000 -#define BCM43xx_DMA_TXSTAT_STAT_DISABLED 0x00000000 -#define BCM43xx_DMA_TXSTAT_STAT_ACTIVE 0x00001000 -#define BCM43xx_DMA_TXSTAT_STAT_IDLEWAIT 0x00002000 -#define BCM43xx_DMA_TXSTAT_STAT_STOPPED 0x00003000 -#define BCM43xx_DMA_TXSTAT_STAT_SUSP 0x00004000 -#define BCM43xx_DMA_TXSTAT_ERROR_MASK 0x000f0000 -#define BCM43xx_DMA_TXSTAT_FLUSHED (1 << 20) -#define BCM43xx_DMA_RXSTAT_DPTR_MASK 0x00000fff -#define BCM43xx_DMA_RXSTAT_STAT_MASK 0x0000f000 -#define BCM43xx_DMA_RXSTAT_STAT_DISABLED 0x00000000 -#define BCM43xx_DMA_RXSTAT_STAT_ACTIVE 0x00001000 -#define BCM43xx_DMA_RXSTAT_STAT_IDLEWAIT 0x00002000 -#define BCM43xx_DMA_RXSTAT_STAT_RESERVED 0x00003000 -#define BCM43xx_DMA_RXSTAT_STAT_ERRORS 0x00004000 -#define BCM43xx_DMA_RXSTAT_ERROR_MASK 0x000f0000 - -/* DMA descriptor control field values. */ -#define BCM43xx_DMADTOR_BYTECNT_MASK 0x00001fff -#define BCM43xx_DMADTOR_DTABLEEND (1 << 28) /* End of descriptor table */ -#define BCM43xx_DMADTOR_COMPIRQ (1 << 29) /* IRQ on completion request */ -#define BCM43xx_DMADTOR_FRAMEEND (1 << 30) -#define BCM43xx_DMADTOR_FRAMESTART (1 << 31) - -/* Misc DMA constants */ -#define BCM43xx_DMA_RINGMEMSIZE PAGE_SIZE -#define BCM43xx_DMA_BUSADDRMAX 0x3FFFFFFF -#define BCM43xx_DMA_DMABUSADDROFFSET (1 << 30) -#define BCM43xx_DMA1_RX_FRAMEOFFSET 30 -#define BCM43xx_DMA4_RX_FRAMEOFFSET 0 - -/* DMA engine tuning knobs */ -#define BCM43xx_TXRING_SLOTS 512 -#define BCM43xx_RXRING_SLOTS 64 -#define BCM43xx_DMA1_RXBUFFERSIZE (2304 + 100) -#define BCM43xx_DMA4_RXBUFFERSIZE 16 -/* Suspend the tx queue, if less than this percent slots are free. */ -#define BCM43xx_TXSUSPEND_PERCENT 20 -/* Resume the tx queue, if more than this percent slots are free. */ -#define BCM43xx_TXRESUME_PERCENT 50 - - - -#ifdef CONFIG_BCM43XX_DMA - - -struct sk_buff; -struct bcm43xx_private; -struct bcm43xx_xmitstatus; - - -struct bcm43xx_dmadesc { - __le32 _control; - __le32 _address; -} __attribute__((__packed__)); - -/* Macros to access the bcm43xx_dmadesc struct */ -#define get_desc_ctl(desc) le32_to_cpu((desc)->_control) -#define set_desc_ctl(desc, ctl) do { (desc)->_control = cpu_to_le32(ctl); } while (0) -#define get_desc_addr(desc) le32_to_cpu((desc)->_address) -#define set_desc_addr(desc, addr) do { (desc)->_address = cpu_to_le32(addr); } while (0) - -struct bcm43xx_dmadesc_meta { - /* The kernel DMA-able buffer. */ - struct sk_buff *skb; - /* DMA base bus-address of the descriptor buffer. */ - dma_addr_t dmaaddr; -}; - -struct bcm43xx_dmaring { - struct bcm43xx_private *bcm; - /* Kernel virtual base address of the ring memory. */ - struct bcm43xx_dmadesc *vbase; - /* DMA memory offset */ - dma_addr_t memoffset; - /* (Unadjusted) DMA base bus-address of the ring memory. */ - dma_addr_t dmabase; - /* Meta data about all descriptors. */ - struct bcm43xx_dmadesc_meta *meta; - /* Number of descriptor slots in the ring. */ - int nr_slots; - /* Number of used descriptor slots. */ - int used_slots; - /* Currently used slot in the ring. */ - int current_slot; - /* Marks to suspend/resume the queue. */ - int suspend_mark; - int resume_mark; - /* Frameoffset in octets. */ - u32 frameoffset; - /* Descriptor buffer size. */ - u16 rx_buffersize; - /* The MMIO base register of the DMA controller, this - * ring is posted to. - */ - u16 mmio_base; - u8 tx:1, /* TRUE, if this is a TX ring. */ - suspended:1; /* TRUE, if transfers are suspended on this ring. */ -#ifdef CONFIG_BCM43XX_DEBUG - /* Maximum number of used slots. */ - int max_used_slots; -#endif /* CONFIG_BCM43XX_DEBUG*/ -}; - - -static inline -u32 bcm43xx_dma_read(struct bcm43xx_dmaring *ring, - u16 offset) -{ - return bcm43xx_read32(ring->bcm, ring->mmio_base + offset); -} - -static inline -void bcm43xx_dma_write(struct bcm43xx_dmaring *ring, - u16 offset, u32 value) -{ - bcm43xx_write32(ring->bcm, ring->mmio_base + offset, value); -} - - -int bcm43xx_dma_init(struct bcm43xx_private *bcm); -void bcm43xx_dma_free(struct bcm43xx_private *bcm); - -int bcm43xx_dmacontroller_rx_reset(struct bcm43xx_private *bcm, - u16 dmacontroller_mmio_base); -int bcm43xx_dmacontroller_tx_reset(struct bcm43xx_private *bcm, - u16 dmacontroller_mmio_base); - -void bcm43xx_dma_tx_suspend(struct bcm43xx_dmaring *ring); -void bcm43xx_dma_tx_resume(struct bcm43xx_dmaring *ring); - -void bcm43xx_dma_handle_xmitstatus(struct bcm43xx_private *bcm, - struct bcm43xx_xmitstatus *status); - -int bcm43xx_dma_tx(struct bcm43xx_private *bcm, - struct ieee80211_txb *txb); -void bcm43xx_dma_rx(struct bcm43xx_dmaring *ring); - - -#else /* CONFIG_BCM43XX_DMA */ - - -static inline -int bcm43xx_dma_init(struct bcm43xx_private *bcm) -{ - return 0; -} -static inline -void bcm43xx_dma_free(struct bcm43xx_private *bcm) -{ -} -static inline -int bcm43xx_dmacontroller_rx_reset(struct bcm43xx_private *bcm, - u16 dmacontroller_mmio_base) -{ - return 0; -} -static inline -int bcm43xx_dmacontroller_tx_reset(struct bcm43xx_private *bcm, - u16 dmacontroller_mmio_base) -{ - return 0; -} -static inline -int bcm43xx_dma_tx(struct bcm43xx_private *bcm, - struct ieee80211_txb *txb) -{ - return 0; -} -static inline -void bcm43xx_dma_handle_xmitstatus(struct bcm43xx_private *bcm, - struct bcm43xx_xmitstatus *status) -{ -} -static inline -void bcm43xx_dma_rx(struct bcm43xx_dmaring *ring) -{ -} - -#endif /* CONFIG_BCM43XX_DMA */ -#endif /* BCM43xx_DMA_H_ */ diff --git a/trunk/drivers/net/wireless/bcm43xx/bcm43xx_ethtool.c b/trunk/drivers/net/wireless/bcm43xx/bcm43xx_ethtool.c deleted file mode 100644 index b3ffcf501311..000000000000 --- a/trunk/drivers/net/wireless/bcm43xx/bcm43xx_ethtool.c +++ /dev/null @@ -1,50 +0,0 @@ -/* - - Broadcom BCM43xx wireless driver - - ethtool support - - Copyright (c) 2006 Jason Lunz - - Some code in this file is derived from the 8139too.c driver - Copyright (C) 2002 Jeff Garzik - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; see the file COPYING. If not, write to - the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor, - Boston, MA 02110-1301, USA. - -*/ - -#include "bcm43xx.h" -#include "bcm43xx_ethtool.h" - -#include -#include -#include -#include - - -static void bcm43xx_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) -{ - struct bcm43xx_private *bcm = bcm43xx_priv(dev); - - strncpy(info->driver, KBUILD_MODNAME, sizeof(info->driver)); - strncpy(info->version, UTS_RELEASE, sizeof(info->version)); - strncpy(info->bus_info, pci_name(bcm->pci_dev), ETHTOOL_BUSINFO_LEN); -} - -struct ethtool_ops bcm43xx_ethtool_ops = { - .get_drvinfo = bcm43xx_get_drvinfo, - .get_link = ethtool_op_get_link, -}; diff --git a/trunk/drivers/net/wireless/bcm43xx/bcm43xx_ethtool.h b/trunk/drivers/net/wireless/bcm43xx/bcm43xx_ethtool.h deleted file mode 100644 index 813704991f62..000000000000 --- a/trunk/drivers/net/wireless/bcm43xx/bcm43xx_ethtool.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef BCM43xx_ETHTOOL_H_ -#define BCM43xx_ETHTOOL_H_ - -#include - -extern struct ethtool_ops bcm43xx_ethtool_ops; - -#endif /* BCM43xx_ETHTOOL_H_ */ diff --git a/trunk/drivers/net/wireless/bcm43xx/bcm43xx_ilt.c b/trunk/drivers/net/wireless/bcm43xx/bcm43xx_ilt.c deleted file mode 100644 index ad8e569d1faf..000000000000 --- a/trunk/drivers/net/wireless/bcm43xx/bcm43xx_ilt.c +++ /dev/null @@ -1,337 +0,0 @@ -/* - - Broadcom BCM43xx wireless driver - - Copyright (c) 2005 Martin Langer , - Stefano Brivio - Michael Buesch - Danny van Dyk - Andreas Jaggi - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; see the file COPYING. If not, write to - the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor, - Boston, MA 02110-1301, USA. - -*/ - -#include "bcm43xx.h" -#include "bcm43xx_ilt.h" -#include "bcm43xx_phy.h" - - -/**** Initial Internal Lookup Tables ****/ - -const u32 bcm43xx_ilt_rotor[BCM43xx_ILT_ROTOR_SIZE] = { - 0xFEB93FFD, 0xFEC63FFD, /* 0 */ - 0xFED23FFD, 0xFEDF3FFD, - 0xFEEC3FFE, 0xFEF83FFE, - 0xFF053FFE, 0xFF113FFE, - 0xFF1E3FFE, 0xFF2A3FFF, /* 8 */ - 0xFF373FFF, 0xFF443FFF, - 0xFF503FFF, 0xFF5D3FFF, - 0xFF693FFF, 0xFF763FFF, - 0xFF824000, 0xFF8F4000, /* 16 */ - 0xFF9B4000, 0xFFA84000, - 0xFFB54000, 0xFFC14000, - 0xFFCE4000, 0xFFDA4000, - 0xFFE74000, 0xFFF34000, /* 24 */ - 0x00004000, 0x000D4000, - 0x00194000, 0x00264000, - 0x00324000, 0x003F4000, - 0x004B4000, 0x00584000, /* 32 */ - 0x00654000, 0x00714000, - 0x007E4000, 0x008A3FFF, - 0x00973FFF, 0x00A33FFF, - 0x00B03FFF, 0x00BC3FFF, /* 40 */ - 0x00C93FFF, 0x00D63FFF, - 0x00E23FFE, 0x00EF3FFE, - 0x00FB3FFE, 0x01083FFE, - 0x01143FFE, 0x01213FFD, /* 48 */ - 0x012E3FFD, 0x013A3FFD, - 0x01473FFD, -}; - -const u32 bcm43xx_ilt_retard[BCM43xx_ILT_RETARD_SIZE] = { - 0xDB93CB87, 0xD666CF64, /* 0 */ - 0xD1FDD358, 0xCDA6D826, - 0xCA38DD9F, 0xC729E2B4, - 0xC469E88E, 0xC26AEE2B, - 0xC0DEF46C, 0xC073FA62, /* 8 */ - 0xC01D00D5, 0xC0760743, - 0xC1560D1E, 0xC2E51369, - 0xC4ED18FF, 0xC7AC1ED7, - 0xCB2823B2, 0xCEFA28D9, /* 16 */ - 0xD2F62D3F, 0xD7BB3197, - 0xDCE53568, 0xE1FE3875, - 0xE7D13B35, 0xED663D35, - 0xF39B3EC4, 0xF98E3FA7, /* 24 */ - 0x00004000, 0x06723FA7, - 0x0C653EC4, 0x129A3D35, - 0x182F3B35, 0x1E023875, - 0x231B3568, 0x28453197, /* 32 */ - 0x2D0A2D3F, 0x310628D9, - 0x34D823B2, 0x38541ED7, - 0x3B1318FF, 0x3D1B1369, - 0x3EAA0D1E, 0x3F8A0743, /* 40 */ - 0x3FE300D5, 0x3F8DFA62, - 0x3F22F46C, 0x3D96EE2B, - 0x3B97E88E, 0x38D7E2B4, - 0x35C8DD9F, 0x325AD826, /* 48 */ - 0x2E03D358, 0x299ACF64, - 0x246DCB87, -}; - -const u16 bcm43xx_ilt_finefreqa[BCM43xx_ILT_FINEFREQA_SIZE] = { - 0x0082, 0x0082, 0x0102, 0x0182, /* 0 */ - 0x0202, 0x0282, 0x0302, 0x0382, - 0x0402, 0x0482, 0x0502, 0x0582, - 0x05E2, 0x0662, 0x06E2, 0x0762, - 0x07E2, 0x0842, 0x08C2, 0x0942, /* 16 */ - 0x09C2, 0x0A22, 0x0AA2, 0x0B02, - 0x0B82, 0x0BE2, 0x0C62, 0x0CC2, - 0x0D42, 0x0DA2, 0x0E02, 0x0E62, - 0x0EE2, 0x0F42, 0x0FA2, 0x1002, /* 32 */ - 0x1062, 0x10C2, 0x1122, 0x1182, - 0x11E2, 0x1242, 0x12A2, 0x12E2, - 0x1342, 0x13A2, 0x1402, 0x1442, - 0x14A2, 0x14E2, 0x1542, 0x1582, /* 48 */ - 0x15E2, 0x1622, 0x1662, 0x16C1, - 0x1701, 0x1741, 0x1781, 0x17E1, - 0x1821, 0x1861, 0x18A1, 0x18E1, - 0x1921, 0x1961, 0x19A1, 0x19E1, /* 64 */ - 0x1A21, 0x1A61, 0x1AA1, 0x1AC1, - 0x1B01, 0x1B41, 0x1B81, 0x1BA1, - 0x1BE1, 0x1C21, 0x1C41, 0x1C81, - 0x1CA1, 0x1CE1, 0x1D01, 0x1D41, /* 80 */ - 0x1D61, 0x1DA1, 0x1DC1, 0x1E01, - 0x1E21, 0x1E61, 0x1E81, 0x1EA1, - 0x1EE1, 0x1F01, 0x1F21, 0x1F41, - 0x1F81, 0x1FA1, 0x1FC1, 0x1FE1, /* 96 */ - 0x2001, 0x2041, 0x2061, 0x2081, - 0x20A1, 0x20C1, 0x20E1, 0x2101, - 0x2121, 0x2141, 0x2161, 0x2181, - 0x21A1, 0x21C1, 0x21E1, 0x2201, /* 112 */ - 0x2221, 0x2241, 0x2261, 0x2281, - 0x22A1, 0x22C1, 0x22C1, 0x22E1, - 0x2301, 0x2321, 0x2341, 0x2361, - 0x2361, 0x2381, 0x23A1, 0x23C1, /* 128 */ - 0x23E1, 0x23E1, 0x2401, 0x2421, - 0x2441, 0x2441, 0x2461, 0x2481, - 0x2481, 0x24A1, 0x24C1, 0x24C1, - 0x24E1, 0x2501, 0x2501, 0x2521, /* 144 */ - 0x2541, 0x2541, 0x2561, 0x2561, - 0x2581, 0x25A1, 0x25A1, 0x25C1, - 0x25C1, 0x25E1, 0x2601, 0x2601, - 0x2621, 0x2621, 0x2641, 0x2641, /* 160 */ - 0x2661, 0x2661, 0x2681, 0x2681, - 0x26A1, 0x26A1, 0x26C1, 0x26C1, - 0x26E1, 0x26E1, 0x2701, 0x2701, - 0x2721, 0x2721, 0x2740, 0x2740, /* 176 */ - 0x2760, 0x2760, 0x2780, 0x2780, - 0x2780, 0x27A0, 0x27A0, 0x27C0, - 0x27C0, 0x27E0, 0x27E0, 0x27E0, - 0x2800, 0x2800, 0x2820, 0x2820, /* 192 */ - 0x2820, 0x2840, 0x2840, 0x2840, - 0x2860, 0x2860, 0x2880, 0x2880, - 0x2880, 0x28A0, 0x28A0, 0x28A0, - 0x28C0, 0x28C0, 0x28C0, 0x28E0, /* 208 */ - 0x28E0, 0x28E0, 0x2900, 0x2900, - 0x2900, 0x2920, 0x2920, 0x2920, - 0x2940, 0x2940, 0x2940, 0x2960, - 0x2960, 0x2960, 0x2960, 0x2980, /* 224 */ - 0x2980, 0x2980, 0x29A0, 0x29A0, - 0x29A0, 0x29A0, 0x29C0, 0x29C0, - 0x29C0, 0x29E0, 0x29E0, 0x29E0, - 0x29E0, 0x2A00, 0x2A00, 0x2A00, /* 240 */ - 0x2A00, 0x2A20, 0x2A20, 0x2A20, - 0x2A20, 0x2A40, 0x2A40, 0x2A40, - 0x2A40, 0x2A60, 0x2A60, 0x2A60, -}; - -const u16 bcm43xx_ilt_finefreqg[BCM43xx_ILT_FINEFREQG_SIZE] = { - 0x0089, 0x02E9, 0x0409, 0x04E9, /* 0 */ - 0x05A9, 0x0669, 0x0709, 0x0789, - 0x0829, 0x08A9, 0x0929, 0x0989, - 0x0A09, 0x0A69, 0x0AC9, 0x0B29, - 0x0BA9, 0x0BE9, 0x0C49, 0x0CA9, /* 16 */ - 0x0D09, 0x0D69, 0x0DA9, 0x0E09, - 0x0E69, 0x0EA9, 0x0F09, 0x0F49, - 0x0FA9, 0x0FE9, 0x1029, 0x1089, - 0x10C9, 0x1109, 0x1169, 0x11A9, /* 32 */ - 0x11E9, 0x1229, 0x1289, 0x12C9, - 0x1309, 0x1349, 0x1389, 0x13C9, - 0x1409, 0x1449, 0x14A9, 0x14E9, - 0x1529, 0x1569, 0x15A9, 0x15E9, /* 48 */ - 0x1629, 0x1669, 0x16A9, 0x16E8, - 0x1728, 0x1768, 0x17A8, 0x17E8, - 0x1828, 0x1868, 0x18A8, 0x18E8, - 0x1928, 0x1968, 0x19A8, 0x19E8, /* 64 */ - 0x1A28, 0x1A68, 0x1AA8, 0x1AE8, - 0x1B28, 0x1B68, 0x1BA8, 0x1BE8, - 0x1C28, 0x1C68, 0x1CA8, 0x1CE8, - 0x1D28, 0x1D68, 0x1DC8, 0x1E08, /* 80 */ - 0x1E48, 0x1E88, 0x1EC8, 0x1F08, - 0x1F48, 0x1F88, 0x1FE8, 0x2028, - 0x2068, 0x20A8, 0x2108, 0x2148, - 0x2188, 0x21C8, 0x2228, 0x2268, /* 96 */ - 0x22C8, 0x2308, 0x2348, 0x23A8, - 0x23E8, 0x2448, 0x24A8, 0x24E8, - 0x2548, 0x25A8, 0x2608, 0x2668, - 0x26C8, 0x2728, 0x2787, 0x27E7, /* 112 */ - 0x2847, 0x28C7, 0x2947, 0x29A7, - 0x2A27, 0x2AC7, 0x2B47, 0x2BE7, - 0x2CA7, 0x2D67, 0x2E47, 0x2F67, - 0x3247, 0x3526, 0x3646, 0x3726, /* 128 */ - 0x3806, 0x38A6, 0x3946, 0x39E6, - 0x3A66, 0x3AE6, 0x3B66, 0x3BC6, - 0x3C45, 0x3CA5, 0x3D05, 0x3D85, - 0x3DE5, 0x3E45, 0x3EA5, 0x3EE5, /* 144 */ - 0x3F45, 0x3FA5, 0x4005, 0x4045, - 0x40A5, 0x40E5, 0x4145, 0x4185, - 0x41E5, 0x4225, 0x4265, 0x42C5, - 0x4305, 0x4345, 0x43A5, 0x43E5, /* 160 */ - 0x4424, 0x4464, 0x44C4, 0x4504, - 0x4544, 0x4584, 0x45C4, 0x4604, - 0x4644, 0x46A4, 0x46E4, 0x4724, - 0x4764, 0x47A4, 0x47E4, 0x4824, /* 176 */ - 0x4864, 0x48A4, 0x48E4, 0x4924, - 0x4964, 0x49A4, 0x49E4, 0x4A24, - 0x4A64, 0x4AA4, 0x4AE4, 0x4B23, - 0x4B63, 0x4BA3, 0x4BE3, 0x4C23, /* 192 */ - 0x4C63, 0x4CA3, 0x4CE3, 0x4D23, - 0x4D63, 0x4DA3, 0x4DE3, 0x4E23, - 0x4E63, 0x4EA3, 0x4EE3, 0x4F23, - 0x4F63, 0x4FC3, 0x5003, 0x5043, /* 208 */ - 0x5083, 0x50C3, 0x5103, 0x5143, - 0x5183, 0x51E2, 0x5222, 0x5262, - 0x52A2, 0x52E2, 0x5342, 0x5382, - 0x53C2, 0x5402, 0x5462, 0x54A2, /* 224 */ - 0x5502, 0x5542, 0x55A2, 0x55E2, - 0x5642, 0x5682, 0x56E2, 0x5722, - 0x5782, 0x57E1, 0x5841, 0x58A1, - 0x5901, 0x5961, 0x59C1, 0x5A21, /* 240 */ - 0x5AA1, 0x5B01, 0x5B81, 0x5BE1, - 0x5C61, 0x5D01, 0x5D80, 0x5E20, - 0x5EE0, 0x5FA0, 0x6080, 0x61C0, -}; - -const u16 bcm43xx_ilt_noisea2[BCM43xx_ILT_NOISEA2_SIZE] = { - 0x0001, 0x0001, 0x0001, 0xFFFE, - 0xFFFE, 0x3FFF, 0x1000, 0x0393, -}; - -const u16 bcm43xx_ilt_noisea3[BCM43xx_ILT_NOISEA3_SIZE] = { - 0x4C4C, 0x4C4C, 0x4C4C, 0x2D36, - 0x4C4C, 0x4C4C, 0x4C4C, 0x2D36, -}; - -const u16 bcm43xx_ilt_noiseg1[BCM43xx_ILT_NOISEG1_SIZE] = { - 0x013C, 0x01F5, 0x031A, 0x0631, - 0x0001, 0x0001, 0x0001, 0x0001, -}; - -const u16 bcm43xx_ilt_noiseg2[BCM43xx_ILT_NOISEG2_SIZE] = { - 0x5484, 0x3C40, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, -}; - -const u16 bcm43xx_ilt_noisescaleg1[BCM43xx_ILT_NOISESCALEG_SIZE] = { - 0x6C77, 0x5162, 0x3B40, 0x3335, /* 0 */ - 0x2F2D, 0x2A2A, 0x2527, 0x1F21, - 0x1A1D, 0x1719, 0x1616, 0x1414, - 0x1414, 0x1400, 0x1414, 0x1614, - 0x1716, 0x1A19, 0x1F1D, 0x2521, /* 16 */ - 0x2A27, 0x2F2A, 0x332D, 0x3B35, - 0x5140, 0x6C62, 0x0077, -}; - -const u16 bcm43xx_ilt_noisescaleg2[BCM43xx_ILT_NOISESCALEG_SIZE] = { - 0xD8DD, 0xCBD4, 0xBCC0, 0XB6B7, /* 0 */ - 0xB2B0, 0xADAD, 0xA7A9, 0x9FA1, - 0x969B, 0x9195, 0x8F8F, 0x8A8A, - 0x8A8A, 0x8A00, 0x8A8A, 0x8F8A, - 0x918F, 0x9695, 0x9F9B, 0xA7A1, /* 16 */ - 0xADA9, 0xB2AD, 0xB6B0, 0xBCB7, - 0xCBC0, 0xD8D4, 0x00DD, -}; - -const u16 bcm43xx_ilt_noisescaleg3[BCM43xx_ILT_NOISESCALEG_SIZE] = { - 0xA4A4, 0xA4A4, 0xA4A4, 0xA4A4, /* 0 */ - 0xA4A4, 0xA4A4, 0xA4A4, 0xA4A4, - 0xA4A4, 0xA4A4, 0xA4A4, 0xA4A4, - 0xA4A4, 0xA400, 0xA4A4, 0xA4A4, - 0xA4A4, 0xA4A4, 0xA4A4, 0xA4A4, /* 16 */ - 0xA4A4, 0xA4A4, 0xA4A4, 0xA4A4, - 0xA4A4, 0xA4A4, 0x00A4, -}; - -const u16 bcm43xx_ilt_sigmasqr1[BCM43xx_ILT_SIGMASQR_SIZE] = { - 0x007A, 0x0075, 0x0071, 0x006C, /* 0 */ - 0x0067, 0x0063, 0x005E, 0x0059, - 0x0054, 0x0050, 0x004B, 0x0046, - 0x0042, 0x003D, 0x003D, 0x003D, - 0x003D, 0x003D, 0x003D, 0x003D, /* 16 */ - 0x003D, 0x003D, 0x003D, 0x003D, - 0x003D, 0x003D, 0x0000, 0x003D, - 0x003D, 0x003D, 0x003D, 0x003D, - 0x003D, 0x003D, 0x003D, 0x003D, /* 32 */ - 0x003D, 0x003D, 0x003D, 0x003D, - 0x0042, 0x0046, 0x004B, 0x0050, - 0x0054, 0x0059, 0x005E, 0x0063, - 0x0067, 0x006C, 0x0071, 0x0075, /* 48 */ - 0x007A, -}; - -const u16 bcm43xx_ilt_sigmasqr2[BCM43xx_ILT_SIGMASQR_SIZE] = { - 0x00DE, 0x00DC, 0x00DA, 0x00D8, /* 0 */ - 0x00D6, 0x00D4, 0x00D2, 0x00CF, - 0x00CD, 0x00CA, 0x00C7, 0x00C4, - 0x00C1, 0x00BE, 0x00BE, 0x00BE, - 0x00BE, 0x00BE, 0x00BE, 0x00BE, /* 16 */ - 0x00BE, 0x00BE, 0x00BE, 0x00BE, - 0x00BE, 0x00BE, 0x0000, 0x00BE, - 0x00BE, 0x00BE, 0x00BE, 0x00BE, - 0x00BE, 0x00BE, 0x00BE, 0x00BE, /* 32 */ - 0x00BE, 0x00BE, 0x00BE, 0x00BE, - 0x00C1, 0x00C4, 0x00C7, 0x00CA, - 0x00CD, 0x00CF, 0x00D2, 0x00D4, - 0x00D6, 0x00D8, 0x00DA, 0x00DC, /* 48 */ - 0x00DE, -}; - -/**** Helper functions to access the device Internal Lookup Tables ****/ - -void bcm43xx_ilt_write(struct bcm43xx_private *bcm, u16 offset, u16 val) -{ - if (bcm43xx_current_phy(bcm)->type == BCM43xx_PHYTYPE_A) { - bcm43xx_phy_write(bcm, BCM43xx_PHY_ILT_A_CTRL, offset); - mmiowb(); - bcm43xx_phy_write(bcm, BCM43xx_PHY_ILT_A_DATA1, val); - } else { - bcm43xx_phy_write(bcm, BCM43xx_PHY_ILT_G_CTRL, offset); - mmiowb(); - bcm43xx_phy_write(bcm, BCM43xx_PHY_ILT_G_DATA1, val); - } -} - -u16 bcm43xx_ilt_read(struct bcm43xx_private *bcm, u16 offset) -{ - if (bcm43xx_current_phy(bcm)->type == BCM43xx_PHYTYPE_A) { - bcm43xx_phy_write(bcm, BCM43xx_PHY_ILT_A_CTRL, offset); - return bcm43xx_phy_read(bcm, BCM43xx_PHY_ILT_A_DATA1); - } else { - bcm43xx_phy_write(bcm, BCM43xx_PHY_ILT_G_CTRL, offset); - return bcm43xx_phy_read(bcm, BCM43xx_PHY_ILT_G_DATA1); - } -} diff --git a/trunk/drivers/net/wireless/bcm43xx/bcm43xx_ilt.h b/trunk/drivers/net/wireless/bcm43xx/bcm43xx_ilt.h deleted file mode 100644 index 464521abf73c..000000000000 --- a/trunk/drivers/net/wireless/bcm43xx/bcm43xx_ilt.h +++ /dev/null @@ -1,32 +0,0 @@ -#ifndef BCM43xx_ILT_H_ -#define BCM43xx_ILT_H_ - -#define BCM43xx_ILT_ROTOR_SIZE 53 -extern const u32 bcm43xx_ilt_rotor[BCM43xx_ILT_ROTOR_SIZE]; -#define BCM43xx_ILT_RETARD_SIZE 53 -extern const u32 bcm43xx_ilt_retard[BCM43xx_ILT_RETARD_SIZE]; -#define BCM43xx_ILT_FINEFREQA_SIZE 256 -extern const u16 bcm43xx_ilt_finefreqa[BCM43xx_ILT_FINEFREQA_SIZE]; -#define BCM43xx_ILT_FINEFREQG_SIZE 256 -extern const u16 bcm43xx_ilt_finefreqg[BCM43xx_ILT_FINEFREQG_SIZE]; -#define BCM43xx_ILT_NOISEA2_SIZE 8 -extern const u16 bcm43xx_ilt_noisea2[BCM43xx_ILT_NOISEA2_SIZE]; -#define BCM43xx_ILT_NOISEA3_SIZE 8 -extern const u16 bcm43xx_ilt_noisea3[BCM43xx_ILT_NOISEA3_SIZE]; -#define BCM43xx_ILT_NOISEG1_SIZE 8 -extern const u16 bcm43xx_ilt_noiseg1[BCM43xx_ILT_NOISEG1_SIZE]; -#define BCM43xx_ILT_NOISEG2_SIZE 8 -extern const u16 bcm43xx_ilt_noiseg2[BCM43xx_ILT_NOISEG2_SIZE]; -#define BCM43xx_ILT_NOISESCALEG_SIZE 27 -extern const u16 bcm43xx_ilt_noisescaleg1[BCM43xx_ILT_NOISESCALEG_SIZE]; -extern const u16 bcm43xx_ilt_noisescaleg2[BCM43xx_ILT_NOISESCALEG_SIZE]; -extern const u16 bcm43xx_ilt_noisescaleg3[BCM43xx_ILT_NOISESCALEG_SIZE]; -#define BCM43xx_ILT_SIGMASQR_SIZE 53 -extern const u16 bcm43xx_ilt_sigmasqr1[BCM43xx_ILT_SIGMASQR_SIZE]; -extern const u16 bcm43xx_ilt_sigmasqr2[BCM43xx_ILT_SIGMASQR_SIZE]; - - -void bcm43xx_ilt_write(struct bcm43xx_private *bcm, u16 offset, u16 val); -u16 bcm43xx_ilt_read(struct bcm43xx_private *bcm, u16 offset); - -#endif /* BCM43xx_ILT_H_ */ diff --git a/trunk/drivers/net/wireless/bcm43xx/bcm43xx_leds.c b/trunk/drivers/net/wireless/bcm43xx/bcm43xx_leds.c deleted file mode 100644 index 4b2c02c0b31e..000000000000 --- a/trunk/drivers/net/wireless/bcm43xx/bcm43xx_leds.c +++ /dev/null @@ -1,293 +0,0 @@ -/* - - Broadcom BCM43xx wireless driver - - Copyright (c) 2005 Martin Langer , - Stefano Brivio - Michael Buesch - Danny van Dyk - Andreas Jaggi - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; see the file COPYING. If not, write to - the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor, - Boston, MA 02110-1301, USA. - -*/ - -#include "bcm43xx_leds.h" -#include "bcm43xx.h" - -#include - - -static void bcm43xx_led_changestate(struct bcm43xx_led *led) -{ - struct bcm43xx_private *bcm = led->bcm; - const int index = bcm43xx_led_index(led); - const u16 mask = (1 << index); - u16 ledctl; - - assert(index >= 0 && index < BCM43xx_NR_LEDS); - assert(led->blink_interval); - ledctl = bcm43xx_read16(bcm, BCM43xx_MMIO_GPIO_CONTROL); - ledctl = (ledctl & mask) ? (ledctl & ~mask) : (ledctl | mask); - bcm43xx_write16(bcm, BCM43xx_MMIO_GPIO_CONTROL, ledctl); -} - -static void bcm43xx_led_blink(unsigned long d) -{ - struct bcm43xx_led *led = (struct bcm43xx_led *)d; - struct bcm43xx_private *bcm = led->bcm; - unsigned long flags; - - bcm43xx_lock_mmio(bcm, flags); - if (led->blink_interval) { - bcm43xx_led_changestate(led); - mod_timer(&led->blink_timer, jiffies + led->blink_interval); - } - bcm43xx_unlock_mmio(bcm, flags); -} - -static void bcm43xx_led_blink_start(struct bcm43xx_led *led, - unsigned long interval) -{ - if (led->blink_interval) - return; - led->blink_interval = interval; - bcm43xx_led_changestate(led); - led->blink_timer.expires = jiffies + interval; - add_timer(&led->blink_timer); -} - -static void bcm43xx_led_blink_stop(struct bcm43xx_led *led, int sync) -{ - struct bcm43xx_private *bcm = led->bcm; - const int index = bcm43xx_led_index(led); - u16 ledctl; - - if (!led->blink_interval) - return; - if (unlikely(sync)) - del_timer_sync(&led->blink_timer); - else - del_timer(&led->blink_timer); - led->blink_interval = 0; - - /* Make sure the LED is turned off. */ - assert(index >= 0 && index < BCM43xx_NR_LEDS); - ledctl = bcm43xx_read16(bcm, BCM43xx_MMIO_GPIO_CONTROL); - if (led->activelow) - ledctl |= (1 << index); - else - ledctl &= ~(1 << index); - bcm43xx_write16(bcm, BCM43xx_MMIO_GPIO_CONTROL, ledctl); -} - -static void bcm43xx_led_init_hardcoded(struct bcm43xx_private *bcm, - struct bcm43xx_led *led, - int led_index) -{ - /* This function is called, if the behaviour (and activelow) - * information for a LED is missing in the SPROM. - * We hardcode the behaviour values for various devices here. - * Note that the BCM43xx_LED_TEST_XXX behaviour values can - * be used to figure out which led is mapped to which index. - */ - - switch (led_index) { - case 0: - led->behaviour = BCM43xx_LED_ACTIVITY; - if (bcm->board_vendor == PCI_VENDOR_ID_COMPAQ) - led->behaviour = BCM43xx_LED_RADIO_ALL; - break; - case 1: - led->behaviour = BCM43xx_LED_RADIO_B; - if (bcm->board_vendor == PCI_VENDOR_ID_ASUSTEK) - led->behaviour = BCM43xx_LED_ASSOC; - break; - case 2: - led->behaviour = BCM43xx_LED_RADIO_A; - break; - case 3: - led->behaviour = BCM43xx_LED_OFF; - break; - default: - assert(0); - } -} - -int bcm43xx_leds_init(struct bcm43xx_private *bcm) -{ - struct bcm43xx_led *led; - u8 sprom[4]; - int i; - - sprom[0] = bcm->sprom.wl0gpio0; - sprom[1] = bcm->sprom.wl0gpio1; - sprom[2] = bcm->sprom.wl0gpio2; - sprom[3] = bcm->sprom.wl0gpio3; - - for (i = 0; i < BCM43xx_NR_LEDS; i++) { - led = &(bcm->leds[i]); - led->bcm = bcm; - setup_timer(&led->blink_timer, - bcm43xx_led_blink, - (unsigned long)led); - - if (sprom[i] == 0xFF) { - bcm43xx_led_init_hardcoded(bcm, led, i); - } else { - led->behaviour = sprom[i] & BCM43xx_LED_BEHAVIOUR; - led->activelow = !!(sprom[i] & BCM43xx_LED_ACTIVELOW); - } - } - - return 0; -} - -void bcm43xx_leds_exit(struct bcm43xx_private *bcm) -{ - struct bcm43xx_led *led; - int i; - - for (i = 0; i < BCM43xx_NR_LEDS; i++) { - led = &(bcm->leds[i]); - bcm43xx_led_blink_stop(led, 1); - } - bcm43xx_leds_switch_all(bcm, 0); -} - -void bcm43xx_leds_update(struct bcm43xx_private *bcm, int activity) -{ - struct bcm43xx_led *led; - struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm); - struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm); - const int transferring = (jiffies - bcm->stats.last_tx) < BCM43xx_LED_XFER_THRES; - int i, turn_on; - unsigned long interval = 0; - u16 ledctl; - - ledctl = bcm43xx_read16(bcm, BCM43xx_MMIO_GPIO_CONTROL); - for (i = 0; i < BCM43xx_NR_LEDS; i++) { - led = &(bcm->leds[i]); - - turn_on = 0; - switch (led->behaviour) { - case BCM43xx_LED_INACTIVE: - continue; - case BCM43xx_LED_OFF: - break; - case BCM43xx_LED_ON: - turn_on = 1; - break; - case BCM43xx_LED_ACTIVITY: - turn_on = activity; - break; - case BCM43xx_LED_RADIO_ALL: - turn_on = radio->enabled; - break; - case BCM43xx_LED_RADIO_A: - turn_on = (radio->enabled && phy->type == BCM43xx_PHYTYPE_A); - break; - case BCM43xx_LED_RADIO_B: - turn_on = (radio->enabled && - (phy->type == BCM43xx_PHYTYPE_B || - phy->type == BCM43xx_PHYTYPE_G)); - break; - case BCM43xx_LED_MODE_BG: - if (phy->type == BCM43xx_PHYTYPE_G && - 1/*FIXME: using G rates.*/) - turn_on = 1; - break; - case BCM43xx_LED_TRANSFER: - if (transferring) - bcm43xx_led_blink_start(led, BCM43xx_LEDBLINK_MEDIUM); - else - bcm43xx_led_blink_stop(led, 0); - continue; - case BCM43xx_LED_APTRANSFER: - if (bcm->ieee->iw_mode == IW_MODE_MASTER) { - if (transferring) { - interval = BCM43xx_LEDBLINK_FAST; - turn_on = 1; - } - } else { - turn_on = 1; - if (0/*TODO: not assoc*/) - interval = BCM43xx_LEDBLINK_SLOW; - else if (transferring) - interval = BCM43xx_LEDBLINK_FAST; - else - turn_on = 0; - } - if (turn_on) - bcm43xx_led_blink_start(led, interval); - else - bcm43xx_led_blink_stop(led, 0); - continue; - case BCM43xx_LED_WEIRD: - //TODO - break; - case BCM43xx_LED_ASSOC: - if (bcm->softmac->associated) - turn_on = 1; - break; -#ifdef CONFIG_BCM43XX_DEBUG - case BCM43xx_LED_TEST_BLINKSLOW: - bcm43xx_led_blink_start(led, BCM43xx_LEDBLINK_SLOW); - continue; - case BCM43xx_LED_TEST_BLINKMEDIUM: - bcm43xx_led_blink_start(led, BCM43xx_LEDBLINK_MEDIUM); - continue; - case BCM43xx_LED_TEST_BLINKFAST: - bcm43xx_led_blink_start(led, BCM43xx_LEDBLINK_FAST); - continue; -#endif /* CONFIG_BCM43XX_DEBUG */ - default: - assert(0); - }; - - if (led->activelow) - turn_on = !turn_on; - if (turn_on) - ledctl |= (1 << i); - else - ledctl &= ~(1 << i); - } - bcm43xx_write16(bcm, BCM43xx_MMIO_GPIO_CONTROL, ledctl); -} - -void bcm43xx_leds_switch_all(struct bcm43xx_private *bcm, int on) -{ - struct bcm43xx_led *led; - u16 ledctl; - int i; - int bit_on; - - ledctl = bcm43xx_read16(bcm, BCM43xx_MMIO_GPIO_CONTROL); - for (i = 0; i < BCM43xx_NR_LEDS; i++) { - led = &(bcm->leds[i]); - if (led->behaviour == BCM43xx_LED_INACTIVE) - continue; - if (on) - bit_on = led->activelow ? 0 : 1; - else - bit_on = led->activelow ? 1 : 0; - if (bit_on) - ledctl |= (1 << i); - else - ledctl &= ~(1 << i); - } - bcm43xx_write16(bcm, BCM43xx_MMIO_GPIO_CONTROL, ledctl); -} diff --git a/trunk/drivers/net/wireless/bcm43xx/bcm43xx_leds.h b/trunk/drivers/net/wireless/bcm43xx/bcm43xx_leds.h deleted file mode 100644 index d3716cf3aebc..000000000000 --- a/trunk/drivers/net/wireless/bcm43xx/bcm43xx_leds.h +++ /dev/null @@ -1,56 +0,0 @@ -#ifndef BCM43xx_LEDS_H_ -#define BCM43xx_LEDS_H_ - -#include -#include - - -struct bcm43xx_led { - u8 behaviour:7; - u8 activelow:1; - - struct bcm43xx_private *bcm; - struct timer_list blink_timer; - unsigned long blink_interval; -}; -#define bcm43xx_led_index(led) ((int)((led) - (led)->bcm->leds)) - -/* Delay between state changes when blinking in jiffies */ -#define BCM43xx_LEDBLINK_SLOW (HZ / 1) -#define BCM43xx_LEDBLINK_MEDIUM (HZ / 4) -#define BCM43xx_LEDBLINK_FAST (HZ / 8) - -#define BCM43xx_LED_XFER_THRES (HZ / 100) - -#define BCM43xx_LED_BEHAVIOUR 0x7F -#define BCM43xx_LED_ACTIVELOW 0x80 -enum { /* LED behaviour values */ - BCM43xx_LED_OFF, - BCM43xx_LED_ON, - BCM43xx_LED_ACTIVITY, - BCM43xx_LED_RADIO_ALL, - BCM43xx_LED_RADIO_A, - BCM43xx_LED_RADIO_B, - BCM43xx_LED_MODE_BG, - BCM43xx_LED_TRANSFER, - BCM43xx_LED_APTRANSFER, - BCM43xx_LED_WEIRD,//FIXME - BCM43xx_LED_ASSOC, - BCM43xx_LED_INACTIVE, - - /* Behaviour values for testing. - * With these values it is easier to figure out - * the real behaviour of leds, in case the SPROM - * is missing information. - */ - BCM43xx_LED_TEST_BLINKSLOW, - BCM43xx_LED_TEST_BLINKMEDIUM, - BCM43xx_LED_TEST_BLINKFAST, -}; - -int bcm43xx_leds_init(struct bcm43xx_private *bcm); -void bcm43xx_leds_exit(struct bcm43xx_private *bcm); -void bcm43xx_leds_update(struct bcm43xx_private *bcm, int activity); -void bcm43xx_leds_switch_all(struct bcm43xx_private *bcm, int on); - -#endif /* BCM43xx_LEDS_H_ */ diff --git a/trunk/drivers/net/wireless/bcm43xx/bcm43xx_main.c b/trunk/drivers/net/wireless/bcm43xx/bcm43xx_main.c deleted file mode 100644 index c37371fc9e01..000000000000 --- a/trunk/drivers/net/wireless/bcm43xx/bcm43xx_main.c +++ /dev/null @@ -1,3973 +0,0 @@ -/* - - Broadcom BCM43xx wireless driver - - Copyright (c) 2005 Martin Langer , - Stefano Brivio - Michael Buesch - Danny van Dyk - Andreas Jaggi - - Some parts of the code in this file are derived from the ipw2200 - driver Copyright(c) 2003 - 2004 Intel Corporation. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; see the file COPYING. If not, write to - the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor, - Boston, MA 02110-1301, USA. - -*/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "bcm43xx.h" -#include "bcm43xx_main.h" -#include "bcm43xx_debugfs.h" -#include "bcm43xx_radio.h" -#include "bcm43xx_phy.h" -#include "bcm43xx_dma.h" -#include "bcm43xx_pio.h" -#include "bcm43xx_power.h" -#include "bcm43xx_wx.h" -#include "bcm43xx_ethtool.h" -#include "bcm43xx_xmit.h" - - -MODULE_DESCRIPTION("Broadcom BCM43xx wireless driver"); -MODULE_AUTHOR("Martin Langer"); -MODULE_AUTHOR("Stefano Brivio"); -MODULE_AUTHOR("Michael Buesch"); -MODULE_LICENSE("GPL"); - -#ifdef CONFIG_BCM947XX -extern char *nvram_get(char *name); -#endif - -#if defined(CONFIG_BCM43XX_DMA) && defined(CONFIG_BCM43XX_PIO) -static int modparam_pio; -module_param_named(pio, modparam_pio, int, 0444); -MODULE_PARM_DESC(pio, "enable(1) / disable(0) PIO mode"); -#elif defined(CONFIG_BCM43XX_DMA) -# define modparam_pio 0 -#elif defined(CONFIG_BCM43XX_PIO) -# define modparam_pio 1 -#endif - -static int modparam_bad_frames_preempt; -module_param_named(bad_frames_preempt, modparam_bad_frames_preempt, int, 0444); -MODULE_PARM_DESC(bad_frames_preempt, "enable(1) / disable(0) Bad Frames Preemption"); - -static int modparam_short_retry = BCM43xx_DEFAULT_SHORT_RETRY_LIMIT; -module_param_named(short_retry, modparam_short_retry, int, 0444); -MODULE_PARM_DESC(short_retry, "Short-Retry-Limit (0 - 15)"); - -static int modparam_long_retry = BCM43xx_DEFAULT_LONG_RETRY_LIMIT; -module_param_named(long_retry, modparam_long_retry, int, 0444); -MODULE_PARM_DESC(long_retry, "Long-Retry-Limit (0 - 15)"); - -static int modparam_locale = -1; -module_param_named(locale, modparam_locale, int, 0444); -MODULE_PARM_DESC(country, "Select LocaleCode 0-11 (For travelers)"); - -static int modparam_noleds; -module_param_named(noleds, modparam_noleds, int, 0444); -MODULE_PARM_DESC(noleds, "Turn off all LED activity"); - -#ifdef CONFIG_BCM43XX_DEBUG -static char modparam_fwpostfix[64]; -module_param_string(fwpostfix, modparam_fwpostfix, 64, 0444); -MODULE_PARM_DESC(fwpostfix, "Postfix for .fw files. Useful for debugging."); -#else -# define modparam_fwpostfix "" -#endif /* CONFIG_BCM43XX_DEBUG*/ - - -/* If you want to debug with just a single device, enable this, - * where the string is the pci device ID (as given by the kernel's - * pci_name function) of the device to be used. - */ -//#define DEBUG_SINGLE_DEVICE_ONLY "0001:11:00.0" - -/* If you want to enable printing of each MMIO access, enable this. */ -//#define DEBUG_ENABLE_MMIO_PRINT - -/* If you want to enable printing of MMIO access within - * ucode/pcm upload, initvals write, enable this. - */ -//#define DEBUG_ENABLE_UCODE_MMIO_PRINT - -/* If you want to enable printing of PCI Config Space access, enable this */ -//#define DEBUG_ENABLE_PCILOG - - -/* Detailed list maintained at: - * http://openfacts.berlios.de/index-en.phtml?title=Bcm43xxDevices - */ - static struct pci_device_id bcm43xx_pci_tbl[] = { - /* Broadcom 4303 802.11b */ - { PCI_VENDOR_ID_BROADCOM, 0x4301, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, - /* Broadcom 4307 802.11b */ - { PCI_VENDOR_ID_BROADCOM, 0x4307, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, - /* Broadcom 4318 802.11b/g */ - { PCI_VENDOR_ID_BROADCOM, 0x4318, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, - /* Broadcom 4306 802.11b/g */ - { PCI_VENDOR_ID_BROADCOM, 0x4320, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, - /* Broadcom 4306 802.11a */ -// { PCI_VENDOR_ID_BROADCOM, 0x4321, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, - /* Broadcom 4309 802.11a/b/g */ - { PCI_VENDOR_ID_BROADCOM, 0x4324, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, - /* Broadcom 43XG 802.11b/g */ - { PCI_VENDOR_ID_BROADCOM, 0x4325, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, -#ifdef CONFIG_BCM947XX - /* SB bus on BCM947xx */ - { PCI_VENDOR_ID_BROADCOM, 0x0800, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, -#endif - { 0 }, -}; -MODULE_DEVICE_TABLE(pci, bcm43xx_pci_tbl); - -static void bcm43xx_ram_write(struct bcm43xx_private *bcm, u16 offset, u32 val) -{ - u32 status; - - status = bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD); - if (!(status & BCM43xx_SBF_XFER_REG_BYTESWAP)) - val = swab32(val); - - bcm43xx_write32(bcm, BCM43xx_MMIO_RAM_CONTROL, offset); - mmiowb(); - bcm43xx_write32(bcm, BCM43xx_MMIO_RAM_DATA, val); -} - -static inline -void bcm43xx_shm_control_word(struct bcm43xx_private *bcm, - u16 routing, u16 offset) -{ - u32 control; - - /* "offset" is the WORD offset. */ - - control = routing; - control <<= 16; - control |= offset; - bcm43xx_write32(bcm, BCM43xx_MMIO_SHM_CONTROL, control); -} - -u32 bcm43xx_shm_read32(struct bcm43xx_private *bcm, - u16 routing, u16 offset) -{ - u32 ret; - - if (routing == BCM43xx_SHM_SHARED) { - if (offset & 0x0003) { - /* Unaligned access */ - bcm43xx_shm_control_word(bcm, routing, offset >> 2); - ret = bcm43xx_read16(bcm, BCM43xx_MMIO_SHM_DATA_UNALIGNED); - ret <<= 16; - bcm43xx_shm_control_word(bcm, routing, (offset >> 2) + 1); - ret |= bcm43xx_read16(bcm, BCM43xx_MMIO_SHM_DATA); - - return ret; - } - offset >>= 2; - } - bcm43xx_shm_control_word(bcm, routing, offset); - ret = bcm43xx_read32(bcm, BCM43xx_MMIO_SHM_DATA); - - return ret; -} - -u16 bcm43xx_shm_read16(struct bcm43xx_private *bcm, - u16 routing, u16 offset) -{ - u16 ret; - - if (routing == BCM43xx_SHM_SHARED) { - if (offset & 0x0003) { - /* Unaligned access */ - bcm43xx_shm_control_word(bcm, routing, offset >> 2); - ret = bcm43xx_read16(bcm, BCM43xx_MMIO_SHM_DATA_UNALIGNED); - - return ret; - } - offset >>= 2; - } - bcm43xx_shm_control_word(bcm, routing, offset); - ret = bcm43xx_read16(bcm, BCM43xx_MMIO_SHM_DATA); - - return ret; -} - -void bcm43xx_shm_write32(struct bcm43xx_private *bcm, - u16 routing, u16 offset, - u32 value) -{ - if (routing == BCM43xx_SHM_SHARED) { - if (offset & 0x0003) { - /* Unaligned access */ - bcm43xx_shm_control_word(bcm, routing, offset >> 2); - mmiowb(); - bcm43xx_write16(bcm, BCM43xx_MMIO_SHM_DATA_UNALIGNED, - (value >> 16) & 0xffff); - mmiowb(); - bcm43xx_shm_control_word(bcm, routing, (offset >> 2) + 1); - mmiowb(); - bcm43xx_write16(bcm, BCM43xx_MMIO_SHM_DATA, - value & 0xffff); - return; - } - offset >>= 2; - } - bcm43xx_shm_control_word(bcm, routing, offset); - mmiowb(); - bcm43xx_write32(bcm, BCM43xx_MMIO_SHM_DATA, value); -} - -void bcm43xx_shm_write16(struct bcm43xx_private *bcm, - u16 routing, u16 offset, - u16 value) -{ - if (routing == BCM43xx_SHM_SHARED) { - if (offset & 0x0003) { - /* Unaligned access */ - bcm43xx_shm_control_word(bcm, routing, offset >> 2); - mmiowb(); - bcm43xx_write16(bcm, BCM43xx_MMIO_SHM_DATA_UNALIGNED, - value); - return; - } - offset >>= 2; - } - bcm43xx_shm_control_word(bcm, routing, offset); - mmiowb(); - bcm43xx_write16(bcm, BCM43xx_MMIO_SHM_DATA, value); -} - -void bcm43xx_tsf_read(struct bcm43xx_private *bcm, u64 *tsf) -{ - /* We need to be careful. As we read the TSF from multiple - * registers, we should take care of register overflows. - * In theory, the whole tsf read process should be atomic. - * We try to be atomic here, by restaring the read process, - * if any of the high registers changed (overflew). - */ - if (bcm->current_core->rev >= 3) { - u32 low, high, high2; - - do { - high = bcm43xx_read32(bcm, BCM43xx_MMIO_REV3PLUS_TSF_HIGH); - low = bcm43xx_read32(bcm, BCM43xx_MMIO_REV3PLUS_TSF_LOW); - high2 = bcm43xx_read32(bcm, BCM43xx_MMIO_REV3PLUS_TSF_HIGH); - } while (unlikely(high != high2)); - - *tsf = high; - *tsf <<= 32; - *tsf |= low; - } else { - u64 tmp; - u16 v0, v1, v2, v3; - u16 test1, test2, test3; - - do { - v3 = bcm43xx_read16(bcm, BCM43xx_MMIO_TSF_3); - v2 = bcm43xx_read16(bcm, BCM43xx_MMIO_TSF_2); - v1 = bcm43xx_read16(bcm, BCM43xx_MMIO_TSF_1); - v0 = bcm43xx_read16(bcm, BCM43xx_MMIO_TSF_0); - - test3 = bcm43xx_read16(bcm, BCM43xx_MMIO_TSF_3); - test2 = bcm43xx_read16(bcm, BCM43xx_MMIO_TSF_2); - test1 = bcm43xx_read16(bcm, BCM43xx_MMIO_TSF_1); - } while (v3 != test3 || v2 != test2 || v1 != test1); - - *tsf = v3; - *tsf <<= 48; - tmp = v2; - tmp <<= 32; - *tsf |= tmp; - tmp = v1; - tmp <<= 16; - *tsf |= tmp; - *tsf |= v0; - } -} - -void bcm43xx_tsf_write(struct bcm43xx_private *bcm, u64 tsf) -{ - u32 status; - - status = bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD); - status |= BCM43xx_SBF_TIME_UPDATE; - bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD, status); - mmiowb(); - - /* Be careful with the in-progress timer. - * First zero out the low register, so we have a full - * register-overflow duration to complete the operation. - */ - if (bcm->current_core->rev >= 3) { - u32 lo = (tsf & 0x00000000FFFFFFFFULL); - u32 hi = (tsf & 0xFFFFFFFF00000000ULL) >> 32; - - bcm43xx_write32(bcm, BCM43xx_MMIO_REV3PLUS_TSF_LOW, 0); - mmiowb(); - bcm43xx_write32(bcm, BCM43xx_MMIO_REV3PLUS_TSF_HIGH, hi); - mmiowb(); - bcm43xx_write32(bcm, BCM43xx_MMIO_REV3PLUS_TSF_LOW, lo); - } else { - u16 v0 = (tsf & 0x000000000000FFFFULL); - u16 v1 = (tsf & 0x00000000FFFF0000ULL) >> 16; - u16 v2 = (tsf & 0x0000FFFF00000000ULL) >> 32; - u16 v3 = (tsf & 0xFFFF000000000000ULL) >> 48; - - bcm43xx_write16(bcm, BCM43xx_MMIO_TSF_0, 0); - mmiowb(); - bcm43xx_write16(bcm, BCM43xx_MMIO_TSF_3, v3); - mmiowb(); - bcm43xx_write16(bcm, BCM43xx_MMIO_TSF_2, v2); - mmiowb(); - bcm43xx_write16(bcm, BCM43xx_MMIO_TSF_1, v1); - mmiowb(); - bcm43xx_write16(bcm, BCM43xx_MMIO_TSF_0, v0); - } - - status = bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD); - status &= ~BCM43xx_SBF_TIME_UPDATE; - bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD, status); -} - -static -void bcm43xx_macfilter_set(struct bcm43xx_private *bcm, - u16 offset, - const u8 *mac) -{ - u16 data; - - offset |= 0x0020; - bcm43xx_write16(bcm, BCM43xx_MMIO_MACFILTER_CONTROL, offset); - - data = mac[0]; - data |= mac[1] << 8; - bcm43xx_write16(bcm, BCM43xx_MMIO_MACFILTER_DATA, data); - data = mac[2]; - data |= mac[3] << 8; - bcm43xx_write16(bcm, BCM43xx_MMIO_MACFILTER_DATA, data); - data = mac[4]; - data |= mac[5] << 8; - bcm43xx_write16(bcm, BCM43xx_MMIO_MACFILTER_DATA, data); -} - -static void bcm43xx_macfilter_clear(struct bcm43xx_private *bcm, - u16 offset) -{ - const u8 zero_addr[ETH_ALEN] = { 0 }; - - bcm43xx_macfilter_set(bcm, offset, zero_addr); -} - -static void bcm43xx_write_mac_bssid_templates(struct bcm43xx_private *bcm) -{ - const u8 *mac = (const u8 *)(bcm->net_dev->dev_addr); - const u8 *bssid = (const u8 *)(bcm->ieee->bssid); - u8 mac_bssid[ETH_ALEN * 2]; - int i; - - memcpy(mac_bssid, mac, ETH_ALEN); - memcpy(mac_bssid + ETH_ALEN, bssid, ETH_ALEN); - - /* Write our MAC address and BSSID to template ram */ - for (i = 0; i < ARRAY_SIZE(mac_bssid); i += sizeof(u32)) - bcm43xx_ram_write(bcm, 0x20 + i, *((u32 *)(mac_bssid + i))); - for (i = 0; i < ARRAY_SIZE(mac_bssid); i += sizeof(u32)) - bcm43xx_ram_write(bcm, 0x78 + i, *((u32 *)(mac_bssid + i))); - for (i = 0; i < ARRAY_SIZE(mac_bssid); i += sizeof(u32)) - bcm43xx_ram_write(bcm, 0x478 + i, *((u32 *)(mac_bssid + i))); -} - -//FIXME: Well, we should probably call them from somewhere. -#if 0 -static void bcm43xx_set_slot_time(struct bcm43xx_private *bcm, u16 slot_time) -{ - /* slot_time is in usec. */ - if (bcm43xx_current_phy(bcm)->type != BCM43xx_PHYTYPE_G) - return; - bcm43xx_write16(bcm, 0x684, 510 + slot_time); - bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, 0x0010, slot_time); -} - -static void bcm43xx_short_slot_timing_enable(struct bcm43xx_private *bcm) -{ - bcm43xx_set_slot_time(bcm, 9); -} - -static void bcm43xx_short_slot_timing_disable(struct bcm43xx_private *bcm) -{ - bcm43xx_set_slot_time(bcm, 20); -} -#endif - -/* FIXME: To get the MAC-filter working, we need to implement the - * following functions (and rename them :) - */ -#if 0 -static void bcm43xx_disassociate(struct bcm43xx_private *bcm) -{ - bcm43xx_mac_suspend(bcm); - bcm43xx_macfilter_clear(bcm, BCM43xx_MACFILTER_ASSOC); - - bcm43xx_ram_write(bcm, 0x0026, 0x0000); - bcm43xx_ram_write(bcm, 0x0028, 0x0000); - bcm43xx_ram_write(bcm, 0x007E, 0x0000); - bcm43xx_ram_write(bcm, 0x0080, 0x0000); - bcm43xx_ram_write(bcm, 0x047E, 0x0000); - bcm43xx_ram_write(bcm, 0x0480, 0x0000); - - if (bcm->current_core->rev < 3) { - bcm43xx_write16(bcm, 0x0610, 0x8000); - bcm43xx_write16(bcm, 0x060E, 0x0000); - } else - bcm43xx_write32(bcm, 0x0188, 0x80000000); - - bcm43xx_shm_write32(bcm, BCM43xx_SHM_WIRELESS, 0x0004, 0x000003ff); - - if (bcm43xx_current_phy(bcm)->type == BCM43xx_PHYTYPE_G && - ieee80211_is_ofdm_rate(bcm->softmac->txrates.default_rate)) - bcm43xx_short_slot_timing_enable(bcm); - - bcm43xx_mac_enable(bcm); -} - -static void bcm43xx_associate(struct bcm43xx_private *bcm, - const u8 *mac) -{ - memcpy(bcm->ieee->bssid, mac, ETH_ALEN); - - bcm43xx_mac_suspend(bcm); - bcm43xx_macfilter_set(bcm, BCM43xx_MACFILTER_ASSOC, mac); - bcm43xx_write_mac_bssid_templates(bcm); - bcm43xx_mac_enable(bcm); -} -#endif - -/* Enable a Generic IRQ. "mask" is the mask of which IRQs to enable. - * Returns the _previously_ enabled IRQ mask. - */ -static inline u32 bcm43xx_interrupt_enable(struct bcm43xx_private *bcm, u32 mask) -{ - u32 old_mask; - - old_mask = bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_MASK); - bcm43xx_write32(bcm, BCM43xx_MMIO_GEN_IRQ_MASK, old_mask | mask); - - return old_mask; -} - -/* Disable a Generic IRQ. "mask" is the mask of which IRQs to disable. - * Returns the _previously_ enabled IRQ mask. - */ -static inline u32 bcm43xx_interrupt_disable(struct bcm43xx_private *bcm, u32 mask) -{ - u32 old_mask; - - old_mask = bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_MASK); - bcm43xx_write32(bcm, BCM43xx_MMIO_GEN_IRQ_MASK, old_mask & ~mask); - - return old_mask; -} - -/* Make sure we don't receive more data from the device. */ -static int bcm43xx_disable_interrupts_sync(struct bcm43xx_private *bcm, u32 *oldstate) -{ - u32 old; - unsigned long flags; - - bcm43xx_lock_mmio(bcm, flags); - if (bcm43xx_is_initializing(bcm) || bcm->shutting_down) { - bcm43xx_unlock_mmio(bcm, flags); - return -EBUSY; - } - old = bcm43xx_interrupt_disable(bcm, BCM43xx_IRQ_ALL); - tasklet_disable(&bcm->isr_tasklet); - bcm43xx_unlock_mmio(bcm, flags); - if (oldstate) - *oldstate = old; - - return 0; -} - -static int bcm43xx_read_radioinfo(struct bcm43xx_private *bcm) -{ - struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm); - struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm); - u32 radio_id; - u16 manufact; - u16 version; - u8 revision; - s8 i; - - if (bcm->chip_id == 0x4317) { - if (bcm->chip_rev == 0x00) - radio_id = 0x3205017F; - else if (bcm->chip_rev == 0x01) - radio_id = 0x4205017F; - else - radio_id = 0x5205017F; - } else { - bcm43xx_write16(bcm, BCM43xx_MMIO_RADIO_CONTROL, BCM43xx_RADIOCTL_ID); - radio_id = bcm43xx_read16(bcm, BCM43xx_MMIO_RADIO_DATA_HIGH); - radio_id <<= 16; - bcm43xx_write16(bcm, BCM43xx_MMIO_RADIO_CONTROL, BCM43xx_RADIOCTL_ID); - radio_id |= bcm43xx_read16(bcm, BCM43xx_MMIO_RADIO_DATA_LOW); - } - - manufact = (radio_id & 0x00000FFF); - version = (radio_id & 0x0FFFF000) >> 12; - revision = (radio_id & 0xF0000000) >> 28; - - dprintk(KERN_INFO PFX "Detected Radio: ID: %x (Manuf: %x Ver: %x Rev: %x)\n", - radio_id, manufact, version, revision); - - switch (phy->type) { - case BCM43xx_PHYTYPE_A: - if ((version != 0x2060) || (revision != 1) || (manufact != 0x17f)) - goto err_unsupported_radio; - break; - case BCM43xx_PHYTYPE_B: - if ((version & 0xFFF0) != 0x2050) - goto err_unsupported_radio; - break; - case BCM43xx_PHYTYPE_G: - if (version != 0x2050) - goto err_unsupported_radio; - break; - } - - radio->manufact = manufact; - radio->version = version; - radio->revision = revision; - - /* Set default attenuation values. */ - radio->baseband_atten = bcm43xx_default_baseband_attenuation(bcm); - radio->radio_atten = bcm43xx_default_radio_attenuation(bcm); - radio->txctl1 = bcm43xx_default_txctl1(bcm); - radio->txctl2 = 0xFFFF; - if (phy->type == BCM43xx_PHYTYPE_A) - radio->txpower_desired = bcm->sprom.maxpower_aphy; - else - radio->txpower_desired = bcm->sprom.maxpower_bgphy; - - /* Initialize the in-memory nrssi Lookup Table. */ - for (i = 0; i < 64; i++) - radio->nrssi_lt[i] = i; - - return 0; - -err_unsupported_radio: - printk(KERN_ERR PFX "Unsupported Radio connected to the PHY!\n"); - return -ENODEV; -} - -static const char * bcm43xx_locale_iso(u8 locale) -{ - /* ISO 3166-1 country codes. - * Note that there aren't ISO 3166-1 codes for - * all or locales. (Not all locales are countries) - */ - switch (locale) { - case BCM43xx_LOCALE_WORLD: - case BCM43xx_LOCALE_ALL: - return "XX"; - case BCM43xx_LOCALE_THAILAND: - return "TH"; - case BCM43xx_LOCALE_ISRAEL: - return "IL"; - case BCM43xx_LOCALE_JORDAN: - return "JO"; - case BCM43xx_LOCALE_CHINA: - return "CN"; - case BCM43xx_LOCALE_JAPAN: - case BCM43xx_LOCALE_JAPAN_HIGH: - return "JP"; - case BCM43xx_LOCALE_USA_CANADA_ANZ: - case BCM43xx_LOCALE_USA_LOW: - return "US"; - case BCM43xx_LOCALE_EUROPE: - return "EU"; - case BCM43xx_LOCALE_NONE: - return " "; - } - assert(0); - return " "; -} - -static const char * bcm43xx_locale_string(u8 locale) -{ - switch (locale) { - case BCM43xx_LOCALE_WORLD: - return "World"; - case BCM43xx_LOCALE_THAILAND: - return "Thailand"; - case BCM43xx_LOCALE_ISRAEL: - return "Israel"; - case BCM43xx_LOCALE_JORDAN: - return "Jordan"; - case BCM43xx_LOCALE_CHINA: - return "China"; - case BCM43xx_LOCALE_JAPAN: - return "Japan"; - case BCM43xx_LOCALE_USA_CANADA_ANZ: - return "USA/Canada/ANZ"; - case BCM43xx_LOCALE_EUROPE: - return "Europe"; - case BCM43xx_LOCALE_USA_LOW: - return "USAlow"; - case BCM43xx_LOCALE_JAPAN_HIGH: - return "JapanHigh"; - case BCM43xx_LOCALE_ALL: - return "All"; - case BCM43xx_LOCALE_NONE: - return "None"; - } - assert(0); - return ""; -} - -static inline u8 bcm43xx_crc8(u8 crc, u8 data) -{ - static const u8 t[] = { - 0x00, 0xF7, 0xB9, 0x4E, 0x25, 0xD2, 0x9C, 0x6B, - 0x4A, 0xBD, 0xF3, 0x04, 0x6F, 0x98, 0xD6, 0x21, - 0x94, 0x63, 0x2D, 0xDA, 0xB1, 0x46, 0x08, 0xFF, - 0xDE, 0x29, 0x67, 0x90, 0xFB, 0x0C, 0x42, 0xB5, - 0x7F, 0x88, 0xC6, 0x31, 0x5A, 0xAD, 0xE3, 0x14, - 0x35, 0xC2, 0x8C, 0x7B, 0x10, 0xE7, 0xA9, 0x5E, - 0xEB, 0x1C, 0x52, 0xA5, 0xCE, 0x39, 0x77, 0x80, - 0xA1, 0x56, 0x18, 0xEF, 0x84, 0x73, 0x3D, 0xCA, - 0xFE, 0x09, 0x47, 0xB0, 0xDB, 0x2C, 0x62, 0x95, - 0xB4, 0x43, 0x0D, 0xFA, 0x91, 0x66, 0x28, 0xDF, - 0x6A, 0x9D, 0xD3, 0x24, 0x4F, 0xB8, 0xF6, 0x01, - 0x20, 0xD7, 0x99, 0x6E, 0x05, 0xF2, 0xBC, 0x4B, - 0x81, 0x76, 0x38, 0xCF, 0xA4, 0x53, 0x1D, 0xEA, - 0xCB, 0x3C, 0x72, 0x85, 0xEE, 0x19, 0x57, 0xA0, - 0x15, 0xE2, 0xAC, 0x5B, 0x30, 0xC7, 0x89, 0x7E, - 0x5F, 0xA8, 0xE6, 0x11, 0x7A, 0x8D, 0xC3, 0x34, - 0xAB, 0x5C, 0x12, 0xE5, 0x8E, 0x79, 0x37, 0xC0, - 0xE1, 0x16, 0x58, 0xAF, 0xC4, 0x33, 0x7D, 0x8A, - 0x3F, 0xC8, 0x86, 0x71, 0x1A, 0xED, 0xA3, 0x54, - 0x75, 0x82, 0xCC, 0x3B, 0x50, 0xA7, 0xE9, 0x1E, - 0xD4, 0x23, 0x6D, 0x9A, 0xF1, 0x06, 0x48, 0xBF, - 0x9E, 0x69, 0x27, 0xD0, 0xBB, 0x4C, 0x02, 0xF5, - 0x40, 0xB7, 0xF9, 0x0E, 0x65, 0x92, 0xDC, 0x2B, - 0x0A, 0xFD, 0xB3, 0x44, 0x2F, 0xD8, 0x96, 0x61, - 0x55, 0xA2, 0xEC, 0x1B, 0x70, 0x87, 0xC9, 0x3E, - 0x1F, 0xE8, 0xA6, 0x51, 0x3A, 0xCD, 0x83, 0x74, - 0xC1, 0x36, 0x78, 0x8F, 0xE4, 0x13, 0x5D, 0xAA, - 0x8B, 0x7C, 0x32, 0xC5, 0xAE, 0x59, 0x17, 0xE0, - 0x2A, 0xDD, 0x93, 0x64, 0x0F, 0xF8, 0xB6, 0x41, - 0x60, 0x97, 0xD9, 0x2E, 0x45, 0xB2, 0xFC, 0x0B, - 0xBE, 0x49, 0x07, 0xF0, 0x9B, 0x6C, 0x22, 0xD5, - 0xF4, 0x03, 0x4D, 0xBA, 0xD1, 0x26, 0x68, 0x9F, - }; - return t[crc ^ data]; -} - -static u8 bcm43xx_sprom_crc(const u16 *sprom) -{ - int word; - u8 crc = 0xFF; - - for (word = 0; word < BCM43xx_SPROM_SIZE - 1; word++) { - crc = bcm43xx_crc8(crc, sprom[word] & 0x00FF); - crc = bcm43xx_crc8(crc, (sprom[word] & 0xFF00) >> 8); - } - crc = bcm43xx_crc8(crc, sprom[BCM43xx_SPROM_VERSION] & 0x00FF); - crc ^= 0xFF; - - return crc; -} - -int bcm43xx_sprom_read(struct bcm43xx_private *bcm, u16 *sprom) -{ - int i; - u8 crc, expected_crc; - - for (i = 0; i < BCM43xx_SPROM_SIZE; i++) - sprom[i] = bcm43xx_read16(bcm, BCM43xx_SPROM_BASE + (i * 2)); - /* CRC-8 check. */ - crc = bcm43xx_sprom_crc(sprom); - expected_crc = (sprom[BCM43xx_SPROM_VERSION] & 0xFF00) >> 8; - if (crc != expected_crc) { - printk(KERN_WARNING PFX "WARNING: Invalid SPROM checksum " - "(0x%02X, expected: 0x%02X)\n", - crc, expected_crc); - return -EINVAL; - } - - return 0; -} - -int bcm43xx_sprom_write(struct bcm43xx_private *bcm, const u16 *sprom) -{ - int i, err; - u8 crc, expected_crc; - u32 spromctl; - - /* CRC-8 validation of the input data. */ - crc = bcm43xx_sprom_crc(sprom); - expected_crc = (sprom[BCM43xx_SPROM_VERSION] & 0xFF00) >> 8; - if (crc != expected_crc) { - printk(KERN_ERR PFX "SPROM input data: Invalid CRC\n"); - return -EINVAL; - } - - printk(KERN_INFO PFX "Writing SPROM. Do NOT turn off the power! Please stand by...\n"); - err = bcm43xx_pci_read_config32(bcm, BCM43xx_PCICFG_SPROMCTL, &spromctl); - if (err) - goto err_ctlreg; - spromctl |= 0x10; /* SPROM WRITE enable. */ - bcm43xx_pci_write_config32(bcm, BCM43xx_PCICFG_SPROMCTL, spromctl); - if (err) - goto err_ctlreg; - /* We must burn lots of CPU cycles here, but that does not - * really matter as one does not write the SPROM every other minute... - */ - printk(KERN_INFO PFX "[ 0%%"); - mdelay(500); - for (i = 0; i < BCM43xx_SPROM_SIZE; i++) { - if (i == 16) - printk("25%%"); - else if (i == 32) - printk("50%%"); - else if (i == 48) - printk("75%%"); - else if (i % 2) - printk("."); - bcm43xx_write16(bcm, BCM43xx_SPROM_BASE + (i * 2), sprom[i]); - mmiowb(); - mdelay(20); - } - spromctl &= ~0x10; /* SPROM WRITE enable. */ - bcm43xx_pci_write_config32(bcm, BCM43xx_PCICFG_SPROMCTL, spromctl); - if (err) - goto err_ctlreg; - mdelay(500); - printk("100%% ]\n"); - printk(KERN_INFO PFX "SPROM written.\n"); - bcm43xx_controller_restart(bcm, "SPROM update"); - - return 0; -err_ctlreg: - printk(KERN_ERR PFX "Could not access SPROM control register.\n"); - return -ENODEV; -} - -static int bcm43xx_sprom_extract(struct bcm43xx_private *bcm) -{ - u16 value; - u16 *sprom; -#ifdef CONFIG_BCM947XX - char *c; -#endif - - sprom = kzalloc(BCM43xx_SPROM_SIZE * sizeof(u16), - GFP_KERNEL); - if (!sprom) { - printk(KERN_ERR PFX "sprom_extract OOM\n"); - return -ENOMEM; - } -#ifdef CONFIG_BCM947XX - sprom[BCM43xx_SPROM_BOARDFLAGS2] = atoi(nvram_get("boardflags2")); - sprom[BCM43xx_SPROM_BOARDFLAGS] = atoi(nvram_get("boardflags")); - - if ((c = nvram_get("il0macaddr")) != NULL) - e_aton(c, (char *) &(sprom[BCM43xx_SPROM_IL0MACADDR])); - - if ((c = nvram_get("et1macaddr")) != NULL) - e_aton(c, (char *) &(sprom[BCM43xx_SPROM_ET1MACADDR])); - - sprom[BCM43xx_SPROM_PA0B0] = atoi(nvram_get("pa0b0")); - sprom[BCM43xx_SPROM_PA0B1] = atoi(nvram_get("pa0b1")); - sprom[BCM43xx_SPROM_PA0B2] = atoi(nvram_get("pa0b2")); - - sprom[BCM43xx_SPROM_PA1B0] = atoi(nvram_get("pa1b0")); - sprom[BCM43xx_SPROM_PA1B1] = atoi(nvram_get("pa1b1")); - sprom[BCM43xx_SPROM_PA1B2] = atoi(nvram_get("pa1b2")); - - sprom[BCM43xx_SPROM_BOARDREV] = atoi(nvram_get("boardrev")); -#else - bcm43xx_sprom_read(bcm, sprom); -#endif - - /* boardflags2 */ - value = sprom[BCM43xx_SPROM_BOARDFLAGS2]; - bcm->sprom.boardflags2 = value; - - /* il0macaddr */ - value = sprom[BCM43xx_SPROM_IL0MACADDR + 0]; - *(((u16 *)bcm->sprom.il0macaddr) + 0) = cpu_to_be16(value); - value = sprom[BCM43xx_SPROM_IL0MACADDR + 1]; - *(((u16 *)bcm->sprom.il0macaddr) + 1) = cpu_to_be16(value); - value = sprom[BCM43xx_SPROM_IL0MACADDR + 2]; - *(((u16 *)bcm->sprom.il0macaddr) + 2) = cpu_to_be16(value); - - /* et0macaddr */ - value = sprom[BCM43xx_SPROM_ET0MACADDR + 0]; - *(((u16 *)bcm->sprom.et0macaddr) + 0) = cpu_to_be16(value); - value = sprom[BCM43xx_SPROM_ET0MACADDR + 1]; - *(((u16 *)bcm->sprom.et0macaddr) + 1) = cpu_to_be16(value); - value = sprom[BCM43xx_SPROM_ET0MACADDR + 2]; - *(((u16 *)bcm->sprom.et0macaddr) + 2) = cpu_to_be16(value); - - /* et1macaddr */ - value = sprom[BCM43xx_SPROM_ET1MACADDR + 0]; - *(((u16 *)bcm->sprom.et1macaddr) + 0) = cpu_to_be16(value); - value = sprom[BCM43xx_SPROM_ET1MACADDR + 1]; - *(((u16 *)bcm->sprom.et1macaddr) + 1) = cpu_to_be16(value); - value = sprom[BCM43xx_SPROM_ET1MACADDR + 2]; - *(((u16 *)bcm->sprom.et1macaddr) + 2) = cpu_to_be16(value); - - /* ethernet phy settings */ - value = sprom[BCM43xx_SPROM_ETHPHY]; - bcm->sprom.et0phyaddr = (value & 0x001F); - bcm->sprom.et1phyaddr = (value & 0x03E0) >> 5; - bcm->sprom.et0mdcport = (value & (1 << 14)) >> 14; - bcm->sprom.et1mdcport = (value & (1 << 15)) >> 15; - - /* boardrev, antennas, locale */ - value = sprom[BCM43xx_SPROM_BOARDREV]; - bcm->sprom.boardrev = (value & 0x00FF); - bcm->sprom.locale = (value & 0x0F00) >> 8; - bcm->sprom.antennas_aphy = (value & 0x3000) >> 12; - bcm->sprom.antennas_bgphy = (value & 0xC000) >> 14; - if (modparam_locale != -1) { - if (modparam_locale >= 0 && modparam_locale <= 11) { - bcm->sprom.locale = modparam_locale; - printk(KERN_WARNING PFX "Operating with modified " - "LocaleCode %u (%s)\n", - bcm->sprom.locale, - bcm43xx_locale_string(bcm->sprom.locale)); - } else { - printk(KERN_WARNING PFX "Module parameter \"locale\" " - "invalid value. (0 - 11)\n"); - } - } - - /* pa0b* */ - value = sprom[BCM43xx_SPROM_PA0B0]; - bcm->sprom.pa0b0 = value; - value = sprom[BCM43xx_SPROM_PA0B1]; - bcm->sprom.pa0b1 = value; - value = sprom[BCM43xx_SPROM_PA0B2]; - bcm->sprom.pa0b2 = value; - - /* wl0gpio* */ - value = sprom[BCM43xx_SPROM_WL0GPIO0]; - if (value == 0x0000) - value = 0xFFFF; - bcm->sprom.wl0gpio0 = value & 0x00FF; - bcm->sprom.wl0gpio1 = (value & 0xFF00) >> 8; - value = sprom[BCM43xx_SPROM_WL0GPIO2]; - if (value == 0x0000) - value = 0xFFFF; - bcm->sprom.wl0gpio2 = value & 0x00FF; - bcm->sprom.wl0gpio3 = (value & 0xFF00) >> 8; - - /* maxpower */ - value = sprom[BCM43xx_SPROM_MAXPWR]; - bcm->sprom.maxpower_aphy = (value & 0xFF00) >> 8; - bcm->sprom.maxpower_bgphy = value & 0x00FF; - - /* pa1b* */ - value = sprom[BCM43xx_SPROM_PA1B0]; - bcm->sprom.pa1b0 = value; - value = sprom[BCM43xx_SPROM_PA1B1]; - bcm->sprom.pa1b1 = value; - value = sprom[BCM43xx_SPROM_PA1B2]; - bcm->sprom.pa1b2 = value; - - /* idle tssi target */ - value = sprom[BCM43xx_SPROM_IDL_TSSI_TGT]; - bcm->sprom.idle_tssi_tgt_aphy = value & 0x00FF; - bcm->sprom.idle_tssi_tgt_bgphy = (value & 0xFF00) >> 8; - - /* boardflags */ - value = sprom[BCM43xx_SPROM_BOARDFLAGS]; - if (value == 0xFFFF) - value = 0x0000; - bcm->sprom.boardflags = value; - /* boardflags workarounds */ - if (bcm->board_vendor == PCI_VENDOR_ID_DELL && - bcm->chip_id == 0x4301 && - bcm->board_revision == 0x74) - bcm->sprom.boardflags |= BCM43xx_BFL_BTCOEXIST; - if (bcm->board_vendor == PCI_VENDOR_ID_APPLE && - bcm->board_type == 0x4E && - bcm->board_revision > 0x40) - bcm->sprom.boardflags |= BCM43xx_BFL_PACTRL; - - /* antenna gain */ - value = sprom[BCM43xx_SPROM_ANTENNA_GAIN]; - if (value == 0x0000 || value == 0xFFFF) - value = 0x0202; - /* convert values to Q5.2 */ - bcm->sprom.antennagain_aphy = ((value & 0xFF00) >> 8) * 4; - bcm->sprom.antennagain_bgphy = (value & 0x00FF) * 4; - - kfree(sprom); - - return 0; -} - -static void bcm43xx_geo_init(struct bcm43xx_private *bcm) -{ - struct ieee80211_geo geo; - struct ieee80211_channel *chan; - int have_a = 0, have_bg = 0; - int i; - u8 channel; - struct bcm43xx_phyinfo *phy; - const char *iso_country; - - memset(&geo, 0, sizeof(geo)); - for (i = 0; i < bcm->nr_80211_available; i++) { - phy = &(bcm->core_80211_ext[i].phy); - switch (phy->type) { - case BCM43xx_PHYTYPE_B: - case BCM43xx_PHYTYPE_G: - have_bg = 1; - break; - case BCM43xx_PHYTYPE_A: - have_a = 1; - break; - default: - assert(0); - } - } - iso_country = bcm43xx_locale_iso(bcm->sprom.locale); - - if (have_a) { - for (i = 0, channel = 0; channel < 201; channel++) { - chan = &geo.a[i++]; - chan->freq = bcm43xx_channel_to_freq_a(channel); - chan->channel = channel; - } - geo.a_channels = i; - } - if (have_bg) { - for (i = 0, channel = 1; channel < 15; channel++) { - chan = &geo.bg[i++]; - chan->freq = bcm43xx_channel_to_freq_bg(channel); - chan->channel = channel; - } - geo.bg_channels = i; - } - memcpy(geo.name, iso_country, 2); - if (0 /*TODO: Outdoor use only */) - geo.name[2] = 'O'; - else if (0 /*TODO: Indoor use only */) - geo.name[2] = 'I'; - else - geo.name[2] = ' '; - geo.name[3] = '\0'; - - ieee80211_set_geo(bcm->ieee, &geo); -} - -/* DummyTransmission function, as documented on - * http://bcm-specs.sipsolutions.net/DummyTransmission - */ -void bcm43xx_dummy_transmission(struct bcm43xx_private *bcm) -{ - struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm); - struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm); - unsigned int i, max_loop; - u16 value = 0; - u32 buffer[5] = { - 0x00000000, - 0x0000D400, - 0x00000000, - 0x00000001, - 0x00000000, - }; - - switch (phy->type) { - case BCM43xx_PHYTYPE_A: - max_loop = 0x1E; - buffer[0] = 0xCC010200; - break; - case BCM43xx_PHYTYPE_B: - case BCM43xx_PHYTYPE_G: - max_loop = 0xFA; - buffer[0] = 0x6E840B00; - break; - default: - assert(0); - return; - } - - for (i = 0; i < 5; i++) - bcm43xx_ram_write(bcm, i * 4, buffer[i]); - - bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD); /* dummy read */ - - bcm43xx_write16(bcm, 0x0568, 0x0000); - bcm43xx_write16(bcm, 0x07C0, 0x0000); - bcm43xx_write16(bcm, 0x050C, ((phy->type == BCM43xx_PHYTYPE_A) ? 1 : 0)); - bcm43xx_write16(bcm, 0x0508, 0x0000); - bcm43xx_write16(bcm, 0x050A, 0x0000); - bcm43xx_write16(bcm, 0x054C, 0x0000); - bcm43xx_write16(bcm, 0x056A, 0x0014); - bcm43xx_write16(bcm, 0x0568, 0x0826); - bcm43xx_write16(bcm, 0x0500, 0x0000); - bcm43xx_write16(bcm, 0x0502, 0x0030); - - if (radio->version == 0x2050 && radio->revision <= 0x5) - bcm43xx_radio_write16(bcm, 0x0051, 0x0017); - for (i = 0x00; i < max_loop; i++) { - value = bcm43xx_read16(bcm, 0x050E); - if (value & 0x0080) - break; - udelay(10); - } - for (i = 0x00; i < 0x0A; i++) { - value = bcm43xx_read16(bcm, 0x050E); - if (value & 0x0400) - break; - udelay(10); - } - for (i = 0x00; i < 0x0A; i++) { - value = bcm43xx_read16(bcm, 0x0690); - if (!(value & 0x0100)) - break; - udelay(10); - } - if (radio->version == 0x2050 && radio->revision <= 0x5) - bcm43xx_radio_write16(bcm, 0x0051, 0x0037); -} - -static void key_write(struct bcm43xx_private *bcm, - u8 index, u8 algorithm, const u16 *key) -{ - unsigned int i, basic_wep = 0; - u32 offset; - u16 value; - - /* Write associated key information */ - bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, 0x100 + (index * 2), - ((index << 4) | (algorithm & 0x0F))); - - /* The first 4 WEP keys need extra love */ - if (((algorithm == BCM43xx_SEC_ALGO_WEP) || - (algorithm == BCM43xx_SEC_ALGO_WEP104)) && (index < 4)) - basic_wep = 1; - - /* Write key payload, 8 little endian words */ - offset = bcm->security_offset + (index * BCM43xx_SEC_KEYSIZE); - for (i = 0; i < (BCM43xx_SEC_KEYSIZE / sizeof(u16)); i++) { - value = cpu_to_le16(key[i]); - bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, - offset + (i * 2), value); - - if (!basic_wep) - continue; - - bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, - offset + (i * 2) + 4 * BCM43xx_SEC_KEYSIZE, - value); - } -} - -static void keymac_write(struct bcm43xx_private *bcm, - u8 index, const u32 *addr) -{ - /* for keys 0-3 there is no associated mac address */ - if (index < 4) - return; - - index -= 4; - if (bcm->current_core->rev >= 5) { - bcm43xx_shm_write32(bcm, - BCM43xx_SHM_HWMAC, - index * 2, - cpu_to_be32(*addr)); - bcm43xx_shm_write16(bcm, - BCM43xx_SHM_HWMAC, - (index * 2) + 1, - cpu_to_be16(*((u16 *)(addr + 1)))); - } else { - if (index < 8) { - TODO(); /* Put them in the macaddress filter */ - } else { - TODO(); - /* Put them BCM43xx_SHM_SHARED, stating index 0x0120. - Keep in mind to update the count of keymacs in 0x003E as well! */ - } - } -} - -static int bcm43xx_key_write(struct bcm43xx_private *bcm, - u8 index, u8 algorithm, - const u8 *_key, int key_len, - const u8 *mac_addr) -{ - u8 key[BCM43xx_SEC_KEYSIZE] = { 0 }; - - if (index >= ARRAY_SIZE(bcm->key)) - return -EINVAL; - if (key_len > ARRAY_SIZE(key)) - return -EINVAL; - if (algorithm < 1 || algorithm > 5) - return -EINVAL; - - memcpy(key, _key, key_len); - key_write(bcm, index, algorithm, (const u16 *)key); - keymac_write(bcm, index, (const u32 *)mac_addr); - - bcm->key[index].algorithm = algorithm; - - return 0; -} - -static void bcm43xx_clear_keys(struct bcm43xx_private *bcm) -{ - static const u32 zero_mac[2] = { 0 }; - unsigned int i,j, nr_keys = 54; - u16 offset; - - if (bcm->current_core->rev < 5) - nr_keys = 16; - assert(nr_keys <= ARRAY_SIZE(bcm->key)); - - for (i = 0; i < nr_keys; i++) { - bcm->key[i].enabled = 0; - /* returns for i < 4 immediately */ - keymac_write(bcm, i, zero_mac); - bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, - 0x100 + (i * 2), 0x0000); - for (j = 0; j < 8; j++) { - offset = bcm->security_offset + (j * 4) + (i * BCM43xx_SEC_KEYSIZE); - bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, - offset, 0x0000); - } - } - dprintk(KERN_INFO PFX "Keys cleared\n"); -} - -/* Lowlevel core-switch function. This is only to be used in - * bcm43xx_switch_core() and bcm43xx_probe_cores() - */ -static int _switch_core(struct bcm43xx_private *bcm, int core) -{ - int err; - int attempts = 0; - u32 current_core; - - assert(core >= 0); - while (1) { - err = bcm43xx_pci_write_config32(bcm, BCM43xx_PCICFG_ACTIVE_CORE, - (core * 0x1000) + 0x18000000); - if (unlikely(err)) - goto error; - err = bcm43xx_pci_read_config32(bcm, BCM43xx_PCICFG_ACTIVE_CORE, - ¤t_core); - if (unlikely(err)) - goto error; - current_core = (current_core - 0x18000000) / 0x1000; - if (current_core == core) - break; - - if (unlikely(attempts++ > BCM43xx_SWITCH_CORE_MAX_RETRIES)) - goto error; - udelay(10); - } -#ifdef CONFIG_BCM947XX - if (bcm->pci_dev->bus->number == 0) - bcm->current_core_offset = 0x1000 * core; - else - bcm->current_core_offset = 0; -#endif - - return 0; -error: - printk(KERN_ERR PFX "Failed to switch to core %d\n", core); - return -ENODEV; -} - -int bcm43xx_switch_core(struct bcm43xx_private *bcm, struct bcm43xx_coreinfo *new_core) -{ - int err; - - if (unlikely(!new_core)) - return 0; - if (!new_core->available) - return -ENODEV; - if (bcm->current_core == new_core) - return 0; - err = _switch_core(bcm, new_core->index); - if (unlikely(err)) - goto out; - - bcm->current_core = new_core; - bcm->current_80211_core_idx = -1; - if (new_core->id == BCM43xx_COREID_80211) - bcm->current_80211_core_idx = (int)(new_core - &(bcm->core_80211[0])); - -out: - return err; -} - -static int bcm43xx_core_enabled(struct bcm43xx_private *bcm) -{ - u32 value; - - value = bcm43xx_read32(bcm, BCM43xx_CIR_SBTMSTATELOW); - value &= BCM43xx_SBTMSTATELOW_CLOCK | BCM43xx_SBTMSTATELOW_RESET - | BCM43xx_SBTMSTATELOW_REJECT; - - return (value == BCM43xx_SBTMSTATELOW_CLOCK); -} - -/* disable current core */ -static int bcm43xx_core_disable(struct bcm43xx_private *bcm, u32 core_flags) -{ - u32 sbtmstatelow; - u32 sbtmstatehigh; - int i; - - /* fetch sbtmstatelow from core information registers */ - sbtmstatelow = bcm43xx_read32(bcm, BCM43xx_CIR_SBTMSTATELOW); - - /* core is already in reset */ - if (sbtmstatelow & BCM43xx_SBTMSTATELOW_RESET) - goto out; - - if (sbtmstatelow & BCM43xx_SBTMSTATELOW_CLOCK) { - sbtmstatelow = BCM43xx_SBTMSTATELOW_CLOCK | - BCM43xx_SBTMSTATELOW_REJECT; - bcm43xx_write32(bcm, BCM43xx_CIR_SBTMSTATELOW, sbtmstatelow); - - for (i = 0; i < 1000; i++) { - sbtmstatelow = bcm43xx_read32(bcm, BCM43xx_CIR_SBTMSTATELOW); - if (sbtmstatelow & BCM43xx_SBTMSTATELOW_REJECT) { - i = -1; - break; - } - udelay(10); - } - if (i != -1) { - printk(KERN_ERR PFX "Error: core_disable() REJECT timeout!\n"); - return -EBUSY; - } - - for (i = 0; i < 1000; i++) { - sbtmstatehigh = bcm43xx_read32(bcm, BCM43xx_CIR_SBTMSTATEHIGH); - if (!(sbtmstatehigh & BCM43xx_SBTMSTATEHIGH_BUSY)) { - i = -1; - break; - } - udelay(10); - } - if (i != -1) { - printk(KERN_ERR PFX "Error: core_disable() BUSY timeout!\n"); - return -EBUSY; - } - - sbtmstatelow = BCM43xx_SBTMSTATELOW_FORCE_GATE_CLOCK | - BCM43xx_SBTMSTATELOW_REJECT | - BCM43xx_SBTMSTATELOW_RESET | - BCM43xx_SBTMSTATELOW_CLOCK | - core_flags; - bcm43xx_write32(bcm, BCM43xx_CIR_SBTMSTATELOW, sbtmstatelow); - udelay(10); - } - - sbtmstatelow = BCM43xx_SBTMSTATELOW_RESET | - BCM43xx_SBTMSTATELOW_REJECT | - core_flags; - bcm43xx_write32(bcm, BCM43xx_CIR_SBTMSTATELOW, sbtmstatelow); - -out: - bcm->current_core->enabled = 0; - - return 0; -} - -/* enable (reset) current core */ -static int bcm43xx_core_enable(struct bcm43xx_private *bcm, u32 core_flags) -{ - u32 sbtmstatelow; - u32 sbtmstatehigh; - u32 sbimstate; - int err; - - err = bcm43xx_core_disable(bcm, core_flags); - if (err) - goto out; - - sbtmstatelow = BCM43xx_SBTMSTATELOW_CLOCK | - BCM43xx_SBTMSTATELOW_RESET | - BCM43xx_SBTMSTATELOW_FORCE_GATE_CLOCK | - core_flags; - bcm43xx_write32(bcm, BCM43xx_CIR_SBTMSTATELOW, sbtmstatelow); - udelay(1); - - sbtmstatehigh = bcm43xx_read32(bcm, BCM43xx_CIR_SBTMSTATEHIGH); - if (sbtmstatehigh & BCM43xx_SBTMSTATEHIGH_SERROR) { - sbtmstatehigh = 0x00000000; - bcm43xx_write32(bcm, BCM43xx_CIR_SBTMSTATEHIGH, sbtmstatehigh); - } - - sbimstate = bcm43xx_read32(bcm, BCM43xx_CIR_SBIMSTATE); - if (sbimstate & (BCM43xx_SBIMSTATE_IB_ERROR | BCM43xx_SBIMSTATE_TIMEOUT)) { - sbimstate &= ~(BCM43xx_SBIMSTATE_IB_ERROR | BCM43xx_SBIMSTATE_TIMEOUT); - bcm43xx_write32(bcm, BCM43xx_CIR_SBIMSTATE, sbimstate); - } - - sbtmstatelow = BCM43xx_SBTMSTATELOW_CLOCK | - BCM43xx_SBTMSTATELOW_FORCE_GATE_CLOCK | - core_flags; - bcm43xx_write32(bcm, BCM43xx_CIR_SBTMSTATELOW, sbtmstatelow); - udelay(1); - - sbtmstatelow = BCM43xx_SBTMSTATELOW_CLOCK | core_flags; - bcm43xx_write32(bcm, BCM43xx_CIR_SBTMSTATELOW, sbtmstatelow); - udelay(1); - - bcm->current_core->enabled = 1; - assert(err == 0); -out: - return err; -} - -/* http://bcm-specs.sipsolutions.net/80211CoreReset */ -void bcm43xx_wireless_core_reset(struct bcm43xx_private *bcm, int connect_phy) -{ - u32 flags = 0x00040000; - - if ((bcm43xx_core_enabled(bcm)) && - !bcm43xx_using_pio(bcm)) { -//FIXME: Do we _really_ want #ifndef CONFIG_BCM947XX here? -#ifndef CONFIG_BCM947XX - /* reset all used DMA controllers. */ - bcm43xx_dmacontroller_tx_reset(bcm, BCM43xx_MMIO_DMA1_BASE); - bcm43xx_dmacontroller_tx_reset(bcm, BCM43xx_MMIO_DMA2_BASE); - bcm43xx_dmacontroller_tx_reset(bcm, BCM43xx_MMIO_DMA3_BASE); - bcm43xx_dmacontroller_tx_reset(bcm, BCM43xx_MMIO_DMA4_BASE); - bcm43xx_dmacontroller_rx_reset(bcm, BCM43xx_MMIO_DMA1_BASE); - if (bcm->current_core->rev < 5) - bcm43xx_dmacontroller_rx_reset(bcm, BCM43xx_MMIO_DMA4_BASE); -#endif - } - if (bcm->shutting_down) { - bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD, - bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD) - & ~(BCM43xx_SBF_MAC_ENABLED | 0x00000002)); - } else { - if (connect_phy) - flags |= 0x20000000; - bcm43xx_phy_connect(bcm, connect_phy); - bcm43xx_core_enable(bcm, flags); - bcm43xx_write16(bcm, 0x03E6, 0x0000); - bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD, - bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD) - | BCM43xx_SBF_400); - } -} - -static void bcm43xx_wireless_core_disable(struct bcm43xx_private *bcm) -{ - bcm43xx_radio_turn_off(bcm); - bcm43xx_write16(bcm, 0x03E6, 0x00F4); - bcm43xx_core_disable(bcm, 0); -} - -/* Mark the current 80211 core inactive. - * "active_80211_core" is the other 80211 core, which is used. - */ -static int bcm43xx_wireless_core_mark_inactive(struct bcm43xx_private *bcm, - struct bcm43xx_coreinfo *active_80211_core) -{ - u32 sbtmstatelow; - struct bcm43xx_coreinfo *old_core; - int err = 0; - - bcm43xx_interrupt_disable(bcm, BCM43xx_IRQ_ALL); - bcm43xx_radio_turn_off(bcm); - sbtmstatelow = bcm43xx_read32(bcm, BCM43xx_CIR_SBTMSTATELOW); - sbtmstatelow &= ~0x200a0000; - sbtmstatelow |= 0xa0000; - bcm43xx_write32(bcm, BCM43xx_CIR_SBTMSTATELOW, sbtmstatelow); - udelay(1); - sbtmstatelow = bcm43xx_read32(bcm, BCM43xx_CIR_SBTMSTATELOW); - sbtmstatelow &= ~0xa0000; - sbtmstatelow |= 0x80000; - bcm43xx_write32(bcm, BCM43xx_CIR_SBTMSTATELOW, sbtmstatelow); - udelay(1); - - if (bcm43xx_current_phy(bcm)->type == BCM43xx_PHYTYPE_G) { - old_core = bcm->current_core; - err = bcm43xx_switch_core(bcm, active_80211_core); - if (err) - goto out; - sbtmstatelow = bcm43xx_read32(bcm, BCM43xx_CIR_SBTMSTATELOW); - sbtmstatelow &= ~0x20000000; - sbtmstatelow |= 0x20000000; - bcm43xx_write32(bcm, BCM43xx_CIR_SBTMSTATELOW, sbtmstatelow); - err = bcm43xx_switch_core(bcm, old_core); - } - -out: - return err; -} - -static void handle_irq_transmit_status(struct bcm43xx_private *bcm) -{ - u32 v0, v1; - u16 tmp; - struct bcm43xx_xmitstatus stat; - - while (1) { - v0 = bcm43xx_read32(bcm, BCM43xx_MMIO_XMITSTAT_0); - if (!v0) - break; - v1 = bcm43xx_read32(bcm, BCM43xx_MMIO_XMITSTAT_1); - - stat.cookie = (v0 >> 16) & 0x0000FFFF; - tmp = (u16)((v0 & 0xFFF0) | ((v0 & 0xF) >> 1)); - stat.flags = tmp & 0xFF; - stat.cnt1 = (tmp & 0x0F00) >> 8; - stat.cnt2 = (tmp & 0xF000) >> 12; - stat.seq = (u16)(v1 & 0xFFFF); - stat.unknown = (u16)((v1 >> 16) & 0xFF); - - bcm43xx_debugfs_log_txstat(bcm, &stat); - - if (stat.flags & BCM43xx_TXSTAT_FLAG_IGNORE) - continue; - if (!(stat.flags & BCM43xx_TXSTAT_FLAG_ACK)) { - //TODO: packet was not acked (was lost) - } - //TODO: There are more (unknown) flags to test. see bcm43xx_main.h - - if (bcm43xx_using_pio(bcm)) - bcm43xx_pio_handle_xmitstatus(bcm, &stat); - else - bcm43xx_dma_handle_xmitstatus(bcm, &stat); - } -} - -static void bcm43xx_generate_noise_sample(struct bcm43xx_private *bcm) -{ - bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, 0x408, 0x7F7F); - bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, 0x40A, 0x7F7F); - bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS2_BITFIELD, - bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS2_BITFIELD) | (1 << 4)); - assert(bcm->noisecalc.core_at_start == bcm->current_core); - assert(bcm->noisecalc.channel_at_start == bcm43xx_current_radio(bcm)->channel); -} - -static void bcm43xx_calculate_link_quality(struct bcm43xx_private *bcm) -{ - /* Top half of Link Quality calculation. */ - - if (bcm->noisecalc.calculation_running) - return; - bcm->noisecalc.core_at_start = bcm->current_core; - bcm->noisecalc.channel_at_start = bcm43xx_current_radio(bcm)->channel; - bcm->noisecalc.calculation_running = 1; - bcm->noisecalc.nr_samples = 0; - - bcm43xx_generate_noise_sample(bcm); -} - -static void handle_irq_noise(struct bcm43xx_private *bcm) -{ - struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm); - u16 tmp; - u8 noise[4]; - u8 i, j; - s32 average; - - /* Bottom half of Link Quality calculation. */ - - assert(bcm->noisecalc.calculation_running); - if (bcm->noisecalc.core_at_start != bcm->current_core || - bcm->noisecalc.channel_at_start != radio->channel) - goto drop_calculation; - tmp = bcm43xx_shm_read16(bcm, BCM43xx_SHM_SHARED, 0x408); - noise[0] = (tmp & 0x00FF); - noise[1] = (tmp & 0xFF00) >> 8; - tmp = bcm43xx_shm_read16(bcm, BCM43xx_SHM_SHARED, 0x40A); - noise[2] = (tmp & 0x00FF); - noise[3] = (tmp & 0xFF00) >> 8; - if (noise[0] == 0x7F || noise[1] == 0x7F || - noise[2] == 0x7F || noise[3] == 0x7F) - goto generate_new; - - /* Get the noise samples. */ - assert(bcm->noisecalc.nr_samples <= 8); - i = bcm->noisecalc.nr_samples; - noise[0] = limit_value(noise[0], 0, ARRAY_SIZE(radio->nrssi_lt) - 1); - noise[1] = limit_value(noise[1], 0, ARRAY_SIZE(radio->nrssi_lt) - 1); - noise[2] = limit_value(noise[2], 0, ARRAY_SIZE(radio->nrssi_lt) - 1); - noise[3] = limit_value(noise[3], 0, ARRAY_SIZE(radio->nrssi_lt) - 1); - bcm->noisecalc.samples[i][0] = radio->nrssi_lt[noise[0]]; - bcm->noisecalc.samples[i][1] = radio->nrssi_lt[noise[1]]; - bcm->noisecalc.samples[i][2] = radio->nrssi_lt[noise[2]]; - bcm->noisecalc.samples[i][3] = radio->nrssi_lt[noise[3]]; - bcm->noisecalc.nr_samples++; - if (bcm->noisecalc.nr_samples == 8) { - /* Calculate the Link Quality by the noise samples. */ - average = 0; - for (i = 0; i < 8; i++) { - for (j = 0; j < 4; j++) - average += bcm->noisecalc.samples[i][j]; - } - average /= (8 * 4); - average *= 125; - average += 64; - average /= 128; - - tmp = bcm43xx_shm_read16(bcm, BCM43xx_SHM_SHARED, 0x40C); - tmp = (tmp / 128) & 0x1F; - if (tmp >= 8) - average += 2; - else - average -= 25; - if (tmp == 8) - average -= 72; - else - average -= 48; - -/* FIXME: This is wrong, but people want fancy stats. well... */ -bcm->stats.noise = average; - if (average > -65) - bcm->stats.link_quality = 0; - else if (average > -75) - bcm->stats.link_quality = 1; - else if (average > -85) - bcm->stats.link_quality = 2; - else - bcm->stats.link_quality = 3; -// dprintk(KERN_INFO PFX "Link Quality: %u (avg was %d)\n", bcm->stats.link_quality, average); -drop_calculation: - bcm->noisecalc.calculation_running = 0; - return; - } -generate_new: - bcm43xx_generate_noise_sample(bcm); -} - -static void handle_irq_ps(struct bcm43xx_private *bcm) -{ - if (bcm->ieee->iw_mode == IW_MODE_MASTER) { - ///TODO: PS TBTT - } else { - if (1/*FIXME: the last PSpoll frame was sent successfully */) - bcm43xx_power_saving_ctl_bits(bcm, -1, -1); - } - if (bcm->ieee->iw_mode == IW_MODE_ADHOC) - bcm->reg124_set_0x4 = 1; - //FIXME else set to false? -} - -static void handle_irq_reg124(struct bcm43xx_private *bcm) -{ - if (!bcm->reg124_set_0x4) - return; - bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS2_BITFIELD, - bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS2_BITFIELD) - | 0x4); - //FIXME: reset reg124_set_0x4 to false? -} - -static void handle_irq_pmq(struct bcm43xx_private *bcm) -{ - u32 tmp; - - //TODO: AP mode. - - while (1) { - tmp = bcm43xx_read32(bcm, BCM43xx_MMIO_PS_STATUS); - if (!(tmp & 0x00000008)) - break; - } - /* 16bit write is odd, but correct. */ - bcm43xx_write16(bcm, BCM43xx_MMIO_PS_STATUS, 0x0002); -} - -static void bcm43xx_generate_beacon_template(struct bcm43xx_private *bcm, - u16 ram_offset, u16 shm_size_offset) -{ - u32 value; - u16 size = 0; - - /* Timestamp. */ - //FIXME: assumption: The chip sets the timestamp - value = 0; - bcm43xx_ram_write(bcm, ram_offset++, value); - bcm43xx_ram_write(bcm, ram_offset++, value); - size += 8; - - /* Beacon Interval / Capability Information */ - value = 0x0000;//FIXME: Which interval? - value |= (1 << 0) << 16; /* ESS */ - value |= (1 << 2) << 16; /* CF Pollable */ //FIXME? - value |= (1 << 3) << 16; /* CF Poll Request */ //FIXME? - if (!bcm->ieee->open_wep) - value |= (1 << 4) << 16; /* Privacy */ - bcm43xx_ram_write(bcm, ram_offset++, value); - size += 4; - - /* SSID */ - //TODO - - /* FH Parameter Set */ - //TODO - - /* DS Parameter Set */ - //TODO - - /* CF Parameter Set */ - //TODO - - /* TIM */ - //TODO - - bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, shm_size_offset, size); -} - -static void handle_irq_beacon(struct bcm43xx_private *bcm) -{ - u32 status; - - bcm->irq_savedstate &= ~BCM43xx_IRQ_BEACON; - status = bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS2_BITFIELD); - - if ((status & 0x1) && (status & 0x2)) { - /* ACK beacon IRQ. */ - bcm43xx_write32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON, - BCM43xx_IRQ_BEACON); - bcm->irq_savedstate |= BCM43xx_IRQ_BEACON; - return; - } - if (!(status & 0x1)) { - bcm43xx_generate_beacon_template(bcm, 0x68, 0x18); - status |= 0x1; - bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS2_BITFIELD, status); - } - if (!(status & 0x2)) { - bcm43xx_generate_beacon_template(bcm, 0x468, 0x1A); - status |= 0x2; - bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS2_BITFIELD, status); - } -} - -/* Interrupt handler bottom-half */ -static void bcm43xx_interrupt_tasklet(struct bcm43xx_private *bcm) -{ - u32 reason; - u32 dma_reason[4]; - int activity = 0; - unsigned long flags; - -#ifdef CONFIG_BCM43XX_DEBUG - u32 _handled = 0x00000000; -# define bcmirq_handled(irq) do { _handled |= (irq); } while (0) -#else -# define bcmirq_handled(irq) do { /* nothing */ } while (0) -#endif /* CONFIG_BCM43XX_DEBUG*/ - - bcm43xx_lock_mmio(bcm, flags); - reason = bcm->irq_reason; - dma_reason[0] = bcm->dma_reason[0]; - dma_reason[1] = bcm->dma_reason[1]; - dma_reason[2] = bcm->dma_reason[2]; - dma_reason[3] = bcm->dma_reason[3]; - - if (unlikely(reason & BCM43xx_IRQ_XMIT_ERROR)) { - /* TX error. We get this when Template Ram is written in wrong endianess - * in dummy_tx(). We also get this if something is wrong with the TX header - * on DMA or PIO queues. - * Maybe we get this in other error conditions, too. - */ - printkl(KERN_ERR PFX "FATAL ERROR: BCM43xx_IRQ_XMIT_ERROR\n"); - bcmirq_handled(BCM43xx_IRQ_XMIT_ERROR); - } - if (unlikely((dma_reason[0] & BCM43xx_DMAIRQ_FATALMASK) | - (dma_reason[1] & BCM43xx_DMAIRQ_FATALMASK) | - (dma_reason[2] & BCM43xx_DMAIRQ_FATALMASK) | - (dma_reason[3] & BCM43xx_DMAIRQ_FATALMASK))) { - printkl(KERN_ERR PFX "FATAL ERROR: Fatal DMA error: " - "0x%08X, 0x%08X, 0x%08X, 0x%08X\n", - dma_reason[0], dma_reason[1], - dma_reason[2], dma_reason[3]); - bcm43xx_controller_restart(bcm, "DMA error"); - bcm43xx_unlock_mmio(bcm, flags); - return; - } - if (unlikely((dma_reason[0] & BCM43xx_DMAIRQ_NONFATALMASK) | - (dma_reason[1] & BCM43xx_DMAIRQ_NONFATALMASK) | - (dma_reason[2] & BCM43xx_DMAIRQ_NONFATALMASK) | - (dma_reason[3] & BCM43xx_DMAIRQ_NONFATALMASK))) { - printkl(KERN_ERR PFX "DMA error: " - "0x%08X, 0x%08X, 0x%08X, 0x%08X\n", - dma_reason[0], dma_reason[1], - dma_reason[2], dma_reason[3]); - } - - if (reason & BCM43xx_IRQ_PS) { - handle_irq_ps(bcm); - bcmirq_handled(BCM43xx_IRQ_PS); - } - - if (reason & BCM43xx_IRQ_REG124) { - handle_irq_reg124(bcm); - bcmirq_handled(BCM43xx_IRQ_REG124); - } - - if (reason & BCM43xx_IRQ_BEACON) { - if (bcm->ieee->iw_mode == IW_MODE_MASTER) - handle_irq_beacon(bcm); - bcmirq_handled(BCM43xx_IRQ_BEACON); - } - - if (reason & BCM43xx_IRQ_PMQ) { - handle_irq_pmq(bcm); - bcmirq_handled(BCM43xx_IRQ_PMQ); - } - - if (reason & BCM43xx_IRQ_SCAN) { - /*TODO*/ - //bcmirq_handled(BCM43xx_IRQ_SCAN); - } - - if (reason & BCM43xx_IRQ_NOISE) { - handle_irq_noise(bcm); - bcmirq_handled(BCM43xx_IRQ_NOISE); - } - - /* Check the DMA reason registers for received data. */ - assert(!(dma_reason[1] & BCM43xx_DMAIRQ_RX_DONE)); - assert(!(dma_reason[2] & BCM43xx_DMAIRQ_RX_DONE)); - if (dma_reason[0] & BCM43xx_DMAIRQ_RX_DONE) { - if (bcm43xx_using_pio(bcm)) - bcm43xx_pio_rx(bcm43xx_current_pio(bcm)->queue0); - else - bcm43xx_dma_rx(bcm43xx_current_dma(bcm)->rx_ring0); - /* We intentionally don't set "activity" to 1, here. */ - } - if (dma_reason[3] & BCM43xx_DMAIRQ_RX_DONE) { - if (bcm43xx_using_pio(bcm)) - bcm43xx_pio_rx(bcm43xx_current_pio(bcm)->queue3); - else - bcm43xx_dma_rx(bcm43xx_current_dma(bcm)->rx_ring1); - activity = 1; - } - bcmirq_handled(BCM43xx_IRQ_RX); - - if (reason & BCM43xx_IRQ_XMIT_STATUS) { - handle_irq_transmit_status(bcm); - activity = 1; - //TODO: In AP mode, this also causes sending of powersave responses. - bcmirq_handled(BCM43xx_IRQ_XMIT_STATUS); - } - - /* IRQ_PIO_WORKAROUND is handled in the top-half. */ - bcmirq_handled(BCM43xx_IRQ_PIO_WORKAROUND); -#ifdef CONFIG_BCM43XX_DEBUG - if (unlikely(reason & ~_handled)) { - printkl(KERN_WARNING PFX - "Unhandled IRQ! Reason: 0x%08x, Unhandled: 0x%08x, " - "DMA: 0x%08x, 0x%08x, 0x%08x, 0x%08x\n", - reason, (reason & ~_handled), - dma_reason[0], dma_reason[1], - dma_reason[2], dma_reason[3]); - } -#endif -#undef bcmirq_handled - - if (!modparam_noleds) - bcm43xx_leds_update(bcm, activity); - bcm43xx_interrupt_enable(bcm, bcm->irq_savedstate); - bcm43xx_unlock_mmio(bcm, flags); -} - -static void pio_irq_workaround(struct bcm43xx_private *bcm, - u16 base, int queueidx) -{ - u16 rxctl; - - rxctl = bcm43xx_read16(bcm, base + BCM43xx_PIO_RXCTL); - if (rxctl & BCM43xx_PIO_RXCTL_DATAAVAILABLE) - bcm->dma_reason[queueidx] |= BCM43xx_DMAIRQ_RX_DONE; - else - bcm->dma_reason[queueidx] &= ~BCM43xx_DMAIRQ_RX_DONE; -} - -static void bcm43xx_interrupt_ack(struct bcm43xx_private *bcm, u32 reason) -{ - if (bcm43xx_using_pio(bcm) && - (bcm->current_core->rev < 3) && - (!(reason & BCM43xx_IRQ_PIO_WORKAROUND))) { - /* Apply a PIO specific workaround to the dma_reasons */ - pio_irq_workaround(bcm, BCM43xx_MMIO_PIO1_BASE, 0); - pio_irq_workaround(bcm, BCM43xx_MMIO_PIO2_BASE, 1); - pio_irq_workaround(bcm, BCM43xx_MMIO_PIO3_BASE, 2); - pio_irq_workaround(bcm, BCM43xx_MMIO_PIO4_BASE, 3); - } - - bcm43xx_write32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON, reason); - - bcm43xx_write32(bcm, BCM43xx_MMIO_DMA1_REASON, - bcm->dma_reason[0]); - bcm43xx_write32(bcm, BCM43xx_MMIO_DMA2_REASON, - bcm->dma_reason[1]); - bcm43xx_write32(bcm, BCM43xx_MMIO_DMA3_REASON, - bcm->dma_reason[2]); - bcm43xx_write32(bcm, BCM43xx_MMIO_DMA4_REASON, - bcm->dma_reason[3]); -} - -/* Interrupt handler top-half */ -static irqreturn_t bcm43xx_interrupt_handler(int irq, void *dev_id, struct pt_regs *regs) -{ - irqreturn_t ret = IRQ_HANDLED; - struct bcm43xx_private *bcm = dev_id; - u32 reason; - - if (!bcm) - return IRQ_NONE; - - spin_lock(&bcm->_lock); - - reason = bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON); - if (reason == 0xffffffff) { - /* irq not for us (shared irq) */ - ret = IRQ_NONE; - goto out; - } - reason &= bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_MASK); - if (!reason) - goto out; - - bcm->dma_reason[0] = bcm43xx_read32(bcm, BCM43xx_MMIO_DMA1_REASON) - & 0x0001dc00; - bcm->dma_reason[1] = bcm43xx_read32(bcm, BCM43xx_MMIO_DMA2_REASON) - & 0x0000dc00; - bcm->dma_reason[2] = bcm43xx_read32(bcm, BCM43xx_MMIO_DMA3_REASON) - & 0x0000dc00; - bcm->dma_reason[3] = bcm43xx_read32(bcm, BCM43xx_MMIO_DMA4_REASON) - & 0x0001dc00; - - bcm43xx_interrupt_ack(bcm, reason); - - /* Only accept IRQs, if we are initialized properly. - * This avoids an RX race while initializing. - * We should probably not enable IRQs before we are initialized - * completely, but some careful work is needed to fix this. I think it - * is best to stay with this cheap workaround for now... . - */ - if (likely(bcm->initialized)) { - /* disable all IRQs. They are enabled again in the bottom half. */ - bcm->irq_savedstate = bcm43xx_interrupt_disable(bcm, BCM43xx_IRQ_ALL); - /* save the reason code and call our bottom half. */ - bcm->irq_reason = reason; - tasklet_schedule(&bcm->isr_tasklet); - } - -out: - mmiowb(); - spin_unlock(&bcm->_lock); - - return ret; -} - -static void bcm43xx_release_firmware(struct bcm43xx_private *bcm, int force) -{ - if (bcm->firmware_norelease && !force) - return; /* Suspending or controller reset. */ - release_firmware(bcm->ucode); - bcm->ucode = NULL; - release_firmware(bcm->pcm); - bcm->pcm = NULL; - release_firmware(bcm->initvals0); - bcm->initvals0 = NULL; - release_firmware(bcm->initvals1); - bcm->initvals1 = NULL; -} - -static int bcm43xx_request_firmware(struct bcm43xx_private *bcm) -{ - struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm); - u8 rev = bcm->current_core->rev; - int err = 0; - int nr; - char buf[22 + sizeof(modparam_fwpostfix) - 1] = { 0 }; - - if (!bcm->ucode) { - snprintf(buf, ARRAY_SIZE(buf), "bcm43xx_microcode%d%s.fw", - (rev >= 5 ? 5 : rev), - modparam_fwpostfix); - err = request_firmware(&bcm->ucode, buf, &bcm->pci_dev->dev); - if (err) { - printk(KERN_ERR PFX - "Error: Microcode \"%s\" not available or load failed.\n", - buf); - goto error; - } - } - - if (!bcm->pcm) { - snprintf(buf, ARRAY_SIZE(buf), - "bcm43xx_pcm%d%s.fw", - (rev < 5 ? 4 : 5), - modparam_fwpostfix); - err = request_firmware(&bcm->pcm, buf, &bcm->pci_dev->dev); - if (err) { - printk(KERN_ERR PFX - "Error: PCM \"%s\" not available or load failed.\n", - buf); - goto error; - } - } - - if (!bcm->initvals0) { - if (rev == 2 || rev == 4) { - switch (phy->type) { - case BCM43xx_PHYTYPE_A: - nr = 3; - break; - case BCM43xx_PHYTYPE_B: - case BCM43xx_PHYTYPE_G: - nr = 1; - break; - default: - goto err_noinitval; - } - - } else if (rev >= 5) { - switch (phy->type) { - case BCM43xx_PHYTYPE_A: - nr = 7; - break; - case BCM43xx_PHYTYPE_B: - case BCM43xx_PHYTYPE_G: - nr = 5; - break; - default: - goto err_noinitval; - } - } else - goto err_noinitval; - snprintf(buf, ARRAY_SIZE(buf), "bcm43xx_initval%02d%s.fw", - nr, modparam_fwpostfix); - - err = request_firmware(&bcm->initvals0, buf, &bcm->pci_dev->dev); - if (err) { - printk(KERN_ERR PFX - "Error: InitVals \"%s\" not available or load failed.\n", - buf); - goto error; - } - if (bcm->initvals0->size % sizeof(struct bcm43xx_initval)) { - printk(KERN_ERR PFX "InitVals fileformat error.\n"); - goto error; - } - } - - if (!bcm->initvals1) { - if (rev >= 5) { - u32 sbtmstatehigh; - - switch (phy->type) { - case BCM43xx_PHYTYPE_A: - sbtmstatehigh = bcm43xx_read32(bcm, BCM43xx_CIR_SBTMSTATEHIGH); - if (sbtmstatehigh & 0x00010000) - nr = 9; - else - nr = 10; - break; - case BCM43xx_PHYTYPE_B: - case BCM43xx_PHYTYPE_G: - nr = 6; - break; - default: - goto err_noinitval; - } - snprintf(buf, ARRAY_SIZE(buf), "bcm43xx_initval%02d%s.fw", - nr, modparam_fwpostfix); - - err = request_firmware(&bcm->initvals1, buf, &bcm->pci_dev->dev); - if (err) { - printk(KERN_ERR PFX - "Error: InitVals \"%s\" not available or load failed.\n", - buf); - goto error; - } - if (bcm->initvals1->size % sizeof(struct bcm43xx_initval)) { - printk(KERN_ERR PFX "InitVals fileformat error.\n"); - goto error; - } - } - } - -out: - return err; -error: - bcm43xx_release_firmware(bcm, 1); - goto out; -err_noinitval: - printk(KERN_ERR PFX "Error: No InitVals available!\n"); - err = -ENOENT; - goto error; -} - -static void bcm43xx_upload_microcode(struct bcm43xx_private *bcm) -{ - const u32 *data; - unsigned int i, len; - - /* Upload Microcode. */ - data = (u32 *)(bcm->ucode->data); - len = bcm->ucode->size / sizeof(u32); - bcm43xx_shm_control_word(bcm, BCM43xx_SHM_UCODE, 0x0000); - for (i = 0; i < len; i++) { - bcm43xx_write32(bcm, BCM43xx_MMIO_SHM_DATA, - be32_to_cpu(data[i])); - udelay(10); - } - - /* Upload PCM data. */ - data = (u32 *)(bcm->pcm->data); - len = bcm->pcm->size / sizeof(u32); - bcm43xx_shm_control_word(bcm, BCM43xx_SHM_PCM, 0x01ea); - bcm43xx_write32(bcm, BCM43xx_MMIO_SHM_DATA, 0x00004000); - bcm43xx_shm_control_word(bcm, BCM43xx_SHM_PCM, 0x01eb); - for (i = 0; i < len; i++) { - bcm43xx_write32(bcm, BCM43xx_MMIO_SHM_DATA, - be32_to_cpu(data[i])); - udelay(10); - } -} - -static int bcm43xx_write_initvals(struct bcm43xx_private *bcm, - const struct bcm43xx_initval *data, - const unsigned int len) -{ - u16 offset, size; - u32 value; - unsigned int i; - - for (i = 0; i < len; i++) { - offset = be16_to_cpu(data[i].offset); - size = be16_to_cpu(data[i].size); - value = be32_to_cpu(data[i].value); - - if (unlikely(offset >= 0x1000)) - goto err_format; - if (size == 2) { - if (unlikely(value & 0xFFFF0000)) - goto err_format; - bcm43xx_write16(bcm, offset, (u16)value); - } else if (size == 4) { - bcm43xx_write32(bcm, offset, value); - } else - goto err_format; - } - - return 0; - -err_format: - printk(KERN_ERR PFX "InitVals (bcm43xx_initvalXX.fw) file-format error. " - "Please fix your bcm43xx firmware files.\n"); - return -EPROTO; -} - -static int bcm43xx_upload_initvals(struct bcm43xx_private *bcm) -{ - int err; - - err = bcm43xx_write_initvals(bcm, (struct bcm43xx_initval *)bcm->initvals0->data, - bcm->initvals0->size / sizeof(struct bcm43xx_initval)); - if (err) - goto out; - if (bcm->initvals1) { - err = bcm43xx_write_initvals(bcm, (struct bcm43xx_initval *)bcm->initvals1->data, - bcm->initvals1->size / sizeof(struct bcm43xx_initval)); - if (err) - goto out; - } -out: - return err; -} - -static int bcm43xx_initialize_irq(struct bcm43xx_private *bcm) -{ - int res; - unsigned int i; - u32 data; - - bcm->irq = bcm->pci_dev->irq; -#ifdef CONFIG_BCM947XX - if (bcm->pci_dev->bus->number == 0) { - struct pci_dev *d = NULL; - /* FIXME: we will probably need more device IDs here... */ - d = pci_find_device(PCI_VENDOR_ID_BROADCOM, 0x4324, NULL); - if (d != NULL) { - bcm->irq = d->irq; - } - } -#endif - res = request_irq(bcm->irq, bcm43xx_interrupt_handler, - SA_SHIRQ, KBUILD_MODNAME, bcm); - if (res) { - printk(KERN_ERR PFX "Cannot register IRQ%d\n", bcm->irq); - return -ENODEV; - } - bcm43xx_write32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON, 0xffffffff); - bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD, 0x00020402); - i = 0; - while (1) { - data = bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON); - if (data == BCM43xx_IRQ_READY) - break; - i++; - if (i >= BCM43xx_IRQWAIT_MAX_RETRIES) { - printk(KERN_ERR PFX "Card IRQ register not responding. " - "Giving up.\n"); - free_irq(bcm->irq, bcm); - return -ENODEV; - } - udelay(10); - } - // dummy read - bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON); - - return 0; -} - -/* Switch to the core used to write the GPIO register. - * This is either the ChipCommon, or the PCI core. - */ -static int switch_to_gpio_core(struct bcm43xx_private *bcm) -{ - int err; - - /* Where to find the GPIO register depends on the chipset. - * If it has a ChipCommon, its register at offset 0x6c is the GPIO - * control register. Otherwise the register at offset 0x6c in the - * PCI core is the GPIO control register. - */ - err = bcm43xx_switch_core(bcm, &bcm->core_chipcommon); - if (err == -ENODEV) { - err = bcm43xx_switch_core(bcm, &bcm->core_pci); - if (unlikely(err == -ENODEV)) { - printk(KERN_ERR PFX "gpio error: " - "Neither ChipCommon nor PCI core available!\n"); - } - } - - return err; -} - -/* Initialize the GPIOs - * http://bcm-specs.sipsolutions.net/GPIO - */ -static int bcm43xx_gpio_init(struct bcm43xx_private *bcm) -{ - struct bcm43xx_coreinfo *old_core; - int err; - u32 mask, set; - - bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD, - bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD) - & 0xFFFF3FFF); - - bcm43xx_leds_switch_all(bcm, 0); - bcm43xx_write16(bcm, BCM43xx_MMIO_GPIO_MASK, - bcm43xx_read16(bcm, BCM43xx_MMIO_GPIO_MASK) | 0x000F); - - mask = 0x0000001F; - set = 0x0000000F; - if (bcm->chip_id == 0x4301) { - mask |= 0x0060; - set |= 0x0060; - } - if (0 /* FIXME: conditional unknown */) { - bcm43xx_write16(bcm, BCM43xx_MMIO_GPIO_MASK, - bcm43xx_read16(bcm, BCM43xx_MMIO_GPIO_MASK) - | 0x0100); - mask |= 0x0180; - set |= 0x0180; - } - if (bcm->sprom.boardflags & BCM43xx_BFL_PACTRL) { - bcm43xx_write16(bcm, BCM43xx_MMIO_GPIO_MASK, - bcm43xx_read16(bcm, BCM43xx_MMIO_GPIO_MASK) - | 0x0200); - mask |= 0x0200; - set |= 0x0200; - } - if (bcm->current_core->rev >= 2) - mask |= 0x0010; /* FIXME: This is redundant. */ - - old_core = bcm->current_core; - err = switch_to_gpio_core(bcm); - if (err) - goto out; - bcm43xx_write32(bcm, BCM43xx_GPIO_CONTROL, - (bcm43xx_read32(bcm, BCM43xx_GPIO_CONTROL) & mask) | set); - err = bcm43xx_switch_core(bcm, old_core); -out: - return err; -} - -/* Turn off all GPIO stuff. Call this on module unload, for example. */ -static int bcm43xx_gpio_cleanup(struct bcm43xx_private *bcm) -{ - struct bcm43xx_coreinfo *old_core; - int err; - - old_core = bcm->current_core; - err = switch_to_gpio_core(bcm); - if (err) - return err; - bcm43xx_write32(bcm, BCM43xx_GPIO_CONTROL, 0x00000000); - err = bcm43xx_switch_core(bcm, old_core); - assert(err == 0); - - return 0; -} - -/* http://bcm-specs.sipsolutions.net/EnableMac */ -void bcm43xx_mac_enable(struct bcm43xx_private *bcm) -{ - bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD, - bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD) - | BCM43xx_SBF_MAC_ENABLED); - bcm43xx_write32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON, BCM43xx_IRQ_READY); - bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD); /* dummy read */ - bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON); /* dummy read */ - bcm43xx_power_saving_ctl_bits(bcm, -1, -1); -} - -/* http://bcm-specs.sipsolutions.net/SuspendMAC */ -void bcm43xx_mac_suspend(struct bcm43xx_private *bcm) -{ - int i; - u32 tmp; - - bcm43xx_power_saving_ctl_bits(bcm, -1, 1); - bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD, - bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD) - & ~BCM43xx_SBF_MAC_ENABLED); - bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON); /* dummy read */ - for (i = 100000; i; i--) { - tmp = bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON); - if (tmp & BCM43xx_IRQ_READY) - return; - udelay(10); - } - printkl(KERN_ERR PFX "MAC suspend failed\n"); -} - -void bcm43xx_set_iwmode(struct bcm43xx_private *bcm, - int iw_mode) -{ - unsigned long flags; - struct net_device *net_dev = bcm->net_dev; - u32 status; - u16 value; - - spin_lock_irqsave(&bcm->ieee->lock, flags); - bcm->ieee->iw_mode = iw_mode; - spin_unlock_irqrestore(&bcm->ieee->lock, flags); - if (iw_mode == IW_MODE_MONITOR) - net_dev->type = ARPHRD_IEEE80211; - else - net_dev->type = ARPHRD_ETHER; - - status = bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD); - /* Reset status to infrastructured mode */ - status &= ~(BCM43xx_SBF_MODE_AP | BCM43xx_SBF_MODE_MONITOR); - status &= ~BCM43xx_SBF_MODE_PROMISC; - status |= BCM43xx_SBF_MODE_NOTADHOC; - -/* FIXME: Always enable promisc mode, until we get the MAC filters working correctly. */ -status |= BCM43xx_SBF_MODE_PROMISC; - - switch (iw_mode) { - case IW_MODE_MONITOR: - status |= BCM43xx_SBF_MODE_MONITOR; - status |= BCM43xx_SBF_MODE_PROMISC; - break; - case IW_MODE_ADHOC: - status &= ~BCM43xx_SBF_MODE_NOTADHOC; - break; - case IW_MODE_MASTER: - status |= BCM43xx_SBF_MODE_AP; - break; - case IW_MODE_SECOND: - case IW_MODE_REPEAT: - TODO(); /* TODO */ - break; - case IW_MODE_INFRA: - /* nothing to be done here... */ - break; - default: - dprintk(KERN_ERR PFX "Unknown mode in set_iwmode: %d\n", iw_mode); - } - if (net_dev->flags & IFF_PROMISC) - status |= BCM43xx_SBF_MODE_PROMISC; - bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD, status); - - value = 0x0002; - if (iw_mode != IW_MODE_ADHOC && iw_mode != IW_MODE_MASTER) { - if (bcm->chip_id == 0x4306 && bcm->chip_rev == 3) - value = 0x0064; - else - value = 0x0032; - } - bcm43xx_write16(bcm, 0x0612, value); -} - -/* This is the opposite of bcm43xx_chip_init() */ -static void bcm43xx_chip_cleanup(struct bcm43xx_private *bcm) -{ - bcm43xx_radio_turn_off(bcm); - if (!modparam_noleds) - bcm43xx_leds_exit(bcm); - bcm43xx_gpio_cleanup(bcm); - free_irq(bcm->irq, bcm); - bcm43xx_release_firmware(bcm, 0); -} - -/* Initialize the chip - * http://bcm-specs.sipsolutions.net/ChipInit - */ -static int bcm43xx_chip_init(struct bcm43xx_private *bcm) -{ - struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm); - struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm); - int err; - int tmp; - u32 value32; - u16 value16; - - bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD, - BCM43xx_SBF_CORE_READY - | BCM43xx_SBF_400); - - err = bcm43xx_request_firmware(bcm); - if (err) - goto out; - bcm43xx_upload_microcode(bcm); - - err = bcm43xx_initialize_irq(bcm); - if (err) - goto err_release_fw; - - err = bcm43xx_gpio_init(bcm); - if (err) - goto err_free_irq; - - err = bcm43xx_upload_initvals(bcm); - if (err) - goto err_gpio_cleanup; - bcm43xx_radio_turn_on(bcm); - - bcm43xx_write16(bcm, 0x03E6, 0x0000); - err = bcm43xx_phy_init(bcm); - if (err) - goto err_radio_off; - - /* Select initial Interference Mitigation. */ - tmp = radio->interfmode; - radio->interfmode = BCM43xx_RADIO_INTERFMODE_NONE; - bcm43xx_radio_set_interference_mitigation(bcm, tmp); - - bcm43xx_phy_set_antenna_diversity(bcm); - bcm43xx_radio_set_txantenna(bcm, BCM43xx_RADIO_TXANTENNA_DEFAULT); - if (phy->type == BCM43xx_PHYTYPE_B) { - value16 = bcm43xx_read16(bcm, 0x005E); - value16 |= 0x0004; - bcm43xx_write16(bcm, 0x005E, value16); - } - bcm43xx_write32(bcm, 0x0100, 0x01000000); - if (bcm->current_core->rev < 5) - bcm43xx_write32(bcm, 0x010C, 0x01000000); - - value32 = bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD); - value32 &= ~ BCM43xx_SBF_MODE_NOTADHOC; - bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD, value32); - value32 = bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD); - value32 |= BCM43xx_SBF_MODE_NOTADHOC; - bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD, value32); - - value32 = bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD); - value32 |= 0x100000; - bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD, value32); - - if (bcm43xx_using_pio(bcm)) { - bcm43xx_write32(bcm, 0x0210, 0x00000100); - bcm43xx_write32(bcm, 0x0230, 0x00000100); - bcm43xx_write32(bcm, 0x0250, 0x00000100); - bcm43xx_write32(bcm, 0x0270, 0x00000100); - bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, 0x0034, 0x0000); - } - - /* Probe Response Timeout value */ - /* FIXME: Default to 0, has to be set by ioctl probably... :-/ */ - bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, 0x0074, 0x0000); - - /* Initially set the wireless operation mode. */ - bcm43xx_set_iwmode(bcm, bcm->ieee->iw_mode); - - if (bcm->current_core->rev < 3) { - bcm43xx_write16(bcm, 0x060E, 0x0000); - bcm43xx_write16(bcm, 0x0610, 0x8000); - bcm43xx_write16(bcm, 0x0604, 0x0000); - bcm43xx_write16(bcm, 0x0606, 0x0200); - } else { - bcm43xx_write32(bcm, 0x0188, 0x80000000); - bcm43xx_write32(bcm, 0x018C, 0x02000000); - } - bcm43xx_write32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON, 0x00004000); - bcm43xx_write32(bcm, BCM43xx_MMIO_DMA1_IRQ_MASK, 0x0001DC00); - bcm43xx_write32(bcm, BCM43xx_MMIO_DMA2_IRQ_MASK, 0x0000DC00); - bcm43xx_write32(bcm, BCM43xx_MMIO_DMA3_IRQ_MASK, 0x0000DC00); - bcm43xx_write32(bcm, BCM43xx_MMIO_DMA4_IRQ_MASK, 0x0001DC00); - - value32 = bcm43xx_read32(bcm, BCM43xx_CIR_SBTMSTATELOW); - value32 |= 0x00100000; - bcm43xx_write32(bcm, BCM43xx_CIR_SBTMSTATELOW, value32); - - bcm43xx_write16(bcm, BCM43xx_MMIO_POWERUP_DELAY, bcm43xx_pctl_powerup_delay(bcm)); - - assert(err == 0); - dprintk(KERN_INFO PFX "Chip initialized\n"); -out: - return err; - -err_radio_off: - bcm43xx_radio_turn_off(bcm); -err_gpio_cleanup: - bcm43xx_gpio_cleanup(bcm); -err_free_irq: - free_irq(bcm->irq, bcm); -err_release_fw: - bcm43xx_release_firmware(bcm, 1); - goto out; -} - -/* Validate chip access - * http://bcm-specs.sipsolutions.net/ValidateChipAccess */ -static int bcm43xx_validate_chip(struct bcm43xx_private *bcm) -{ - u32 value; - u32 shm_backup; - - shm_backup = bcm43xx_shm_read32(bcm, BCM43xx_SHM_SHARED, 0x0000); - bcm43xx_shm_write32(bcm, BCM43xx_SHM_SHARED, 0x0000, 0xAA5555AA); - if (bcm43xx_shm_read32(bcm, BCM43xx_SHM_SHARED, 0x0000) != 0xAA5555AA) - goto error; - bcm43xx_shm_write32(bcm, BCM43xx_SHM_SHARED, 0x0000, 0x55AAAA55); - if (bcm43xx_shm_read32(bcm, BCM43xx_SHM_SHARED, 0x0000) != 0x55AAAA55) - goto error; - bcm43xx_shm_write32(bcm, BCM43xx_SHM_SHARED, 0x0000, shm_backup); - - value = bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD); - if ((value | 0x80000000) != 0x80000400) - goto error; - - value = bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON); - if (value != 0x00000000) - goto error; - - return 0; -error: - printk(KERN_ERR PFX "Failed to validate the chipaccess\n"); - return -ENODEV; -} - -static void bcm43xx_init_struct_phyinfo(struct bcm43xx_phyinfo *phy) -{ - /* Initialize a "phyinfo" structure. The structure is already - * zeroed out. - */ - phy->antenna_diversity = 0xFFFF; - phy->savedpctlreg = 0xFFFF; - phy->minlowsig[0] = 0xFFFF; - phy->minlowsig[1] = 0xFFFF; - spin_lock_init(&phy->lock); -} - -static void bcm43xx_init_struct_radioinfo(struct bcm43xx_radioinfo *radio) -{ - /* Initialize a "radioinfo" structure. The structure is already - * zeroed out. - */ - radio->interfmode = BCM43xx_RADIO_INTERFMODE_NONE; - radio->channel = 0xFF; - radio->initial_channel = 0xFF; - radio->lofcal = 0xFFFF; - radio->initval = 0xFFFF; - radio->nrssi[0] = -1000; - radio->nrssi[1] = -1000; -} - -static int bcm43xx_probe_cores(struct bcm43xx_private *bcm) -{ - int err, i; - int current_core; - u32 core_vendor, core_id, core_rev; - u32 sb_id_hi, chip_id_32 = 0; - u16 pci_device, chip_id_16; - u8 core_count; - - memset(&bcm->core_chipcommon, 0, sizeof(struct bcm43xx_coreinfo)); - memset(&bcm->core_pci, 0, sizeof(struct bcm43xx_coreinfo)); - memset(&bcm->core_80211, 0, sizeof(struct bcm43xx_coreinfo) - * BCM43xx_MAX_80211_CORES); - memset(&bcm->core_80211_ext, 0, sizeof(struct bcm43xx_coreinfo_80211) - * BCM43xx_MAX_80211_CORES); - bcm->current_80211_core_idx = -1; - bcm->nr_80211_available = 0; - bcm->current_core = NULL; - bcm->active_80211_core = NULL; - - /* map core 0 */ - err = _switch_core(bcm, 0); - if (err) - goto out; - - /* fetch sb_id_hi from core information registers */ - sb_id_hi = bcm43xx_read32(bcm, BCM43xx_CIR_SB_ID_HI); - - core_id = (sb_id_hi & 0xFFF0) >> 4; - core_rev = (sb_id_hi & 0xF); - core_vendor = (sb_id_hi & 0xFFFF0000) >> 16; - - /* if present, chipcommon is always core 0; read the chipid from it */ - if (core_id == BCM43xx_COREID_CHIPCOMMON) { - chip_id_32 = bcm43xx_read32(bcm, 0); - chip_id_16 = chip_id_32 & 0xFFFF; - bcm->core_chipcommon.available = 1; - bcm->core_chipcommon.id = core_id; - bcm->core_chipcommon.rev = core_rev; - bcm->core_chipcommon.index = 0; - /* While we are at it, also read the capabilities. */ - bcm->chipcommon_capabilities = bcm43xx_read32(bcm, BCM43xx_CHIPCOMMON_CAPABILITIES); - } else { - /* without a chipCommon, use a hard coded table. */ - pci_device = bcm->pci_dev->device; - if (pci_device == 0x4301) - chip_id_16 = 0x4301; - else if ((pci_device >= 0x4305) && (pci_device <= 0x4307)) - chip_id_16 = 0x4307; - else if ((pci_device >= 0x4402) && (pci_device <= 0x4403)) - chip_id_16 = 0x4402; - else if ((pci_device >= 0x4610) && (pci_device <= 0x4615)) - chip_id_16 = 0x4610; - else if ((pci_device >= 0x4710) && (pci_device <= 0x4715)) - chip_id_16 = 0x4710; -#ifdef CONFIG_BCM947XX - else if ((pci_device >= 0x4320) && (pci_device <= 0x4325)) - chip_id_16 = 0x4309; -#endif - else { - printk(KERN_ERR PFX "Could not determine Chip ID\n"); - return -ENODEV; - } - } - - /* ChipCommon with Core Rev >=4 encodes number of cores, - * otherwise consult hardcoded table */ - if ((core_id == BCM43xx_COREID_CHIPCOMMON) && (core_rev >= 4)) { - core_count = (chip_id_32 & 0x0F000000) >> 24; - } else { - switch (chip_id_16) { - case 0x4610: - case 0x4704: - case 0x4710: - core_count = 9; - break; - case 0x4310: - core_count = 8; - break; - case 0x5365: - core_count = 7; - break; - case 0x4306: - core_count = 6; - break; - case 0x4301: - case 0x4307: - core_count = 5; - break; - case 0x4402: - core_count = 3; - break; - default: - /* SOL if we get here */ - assert(0); - core_count = 1; - } - } - - bcm->chip_id = chip_id_16; - bcm->chip_rev = (chip_id_32 & 0x000F0000) >> 16; - bcm->chip_package = (chip_id_32 & 0x00F00000) >> 20; - - dprintk(KERN_INFO PFX "Chip ID 0x%x, rev 0x%x\n", - bcm->chip_id, bcm->chip_rev); - dprintk(KERN_INFO PFX "Number of cores: %d\n", core_count); - if (bcm->core_chipcommon.available) { - dprintk(KERN_INFO PFX "Core 0: ID 0x%x, rev 0x%x, vendor 0x%x, %s\n", - core_id, core_rev, core_vendor, - bcm43xx_core_enabled(bcm) ? "enabled" : "disabled"); - } - - if (bcm->core_chipcommon.available) - current_core = 1; - else - current_core = 0; - for ( ; current_core < core_count; current_core++) { - struct bcm43xx_coreinfo *core; - struct bcm43xx_coreinfo_80211 *ext_80211; - - err = _switch_core(bcm, current_core); - if (err) - goto out; - /* Gather information */ - /* fetch sb_id_hi from core information registers */ - sb_id_hi = bcm43xx_read32(bcm, BCM43xx_CIR_SB_ID_HI); - - /* extract core_id, core_rev, core_vendor */ - core_id = (sb_id_hi & 0xFFF0) >> 4; - core_rev = (sb_id_hi & 0xF); - core_vendor = (sb_id_hi & 0xFFFF0000) >> 16; - - dprintk(KERN_INFO PFX "Core %d: ID 0x%x, rev 0x%x, vendor 0x%x, %s\n", - current_core, core_id, core_rev, core_vendor, - bcm43xx_core_enabled(bcm) ? "enabled" : "disabled" ); - - core = NULL; - switch (core_id) { - case BCM43xx_COREID_PCI: - core = &bcm->core_pci; - if (core->available) { - printk(KERN_WARNING PFX "Multiple PCI cores found.\n"); - continue; - } - break; - case BCM43xx_COREID_80211: - for (i = 0; i < BCM43xx_MAX_80211_CORES; i++) { - core = &(bcm->core_80211[i]); - ext_80211 = &(bcm->core_80211_ext[i]); - if (!core->available) - break; - core = NULL; - } - if (!core) { - printk(KERN_WARNING PFX "More than %d cores of type 802.11 found.\n", - BCM43xx_MAX_80211_CORES); - continue; - } - if (i != 0) { - /* More than one 80211 core is only supported - * by special chips. - * There are chips with two 80211 cores, but with - * dangling pins on the second core. Be careful - * and ignore these cores here. - */ - if (bcm->pci_dev->device != 0x4324) { - dprintk(KERN_INFO PFX "Ignoring additional 802.11 core.\n"); - continue; - } - } - switch (core_rev) { - case 2: - case 4: - case 5: - case 6: - case 7: - case 9: - break; - default: - printk(KERN_ERR PFX "Error: Unsupported 80211 core revision %u\n", - core_rev); - err = -ENODEV; - goto out; - } - bcm->nr_80211_available++; - bcm43xx_init_struct_phyinfo(&ext_80211->phy); - bcm43xx_init_struct_radioinfo(&ext_80211->radio); - break; - case BCM43xx_COREID_CHIPCOMMON: - printk(KERN_WARNING PFX "Multiple CHIPCOMMON cores found.\n"); - break; - } - if (core) { - core->available = 1; - core->id = core_id; - core->rev = core_rev; - core->index = current_core; - } - } - - if (!bcm->core_80211[0].available) { - printk(KERN_ERR PFX "Error: No 80211 core found!\n"); - err = -ENODEV; - goto out; - } - - err = bcm43xx_switch_core(bcm, &bcm->core_80211[0]); - - assert(err == 0); -out: - return err; -} - -static void bcm43xx_gen_bssid(struct bcm43xx_private *bcm) -{ - const u8 *mac = (const u8*)(bcm->net_dev->dev_addr); - u8 *bssid = bcm->ieee->bssid; - - switch (bcm->ieee->iw_mode) { - case IW_MODE_ADHOC: - random_ether_addr(bssid); - break; - case IW_MODE_MASTER: - case IW_MODE_INFRA: - case IW_MODE_REPEAT: - case IW_MODE_SECOND: - case IW_MODE_MONITOR: - memcpy(bssid, mac, ETH_ALEN); - break; - default: - assert(0); - } -} - -static void bcm43xx_rate_memory_write(struct bcm43xx_private *bcm, - u16 rate, - int is_ofdm) -{ - u16 offset; - - if (is_ofdm) { - offset = 0x480; - offset += (bcm43xx_plcp_get_ratecode_ofdm(rate) & 0x000F) * 2; - } - else { - offset = 0x4C0; - offset += (bcm43xx_plcp_get_ratecode_cck(rate) & 0x000F) * 2; - } - bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, offset + 0x20, - bcm43xx_shm_read16(bcm, BCM43xx_SHM_SHARED, offset)); -} - -static void bcm43xx_rate_memory_init(struct bcm43xx_private *bcm) -{ - switch (bcm43xx_current_phy(bcm)->type) { - case BCM43xx_PHYTYPE_A: - case BCM43xx_PHYTYPE_G: - bcm43xx_rate_memory_write(bcm, IEEE80211_OFDM_RATE_6MB, 1); - bcm43xx_rate_memory_write(bcm, IEEE80211_OFDM_RATE_12MB, 1); - bcm43xx_rate_memory_write(bcm, IEEE80211_OFDM_RATE_18MB, 1); - bcm43xx_rate_memory_write(bcm, IEEE80211_OFDM_RATE_24MB, 1); - bcm43xx_rate_memory_write(bcm, IEEE80211_OFDM_RATE_36MB, 1); - bcm43xx_rate_memory_write(bcm, IEEE80211_OFDM_RATE_48MB, 1); - bcm43xx_rate_memory_write(bcm, IEEE80211_OFDM_RATE_54MB, 1); - case BCM43xx_PHYTYPE_B: - bcm43xx_rate_memory_write(bcm, IEEE80211_CCK_RATE_1MB, 0); - bcm43xx_rate_memory_write(bcm, IEEE80211_CCK_RATE_2MB, 0); - bcm43xx_rate_memory_write(bcm, IEEE80211_CCK_RATE_5MB, 0); - bcm43xx_rate_memory_write(bcm, IEEE80211_CCK_RATE_11MB, 0); - break; - default: - assert(0); - } -} - -static void bcm43xx_wireless_core_cleanup(struct bcm43xx_private *bcm) -{ - bcm43xx_chip_cleanup(bcm); - bcm43xx_pio_free(bcm); - bcm43xx_dma_free(bcm); - - bcm->current_core->initialized = 0; -} - -/* http://bcm-specs.sipsolutions.net/80211Init */ -static int bcm43xx_wireless_core_init(struct bcm43xx_private *bcm) -{ - struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm); - struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm); - u32 ucodeflags; - int err; - u32 sbimconfiglow; - u8 limit; - - if (bcm->chip_rev < 5) { - sbimconfiglow = bcm43xx_read32(bcm, BCM43xx_CIR_SBIMCONFIGLOW); - sbimconfiglow &= ~ BCM43xx_SBIMCONFIGLOW_REQUEST_TOUT_MASK; - sbimconfiglow &= ~ BCM43xx_SBIMCONFIGLOW_SERVICE_TOUT_MASK; - if (bcm->bustype == BCM43xx_BUSTYPE_PCI) - sbimconfiglow |= 0x32; - else if (bcm->bustype == BCM43xx_BUSTYPE_SB) - sbimconfiglow |= 0x53; - else - assert(0); - bcm43xx_write32(bcm, BCM43xx_CIR_SBIMCONFIGLOW, sbimconfiglow); - } - - bcm43xx_phy_calibrate(bcm); - err = bcm43xx_chip_init(bcm); - if (err) - goto out; - - bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, 0x0016, bcm->current_core->rev); - ucodeflags = bcm43xx_shm_read32(bcm, BCM43xx_SHM_SHARED, BCM43xx_UCODEFLAGS_OFFSET); - - if (0 /*FIXME: which condition has to be used here? */) - ucodeflags |= 0x00000010; - - /* HW decryption needs to be set now */ - ucodeflags |= 0x40000000; - - if (phy->type == BCM43xx_PHYTYPE_G) { - ucodeflags |= BCM43xx_UCODEFLAG_UNKBGPHY; - if (phy->rev == 1) - ucodeflags |= BCM43xx_UCODEFLAG_UNKGPHY; - if (bcm->sprom.boardflags & BCM43xx_BFL_PACTRL) - ucodeflags |= BCM43xx_UCODEFLAG_UNKPACTRL; - } else if (phy->type == BCM43xx_PHYTYPE_B) { - ucodeflags |= BCM43xx_UCODEFLAG_UNKBGPHY; - if (phy->rev >= 2 && radio->version == 0x2050) - ucodeflags &= ~BCM43xx_UCODEFLAG_UNKGPHY; - } - - if (ucodeflags != bcm43xx_shm_read32(bcm, BCM43xx_SHM_SHARED, - BCM43xx_UCODEFLAGS_OFFSET)) { - bcm43xx_shm_write32(bcm, BCM43xx_SHM_SHARED, - BCM43xx_UCODEFLAGS_OFFSET, ucodeflags); - } - - /* Short/Long Retry Limit. - * The retry-limit is a 4-bit counter. Enforce this to avoid overflowing - * the chip-internal counter. - */ - limit = limit_value(modparam_short_retry, 0, 0xF); - bcm43xx_shm_write32(bcm, BCM43xx_SHM_WIRELESS, 0x0006, limit); - limit = limit_value(modparam_long_retry, 0, 0xF); - bcm43xx_shm_write32(bcm, BCM43xx_SHM_WIRELESS, 0x0007, limit); - - bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, 0x0044, 3); - bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, 0x0046, 2); - - bcm43xx_rate_memory_init(bcm); - - /* Minimum Contention Window */ - if (phy->type == BCM43xx_PHYTYPE_B) - bcm43xx_shm_write32(bcm, BCM43xx_SHM_WIRELESS, 0x0003, 0x0000001f); - else - bcm43xx_shm_write32(bcm, BCM43xx_SHM_WIRELESS, 0x0003, 0x0000000f); - /* Maximum Contention Window */ - bcm43xx_shm_write32(bcm, BCM43xx_SHM_WIRELESS, 0x0004, 0x000003ff); - - bcm43xx_gen_bssid(bcm); - bcm43xx_write_mac_bssid_templates(bcm); - - if (bcm->current_core->rev >= 5) - bcm43xx_write16(bcm, 0x043C, 0x000C); - - if (bcm43xx_using_pio(bcm)) - err = bcm43xx_pio_init(bcm); - else - err = bcm43xx_dma_init(bcm); - if (err) - goto err_chip_cleanup; - bcm43xx_write16(bcm, 0x0612, 0x0050); - bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, 0x0416, 0x0050); - bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, 0x0414, 0x01F4); - - bcm43xx_mac_enable(bcm); - bcm43xx_interrupt_enable(bcm, bcm->irq_savedstate); - - bcm->current_core->initialized = 1; -out: - return err; - -err_chip_cleanup: - bcm43xx_chip_cleanup(bcm); - goto out; -} - -static int bcm43xx_chipset_attach(struct bcm43xx_private *bcm) -{ - int err; - u16 pci_status; - - err = bcm43xx_pctl_set_crystal(bcm, 1); - if (err) - goto out; - bcm43xx_pci_read_config16(bcm, PCI_STATUS, &pci_status); - bcm43xx_pci_write_config16(bcm, PCI_STATUS, pci_status & ~PCI_STATUS_SIG_TARGET_ABORT); - -out: - return err; -} - -static void bcm43xx_chipset_detach(struct bcm43xx_private *bcm) -{ - bcm43xx_pctl_set_clock(bcm, BCM43xx_PCTL_CLK_SLOW); - bcm43xx_pctl_set_crystal(bcm, 0); -} - -static void bcm43xx_pcicore_broadcast_value(struct bcm43xx_private *bcm, - u32 address, - u32 data) -{ - bcm43xx_write32(bcm, BCM43xx_PCICORE_BCAST_ADDR, address); - bcm43xx_write32(bcm, BCM43xx_PCICORE_BCAST_DATA, data); -} - -static int bcm43xx_pcicore_commit_settings(struct bcm43xx_private *bcm) -{ - int err; - struct bcm43xx_coreinfo *old_core; - - old_core = bcm->current_core; - err = bcm43xx_switch_core(bcm, &bcm->core_pci); - if (err) - goto out; - - bcm43xx_pcicore_broadcast_value(bcm, 0xfd8, 0x00000000); - - bcm43xx_switch_core(bcm, old_core); - assert(err == 0); -out: - return err; -} - -/* Make an I/O Core usable. "core_mask" is the bitmask of the cores to enable. - * To enable core 0, pass a core_mask of 1<<0 - */ -static int bcm43xx_setup_backplane_pci_connection(struct bcm43xx_private *bcm, - u32 core_mask) -{ - u32 backplane_flag_nr; - u32 value; - struct bcm43xx_coreinfo *old_core; - int err = 0; - - value = bcm43xx_read32(bcm, BCM43xx_CIR_SBTPSFLAG); - backplane_flag_nr = value & BCM43xx_BACKPLANE_FLAG_NR_MASK; - - old_core = bcm->current_core; - err = bcm43xx_switch_core(bcm, &bcm->core_pci); - if (err) - goto out; - - if (bcm->core_pci.rev < 6) { - value = bcm43xx_read32(bcm, BCM43xx_CIR_SBINTVEC); - value |= (1 << backplane_flag_nr); - bcm43xx_write32(bcm, BCM43xx_CIR_SBINTVEC, value); - } else { - err = bcm43xx_pci_read_config32(bcm, BCM43xx_PCICFG_ICR, &value); - if (err) { - printk(KERN_ERR PFX "Error: ICR setup failure!\n"); - goto out_switch_back; - } - value |= core_mask << 8; - err = bcm43xx_pci_write_config32(bcm, BCM43xx_PCICFG_ICR, value); - if (err) { - printk(KERN_ERR PFX "Error: ICR setup failure!\n"); - goto out_switch_back; - } - } - - value = bcm43xx_read32(bcm, BCM43xx_PCICORE_SBTOPCI2); - value |= BCM43xx_SBTOPCI2_PREFETCH | BCM43xx_SBTOPCI2_BURST; - bcm43xx_write32(bcm, BCM43xx_PCICORE_SBTOPCI2, value); - - if (bcm->core_pci.rev < 5) { - value = bcm43xx_read32(bcm, BCM43xx_CIR_SBIMCONFIGLOW); - value |= (2 << BCM43xx_SBIMCONFIGLOW_SERVICE_TOUT_SHIFT) - & BCM43xx_SBIMCONFIGLOW_SERVICE_TOUT_MASK; - value |= (3 << BCM43xx_SBIMCONFIGLOW_REQUEST_TOUT_SHIFT) - & BCM43xx_SBIMCONFIGLOW_REQUEST_TOUT_MASK; - bcm43xx_write32(bcm, BCM43xx_CIR_SBIMCONFIGLOW, value); - err = bcm43xx_pcicore_commit_settings(bcm); - assert(err == 0); - } - -out_switch_back: - err = bcm43xx_switch_core(bcm, old_core); -out: - return err; -} - -static void bcm43xx_softmac_init(struct bcm43xx_private *bcm) -{ - ieee80211softmac_start(bcm->net_dev); -} - -static void bcm43xx_periodic_every120sec(struct bcm43xx_private *bcm) -{ - struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm); - - if (phy->type != BCM43xx_PHYTYPE_G || phy->rev < 2) - return; - - bcm43xx_mac_suspend(bcm); - bcm43xx_phy_lo_g_measure(bcm); - bcm43xx_mac_enable(bcm); -} - -static void bcm43xx_periodic_every60sec(struct bcm43xx_private *bcm) -{ - bcm43xx_phy_lo_mark_all_unused(bcm); - if (bcm->sprom.boardflags & BCM43xx_BFL_RSSI) { - bcm43xx_mac_suspend(bcm); - bcm43xx_calc_nrssi_slope(bcm); - bcm43xx_mac_enable(bcm); - } -} - -static void bcm43xx_periodic_every30sec(struct bcm43xx_private *bcm) -{ - /* Update device statistics. */ - bcm43xx_calculate_link_quality(bcm); -} - -static void bcm43xx_periodic_every15sec(struct bcm43xx_private *bcm) -{ - struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm); - struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm); - - if (phy->type == BCM43xx_PHYTYPE_G) { - //TODO: update_aci_moving_average - if (radio->aci_enable && radio->aci_wlan_automatic) { - bcm43xx_mac_suspend(bcm); - if (!radio->aci_enable && 1 /*TODO: not scanning? */) { - if (0 /*TODO: bunch of conditions*/) { - bcm43xx_radio_set_interference_mitigation(bcm, - BCM43xx_RADIO_INTERFMODE_MANUALWLAN); - } - } else if (1/*TODO*/) { - /* - if ((aci_average > 1000) && !(bcm43xx_radio_aci_scan(bcm))) { - bcm43xx_radio_set_interference_mitigation(bcm, - BCM43xx_RADIO_INTERFMODE_NONE); - } - */ - } - bcm43xx_mac_enable(bcm); - } else if (radio->interfmode == BCM43xx_RADIO_INTERFMODE_NONWLAN && - phy->rev == 1) { - //TODO: implement rev1 workaround - } - } - bcm43xx_phy_xmitpower(bcm); //FIXME: unless scanning? - //TODO for APHY (temperature?) -} - -static void bcm43xx_periodic_task_handler(unsigned long d) -{ - struct bcm43xx_private *bcm = (struct bcm43xx_private *)d; - unsigned long flags; - unsigned int state; - - bcm43xx_lock_mmio(bcm, flags); - - assert(bcm->initialized); - state = bcm->periodic_state; - if (state % 8 == 0) - bcm43xx_periodic_every120sec(bcm); - if (state % 4 == 0) - bcm43xx_periodic_every60sec(bcm); - if (state % 2 == 0) - bcm43xx_periodic_every30sec(bcm); - bcm43xx_periodic_every15sec(bcm); - bcm->periodic_state = state + 1; - - mod_timer(&bcm->periodic_tasks, jiffies + (HZ * 15)); - - bcm43xx_unlock_mmio(bcm, flags); -} - -static void bcm43xx_periodic_tasks_delete(struct bcm43xx_private *bcm) -{ - del_timer_sync(&bcm->periodic_tasks); -} - -static void bcm43xx_periodic_tasks_setup(struct bcm43xx_private *bcm) -{ - struct timer_list *timer = &(bcm->periodic_tasks); - - assert(bcm->initialized); - setup_timer(timer, - bcm43xx_periodic_task_handler, - (unsigned long)bcm); - timer->expires = jiffies; - add_timer(timer); -} - -static void bcm43xx_security_init(struct bcm43xx_private *bcm) -{ - bcm->security_offset = bcm43xx_shm_read16(bcm, BCM43xx_SHM_SHARED, - 0x0056) * 2; - bcm43xx_clear_keys(bcm); -} - -/* This is the opposite of bcm43xx_init_board() */ -static void bcm43xx_free_board(struct bcm43xx_private *bcm) -{ - int i, err; - unsigned long flags; - - bcm43xx_sysfs_unregister(bcm); - - bcm43xx_periodic_tasks_delete(bcm); - - bcm43xx_lock(bcm, flags); - bcm->initialized = 0; - bcm->shutting_down = 1; - bcm43xx_unlock(bcm, flags); - - for (i = 0; i < BCM43xx_MAX_80211_CORES; i++) { - if (!bcm->core_80211[i].available) - continue; - if (!bcm->core_80211[i].initialized) - continue; - - err = bcm43xx_switch_core(bcm, &bcm->core_80211[i]); - assert(err == 0); - bcm43xx_wireless_core_cleanup(bcm); - } - - bcm43xx_pctl_set_crystal(bcm, 0); - - bcm43xx_lock(bcm, flags); - bcm->shutting_down = 0; - bcm43xx_unlock(bcm, flags); -} - -static int bcm43xx_init_board(struct bcm43xx_private *bcm) -{ - int i, err; - int connect_phy; - unsigned long flags; - - might_sleep(); - - bcm43xx_lock(bcm, flags); - bcm->initialized = 0; - bcm->shutting_down = 0; - bcm43xx_unlock(bcm, flags); - - err = bcm43xx_pctl_set_crystal(bcm, 1); - if (err) - goto out; - err = bcm43xx_pctl_init(bcm); - if (err) - goto err_crystal_off; - err = bcm43xx_pctl_set_clock(bcm, BCM43xx_PCTL_CLK_FAST); - if (err) - goto err_crystal_off; - - tasklet_enable(&bcm->isr_tasklet); - for (i = 0; i < bcm->nr_80211_available; i++) { - err = bcm43xx_switch_core(bcm, &bcm->core_80211[i]); - assert(err != -ENODEV); - if (err) - goto err_80211_unwind; - - /* Enable the selected wireless core. - * Connect PHY only on the first core. - */ - if (!bcm43xx_core_enabled(bcm)) { - if (bcm->nr_80211_available == 1) { - connect_phy = bcm43xx_current_phy(bcm)->connected; - } else { - if (i == 0) - connect_phy = 1; - else - connect_phy = 0; - } - bcm43xx_wireless_core_reset(bcm, connect_phy); - } - - if (i != 0) - bcm43xx_wireless_core_mark_inactive(bcm, &bcm->core_80211[0]); - - err = bcm43xx_wireless_core_init(bcm); - if (err) - goto err_80211_unwind; - - if (i != 0) { - bcm43xx_mac_suspend(bcm); - bcm43xx_interrupt_disable(bcm, BCM43xx_IRQ_ALL); - bcm43xx_radio_turn_off(bcm); - } - } - bcm->active_80211_core = &bcm->core_80211[0]; - if (bcm->nr_80211_available >= 2) { - bcm43xx_switch_core(bcm, &bcm->core_80211[0]); - bcm43xx_mac_enable(bcm); - } - bcm43xx_macfilter_clear(bcm, BCM43xx_MACFILTER_ASSOC); - bcm43xx_macfilter_set(bcm, BCM43xx_MACFILTER_SELF, (u8 *)(bcm->net_dev->dev_addr)); - dprintk(KERN_INFO PFX "80211 cores initialized\n"); - bcm43xx_security_init(bcm); - bcm43xx_softmac_init(bcm); - - bcm43xx_pctl_set_clock(bcm, BCM43xx_PCTL_CLK_DYNAMIC); - - if (bcm43xx_current_radio(bcm)->initial_channel != 0xFF) { - bcm43xx_mac_suspend(bcm); - bcm43xx_radio_selectchannel(bcm, bcm43xx_current_radio(bcm)->initial_channel, 0); - bcm43xx_mac_enable(bcm); - } - - /* Initialization of the board is done. Flag it as such. */ - bcm43xx_lock(bcm, flags); - bcm->initialized = 1; - bcm43xx_unlock(bcm, flags); - - bcm43xx_periodic_tasks_setup(bcm); - bcm43xx_sysfs_register(bcm); - //FIXME: check for bcm43xx_sysfs_register failure. This function is a bit messy regarding unwinding, though... - - assert(err == 0); -out: - return err; - -err_80211_unwind: - tasklet_disable(&bcm->isr_tasklet); - /* unwind all 80211 initialization */ - for (i = 0; i < bcm->nr_80211_available; i++) { - if (!bcm->core_80211[i].initialized) - continue; - bcm43xx_interrupt_disable(bcm, BCM43xx_IRQ_ALL); - bcm43xx_wireless_core_cleanup(bcm); - } -err_crystal_off: - bcm43xx_pctl_set_crystal(bcm, 0); - goto out; -} - -static void bcm43xx_detach_board(struct bcm43xx_private *bcm) -{ - struct pci_dev *pci_dev = bcm->pci_dev; - int i; - - bcm43xx_chipset_detach(bcm); - /* Do _not_ access the chip, after it is detached. */ - iounmap(bcm->mmio_addr); - - pci_release_regions(pci_dev); - pci_disable_device(pci_dev); - - /* Free allocated structures/fields */ - for (i = 0; i < BCM43xx_MAX_80211_CORES; i++) { - kfree(bcm->core_80211_ext[i].phy._lo_pairs); - if (bcm->core_80211_ext[i].phy.dyn_tssi_tbl) - kfree(bcm->core_80211_ext[i].phy.tssi2dbm); - } -} - -static int bcm43xx_read_phyinfo(struct bcm43xx_private *bcm) -{ - struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm); - u16 value; - u8 phy_version; - u8 phy_type; - u8 phy_rev; - int phy_rev_ok = 1; - void *p; - - value = bcm43xx_read16(bcm, BCM43xx_MMIO_PHY_VER); - - phy_version = (value & 0xF000) >> 12; - phy_type = (value & 0x0F00) >> 8; - phy_rev = (value & 0x000F); - - dprintk(KERN_INFO PFX "Detected PHY: Version: %x, Type %x, Revision %x\n", - phy_version, phy_type, phy_rev); - - switch (phy_type) { - case BCM43xx_PHYTYPE_A: - if (phy_rev >= 4) - phy_rev_ok = 0; - /*FIXME: We need to switch the ieee->modulation, etc.. flags, - * if we switch 80211 cores after init is done. - * As we do not implement on the fly switching between - * wireless cores, I will leave this as a future task. - */ - bcm->ieee->modulation = IEEE80211_OFDM_MODULATION; - bcm->ieee->mode = IEEE_A; - bcm->ieee->freq_band = IEEE80211_52GHZ_BAND | - IEEE80211_24GHZ_BAND; - break; - case BCM43xx_PHYTYPE_B: - if (phy_rev != 2 && phy_rev != 4 && phy_rev != 6 && phy_rev != 7) - phy_rev_ok = 0; - bcm->ieee->modulation = IEEE80211_CCK_MODULATION; - bcm->ieee->mode = IEEE_B; - bcm->ieee->freq_band = IEEE80211_24GHZ_BAND; - break; - case BCM43xx_PHYTYPE_G: - if (phy_rev > 7) - phy_rev_ok = 0; - bcm->ieee->modulation = IEEE80211_OFDM_MODULATION | - IEEE80211_CCK_MODULATION; - bcm->ieee->mode = IEEE_G; - bcm->ieee->freq_band = IEEE80211_24GHZ_BAND; - break; - default: - printk(KERN_ERR PFX "Error: Unknown PHY Type %x\n", - phy_type); - return -ENODEV; - }; - if (!phy_rev_ok) { - printk(KERN_WARNING PFX "Invalid PHY Revision %x\n", - phy_rev); - } - - phy->version = phy_version; - phy->type = phy_type; - phy->rev = phy_rev; - if ((phy_type == BCM43xx_PHYTYPE_B) || (phy_type == BCM43xx_PHYTYPE_G)) { - p = kzalloc(sizeof(struct bcm43xx_lopair) * BCM43xx_LO_COUNT, - GFP_KERNEL); - if (!p) - return -ENOMEM; - phy->_lo_pairs = p; - } - - return 0; -} - -static int bcm43xx_attach_board(struct bcm43xx_private *bcm) -{ - struct pci_dev *pci_dev = bcm->pci_dev; - struct net_device *net_dev = bcm->net_dev; - int err; - int i; - unsigned long mmio_start, mmio_flags, mmio_len; - u32 coremask; - - err = pci_enable_device(pci_dev); - if (err) { - printk(KERN_ERR PFX "unable to wake up pci device (%i)\n", err); - goto out; - } - mmio_start = pci_resource_start(pci_dev, 0); - mmio_flags = pci_resource_flags(pci_dev, 0); - mmio_len = pci_resource_len(pci_dev, 0); - if (!(mmio_flags & IORESOURCE_MEM)) { - printk(KERN_ERR PFX - "%s, region #0 not an MMIO resource, aborting\n", - pci_name(pci_dev)); - err = -ENODEV; - goto err_pci_disable; - } - err = pci_request_regions(pci_dev, KBUILD_MODNAME); - if (err) { - printk(KERN_ERR PFX - "could not access PCI resources (%i)\n", err); - goto err_pci_disable; - } - /* enable PCI bus-mastering */ - pci_set_master(pci_dev); - bcm->mmio_addr = ioremap(mmio_start, mmio_len); - if (!bcm->mmio_addr) { - printk(KERN_ERR PFX "%s: cannot remap MMIO, aborting\n", - pci_name(pci_dev)); - err = -EIO; - goto err_pci_release; - } - bcm->mmio_len = mmio_len; - net_dev->base_addr = (unsigned long)bcm->mmio_addr; - - bcm43xx_pci_read_config16(bcm, PCI_SUBSYSTEM_VENDOR_ID, - &bcm->board_vendor); - bcm43xx_pci_read_config16(bcm, PCI_SUBSYSTEM_ID, - &bcm->board_type); - bcm43xx_pci_read_config16(bcm, PCI_REVISION_ID, - &bcm->board_revision); - - err = bcm43xx_chipset_attach(bcm); - if (err) - goto err_iounmap; - err = bcm43xx_pctl_init(bcm); - if (err) - goto err_chipset_detach; - err = bcm43xx_probe_cores(bcm); - if (err) - goto err_chipset_detach; - - /* Attach all IO cores to the backplane. */ - coremask = 0; - for (i = 0; i < bcm->nr_80211_available; i++) - coremask |= (1 << bcm->core_80211[i].index); - //FIXME: Also attach some non80211 cores? - err = bcm43xx_setup_backplane_pci_connection(bcm, coremask); - if (err) { - printk(KERN_ERR PFX "Backplane->PCI connection failed!\n"); - goto err_chipset_detach; - } - - err = bcm43xx_sprom_extract(bcm); - if (err) - goto err_chipset_detach; - err = bcm43xx_leds_init(bcm); - if (err) - goto err_chipset_detach; - - for (i = 0; i < bcm->nr_80211_available; i++) { - err = bcm43xx_switch_core(bcm, &bcm->core_80211[i]); - assert(err != -ENODEV); - if (err) - goto err_80211_unwind; - - /* Enable the selected wireless core. - * Connect PHY only on the first core. - */ - bcm43xx_wireless_core_reset(bcm, (i == 0)); - - err = bcm43xx_read_phyinfo(bcm); - if (err && (i == 0)) - goto err_80211_unwind; - - err = bcm43xx_read_radioinfo(bcm); - if (err && (i == 0)) - goto err_80211_unwind; - - err = bcm43xx_validate_chip(bcm); - if (err && (i == 0)) - goto err_80211_unwind; - - bcm43xx_radio_turn_off(bcm); - err = bcm43xx_phy_init_tssi2dbm_table(bcm); - if (err) - goto err_80211_unwind; - bcm43xx_wireless_core_disable(bcm); - } - bcm43xx_pctl_set_crystal(bcm, 0); - - /* Set the MAC address in the networking subsystem */ - if (bcm43xx_current_phy(bcm)->type == BCM43xx_PHYTYPE_A) - memcpy(bcm->net_dev->dev_addr, bcm->sprom.et1macaddr, 6); - else - memcpy(bcm->net_dev->dev_addr, bcm->sprom.il0macaddr, 6); - - bcm43xx_geo_init(bcm); - - snprintf(bcm->nick, IW_ESSID_MAX_SIZE, - "Broadcom %04X", bcm->chip_id); - - assert(err == 0); -out: - return err; - -err_80211_unwind: - for (i = 0; i < BCM43xx_MAX_80211_CORES; i++) { - kfree(bcm->core_80211_ext[i].phy._lo_pairs); - if (bcm->core_80211_ext[i].phy.dyn_tssi_tbl) - kfree(bcm->core_80211_ext[i].phy.tssi2dbm); - } -err_chipset_detach: - bcm43xx_chipset_detach(bcm); -err_iounmap: - iounmap(bcm->mmio_addr); -err_pci_release: - pci_release_regions(pci_dev); -err_pci_disable: - pci_disable_device(pci_dev); - goto out; -} - -/* Do the Hardware IO operations to send the txb */ -static inline int bcm43xx_tx(struct bcm43xx_private *bcm, - struct ieee80211_txb *txb) -{ - int err = -ENODEV; - - if (bcm43xx_using_pio(bcm)) - err = bcm43xx_pio_tx(bcm, txb); - else - err = bcm43xx_dma_tx(bcm, txb); - - return err; -} - -static void bcm43xx_ieee80211_set_chan(struct net_device *net_dev, - u8 channel) -{ - struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); - struct bcm43xx_radioinfo *radio; - unsigned long flags; - - bcm43xx_lock_mmio(bcm, flags); - if (bcm->initialized) { - bcm43xx_mac_suspend(bcm); - bcm43xx_radio_selectchannel(bcm, channel, 0); - bcm43xx_mac_enable(bcm); - } else { - radio = bcm43xx_current_radio(bcm); - radio->initial_channel = channel; - } - bcm43xx_unlock_mmio(bcm, flags); -} - -/* set_security() callback in struct ieee80211_device */ -static void bcm43xx_ieee80211_set_security(struct net_device *net_dev, - struct ieee80211_security *sec) -{ - struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); - struct ieee80211_security *secinfo = &bcm->ieee->sec; - unsigned long flags; - int keyidx; - - dprintk(KERN_INFO PFX "set security called\n"); - - bcm43xx_lock_mmio(bcm, flags); - - for (keyidx = 0; keyidxflags & (1<encode_alg[keyidx] = sec->encode_alg[keyidx]; - secinfo->key_sizes[keyidx] = sec->key_sizes[keyidx]; - memcpy(secinfo->keys[keyidx], sec->keys[keyidx], SCM_KEY_LEN); - } - - if (sec->flags & SEC_ACTIVE_KEY) { - secinfo->active_key = sec->active_key; - dprintk(KERN_INFO PFX " .active_key = %d\n", sec->active_key); - } - if (sec->flags & SEC_UNICAST_GROUP) { - secinfo->unicast_uses_group = sec->unicast_uses_group; - dprintk(KERN_INFO PFX " .unicast_uses_group = %d\n", sec->unicast_uses_group); - } - if (sec->flags & SEC_LEVEL) { - secinfo->level = sec->level; - dprintk(KERN_INFO PFX " .level = %d\n", sec->level); - } - if (sec->flags & SEC_ENABLED) { - secinfo->enabled = sec->enabled; - dprintk(KERN_INFO PFX " .enabled = %d\n", sec->enabled); - } - if (sec->flags & SEC_ENCRYPT) { - secinfo->encrypt = sec->encrypt; - dprintk(KERN_INFO PFX " .encrypt = %d\n", sec->encrypt); - } - if (bcm->initialized && !bcm->ieee->host_encrypt) { - if (secinfo->enabled) { - /* upload WEP keys to hardware */ - char null_address[6] = { 0 }; - u8 algorithm = 0; - for (keyidx = 0; keyidxflags & (1<encode_alg[keyidx]) { - case SEC_ALG_NONE: algorithm = BCM43xx_SEC_ALGO_NONE; break; - case SEC_ALG_WEP: - algorithm = BCM43xx_SEC_ALGO_WEP; - if (secinfo->key_sizes[keyidx] == 13) - algorithm = BCM43xx_SEC_ALGO_WEP104; - break; - case SEC_ALG_TKIP: - FIXME(); - algorithm = BCM43xx_SEC_ALGO_TKIP; - break; - case SEC_ALG_CCMP: - FIXME(); - algorithm = BCM43xx_SEC_ALGO_AES; - break; - default: - assert(0); - break; - } - bcm43xx_key_write(bcm, keyidx, algorithm, sec->keys[keyidx], secinfo->key_sizes[keyidx], &null_address[0]); - bcm->key[keyidx].enabled = 1; - bcm->key[keyidx].algorithm = algorithm; - } - } else - bcm43xx_clear_keys(bcm); - } - bcm43xx_unlock_mmio(bcm, flags); -} - -/* hard_start_xmit() callback in struct ieee80211_device */ -static int bcm43xx_ieee80211_hard_start_xmit(struct ieee80211_txb *txb, - struct net_device *net_dev, - int pri) -{ - struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); - int err = -ENODEV; - unsigned long flags; - - bcm43xx_lock_mmio(bcm, flags); - if (likely(bcm->initialized)) - err = bcm43xx_tx(bcm, txb); - bcm43xx_unlock_mmio(bcm, flags); - - return err; -} - -static struct net_device_stats * bcm43xx_net_get_stats(struct net_device *net_dev) -{ - return &(bcm43xx_priv(net_dev)->ieee->stats); -} - -static void bcm43xx_net_tx_timeout(struct net_device *net_dev) -{ - struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); - unsigned long flags; - - bcm43xx_lock_mmio(bcm, flags); - bcm43xx_controller_restart(bcm, "TX timeout"); - bcm43xx_unlock_mmio(bcm, flags); -} - -#ifdef CONFIG_NET_POLL_CONTROLLER -static void bcm43xx_net_poll_controller(struct net_device *net_dev) -{ - struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); - unsigned long flags; - - local_irq_save(flags); - bcm43xx_interrupt_handler(bcm->irq, bcm, NULL); - local_irq_restore(flags); -} -#endif /* CONFIG_NET_POLL_CONTROLLER */ - -static int bcm43xx_net_open(struct net_device *net_dev) -{ - struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); - - return bcm43xx_init_board(bcm); -} - -static int bcm43xx_net_stop(struct net_device *net_dev) -{ - struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); - - ieee80211softmac_stop(net_dev); - bcm43xx_disable_interrupts_sync(bcm, NULL); - bcm43xx_free_board(bcm); - - return 0; -} - -static int bcm43xx_init_private(struct bcm43xx_private *bcm, - struct net_device *net_dev, - struct pci_dev *pci_dev) -{ - int err; - - bcm->ieee = netdev_priv(net_dev); - bcm->softmac = ieee80211_priv(net_dev); - bcm->softmac->set_channel = bcm43xx_ieee80211_set_chan; - - bcm->irq_savedstate = BCM43xx_IRQ_INITIAL; - bcm->pci_dev = pci_dev; - bcm->net_dev = net_dev; - bcm->bad_frames_preempt = modparam_bad_frames_preempt; - spin_lock_init(&bcm->_lock); - tasklet_init(&bcm->isr_tasklet, - (void (*)(unsigned long))bcm43xx_interrupt_tasklet, - (unsigned long)bcm); - tasklet_disable_nosync(&bcm->isr_tasklet); - if (modparam_pio) { - bcm->__using_pio = 1; - } else { - err = pci_set_dma_mask(pci_dev, DMA_30BIT_MASK); - err |= pci_set_consistent_dma_mask(pci_dev, DMA_30BIT_MASK); - if (err) { -#ifdef CONFIG_BCM43XX_PIO - printk(KERN_WARNING PFX "DMA not supported. Falling back to PIO.\n"); - bcm->__using_pio = 1; -#else - printk(KERN_ERR PFX "FATAL: DMA not supported and PIO not configured. " - "Recompile the driver with PIO support, please.\n"); - return -ENODEV; -#endif /* CONFIG_BCM43XX_PIO */ - } - } - bcm->rts_threshold = BCM43xx_DEFAULT_RTS_THRESHOLD; - - /* default to sw encryption for now */ - bcm->ieee->host_build_iv = 0; - bcm->ieee->host_encrypt = 1; - bcm->ieee->host_decrypt = 1; - - bcm->ieee->iw_mode = BCM43xx_INITIAL_IWMODE; - bcm->ieee->tx_headroom = sizeof(struct bcm43xx_txhdr); - bcm->ieee->set_security = bcm43xx_ieee80211_set_security; - bcm->ieee->hard_start_xmit = bcm43xx_ieee80211_hard_start_xmit; - - return 0; -} - -static int __devinit bcm43xx_init_one(struct pci_dev *pdev, - const struct pci_device_id *ent) -{ - struct net_device *net_dev; - struct bcm43xx_private *bcm; - int err; - -#ifdef CONFIG_BCM947XX - if ((pdev->bus->number == 0) && (pdev->device != 0x0800)) - return -ENODEV; -#endif - -#ifdef DEBUG_SINGLE_DEVICE_ONLY - if (strcmp(pci_name(pdev), DEBUG_SINGLE_DEVICE_ONLY)) - return -ENODEV; -#endif - - net_dev = alloc_ieee80211softmac(sizeof(*bcm)); - if (!net_dev) { - printk(KERN_ERR PFX - "could not allocate ieee80211 device %s\n", - pci_name(pdev)); - err = -ENOMEM; - goto out; - } - /* initialize the net_device struct */ - SET_MODULE_OWNER(net_dev); - SET_NETDEV_DEV(net_dev, &pdev->dev); - - net_dev->open = bcm43xx_net_open; - net_dev->stop = bcm43xx_net_stop; - net_dev->get_stats = bcm43xx_net_get_stats; - net_dev->tx_timeout = bcm43xx_net_tx_timeout; -#ifdef CONFIG_NET_POLL_CONTROLLER - net_dev->poll_controller = bcm43xx_net_poll_controller; -#endif - net_dev->wireless_handlers = &bcm43xx_wx_handlers_def; - net_dev->irq = pdev->irq; - SET_ETHTOOL_OPS(net_dev, &bcm43xx_ethtool_ops); - - /* initialize the bcm43xx_private struct */ - bcm = bcm43xx_priv(net_dev); - memset(bcm, 0, sizeof(*bcm)); - err = bcm43xx_init_private(bcm, net_dev, pdev); - if (err) - goto err_free_netdev; - - pci_set_drvdata(pdev, net_dev); - - err = bcm43xx_attach_board(bcm); - if (err) - goto err_free_netdev; - - err = register_netdev(net_dev); - if (err) { - printk(KERN_ERR PFX "Cannot register net device, " - "aborting.\n"); - err = -ENOMEM; - goto err_detach_board; - } - - bcm43xx_debugfs_add_device(bcm); - - assert(err == 0); -out: - return err; - -err_detach_board: - bcm43xx_detach_board(bcm); -err_free_netdev: - free_ieee80211softmac(net_dev); - goto out; -} - -static void __devexit bcm43xx_remove_one(struct pci_dev *pdev) -{ - struct net_device *net_dev = pci_get_drvdata(pdev); - struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); - - bcm43xx_debugfs_remove_device(bcm); - unregister_netdev(net_dev); - bcm43xx_detach_board(bcm); - assert(bcm->ucode == NULL); - free_ieee80211softmac(net_dev); -} - -/* Hard-reset the chip. Do not call this directly. - * Use bcm43xx_controller_restart() - */ -static void bcm43xx_chip_reset(void *_bcm) -{ - struct bcm43xx_private *bcm = _bcm; - struct net_device *net_dev = bcm->net_dev; - struct pci_dev *pci_dev = bcm->pci_dev; - int err; - int was_initialized = bcm->initialized; - - netif_stop_queue(bcm->net_dev); - tasklet_disable(&bcm->isr_tasklet); - - bcm->firmware_norelease = 1; - if (was_initialized) - bcm43xx_free_board(bcm); - bcm->firmware_norelease = 0; - bcm43xx_detach_board(bcm); - err = bcm43xx_init_private(bcm, net_dev, pci_dev); - if (err) - goto failure; - err = bcm43xx_attach_board(bcm); - if (err) - goto failure; - if (was_initialized) { - err = bcm43xx_init_board(bcm); - if (err) - goto failure; - } - netif_wake_queue(bcm->net_dev); - printk(KERN_INFO PFX "Controller restarted\n"); - - return; -failure: - printk(KERN_ERR PFX "Controller restart failed\n"); -} - -/* Hard-reset the chip. - * This can be called from interrupt or process context. - * Make sure to _not_ re-enable device interrupts after this has been called. -*/ -void bcm43xx_controller_restart(struct bcm43xx_private *bcm, const char *reason) -{ - bcm43xx_interrupt_disable(bcm, BCM43xx_IRQ_ALL); - bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD); /* dummy read */ - printk(KERN_ERR PFX "Controller RESET (%s) ...\n", reason); - INIT_WORK(&bcm->restart_work, bcm43xx_chip_reset, bcm); - schedule_work(&bcm->restart_work); -} - -#ifdef CONFIG_PM - -static int bcm43xx_suspend(struct pci_dev *pdev, pm_message_t state) -{ - struct net_device *net_dev = pci_get_drvdata(pdev); - struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); - unsigned long flags; - int try_to_shutdown = 0, err; - - dprintk(KERN_INFO PFX "Suspending...\n"); - - bcm43xx_lock(bcm, flags); - bcm->was_initialized = bcm->initialized; - if (bcm->initialized) - try_to_shutdown = 1; - bcm43xx_unlock(bcm, flags); - - netif_device_detach(net_dev); - if (try_to_shutdown) { - ieee80211softmac_stop(net_dev); - err = bcm43xx_disable_interrupts_sync(bcm, &bcm->irq_savedstate); - if (unlikely(err)) { - dprintk(KERN_ERR PFX "Suspend failed.\n"); - return -EAGAIN; - } - bcm->firmware_norelease = 1; - bcm43xx_free_board(bcm); - bcm->firmware_norelease = 0; - } - bcm43xx_chipset_detach(bcm); - - pci_save_state(pdev); - pci_disable_device(pdev); - pci_set_power_state(pdev, pci_choose_state(pdev, state)); - - dprintk(KERN_INFO PFX "Device suspended.\n"); - - return 0; -} - -static int bcm43xx_resume(struct pci_dev *pdev) -{ - struct net_device *net_dev = pci_get_drvdata(pdev); - struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); - int err = 0; - - dprintk(KERN_INFO PFX "Resuming...\n"); - - pci_set_power_state(pdev, 0); - pci_enable_device(pdev); - pci_restore_state(pdev); - - bcm43xx_chipset_attach(bcm); - if (bcm->was_initialized) { - bcm->irq_savedstate = BCM43xx_IRQ_INITIAL; - err = bcm43xx_init_board(bcm); - } - if (err) { - printk(KERN_ERR PFX "Resume failed!\n"); - return err; - } - - netif_device_attach(net_dev); - - /*FIXME: This should be handled by softmac instead. */ - schedule_work(&bcm->softmac->associnfo.work); - - dprintk(KERN_INFO PFX "Device resumed.\n"); - - return 0; -} - -#endif /* CONFIG_PM */ - -static struct pci_driver bcm43xx_pci_driver = { - .name = KBUILD_MODNAME, - .id_table = bcm43xx_pci_tbl, - .probe = bcm43xx_init_one, - .remove = __devexit_p(bcm43xx_remove_one), -#ifdef CONFIG_PM - .suspend = bcm43xx_suspend, - .resume = bcm43xx_resume, -#endif /* CONFIG_PM */ -}; - -static int __init bcm43xx_init(void) -{ - printk(KERN_INFO KBUILD_MODNAME " driver\n"); - bcm43xx_debugfs_init(); - return pci_register_driver(&bcm43xx_pci_driver); -} - -static void __exit bcm43xx_exit(void) -{ - pci_unregister_driver(&bcm43xx_pci_driver); - bcm43xx_debugfs_exit(); -} - -module_init(bcm43xx_init) -module_exit(bcm43xx_exit) diff --git a/trunk/drivers/net/wireless/bcm43xx/bcm43xx_main.h b/trunk/drivers/net/wireless/bcm43xx/bcm43xx_main.h deleted file mode 100644 index eca79a38594a..000000000000 --- a/trunk/drivers/net/wireless/bcm43xx/bcm43xx_main.h +++ /dev/null @@ -1,168 +0,0 @@ -/* - - Broadcom BCM43xx wireless driver - - Copyright (c) 2005 Martin Langer , - Stefano Brivio - Michael Buesch - Danny van Dyk - Andreas Jaggi - - Some parts of the code in this file are derived from the ipw2200 - driver Copyright(c) 2003 - 2004 Intel Corporation. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; see the file COPYING. If not, write to - the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor, - Boston, MA 02110-1301, USA. - -*/ - -#ifndef BCM43xx_MAIN_H_ -#define BCM43xx_MAIN_H_ - -#include "bcm43xx.h" - -#ifdef CONFIG_BCM947XX -#define atoi(str) simple_strtoul(((str != NULL) ? str : ""), NULL, 0) - -static inline void e_aton(char *str, char *dest) -{ - int i = 0; - u16 *d = (u16 *) dest; - - for (;;) { - dest[i++] = (char) simple_strtoul(str, NULL, 16); - str += 2; - if (!*str++ || i == 6) - break; - } - for (i = 0; i < 3; i++) - d[i] = cpu_to_be16(d[i]); -} -#endif - -#define P4D_BYT3S(magic, nr_bytes) u8 __p4dding##magic[nr_bytes] -#define P4D_BYTES(line, nr_bytes) P4D_BYT3S(line, nr_bytes) -/* Magic helper macro to pad structures. Ignore those above. It's magic. */ -#define PAD_BYTES(nr_bytes) P4D_BYTES( __LINE__ , (nr_bytes)) - - -/* Lightweight function to convert a frequency (in Mhz) to a channel number. */ -static inline -u8 bcm43xx_freq_to_channel_a(int freq) -{ - return ((freq - 5000) / 5); -} -static inline -u8 bcm43xx_freq_to_channel_bg(int freq) -{ - u8 channel; - - if (freq == 2484) - channel = 14; - else - channel = (freq - 2407) / 5; - - return channel; -} -static inline -u8 bcm43xx_freq_to_channel(struct bcm43xx_private *bcm, - int freq) -{ - if (bcm43xx_current_phy(bcm)->type == BCM43xx_PHYTYPE_A) - return bcm43xx_freq_to_channel_a(freq); - return bcm43xx_freq_to_channel_bg(freq); -} - -/* Lightweight function to convert a channel number to a frequency (in Mhz). */ -static inline -int bcm43xx_channel_to_freq_a(u8 channel) -{ - return (5000 + (5 * channel)); -} -static inline -int bcm43xx_channel_to_freq_bg(u8 channel) -{ - int freq; - - if (channel == 14) - freq = 2484; - else - freq = 2407 + (5 * channel); - - return freq; -} -static inline -int bcm43xx_channel_to_freq(struct bcm43xx_private *bcm, - u8 channel) -{ - if (bcm43xx_current_phy(bcm)->type == BCM43xx_PHYTYPE_A) - return bcm43xx_channel_to_freq_a(channel); - return bcm43xx_channel_to_freq_bg(channel); -} - -/* Lightweight function to check if a channel number is valid. - * Note that this does _NOT_ check for geographical restrictions! - */ -static inline -int bcm43xx_is_valid_channel_a(u8 channel) -{ - return (channel <= 200); -} -static inline -int bcm43xx_is_valid_channel_bg(u8 channel) -{ - return (channel >= 1 && channel <= 14); -} -static inline -int bcm43xx_is_valid_channel(struct bcm43xx_private *bcm, - u8 channel) -{ - if (bcm43xx_current_phy(bcm)->type == BCM43xx_PHYTYPE_A) - return bcm43xx_is_valid_channel_a(channel); - return bcm43xx_is_valid_channel_bg(channel); -} - -void bcm43xx_tsf_read(struct bcm43xx_private *bcm, u64 *tsf); -void bcm43xx_tsf_write(struct bcm43xx_private *bcm, u64 tsf); - -void bcm43xx_set_iwmode(struct bcm43xx_private *bcm, - int iw_mode); - -u32 bcm43xx_shm_read32(struct bcm43xx_private *bcm, - u16 routing, u16 offset); -u16 bcm43xx_shm_read16(struct bcm43xx_private *bcm, - u16 routing, u16 offset); -void bcm43xx_shm_write32(struct bcm43xx_private *bcm, - u16 routing, u16 offset, - u32 value); -void bcm43xx_shm_write16(struct bcm43xx_private *bcm, - u16 routing, u16 offset, - u16 value); - -void bcm43xx_dummy_transmission(struct bcm43xx_private *bcm); - -int bcm43xx_switch_core(struct bcm43xx_private *bcm, struct bcm43xx_coreinfo *new_core); - -void bcm43xx_wireless_core_reset(struct bcm43xx_private *bcm, int connect_phy); - -void bcm43xx_mac_suspend(struct bcm43xx_private *bcm); -void bcm43xx_mac_enable(struct bcm43xx_private *bcm); - -void bcm43xx_controller_restart(struct bcm43xx_private *bcm, const char *reason); - -int bcm43xx_sprom_read(struct bcm43xx_private *bcm, u16 *sprom); -int bcm43xx_sprom_write(struct bcm43xx_private *bcm, const u16 *sprom); - -#endif /* BCM43xx_MAIN_H_ */ diff --git a/trunk/drivers/net/wireless/bcm43xx/bcm43xx_phy.c b/trunk/drivers/net/wireless/bcm43xx/bcm43xx_phy.c deleted file mode 100644 index 0a66f43ca0c0..000000000000 --- a/trunk/drivers/net/wireless/bcm43xx/bcm43xx_phy.c +++ /dev/null @@ -1,2345 +0,0 @@ -/* - - Broadcom BCM43xx wireless driver - - Copyright (c) 2005 Martin Langer , - Stefano Brivio - Michael Buesch - Danny van Dyk - Andreas Jaggi - - Some parts of the code in this file are derived from the ipw2200 - driver Copyright(c) 2003 - 2004 Intel Corporation. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; see the file COPYING. If not, write to - the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor, - Boston, MA 02110-1301, USA. - -*/ - -#include -#include -#include - -#include "bcm43xx.h" -#include "bcm43xx_phy.h" -#include "bcm43xx_main.h" -#include "bcm43xx_radio.h" -#include "bcm43xx_ilt.h" -#include "bcm43xx_power.h" - - -static const s8 bcm43xx_tssi2dbm_b_table[] = { - 0x4D, 0x4C, 0x4B, 0x4A, - 0x4A, 0x49, 0x48, 0x47, - 0x47, 0x46, 0x45, 0x45, - 0x44, 0x43, 0x42, 0x42, - 0x41, 0x40, 0x3F, 0x3E, - 0x3D, 0x3C, 0x3B, 0x3A, - 0x39, 0x38, 0x37, 0x36, - 0x35, 0x34, 0x32, 0x31, - 0x30, 0x2F, 0x2D, 0x2C, - 0x2B, 0x29, 0x28, 0x26, - 0x25, 0x23, 0x21, 0x1F, - 0x1D, 0x1A, 0x17, 0x14, - 0x10, 0x0C, 0x06, 0x00, - -7, -7, -7, -7, - -7, -7, -7, -7, - -7, -7, -7, -7, -}; - -static const s8 bcm43xx_tssi2dbm_g_table[] = { - 77, 77, 77, 76, - 76, 76, 75, 75, - 74, 74, 73, 73, - 73, 72, 72, 71, - 71, 70, 70, 69, - 68, 68, 67, 67, - 66, 65, 65, 64, - 63, 63, 62, 61, - 60, 59, 58, 57, - 56, 55, 54, 53, - 52, 50, 49, 47, - 45, 43, 40, 37, - 33, 28, 22, 14, - 5, -7, -20, -20, - -20, -20, -20, -20, - -20, -20, -20, -20, -}; - -static void bcm43xx_phy_initg(struct bcm43xx_private *bcm); - - -void bcm43xx_raw_phy_lock(struct bcm43xx_private *bcm) -{ - struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm); - - assert(irqs_disabled()); - if (bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD) == 0x00000000) { - phy->is_locked = 0; - return; - } - if (bcm->current_core->rev < 3) { - bcm43xx_mac_suspend(bcm); - spin_lock(&phy->lock); - } else { - if (bcm->ieee->iw_mode != IW_MODE_MASTER) - bcm43xx_power_saving_ctl_bits(bcm, -1, 1); - } - phy->is_locked = 1; -} - -void bcm43xx_raw_phy_unlock(struct bcm43xx_private *bcm) -{ - struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm); - - assert(irqs_disabled()); - if (bcm->current_core->rev < 3) { - if (phy->is_locked) { - spin_unlock(&phy->lock); - bcm43xx_mac_enable(bcm); - } - } else { - if (bcm->ieee->iw_mode != IW_MODE_MASTER) - bcm43xx_power_saving_ctl_bits(bcm, -1, -1); - } - phy->is_locked = 0; -} - -u16 bcm43xx_phy_read(struct bcm43xx_private *bcm, u16 offset) -{ - bcm43xx_write16(bcm, BCM43xx_MMIO_PHY_CONTROL, offset); - return bcm43xx_read16(bcm, BCM43xx_MMIO_PHY_DATA); -} - -void bcm43xx_phy_write(struct bcm43xx_private *bcm, u16 offset, u16 val) -{ - bcm43xx_write16(bcm, BCM43xx_MMIO_PHY_CONTROL, offset); - mmiowb(); - bcm43xx_write16(bcm, BCM43xx_MMIO_PHY_DATA, val); -} - -void bcm43xx_phy_calibrate(struct bcm43xx_private *bcm) -{ - struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm); - unsigned long flags; - - bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD); /* Dummy read. */ - if (phy->calibrated) - return; - if (phy->type == BCM43xx_PHYTYPE_G && phy->rev == 1) { - /* We do not want to be preempted while calibrating - * the hardware. - */ - local_irq_save(flags); - - bcm43xx_wireless_core_reset(bcm, 0); - bcm43xx_phy_initg(bcm); - bcm43xx_wireless_core_reset(bcm, 1); - - local_irq_restore(flags); - } - phy->calibrated = 1; -} - -/* Connect the PHY - * http://bcm-specs.sipsolutions.net/SetPHY - */ -int bcm43xx_phy_connect(struct bcm43xx_private *bcm, int connect) -{ - struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm); - u32 flags; - - if (bcm->current_core->rev < 5) - goto out; - - flags = bcm43xx_read32(bcm, BCM43xx_CIR_SBTMSTATEHIGH); - if (connect) { - if (!(flags & 0x00010000)) - return -ENODEV; - flags = bcm43xx_read32(bcm, BCM43xx_CIR_SBTMSTATELOW); - flags |= (0x800 << 18); - bcm43xx_write32(bcm, BCM43xx_CIR_SBTMSTATELOW, flags); - } else { - if (!(flags & 0x00020000)) - return -ENODEV; - flags = bcm43xx_read32(bcm, BCM43xx_CIR_SBTMSTATELOW); - flags &= ~(0x800 << 18); - bcm43xx_write32(bcm, BCM43xx_CIR_SBTMSTATELOW, flags); - } -out: - phy->connected = connect; - if (connect) - dprintk(KERN_INFO PFX "PHY connected\n"); - else - dprintk(KERN_INFO PFX "PHY disconnected\n"); - - return 0; -} - -/* intialize B PHY power control - * as described in http://bcm-specs.sipsolutions.net/InitPowerControl - */ -static void bcm43xx_phy_init_pctl(struct bcm43xx_private *bcm) -{ - struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm); - struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm); - u16 saved_batt = 0, saved_ratt = 0, saved_txctl1 = 0; - int must_reset_txpower = 0; - - assert(phy->type != BCM43xx_PHYTYPE_A); - if ((bcm->board_vendor == PCI_VENDOR_ID_BROADCOM) && - (bcm->board_type == 0x0416)) - return; - - bcm43xx_write16(bcm, 0x03E6, bcm43xx_read16(bcm, 0x03E6) & 0xFFDF); - bcm43xx_phy_write(bcm, 0x0028, 0x8018); - - if (phy->type == BCM43xx_PHYTYPE_G) { - if (!phy->connected) - return; - bcm43xx_phy_write(bcm, 0x047A, 0xC111); - } - if (phy->savedpctlreg != 0xFFFF) - return; - - if (phy->type == BCM43xx_PHYTYPE_B && - phy->rev >= 2 && - radio->version == 0x2050) { - bcm43xx_radio_write16(bcm, 0x0076, - bcm43xx_radio_read16(bcm, 0x0076) | 0x0084); - } else { - saved_batt = radio->baseband_atten; - saved_ratt = radio->radio_atten; - saved_txctl1 = radio->txctl1; - if ((radio->revision >= 6) && (radio->revision <= 8) - && /*FIXME: incomplete specs for 5 < revision < 9 */ 0) - bcm43xx_radio_set_txpower_bg(bcm, 0xB, 0x1F, 0); - else - bcm43xx_radio_set_txpower_bg(bcm, 0xB, 9, 0); - must_reset_txpower = 1; - } - bcm43xx_dummy_transmission(bcm); - - phy->savedpctlreg = bcm43xx_phy_read(bcm, BCM43xx_PHY_G_PCTL); - - if (must_reset_txpower) - bcm43xx_radio_set_txpower_bg(bcm, saved_batt, saved_ratt, saved_txctl1); - else - bcm43xx_radio_write16(bcm, 0x0076, bcm43xx_radio_read16(bcm, 0x0076) & 0xFF7B); - bcm43xx_radio_clear_tssi(bcm); -} - -static void bcm43xx_phy_agcsetup(struct bcm43xx_private *bcm) -{ - struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm); - u16 offset = 0x0000; - - if (phy->rev == 1) - offset = 0x4C00; - - bcm43xx_ilt_write(bcm, offset, 0x00FE); - bcm43xx_ilt_write(bcm, offset + 1, 0x000D); - bcm43xx_ilt_write(bcm, offset + 2, 0x0013); - bcm43xx_ilt_write(bcm, offset + 3, 0x0019); - - if (phy->rev == 1) { - bcm43xx_ilt_write(bcm, 0x1800, 0x2710); - bcm43xx_ilt_write(bcm, 0x1801, 0x9B83); - bcm43xx_ilt_write(bcm, 0x1802, 0x9B83); - bcm43xx_ilt_write(bcm, 0x1803, 0x0F8D); - bcm43xx_phy_write(bcm, 0x0455, 0x0004); - } - - bcm43xx_phy_write(bcm, 0x04A5, (bcm43xx_phy_read(bcm, 0x04A5) & 0x00FF) | 0x5700); - bcm43xx_phy_write(bcm, 0x041A, (bcm43xx_phy_read(bcm, 0x041A) & 0xFF80) | 0x000F); - bcm43xx_phy_write(bcm, 0x041A, (bcm43xx_phy_read(bcm, 0x041A) & 0xC07F) | 0x2B80); - bcm43xx_phy_write(bcm, 0x048C, (bcm43xx_phy_read(bcm, 0x048C) & 0xF0FF) | 0x0300); - - bcm43xx_radio_write16(bcm, 0x007A, bcm43xx_radio_read16(bcm, 0x007A) | 0x0008); - - bcm43xx_phy_write(bcm, 0x04A0, (bcm43xx_phy_read(bcm, 0x04A0) & 0xFFF0) | 0x0008); - bcm43xx_phy_write(bcm, 0x04A1, (bcm43xx_phy_read(bcm, 0x04A1) & 0xF0FF) | 0x0600); - bcm43xx_phy_write(bcm, 0x04A2, (bcm43xx_phy_read(bcm, 0x04A2) & 0xF0FF) | 0x0700); - bcm43xx_phy_write(bcm, 0x04A0, (bcm43xx_phy_read(bcm, 0x04A0) & 0xF0FF) | 0x0100); - - if (phy->rev == 1) - bcm43xx_phy_write(bcm, 0x04A2, (bcm43xx_phy_read(bcm, 0x04A2) & 0xFFF0) | 0x0007); - - bcm43xx_phy_write(bcm, 0x0488, (bcm43xx_phy_read(bcm, 0x0488) & 0xFF00) | 0x001C); - bcm43xx_phy_write(bcm, 0x0488, (bcm43xx_phy_read(bcm, 0x0488) & 0xC0FF) | 0x0200); - bcm43xx_phy_write(bcm, 0x0496, (bcm43xx_phy_read(bcm, 0x0496) & 0xFF00) | 0x001C); - bcm43xx_phy_write(bcm, 0x0489, (bcm43xx_phy_read(bcm, 0x0489) & 0xFF00) | 0x0020); - bcm43xx_phy_write(bcm, 0x0489, (bcm43xx_phy_read(bcm, 0x0489) & 0xC0FF) | 0x0200); - bcm43xx_phy_write(bcm, 0x0482, (bcm43xx_phy_read(bcm, 0x0482) & 0xFF00) | 0x002E); - bcm43xx_phy_write(bcm, 0x0496, (bcm43xx_phy_read(bcm, 0x0496) & 0x00FF) | 0x1A00); - bcm43xx_phy_write(bcm, 0x0481, (bcm43xx_phy_read(bcm, 0x0481) & 0xFF00) | 0x0028); - bcm43xx_phy_write(bcm, 0x0481, (bcm43xx_phy_read(bcm, 0x0481) & 0x00FF) | 0x2C00); - - if (phy->rev == 1) { - bcm43xx_phy_write(bcm, 0x0430, 0x092B); - bcm43xx_phy_write(bcm, 0x041B, (bcm43xx_phy_read(bcm, 0x041B) & 0xFFE1) | 0x0002); - } else { - bcm43xx_phy_write(bcm, 0x041B, bcm43xx_phy_read(bcm, 0x041B) & 0xFFE1); - bcm43xx_phy_write(bcm, 0x041F, 0x287A); - bcm43xx_phy_write(bcm, 0x0420, (bcm43xx_phy_read(bcm, 0x0420) & 0xFFF0) | 0x0004); - } - - if (phy->rev > 2) { - bcm43xx_phy_write(bcm, 0x0422, 0x287A); - bcm43xx_phy_write(bcm, 0x0420, (bcm43xx_phy_read(bcm, 0x0420) & 0x0FFF) | 0x3000); - } - - bcm43xx_phy_write(bcm, 0x04A8, (bcm43xx_phy_read(bcm, 0x04A8) & 0x8080) | 0x7874); - bcm43xx_phy_write(bcm, 0x048E, 0x1C00); - - if (phy->rev == 1) { - bcm43xx_phy_write(bcm, 0x04AB, (bcm43xx_phy_read(bcm, 0x04AB) & 0xF0FF) | 0x0600); - bcm43xx_phy_write(bcm, 0x048B, 0x005E); - bcm43xx_phy_write(bcm, 0x048C, (bcm43xx_phy_read(bcm, 0x048C) & 0xFF00) | 0x001E); - bcm43xx_phy_write(bcm, 0x048D, 0x0002); - } - - bcm43xx_ilt_write(bcm, offset + 0x0800, 0); - bcm43xx_ilt_write(bcm, offset + 0x0801, 7); - bcm43xx_ilt_write(bcm, offset + 0x0802, 16); - bcm43xx_ilt_write(bcm, offset + 0x0803, 28); -} - -static void bcm43xx_phy_setupg(struct bcm43xx_private *bcm) -{ - struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm); - u16 i; - - assert(phy->type == BCM43xx_PHYTYPE_G); - if (phy->rev == 1) { - bcm43xx_phy_write(bcm, 0x0406, 0x4F19); - bcm43xx_phy_write(bcm, BCM43xx_PHY_G_CRS, - (bcm43xx_phy_read(bcm, BCM43xx_PHY_G_CRS) & 0xFC3F) | 0x0340); - bcm43xx_phy_write(bcm, 0x042C, 0x005A); - bcm43xx_phy_write(bcm, 0x0427, 0x001A); - - for (i = 0; i < BCM43xx_ILT_FINEFREQG_SIZE; i++) - bcm43xx_ilt_write(bcm, 0x5800 + i, bcm43xx_ilt_finefreqg[i]); - for (i = 0; i < BCM43xx_ILT_NOISEG1_SIZE; i++) - bcm43xx_ilt_write(bcm, 0x1800 + i, bcm43xx_ilt_noiseg1[i]); - for (i = 0; i < BCM43xx_ILT_ROTOR_SIZE; i++) - bcm43xx_ilt_write(bcm, 0x2000 + i, bcm43xx_ilt_rotor[i]); - } else { - /* nrssi values are signed 6-bit values. Not sure why we write 0x7654 here... */ - bcm43xx_nrssi_hw_write(bcm, 0xBA98, (s16)0x7654); - - if (phy->rev == 2) { - bcm43xx_phy_write(bcm, 0x04C0, 0x1861); - bcm43xx_phy_write(bcm, 0x04C1, 0x0271); - } else if (phy->rev > 2) { - bcm43xx_phy_write(bcm, 0x04C0, 0x0098); - bcm43xx_phy_write(bcm, 0x04C1, 0x0070); - bcm43xx_phy_write(bcm, 0x04C9, 0x0080); - } - bcm43xx_phy_write(bcm, 0x042B, bcm43xx_phy_read(bcm, 0x042B) | 0x800); - - for (i = 0; i < 64; i++) - bcm43xx_ilt_write(bcm, 0x4000 + i, i); - for (i = 0; i < BCM43xx_ILT_NOISEG2_SIZE; i++) - bcm43xx_ilt_write(bcm, 0x1800 + i, bcm43xx_ilt_noiseg2[i]); - } - - if (phy->rev <= 2) - for (i = 0; i < BCM43xx_ILT_NOISESCALEG_SIZE; i++) - bcm43xx_ilt_write(bcm, 0x1400 + i, bcm43xx_ilt_noisescaleg1[i]); - else if ((phy->rev == 7) && (bcm43xx_phy_read(bcm, 0x0449) & 0x0200)) - for (i = 0; i < BCM43xx_ILT_NOISESCALEG_SIZE; i++) - bcm43xx_ilt_write(bcm, 0x1400 + i, bcm43xx_ilt_noisescaleg3[i]); - else - for (i = 0; i < BCM43xx_ILT_NOISESCALEG_SIZE; i++) - bcm43xx_ilt_write(bcm, 0x1400 + i, bcm43xx_ilt_noisescaleg2[i]); - - if (phy->rev == 2) - for (i = 0; i < BCM43xx_ILT_SIGMASQR_SIZE; i++) - bcm43xx_ilt_write(bcm, 0x5000 + i, bcm43xx_ilt_sigmasqr1[i]); - else if ((phy->rev > 2) && (phy->rev <= 7)) - for (i = 0; i < BCM43xx_ILT_SIGMASQR_SIZE; i++) - bcm43xx_ilt_write(bcm, 0x5000 + i, bcm43xx_ilt_sigmasqr2[i]); - - if (phy->rev == 1) { - for (i = 0; i < BCM43xx_ILT_RETARD_SIZE; i++) - bcm43xx_ilt_write(bcm, 0x2400 + i, bcm43xx_ilt_retard[i]); - for (i = 0; i < 4; i++) { - bcm43xx_ilt_write(bcm, 0x5404 + i, 0x0020); - bcm43xx_ilt_write(bcm, 0x5408 + i, 0x0020); - bcm43xx_ilt_write(bcm, 0x540C + i, 0x0020); - bcm43xx_ilt_write(bcm, 0x5410 + i, 0x0020); - } - bcm43xx_phy_agcsetup(bcm); - - if ((bcm->board_vendor == PCI_VENDOR_ID_BROADCOM) && - (bcm->board_type == 0x0416) && - (bcm->board_revision == 0x0017)) - return; - - bcm43xx_ilt_write(bcm, 0x5001, 0x0002); - bcm43xx_ilt_write(bcm, 0x5002, 0x0001); - } else { - for (i = 0; i <= 0x2F; i++) - bcm43xx_ilt_write(bcm, 0x1000 + i, 0x0820); - bcm43xx_phy_agcsetup(bcm); - bcm43xx_phy_read(bcm, 0x0400); /* dummy read */ - bcm43xx_phy_write(bcm, 0x0403, 0x1000); - bcm43xx_ilt_write(bcm, 0x3C02, 0x000F); - bcm43xx_ilt_write(bcm, 0x3C03, 0x0014); - - if ((bcm->board_vendor == PCI_VENDOR_ID_BROADCOM) && - (bcm->board_type == 0x0416) && - (bcm->board_revision == 0x0017)) - return; - - bcm43xx_ilt_write(bcm, 0x0401, 0x0002); - bcm43xx_ilt_write(bcm, 0x0402, 0x0001); - } -} - -/* Initialize the noisescaletable for APHY */ -static void bcm43xx_phy_init_noisescaletbl(struct bcm43xx_private *bcm) -{ - struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm); - int i; - - bcm43xx_phy_write(bcm, BCM43xx_PHY_ILT_A_CTRL, 0x1400); - for (i = 0; i < 12; i++) { - if (phy->rev == 2) - bcm43xx_phy_write(bcm, BCM43xx_PHY_ILT_A_DATA1, 0x6767); - else - bcm43xx_phy_write(bcm, BCM43xx_PHY_ILT_A_DATA1, 0x2323); - } - if (phy->rev == 2) - bcm43xx_phy_write(bcm, BCM43xx_PHY_ILT_A_DATA1, 0x6700); - else - bcm43xx_phy_write(bcm, BCM43xx_PHY_ILT_A_DATA1, 0x2300); - for (i = 0; i < 11; i++) { - if (phy->rev == 2) - bcm43xx_phy_write(bcm, BCM43xx_PHY_ILT_A_DATA1, 0x6767); - else - bcm43xx_phy_write(bcm, BCM43xx_PHY_ILT_A_DATA1, 0x2323); - } - if (phy->rev == 2) - bcm43xx_phy_write(bcm, BCM43xx_PHY_ILT_A_DATA1, 0x0067); - else - bcm43xx_phy_write(bcm, BCM43xx_PHY_ILT_A_DATA1, 0x0023); -} - -static void bcm43xx_phy_setupa(struct bcm43xx_private *bcm) -{ - struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm); - u16 i; - - assert(phy->type == BCM43xx_PHYTYPE_A); - switch (phy->rev) { - case 2: - bcm43xx_phy_write(bcm, 0x008E, 0x3800); - bcm43xx_phy_write(bcm, 0x0035, 0x03FF); - bcm43xx_phy_write(bcm, 0x0036, 0x0400); - - bcm43xx_ilt_write(bcm, 0x3807, 0x0051); - - bcm43xx_phy_write(bcm, 0x001C, 0x0FF9); - bcm43xx_phy_write(bcm, 0x0020, bcm43xx_phy_read(bcm, 0x0020) & 0xFF0F); - bcm43xx_ilt_write(bcm, 0x3C0C, 0x07BF); - bcm43xx_radio_write16(bcm, 0x0002, 0x07BF); - - bcm43xx_phy_write(bcm, 0x0024, 0x4680); - bcm43xx_phy_write(bcm, 0x0020, 0x0003); - bcm43xx_phy_write(bcm, 0x001D, 0x0F40); - bcm43xx_phy_write(bcm, 0x001F, 0x1C00); - - bcm43xx_phy_write(bcm, 0x002A, (bcm43xx_phy_read(bcm, 0x002A) & 0x00FF) | 0x0400); - bcm43xx_phy_write(bcm, 0x002B, bcm43xx_phy_read(bcm, 0x002B) & 0xFBFF); - bcm43xx_phy_write(bcm, 0x008E, 0x58C1); - - bcm43xx_ilt_write(bcm, 0x0803, 0x000F); - bcm43xx_ilt_write(bcm, 0x0804, 0x001F); - bcm43xx_ilt_write(bcm, 0x0805, 0x002A); - bcm43xx_ilt_write(bcm, 0x0805, 0x0030); - bcm43xx_ilt_write(bcm, 0x0807, 0x003A); - - bcm43xx_ilt_write(bcm, 0x0000, 0x0013); - bcm43xx_ilt_write(bcm, 0x0001, 0x0013); - bcm43xx_ilt_write(bcm, 0x0002, 0x0013); - bcm43xx_ilt_write(bcm, 0x0003, 0x0013); - bcm43xx_ilt_write(bcm, 0x0004, 0x0015); - bcm43xx_ilt_write(bcm, 0x0005, 0x0015); - bcm43xx_ilt_write(bcm, 0x0006, 0x0019); - - bcm43xx_ilt_write(bcm, 0x0404, 0x0003); - bcm43xx_ilt_write(bcm, 0x0405, 0x0003); - bcm43xx_ilt_write(bcm, 0x0406, 0x0007); - - for (i = 0; i < 16; i++) - bcm43xx_ilt_write(bcm, 0x4000 + i, (0x8 + i) & 0x000F); - - bcm43xx_ilt_write(bcm, 0x3003, 0x1044); - bcm43xx_ilt_write(bcm, 0x3004, 0x7201); - bcm43xx_ilt_write(bcm, 0x3006, 0x0040); - bcm43xx_ilt_write(bcm, 0x3001, (bcm43xx_ilt_read(bcm, 0x3001) & 0x0010) | 0x0008); - - for (i = 0; i < BCM43xx_ILT_FINEFREQA_SIZE; i++) - bcm43xx_ilt_write(bcm, 0x5800 + i, bcm43xx_ilt_finefreqa[i]); - for (i = 0; i < BCM43xx_ILT_NOISEA2_SIZE; i++) - bcm43xx_ilt_write(bcm, 0x1800 + i, bcm43xx_ilt_noisea2[i]); - for (i = 0; i < BCM43xx_ILT_ROTOR_SIZE; i++) - bcm43xx_ilt_write(bcm, 0x2000 + i, bcm43xx_ilt_rotor[i]); - bcm43xx_phy_init_noisescaletbl(bcm); - for (i = 0; i < BCM43xx_ILT_RETARD_SIZE; i++) - bcm43xx_ilt_write(bcm, 0x2400 + i, bcm43xx_ilt_retard[i]); - break; - case 3: - for (i = 0; i < 64; i++) - bcm43xx_ilt_write(bcm, 0x4000 + i, i); - - bcm43xx_ilt_write(bcm, 0x3807, 0x0051); - - bcm43xx_phy_write(bcm, 0x001C, 0x0FF9); - bcm43xx_phy_write(bcm, 0x0020, bcm43xx_phy_read(bcm, 0x0020) & 0xFF0F); - bcm43xx_radio_write16(bcm, 0x0002, 0x07BF); - - bcm43xx_phy_write(bcm, 0x0024, 0x4680); - bcm43xx_phy_write(bcm, 0x0020, 0x0003); - bcm43xx_phy_write(bcm, 0x001D, 0x0F40); - bcm43xx_phy_write(bcm, 0x001F, 0x1C00); - bcm43xx_phy_write(bcm, 0x002A, (bcm43xx_phy_read(bcm, 0x002A) & 0x00FF) | 0x0400); - - bcm43xx_ilt_write(bcm, 0x3001, (bcm43xx_ilt_read(bcm, 0x3001) & 0x0010) | 0x0008); - for (i = 0; i < BCM43xx_ILT_NOISEA3_SIZE; i++) - bcm43xx_ilt_write(bcm, 0x1800 + i, bcm43xx_ilt_noisea3[i]); - bcm43xx_phy_init_noisescaletbl(bcm); - for (i = 0; i < BCM43xx_ILT_SIGMASQR_SIZE; i++) - bcm43xx_ilt_write(bcm, 0x5000 + i, bcm43xx_ilt_sigmasqr1[i]); - - bcm43xx_phy_write(bcm, 0x0003, 0x1808); - - bcm43xx_ilt_write(bcm, 0x0803, 0x000F); - bcm43xx_ilt_write(bcm, 0x0804, 0x001F); - bcm43xx_ilt_write(bcm, 0x0805, 0x002A); - bcm43xx_ilt_write(bcm, 0x0805, 0x0030); - bcm43xx_ilt_write(bcm, 0x0807, 0x003A); - - bcm43xx_ilt_write(bcm, 0x0000, 0x0013); - bcm43xx_ilt_write(bcm, 0x0001, 0x0013); - bcm43xx_ilt_write(bcm, 0x0002, 0x0013); - bcm43xx_ilt_write(bcm, 0x0003, 0x0013); - bcm43xx_ilt_write(bcm, 0x0004, 0x0015); - bcm43xx_ilt_write(bcm, 0x0005, 0x0015); - bcm43xx_ilt_write(bcm, 0x0006, 0x0019); - - bcm43xx_ilt_write(bcm, 0x0404, 0x0003); - bcm43xx_ilt_write(bcm, 0x0405, 0x0003); - bcm43xx_ilt_write(bcm, 0x0406, 0x0007); - - bcm43xx_ilt_write(bcm, 0x3C02, 0x000F); - bcm43xx_ilt_write(bcm, 0x3C03, 0x0014); - break; - default: - assert(0); - } -} - -/* Initialize APHY. This is also called for the GPHY in some cases. */ -static void bcm43xx_phy_inita(struct bcm43xx_private *bcm) -{ - struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm); - struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm); - u16 tval; - - if (phy->type == BCM43xx_PHYTYPE_A) { - bcm43xx_phy_setupa(bcm); - } else { - bcm43xx_phy_setupg(bcm); - if (bcm->sprom.boardflags & BCM43xx_BFL_PACTRL) - bcm43xx_phy_write(bcm, 0x046E, 0x03CF); - return; - } - - bcm43xx_phy_write(bcm, BCM43xx_PHY_A_CRS, - (bcm43xx_phy_read(bcm, BCM43xx_PHY_A_CRS) & 0xF83C) | 0x0340); - bcm43xx_phy_write(bcm, 0x0034, 0x0001); - - TODO();//TODO: RSSI AGC - bcm43xx_phy_write(bcm, BCM43xx_PHY_A_CRS, - bcm43xx_phy_read(bcm, BCM43xx_PHY_A_CRS) | (1 << 14)); - bcm43xx_radio_init2060(bcm); - - if ((bcm->board_vendor == PCI_VENDOR_ID_BROADCOM) - && ((bcm->board_type == 0x0416) || (bcm->board_type == 0x040A))) { - if (radio->lofcal == 0xFFFF) { - TODO();//TODO: LOF Cal - bcm43xx_radio_set_tx_iq(bcm); - } else - bcm43xx_radio_write16(bcm, 0x001E, radio->lofcal); - } - - bcm43xx_phy_write(bcm, 0x007A, 0xF111); - - if (phy->savedpctlreg == 0xFFFF) { - bcm43xx_radio_write16(bcm, 0x0019, 0x0000); - bcm43xx_radio_write16(bcm, 0x0017, 0x0020); - - tval = bcm43xx_ilt_read(bcm, 0x3001); - if (phy->rev == 1) { - bcm43xx_ilt_write(bcm, 0x3001, - (bcm43xx_ilt_read(bcm, 0x3001) & 0xFF87) - | 0x0058); - } else { - bcm43xx_ilt_write(bcm, 0x3001, - (bcm43xx_ilt_read(bcm, 0x3001) & 0xFFC3) - | 0x002C); - } - bcm43xx_dummy_transmission(bcm); - phy->savedpctlreg = bcm43xx_phy_read(bcm, BCM43xx_PHY_A_PCTL); - bcm43xx_ilt_write(bcm, 0x3001, tval); - - bcm43xx_radio_set_txpower_a(bcm, 0x0018); - } - bcm43xx_radio_clear_tssi(bcm); -} - -static void bcm43xx_phy_initb2(struct bcm43xx_private *bcm) -{ - struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm); - u16 offset, val; - - bcm43xx_write16(bcm, 0x03EC, 0x3F22); - bcm43xx_phy_write(bcm, 0x0020, 0x301C); - bcm43xx_phy_write(bcm, 0x0026, 0x0000); - bcm43xx_phy_write(bcm, 0x0030, 0x00C6); - bcm43xx_phy_write(bcm, 0x0088, 0x3E00); - val = 0x3C3D; - for (offset = 0x0089; offset < 0x00A7; offset++) { - bcm43xx_phy_write(bcm, offset, val); - val -= 0x0202; - } - bcm43xx_phy_write(bcm, 0x03E4, 0x3000); - if (radio->channel == 0xFF) - bcm43xx_radio_selectchannel(bcm, BCM43xx_RADIO_DEFAULT_CHANNEL_BG, 0); - else - bcm43xx_radio_selectchannel(bcm, radio->channel, 0); - if (radio->version != 0x2050) { - bcm43xx_radio_write16(bcm, 0x0075, 0x0080); - bcm43xx_radio_write16(bcm, 0x0079, 0x0081); - } - bcm43xx_radio_write16(bcm, 0x0050, 0x0020); - bcm43xx_radio_write16(bcm, 0x0050, 0x0023); - if (radio->version == 0x2050) { - bcm43xx_radio_write16(bcm, 0x0050, 0x0020); - bcm43xx_radio_write16(bcm, 0x005A, 0x0070); - bcm43xx_radio_write16(bcm, 0x005B, 0x007B); - bcm43xx_radio_write16(bcm, 0x005C, 0x00B0); - bcm43xx_radio_write16(bcm, 0x007A, 0x000F); - bcm43xx_phy_write(bcm, 0x0038, 0x0677); - bcm43xx_radio_init2050(bcm); - } - bcm43xx_phy_write(bcm, 0x0014, 0x0080); - bcm43xx_phy_write(bcm, 0x0032, 0x00CA); - bcm43xx_phy_write(bcm, 0x0032, 0x00CC); - bcm43xx_phy_write(bcm, 0x0035, 0x07C2); - bcm43xx_phy_lo_b_measure(bcm); - bcm43xx_phy_write(bcm, 0x0026, 0xCC00); - if (radio->version != 0x2050) - bcm43xx_phy_write(bcm, 0x0026, 0xCE00); - bcm43xx_write16(bcm, BCM43xx_MMIO_CHANNEL_EXT, 0x1000); - bcm43xx_phy_write(bcm, 0x002A, 0x88A3); - if (radio->version != 0x2050) - bcm43xx_phy_write(bcm, 0x002A, 0x88C2); - bcm43xx_radio_set_txpower_bg(bcm, 0xFFFF, 0xFFFF, 0xFFFF); - bcm43xx_phy_init_pctl(bcm); -} - -static void bcm43xx_phy_initb4(struct bcm43xx_private *bcm) -{ - struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm); - u16 offset, val; - - bcm43xx_write16(bcm, 0x03EC, 0x3F22); - bcm43xx_phy_write(bcm, 0x0020, 0x301C); - bcm43xx_phy_write(bcm, 0x0026, 0x0000); - bcm43xx_phy_write(bcm, 0x0030, 0x00C6); - bcm43xx_phy_write(bcm, 0x0088, 0x3E00); - val = 0x3C3D; - for (offset = 0x0089; offset < 0x00A7; offset++) { - bcm43xx_phy_write(bcm, offset, val); - val -= 0x0202; - } - bcm43xx_phy_write(bcm, 0x03E4, 0x3000); - if (radio->channel == 0xFF) - bcm43xx_radio_selectchannel(bcm, BCM43xx_RADIO_DEFAULT_CHANNEL_BG, 0); - else - bcm43xx_radio_selectchannel(bcm, radio->channel, 0); - if (radio->version != 0x2050) { - bcm43xx_radio_write16(bcm, 0x0075, 0x0080); - bcm43xx_radio_write16(bcm, 0x0079, 0x0081); - } - bcm43xx_radio_write16(bcm, 0x0050, 0x0020); - bcm43xx_radio_write16(bcm, 0x0050, 0x0023); - if (radio->version == 0x2050) { - bcm43xx_radio_write16(bcm, 0x0050, 0x0020); - bcm43xx_radio_write16(bcm, 0x005A, 0x0070); - bcm43xx_radio_write16(bcm, 0x005B, 0x007B); - bcm43xx_radio_write16(bcm, 0x005C, 0x00B0); - bcm43xx_radio_write16(bcm, 0x007A, 0x000F); - bcm43xx_phy_write(bcm, 0x0038, 0x0677); - bcm43xx_radio_init2050(bcm); - } - bcm43xx_phy_write(bcm, 0x0014, 0x0080); - bcm43xx_phy_write(bcm, 0x0032, 0x00CA); - if (radio->version == 0x2050) - bcm43xx_phy_write(bcm, 0x0032, 0x00E0); - bcm43xx_phy_write(bcm, 0x0035, 0x07C2); - - bcm43xx_phy_lo_b_measure(bcm); - - bcm43xx_phy_write(bcm, 0x0026, 0xCC00); - if (radio->version == 0x2050) - bcm43xx_phy_write(bcm, 0x0026, 0xCE00); - bcm43xx_write16(bcm, BCM43xx_MMIO_CHANNEL_EXT, 0x1100); - bcm43xx_phy_write(bcm, 0x002A, 0x88A3); - if (radio->version == 0x2050) - bcm43xx_phy_write(bcm, 0x002A, 0x88C2); - bcm43xx_radio_set_txpower_bg(bcm, 0xFFFF, 0xFFFF, 0xFFFF); - if (bcm->sprom.boardflags & BCM43xx_BFL_RSSI) { - bcm43xx_calc_nrssi_slope(bcm); - bcm43xx_calc_nrssi_threshold(bcm); - } - bcm43xx_phy_init_pctl(bcm); -} - -static void bcm43xx_phy_initb5(struct bcm43xx_private *bcm) -{ - struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm); - struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm); - u16 offset; - - if (phy->version == 1 && - radio->version == 0x2050) { - bcm43xx_radio_write16(bcm, 0x007A, - bcm43xx_radio_read16(bcm, 0x007A) - | 0x0050); - } - if ((bcm->board_vendor != PCI_VENDOR_ID_BROADCOM) && - (bcm->board_type != 0x0416)) { - for (offset = 0x00A8 ; offset < 0x00C7; offset++) { - bcm43xx_phy_write(bcm, offset, - (bcm43xx_phy_read(bcm, offset) + 0x2020) - & 0x3F3F); - } - } - bcm43xx_phy_write(bcm, 0x0035, - (bcm43xx_phy_read(bcm, 0x0035) & 0xF0FF) - | 0x0700); - if (radio->version == 0x2050) - bcm43xx_phy_write(bcm, 0x0038, 0x0667); - - if (phy->connected) { - if (radio->version == 0x2050) { - bcm43xx_radio_write16(bcm, 0x007A, - bcm43xx_radio_read16(bcm, 0x007A) - | 0x0020); - bcm43xx_radio_write16(bcm, 0x0051, - bcm43xx_radio_read16(bcm, 0x0051) - | 0x0004); - } - bcm43xx_write16(bcm, BCM43xx_MMIO_PHY_RADIO, 0x0000); - - bcm43xx_phy_write(bcm, 0x0802, bcm43xx_phy_read(bcm, 0x0802) | 0x0100); - bcm43xx_phy_write(bcm, 0x042B, bcm43xx_phy_read(bcm, 0x042B) | 0x2000); - - bcm43xx_phy_write(bcm, 0x001C, 0x186A); - - bcm43xx_phy_write(bcm, 0x0013, (bcm43xx_phy_read(bcm, 0x0013) & 0x00FF) | 0x1900); - bcm43xx_phy_write(bcm, 0x0035, (bcm43xx_phy_read(bcm, 0x0035) & 0xFFC0) | 0x0064); - bcm43xx_phy_write(bcm, 0x005D, (bcm43xx_phy_read(bcm, 0x005D) & 0xFF80) | 0x000A); - } - - if (bcm->bad_frames_preempt) { - bcm43xx_phy_write(bcm, BCM43xx_PHY_RADIO_BITFIELD, - bcm43xx_phy_read(bcm, BCM43xx_PHY_RADIO_BITFIELD) | (1 << 11)); - } - - if (phy->version == 1 && radio->version == 0x2050) { - bcm43xx_phy_write(bcm, 0x0026, 0xCE00); - bcm43xx_phy_write(bcm, 0x0021, 0x3763); - bcm43xx_phy_write(bcm, 0x0022, 0x1BC3); - bcm43xx_phy_write(bcm, 0x0023, 0x06F9); - bcm43xx_phy_write(bcm, 0x0024, 0x037E); - } else - bcm43xx_phy_write(bcm, 0x0026, 0xCC00); - bcm43xx_phy_write(bcm, 0x0030, 0x00C6); - bcm43xx_write16(bcm, 0x03EC, 0x3F22); - - if (phy->version == 1 && radio->version == 0x2050) - bcm43xx_phy_write(bcm, 0x0020, 0x3E1C); - else - bcm43xx_phy_write(bcm, 0x0020, 0x301C); - - if (phy->version == 0) - bcm43xx_write16(bcm, 0x03E4, 0x3000); - - /* Force to channel 7, even if not supported. */ - bcm43xx_radio_selectchannel(bcm, 7, 0); - - if (radio->version != 0x2050) { - bcm43xx_radio_write16(bcm, 0x0075, 0x0080); - bcm43xx_radio_write16(bcm, 0x0079, 0x0081); - } - - bcm43xx_radio_write16(bcm, 0x0050, 0x0020); - bcm43xx_radio_write16(bcm, 0x0050, 0x0023); - - if (radio->version == 0x2050) { - bcm43xx_radio_write16(bcm, 0x0050, 0x0020); - bcm43xx_radio_write16(bcm, 0x005A, 0x0070); - } - - bcm43xx_radio_write16(bcm, 0x005B, 0x007B); - bcm43xx_radio_write16(bcm, 0x005C, 0x00B0); - - bcm43xx_radio_write16(bcm, 0x007A, bcm43xx_radio_read16(bcm, 0x007A) | 0x0007); - - bcm43xx_radio_selectchannel(bcm, BCM43xx_RADIO_DEFAULT_CHANNEL_BG, 0); - - bcm43xx_phy_write(bcm, 0x0014, 0x0080); - bcm43xx_phy_write(bcm, 0x0032, 0x00CA); - bcm43xx_phy_write(bcm, 0x88A3, 0x002A); - - bcm43xx_radio_set_txpower_bg(bcm, 0xFFFF, 0xFFFF, 0xFFFF); - - if (radio->version == 0x2050) - bcm43xx_radio_write16(bcm, 0x005D, 0x000D); - - bcm43xx_write16(bcm, 0x03E4, (bcm43xx_read16(bcm, 0x03E4) & 0xFFC0) | 0x0004); -} - -static void bcm43xx_phy_initb6(struct bcm43xx_private *bcm) -{ - struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm); - struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm); - u16 offset, val; - - bcm43xx_phy_write(bcm, 0x003E, 0x817A); - bcm43xx_radio_write16(bcm, 0x007A, - (bcm43xx_radio_read16(bcm, 0x007A) | 0x0058)); - if ((radio->manufact == 0x17F) && - (radio->version == 0x2050) && - (radio->revision == 3 || - radio->revision == 4 || - radio->revision == 5)) { - bcm43xx_radio_write16(bcm, 0x0051, 0x001F); - bcm43xx_radio_write16(bcm, 0x0052, 0x0040); - bcm43xx_radio_write16(bcm, 0x0053, 0x005B); - bcm43xx_radio_write16(bcm, 0x0054, 0x0098); - bcm43xx_radio_write16(bcm, 0x005A, 0x0088); - bcm43xx_radio_write16(bcm, 0x005B, 0x0088); - bcm43xx_radio_write16(bcm, 0x005D, 0x0088); - bcm43xx_radio_write16(bcm, 0x005E, 0x0088); - bcm43xx_radio_write16(bcm, 0x007D, 0x0088); - } - if ((radio->manufact == 0x17F) && - (radio->version == 0x2050) && - (radio->revision == 6)) { - bcm43xx_radio_write16(bcm, 0x0051, 0x0000); - bcm43xx_radio_write16(bcm, 0x0052, 0x0040); - bcm43xx_radio_write16(bcm, 0x0053, 0x00B7); - bcm43xx_radio_write16(bcm, 0x0054, 0x0098); - bcm43xx_radio_write16(bcm, 0x005A, 0x0088); - bcm43xx_radio_write16(bcm, 0x005B, 0x008B); - bcm43xx_radio_write16(bcm, 0x005C, 0x00B5); - bcm43xx_radio_write16(bcm, 0x005D, 0x0088); - bcm43xx_radio_write16(bcm, 0x005E, 0x0088); - bcm43xx_radio_write16(bcm, 0x007D, 0x0088); - bcm43xx_radio_write16(bcm, 0x007C, 0x0001); - bcm43xx_radio_write16(bcm, 0x007E, 0x0008); - } - if ((radio->manufact == 0x17F) && - (radio->version == 0x2050) && - (radio->revision == 7)) { - bcm43xx_radio_write16(bcm, 0x0051, 0x0000); - bcm43xx_radio_write16(bcm, 0x0052, 0x0040); - bcm43xx_radio_write16(bcm, 0x0053, 0x00B7); - bcm43xx_radio_write16(bcm, 0x0054, 0x0098); - bcm43xx_radio_write16(bcm, 0x005A, 0x0088); - bcm43xx_radio_write16(bcm, 0x005B, 0x00A8); - bcm43xx_radio_write16(bcm, 0x005C, 0x0075); - bcm43xx_radio_write16(bcm, 0x005D, 0x00F5); - bcm43xx_radio_write16(bcm, 0x005E, 0x00B8); - bcm43xx_radio_write16(bcm, 0x007D, 0x00E8); - bcm43xx_radio_write16(bcm, 0x007C, 0x0001); - bcm43xx_radio_write16(bcm, 0x007E, 0x0008); - bcm43xx_radio_write16(bcm, 0x007B, 0x0000); - } - if ((radio->manufact == 0x17F) && - (radio->version == 0x2050) && - (radio->revision == 8)) { - bcm43xx_radio_write16(bcm, 0x0051, 0x0000); - bcm43xx_radio_write16(bcm, 0x0052, 0x0040); - bcm43xx_radio_write16(bcm, 0x0053, 0x00B7); - bcm43xx_radio_write16(bcm, 0x0054, 0x0098); - bcm43xx_radio_write16(bcm, 0x005A, 0x0088); - bcm43xx_radio_write16(bcm, 0x005B, 0x006B); - bcm43xx_radio_write16(bcm, 0x005C, 0x000F); - if (bcm->sprom.boardflags & 0x8000) { - bcm43xx_radio_write16(bcm, 0x005D, 0x00FA); - bcm43xx_radio_write16(bcm, 0x005E, 0x00D8); - } else { - bcm43xx_radio_write16(bcm, 0x005D, 0x00F5); - bcm43xx_radio_write16(bcm, 0x005E, 0x00B8); - } - bcm43xx_radio_write16(bcm, 0x0073, 0x0003); - bcm43xx_radio_write16(bcm, 0x007D, 0x00A8); - bcm43xx_radio_write16(bcm, 0x007C, 0x0001); - bcm43xx_radio_write16(bcm, 0x007E, 0x0008); - } - val = 0x1E1F; - for (offset = 0x0088; offset < 0x0098; offset++) { - bcm43xx_phy_write(bcm, offset, val); - val -= 0x0202; - } - val = 0x3E3F; - for (offset = 0x0098; offset < 0x00A8; offset++) { - bcm43xx_phy_write(bcm, offset, val); - val -= 0x0202; - } - val = 0x2120; - for (offset = 0x00A8; offset < 0x00C8; offset++) { - bcm43xx_phy_write(bcm, offset, (val & 0x3F3F)); - val += 0x0202; - } - if (phy->type == BCM43xx_PHYTYPE_G) { - bcm43xx_radio_write16(bcm, 0x007A, - bcm43xx_radio_read16(bcm, 0x007A) | 0x0020); - bcm43xx_radio_write16(bcm, 0x0051, - bcm43xx_radio_read16(bcm, 0x0051) | 0x0004); - bcm43xx_phy_write(bcm, 0x0802, - bcm43xx_phy_read(bcm, 0x0802) | 0x0100); - bcm43xx_phy_write(bcm, 0x042B, - bcm43xx_phy_read(bcm, 0x042B) | 0x2000); - } - - /* Force to channel 7, even if not supported. */ - bcm43xx_radio_selectchannel(bcm, 7, 0); - - bcm43xx_radio_write16(bcm, 0x0050, 0x0020); - bcm43xx_radio_write16(bcm, 0x0050, 0x0023); - udelay(40); - bcm43xx_radio_write16(bcm, 0x007C, (bcm43xx_radio_read16(bcm, 0x007C) | 0x0002)); - bcm43xx_radio_write16(bcm, 0x0050, 0x0020); - if (radio->manufact == 0x17F && - radio->version == 0x2050 && - radio->revision <= 2) { - bcm43xx_radio_write16(bcm, 0x0050, 0x0020); - bcm43xx_radio_write16(bcm, 0x005A, 0x0070); - bcm43xx_radio_write16(bcm, 0x005B, 0x007B); - bcm43xx_radio_write16(bcm, 0x005C, 0x00B0); - } - bcm43xx_radio_write16(bcm, 0x007A, - (bcm43xx_radio_read16(bcm, 0x007A) & 0x00F8) | 0x0007); - - bcm43xx_radio_selectchannel(bcm, BCM43xx_RADIO_DEFAULT_CHANNEL_BG, 0); - - bcm43xx_phy_write(bcm, 0x0014, 0x0200); - if (radio->version == 0x2050){ - if (radio->revision == 3 || - radio->revision == 4 || - radio->revision == 5) - bcm43xx_phy_write(bcm, 0x002A, 0x8AC0); - else - bcm43xx_phy_write(bcm, 0x002A, 0x88C2); - } - bcm43xx_phy_write(bcm, 0x0038, 0x0668); - bcm43xx_radio_set_txpower_bg(bcm, 0xFFFF, 0xFFFF, 0xFFFF); - if (radio->version == 0x2050) { - if (radio->revision == 3 || - radio->revision == 4 || - radio->revision == 5) - bcm43xx_phy_write(bcm, 0x005D, bcm43xx_phy_read(bcm, 0x005D) | 0x0003); - else if (radio->revision <= 2) - bcm43xx_radio_write16(bcm, 0x005D, 0x000D); - } - - if (phy->rev == 4) - bcm43xx_phy_write(bcm, 0x0002, (bcm43xx_phy_read(bcm, 0x0002) & 0xFFC0) | 0x0004); - else - bcm43xx_write16(bcm, 0x03E4, 0x0009); - if (phy->type == BCM43xx_PHYTYPE_B) { - bcm43xx_write16(bcm, 0x03E6, 0x8140); - bcm43xx_phy_write(bcm, 0x0016, 0x0410); - bcm43xx_phy_write(bcm, 0x0017, 0x0820); - bcm43xx_phy_write(bcm, 0x0062, 0x0007); - (void) bcm43xx_radio_calibrationvalue(bcm); - bcm43xx_phy_lo_b_measure(bcm); - if (bcm->sprom.boardflags & BCM43xx_BFL_RSSI) { - bcm43xx_calc_nrssi_slope(bcm); - bcm43xx_calc_nrssi_threshold(bcm); - } - bcm43xx_phy_init_pctl(bcm); - } else - bcm43xx_write16(bcm, 0x03E6, 0x0); -} - -static void bcm43xx_calc_loopback_gain(struct bcm43xx_private *bcm) -{ - struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm); - struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm); - u16 backup_phy[15]; - u16 backup_radio[3]; - u16 backup_bband; - u16 i; - u16 loop1_cnt, loop1_done, loop1_omitted; - u16 loop2_done; - - backup_phy[0] = bcm43xx_phy_read(bcm, 0x0429); - backup_phy[1] = bcm43xx_phy_read(bcm, 0x0001); - backup_phy[2] = bcm43xx_phy_read(bcm, 0x0811); - backup_phy[3] = bcm43xx_phy_read(bcm, 0x0812); - backup_phy[4] = bcm43xx_phy_read(bcm, 0x0814); - backup_phy[5] = bcm43xx_phy_read(bcm, 0x0815); - backup_phy[6] = bcm43xx_phy_read(bcm, 0x005A); - backup_phy[7] = bcm43xx_phy_read(bcm, 0x0059); - backup_phy[8] = bcm43xx_phy_read(bcm, 0x0058); - backup_phy[9] = bcm43xx_phy_read(bcm, 0x000A); - backup_phy[10] = bcm43xx_phy_read(bcm, 0x0003); - backup_phy[11] = bcm43xx_phy_read(bcm, 0x080F); - backup_phy[12] = bcm43xx_phy_read(bcm, 0x0810); - backup_phy[13] = bcm43xx_phy_read(bcm, 0x002B); - backup_phy[14] = bcm43xx_phy_read(bcm, 0x0015); - bcm43xx_phy_read(bcm, 0x002D); /* dummy read */ - backup_bband = radio->baseband_atten; - backup_radio[0] = bcm43xx_radio_read16(bcm, 0x0052); - backup_radio[1] = bcm43xx_radio_read16(bcm, 0x0043); - backup_radio[2] = bcm43xx_radio_read16(bcm, 0x007A); - - bcm43xx_phy_write(bcm, 0x0429, - bcm43xx_phy_read(bcm, 0x0429) & 0x3FFF); - bcm43xx_phy_write(bcm, 0x0001, - bcm43xx_phy_read(bcm, 0x0001) & 0x8000); - bcm43xx_phy_write(bcm, 0x0811, - bcm43xx_phy_read(bcm, 0x0811) | 0x0002); - bcm43xx_phy_write(bcm, 0x0812, - bcm43xx_phy_read(bcm, 0x0812) & 0xFFFD); - bcm43xx_phy_write(bcm, 0x0811, - bcm43xx_phy_read(bcm, 0x0811) | 0x0001); - bcm43xx_phy_write(bcm, 0x0812, - bcm43xx_phy_read(bcm, 0x0812) & 0xFFFE); - bcm43xx_phy_write(bcm, 0x0814, - bcm43xx_phy_read(bcm, 0x0814) | 0x0001); - bcm43xx_phy_write(bcm, 0x0815, - bcm43xx_phy_read(bcm, 0x0815) & 0xFFFE); - bcm43xx_phy_write(bcm, 0x0814, - bcm43xx_phy_read(bcm, 0x0814) | 0x0002); - bcm43xx_phy_write(bcm, 0x0815, - bcm43xx_phy_read(bcm, 0x0815) & 0xFFFD); - bcm43xx_phy_write(bcm, 0x0811, - bcm43xx_phy_read(bcm, 0x0811) | 0x000C); - bcm43xx_phy_write(bcm, 0x0812, - bcm43xx_phy_read(bcm, 0x0812) | 0x000C); - - bcm43xx_phy_write(bcm, 0x0811, - (bcm43xx_phy_read(bcm, 0x0811) - & 0xFFCF) | 0x0030); - bcm43xx_phy_write(bcm, 0x0812, - (bcm43xx_phy_read(bcm, 0x0812) - & 0xFFCF) | 0x0010); - - bcm43xx_phy_write(bcm, 0x005A, 0x0780); - bcm43xx_phy_write(bcm, 0x0059, 0xC810); - bcm43xx_phy_write(bcm, 0x0058, 0x000D); - if (phy->version == 0) { - bcm43xx_phy_write(bcm, 0x0003, 0x0122); - } else { - bcm43xx_phy_write(bcm, 0x000A, - bcm43xx_phy_read(bcm, 0x000A) - | 0x2000); - } - bcm43xx_phy_write(bcm, 0x0814, - bcm43xx_phy_read(bcm, 0x0814) | 0x0004); - bcm43xx_phy_write(bcm, 0x0815, - bcm43xx_phy_read(bcm, 0x0815) & 0xFFFB); - bcm43xx_phy_write(bcm, 0x0003, - (bcm43xx_phy_read(bcm, 0x0003) - & 0xFF9F) | 0x0040); - if (radio->version == 0x2050 && radio->revision == 2) { - bcm43xx_radio_write16(bcm, 0x0052, 0x0000); - bcm43xx_radio_write16(bcm, 0x0043, - (bcm43xx_radio_read16(bcm, 0x0043) - & 0xFFF0) | 0x0009); - loop1_cnt = 9; - } else if (radio->revision == 8) { - bcm43xx_radio_write16(bcm, 0x0043, 0x000F); - loop1_cnt = 15; - } else - loop1_cnt = 0; - - bcm43xx_phy_set_baseband_attenuation(bcm, 11); - - if (phy->rev >= 3) - bcm43xx_phy_write(bcm, 0x080F, 0xC020); - else - bcm43xx_phy_write(bcm, 0x080F, 0x8020); - bcm43xx_phy_write(bcm, 0x0810, 0x0000); - - bcm43xx_phy_write(bcm, 0x002B, - (bcm43xx_phy_read(bcm, 0x002B) - & 0xFFC0) | 0x0001); - bcm43xx_phy_write(bcm, 0x002B, - (bcm43xx_phy_read(bcm, 0x002B) - & 0xC0FF) | 0x0800); - bcm43xx_phy_write(bcm, 0x0811, - bcm43xx_phy_read(bcm, 0x0811) | 0x0100); - bcm43xx_phy_write(bcm, 0x0812, - bcm43xx_phy_read(bcm, 0x0812) & 0xCFFF); - if (bcm->sprom.boardflags & BCM43xx_BFL_EXTLNA) { - if (phy->rev >= 7) { - bcm43xx_phy_write(bcm, 0x0811, - bcm43xx_phy_read(bcm, 0x0811) - | 0x0800); - bcm43xx_phy_write(bcm, 0x0812, - bcm43xx_phy_read(bcm, 0x0812) - | 0x8000); - } - } - bcm43xx_radio_write16(bcm, 0x007A, - bcm43xx_radio_read16(bcm, 0x007A) - & 0x00F7); - - for (i = 0; i < loop1_cnt; i++) { - bcm43xx_radio_write16(bcm, 0x0043, loop1_cnt); - bcm43xx_phy_write(bcm, 0x0812, - (bcm43xx_phy_read(bcm, 0x0812) - & 0xF0FF) | (i << 8)); - bcm43xx_phy_write(bcm, 0x0015, - (bcm43xx_phy_read(bcm, 0x0015) - & 0x0FFF) | 0xA000); - bcm43xx_phy_write(bcm, 0x0015, - (bcm43xx_phy_read(bcm, 0x0015) - & 0x0FFF) | 0xF000); - udelay(20); - if (bcm43xx_phy_read(bcm, 0x002D) >= 0x0DFC) - break; - } - loop1_done = i; - loop1_omitted = loop1_cnt - loop1_done; - - loop2_done = 0; - if (loop1_done >= 8) { - bcm43xx_phy_write(bcm, 0x0812, - bcm43xx_phy_read(bcm, 0x0812) - | 0x0030); - for (i = loop1_done - 8; i < 16; i++) { - bcm43xx_phy_write(bcm, 0x0812, - (bcm43xx_phy_read(bcm, 0x0812) - & 0xF0FF) | (i << 8)); - bcm43xx_phy_write(bcm, 0x0015, - (bcm43xx_phy_read(bcm, 0x0015) - & 0x0FFF) | 0xA000); - bcm43xx_phy_write(bcm, 0x0015, - (bcm43xx_phy_read(bcm, 0x0015) - & 0x0FFF) | 0xF000); - udelay(20); - if (bcm43xx_phy_read(bcm, 0x002D) >= 0x0DFC) - break; - } - } - - bcm43xx_phy_write(bcm, 0x0814, backup_phy[4]); - bcm43xx_phy_write(bcm, 0x0815, backup_phy[5]); - bcm43xx_phy_write(bcm, 0x005A, backup_phy[6]); - bcm43xx_phy_write(bcm, 0x0059, backup_phy[7]); - bcm43xx_phy_write(bcm, 0x0058, backup_phy[8]); - bcm43xx_phy_write(bcm, 0x000A, backup_phy[9]); - bcm43xx_phy_write(bcm, 0x0003, backup_phy[10]); - bcm43xx_phy_write(bcm, 0x080F, backup_phy[11]); - bcm43xx_phy_write(bcm, 0x0810, backup_phy[12]); - bcm43xx_phy_write(bcm, 0x002B, backup_phy[13]); - bcm43xx_phy_write(bcm, 0x0015, backup_phy[14]); - - bcm43xx_phy_set_baseband_attenuation(bcm, backup_bband); - - bcm43xx_radio_write16(bcm, 0x0052, backup_radio[0]); - bcm43xx_radio_write16(bcm, 0x0043, backup_radio[1]); - bcm43xx_radio_write16(bcm, 0x007A, backup_radio[2]); - - bcm43xx_phy_write(bcm, 0x0811, backup_phy[2] | 0x0003); - udelay(10); - bcm43xx_phy_write(bcm, 0x0811, backup_phy[2]); - bcm43xx_phy_write(bcm, 0x0812, backup_phy[3]); - bcm43xx_phy_write(bcm, 0x0429, backup_phy[0]); - bcm43xx_phy_write(bcm, 0x0001, backup_phy[1]); - - phy->loopback_gain[0] = ((loop1_done * 6) - (loop1_omitted * 4)) - 11; - phy->loopback_gain[1] = (24 - (3 * loop2_done)) * 2; -} - -static void bcm43xx_phy_initg(struct bcm43xx_private *bcm) -{ - struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm); - struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm); - u16 tmp; - - if (phy->rev == 1) - bcm43xx_phy_initb5(bcm); - else if (phy->rev >= 2 && phy->rev <= 7) - bcm43xx_phy_initb6(bcm); - if (phy->rev >= 2 || phy->connected) - bcm43xx_phy_inita(bcm); - - if (phy->rev >= 2) { - bcm43xx_phy_write(bcm, 0x0814, 0x0000); - bcm43xx_phy_write(bcm, 0x0815, 0x0000); - if (phy->rev == 2) - bcm43xx_phy_write(bcm, 0x0811, 0x0000); - else if (phy->rev >= 3) - bcm43xx_phy_write(bcm, 0x0811, 0x0400); - bcm43xx_phy_write(bcm, 0x0015, 0x00C0); - if (phy->connected) { - tmp = bcm43xx_phy_read(bcm, 0x0400) & 0xFF; - if (tmp < 6) { - bcm43xx_phy_write(bcm, 0x04C2, 0x1816); - bcm43xx_phy_write(bcm, 0x04C3, 0x8006); - if (tmp != 3) { - bcm43xx_phy_write(bcm, 0x04CC, - (bcm43xx_phy_read(bcm, 0x04CC) - & 0x00FF) | 0x1F00); - } - } - } - } - if (phy->rev < 3 && phy->connected) - bcm43xx_phy_write(bcm, 0x047E, 0x0078); - if (phy->rev >= 6 && phy->rev <= 8) { - bcm43xx_phy_write(bcm, 0x0801, bcm43xx_phy_read(bcm, 0x0801) | 0x0080); - bcm43xx_phy_write(bcm, 0x043E, bcm43xx_phy_read(bcm, 0x043E) | 0x0004); - } - if (phy->rev >= 2 && phy->connected) - bcm43xx_calc_loopback_gain(bcm); - if (radio->revision != 8) { - if (radio->initval == 0xFFFF) - radio->initval = bcm43xx_radio_init2050(bcm); - else - bcm43xx_radio_write16(bcm, 0x0078, radio->initval); - } - if (radio->txctl2 == 0xFFFF) { - bcm43xx_phy_lo_g_measure(bcm); - } else { - if (radio->version == 0x2050 && radio->revision == 8) { - //FIXME - } else { - bcm43xx_radio_write16(bcm, 0x0052, - (bcm43xx_radio_read16(bcm, 0x0052) - & 0xFFF0) | radio->txctl1); - } - if (phy->rev >= 6) { - /* - bcm43xx_phy_write(bcm, 0x0036, - (bcm43xx_phy_read(bcm, 0x0036) - & 0xF000) | (FIXME << 12)); - */ - } - if (bcm->sprom.boardflags & BCM43xx_BFL_PACTRL) - bcm43xx_phy_write(bcm, 0x002E, 0x8075); - else - bcm43xx_phy_write(bcm, 0x003E, 0x807F); - if (phy->rev < 2) - bcm43xx_phy_write(bcm, 0x002F, 0x0101); - else - bcm43xx_phy_write(bcm, 0x002F, 0x0202); - } - if (phy->connected) { - bcm43xx_phy_lo_adjust(bcm, 0); - bcm43xx_phy_write(bcm, 0x080F, 0x8078); - } - - if (!(bcm->sprom.boardflags & BCM43xx_BFL_RSSI)) { - /* The specs state to update the NRSSI LT with - * the value 0x7FFFFFFF here. I think that is some weird - * compiler optimization in the original driver. - * Essentially, what we do here is resetting all NRSSI LT - * entries to -32 (see the limit_value() in nrssi_hw_update()) - */ - bcm43xx_nrssi_hw_update(bcm, 0xFFFF); - bcm43xx_calc_nrssi_threshold(bcm); - } else if (phy->connected) { - if (radio->nrssi[0] == -1000) { - assert(radio->nrssi[1] == -1000); - bcm43xx_calc_nrssi_slope(bcm); - } else { - assert(radio->nrssi[1] != -1000); - bcm43xx_calc_nrssi_threshold(bcm); - } - } - if (radio->revision == 8) - bcm43xx_phy_write(bcm, 0x0805, 0x3230); - bcm43xx_phy_init_pctl(bcm); - if (bcm->chip_id == 0x4306 && bcm->chip_package != 2) { - bcm43xx_phy_write(bcm, 0x0429, - bcm43xx_phy_read(bcm, 0x0429) & 0xBFFF); - bcm43xx_phy_write(bcm, 0x04C3, - bcm43xx_phy_read(bcm, 0x04C3) & 0x7FFF); - } -} - -static u16 bcm43xx_phy_lo_b_r15_loop(struct bcm43xx_private *bcm) -{ - int i; - u16 ret = 0; - - for (i = 0; i < 10; i++){ - bcm43xx_phy_write(bcm, 0x0015, 0xAFA0); - udelay(1); - bcm43xx_phy_write(bcm, 0x0015, 0xEFA0); - udelay(10); - bcm43xx_phy_write(bcm, 0x0015, 0xFFA0); - udelay(40); - ret += bcm43xx_phy_read(bcm, 0x002C); - } - - return ret; -} - -void bcm43xx_phy_lo_b_measure(struct bcm43xx_private *bcm) -{ - struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm); - struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm); - u16 regstack[12] = { 0 }; - u16 mls; - u16 fval; - int i, j; - - regstack[0] = bcm43xx_phy_read(bcm, 0x0015); - regstack[1] = bcm43xx_radio_read16(bcm, 0x0052) & 0xFFF0; - - if (radio->version == 0x2053) { - regstack[2] = bcm43xx_phy_read(bcm, 0x000A); - regstack[3] = bcm43xx_phy_read(bcm, 0x002A); - regstack[4] = bcm43xx_phy_read(bcm, 0x0035); - regstack[5] = bcm43xx_phy_read(bcm, 0x0003); - regstack[6] = bcm43xx_phy_read(bcm, 0x0001); - regstack[7] = bcm43xx_phy_read(bcm, 0x0030); - - regstack[8] = bcm43xx_radio_read16(bcm, 0x0043); - regstack[9] = bcm43xx_radio_read16(bcm, 0x007A); - regstack[10] = bcm43xx_read16(bcm, 0x03EC); - regstack[11] = bcm43xx_radio_read16(bcm, 0x0052) & 0x00F0; - - bcm43xx_phy_write(bcm, 0x0030, 0x00FF); - bcm43xx_write16(bcm, 0x03EC, 0x3F3F); - bcm43xx_phy_write(bcm, 0x0035, regstack[4] & 0xFF7F); - bcm43xx_radio_write16(bcm, 0x007A, regstack[9] & 0xFFF0); - } - bcm43xx_phy_write(bcm, 0x0015, 0xB000); - bcm43xx_phy_write(bcm, 0x002B, 0x0004); - - if (radio->version == 0x2053) { - bcm43xx_phy_write(bcm, 0x002B, 0x0203); - bcm43xx_phy_write(bcm, 0x002A, 0x08A3); - } - - phy->minlowsig[0] = 0xFFFF; - - for (i = 0; i < 4; i++) { - bcm43xx_radio_write16(bcm, 0x0052, regstack[1] | i); - bcm43xx_phy_lo_b_r15_loop(bcm); - } - for (i = 0; i < 10; i++) { - bcm43xx_radio_write16(bcm, 0x0052, regstack[1] | i); - mls = bcm43xx_phy_lo_b_r15_loop(bcm) / 10; - if (mls < phy->minlowsig[0]) { - phy->minlowsig[0] = mls; - phy->minlowsigpos[0] = i; - } - } - bcm43xx_radio_write16(bcm, 0x0052, regstack[1] | phy->minlowsigpos[0]); - - phy->minlowsig[1] = 0xFFFF; - - for (i = -4; i < 5; i += 2) { - for (j = -4; j < 5; j += 2) { - if (j < 0) - fval = (0x0100 * i) + j + 0x0100; - else - fval = (0x0100 * i) + j; - bcm43xx_phy_write(bcm, 0x002F, fval); - mls = bcm43xx_phy_lo_b_r15_loop(bcm) / 10; - if (mls < phy->minlowsig[1]) { - phy->minlowsig[1] = mls; - phy->minlowsigpos[1] = fval; - } - } - } - phy->minlowsigpos[1] += 0x0101; - - bcm43xx_phy_write(bcm, 0x002F, phy->minlowsigpos[1]); - if (radio->version == 0x2053) { - bcm43xx_phy_write(bcm, 0x000A, regstack[2]); - bcm43xx_phy_write(bcm, 0x002A, regstack[3]); - bcm43xx_phy_write(bcm, 0x0035, regstack[4]); - bcm43xx_phy_write(bcm, 0x0003, regstack[5]); - bcm43xx_phy_write(bcm, 0x0001, regstack[6]); - bcm43xx_phy_write(bcm, 0x0030, regstack[7]); - - bcm43xx_radio_write16(bcm, 0x0043, regstack[8]); - bcm43xx_radio_write16(bcm, 0x007A, regstack[9]); - - bcm43xx_radio_write16(bcm, 0x0052, - (bcm43xx_radio_read16(bcm, 0x0052) & 0x000F) - | regstack[11]); - - bcm43xx_write16(bcm, 0x03EC, regstack[10]); - } - bcm43xx_phy_write(bcm, 0x0015, regstack[0]); -} - -static inline -u16 bcm43xx_phy_lo_g_deviation_subval(struct bcm43xx_private *bcm, u16 control) -{ - struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm); - - if (phy->connected) { - bcm43xx_phy_write(bcm, 0x15, 0xE300); - control <<= 8; - bcm43xx_phy_write(bcm, 0x0812, control | 0x00B0); - udelay(5); - bcm43xx_phy_write(bcm, 0x0812, control | 0x00B2); - udelay(2); - bcm43xx_phy_write(bcm, 0x0812, control | 0x00B3); - udelay(4); - bcm43xx_phy_write(bcm, 0x0015, 0xF300); - udelay(8); - } else { - bcm43xx_phy_write(bcm, 0x0015, control | 0xEFA0); - udelay(2); - bcm43xx_phy_write(bcm, 0x0015, control | 0xEFE0); - udelay(4); - bcm43xx_phy_write(bcm, 0x0015, control | 0xFFE0); - udelay(8); - } - - return bcm43xx_phy_read(bcm, 0x002D); -} - -static u32 bcm43xx_phy_lo_g_singledeviation(struct bcm43xx_private *bcm, u16 control) -{ - int i; - u32 ret = 0; - - for (i = 0; i < 8; i++) - ret += bcm43xx_phy_lo_g_deviation_subval(bcm, control); - - return ret; -} - -/* Write the LocalOscillator CONTROL */ -static inline -void bcm43xx_lo_write(struct bcm43xx_private *bcm, - struct bcm43xx_lopair *pair) -{ - u16 value; - - value = (u8)(pair->low); - value |= ((u8)(pair->high)) << 8; - -#ifdef CONFIG_BCM43XX_DEBUG - /* Sanity check. */ - if (pair->low < -8 || pair->low > 8 || - pair->high < -8 || pair->high > 8) { - printk(KERN_WARNING PFX - "WARNING: Writing invalid LOpair " - "(low: %d, high: %d, index: %lu)\n", - pair->low, pair->high, - (unsigned long)(pair - bcm43xx_current_phy(bcm)->_lo_pairs)); - dump_stack(); - } -#endif - - bcm43xx_phy_write(bcm, BCM43xx_PHY_G_LO_CONTROL, value); -} - -static inline -struct bcm43xx_lopair * bcm43xx_find_lopair(struct bcm43xx_private *bcm, - u16 baseband_attenuation, - u16 radio_attenuation, - u16 tx) -{ - static const u8 dict[10] = { 11, 10, 11, 12, 13, 12, 13, 12, 13, 12 }; - struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm); - - if (baseband_attenuation > 6) - baseband_attenuation = 6; - assert(radio_attenuation < 10); - - if (tx == 3) { - return bcm43xx_get_lopair(phy, - radio_attenuation, - baseband_attenuation); - } - return bcm43xx_get_lopair(phy, dict[radio_attenuation], baseband_attenuation); -} - -static inline -struct bcm43xx_lopair * bcm43xx_current_lopair(struct bcm43xx_private *bcm) -{ - struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm); - - return bcm43xx_find_lopair(bcm, - radio->baseband_atten, - radio->radio_atten, - radio->txctl1); -} - -/* Adjust B/G LO */ -void bcm43xx_phy_lo_adjust(struct bcm43xx_private *bcm, int fixed) -{ - struct bcm43xx_lopair *pair; - - if (fixed) { - /* Use fixed values. Only for initialization. */ - pair = bcm43xx_find_lopair(bcm, 2, 3, 0); - } else - pair = bcm43xx_current_lopair(bcm); - bcm43xx_lo_write(bcm, pair); -} - -static void bcm43xx_phy_lo_g_measure_txctl2(struct bcm43xx_private *bcm) -{ - struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm); - u16 txctl2 = 0, i; - u32 smallest, tmp; - - bcm43xx_radio_write16(bcm, 0x0052, 0x0000); - udelay(10); - smallest = bcm43xx_phy_lo_g_singledeviation(bcm, 0); - for (i = 0; i < 16; i++) { - bcm43xx_radio_write16(bcm, 0x0052, i); - udelay(10); - tmp = bcm43xx_phy_lo_g_singledeviation(bcm, 0); - if (tmp < smallest) { - smallest = tmp; - txctl2 = i; - } - } - radio->txctl2 = txctl2; -} - -static -void bcm43xx_phy_lo_g_state(struct bcm43xx_private *bcm, - const struct bcm43xx_lopair *in_pair, - struct bcm43xx_lopair *out_pair, - u16 r27) -{ - static const struct bcm43xx_lopair transitions[8] = { - { .high = 1, .low = 1, }, - { .high = 1, .low = 0, }, - { .high = 1, .low = -1, }, - { .high = 0, .low = -1, }, - { .high = -1, .low = -1, }, - { .high = -1, .low = 0, }, - { .high = -1, .low = 1, }, - { .high = 0, .low = 1, }, - }; - struct bcm43xx_lopair lowest_transition = { - .high = in_pair->high, - .low = in_pair->low, - }; - struct bcm43xx_lopair tmp_pair; - struct bcm43xx_lopair transition; - int i = 12; - int state = 0; - int found_lower; - int j, begin, end; - u32 lowest_deviation; - u32 tmp; - - /* Note that in_pair and out_pair can point to the same pair. Be careful. */ - - bcm43xx_lo_write(bcm, &lowest_transition); - lowest_deviation = bcm43xx_phy_lo_g_singledeviation(bcm, r27); - do { - found_lower = 0; - assert(state >= 0 && state <= 8); - if (state == 0) { - begin = 1; - end = 8; - } else if (state % 2 == 0) { - begin = state - 1; - end = state + 1; - } else { - begin = state - 2; - end = state + 2; - } - if (begin < 1) - begin += 8; - if (end > 8) - end -= 8; - - j = begin; - tmp_pair.high = lowest_transition.high; - tmp_pair.low = lowest_transition.low; - while (1) { - assert(j >= 1 && j <= 8); - transition.high = tmp_pair.high + transitions[j - 1].high; - transition.low = tmp_pair.low + transitions[j - 1].low; - if ((abs(transition.low) < 9) && (abs(transition.high) < 9)) { - bcm43xx_lo_write(bcm, &transition); - tmp = bcm43xx_phy_lo_g_singledeviation(bcm, r27); - if (tmp < lowest_deviation) { - lowest_deviation = tmp; - state = j; - found_lower = 1; - - lowest_transition.high = transition.high; - lowest_transition.low = transition.low; - } - } - if (j == end) - break; - if (j == 8) - j = 1; - else - j++; - } - } while (i-- && found_lower); - - out_pair->high = lowest_transition.high; - out_pair->low = lowest_transition.low; -} - -/* Set the baseband attenuation value on chip. */ -void bcm43xx_phy_set_baseband_attenuation(struct bcm43xx_private *bcm, - u16 baseband_attenuation) -{ - struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm); - u16 value; - - if (phy->version == 0) { - value = (bcm43xx_read16(bcm, 0x03E6) & 0xFFF0); - value |= (baseband_attenuation & 0x000F); - bcm43xx_write16(bcm, 0x03E6, value); - return; - } - - if (phy->version > 1) { - value = bcm43xx_phy_read(bcm, 0x0060) & ~0x003C; - value |= (baseband_attenuation << 2) & 0x003C; - } else { - value = bcm43xx_phy_read(bcm, 0x0060) & ~0x0078; - value |= (baseband_attenuation << 3) & 0x0078; - } - bcm43xx_phy_write(bcm, 0x0060, value); -} - -/* http://bcm-specs.sipsolutions.net/LocalOscillator/Measure */ -void bcm43xx_phy_lo_g_measure(struct bcm43xx_private *bcm) -{ - static const u8 pairorder[10] = { 3, 1, 5, 7, 9, 2, 0, 4, 6, 8 }; - const int is_initializing = bcm43xx_is_initializing(bcm); - struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm); - struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm); - u16 h, i, oldi = 0, j; - struct bcm43xx_lopair control; - struct bcm43xx_lopair *tmp_control; - u16 tmp; - u16 regstack[16] = { 0 }; - u8 oldchannel; - - //XXX: What are these? - u8 r27 = 0, r31; - - oldchannel = radio->channel; - /* Setup */ - if (phy->connected) { - regstack[0] = bcm43xx_phy_read(bcm, BCM43xx_PHY_G_CRS); - regstack[1] = bcm43xx_phy_read(bcm, 0x0802); - bcm43xx_phy_write(bcm, BCM43xx_PHY_G_CRS, regstack[0] & 0x7FFF); - bcm43xx_phy_write(bcm, 0x0802, regstack[1] & 0xFFFC); - } - regstack[3] = bcm43xx_read16(bcm, 0x03E2); - bcm43xx_write16(bcm, 0x03E2, regstack[3] | 0x8000); - regstack[4] = bcm43xx_read16(bcm, BCM43xx_MMIO_CHANNEL_EXT); - regstack[5] = bcm43xx_phy_read(bcm, 0x15); - regstack[6] = bcm43xx_phy_read(bcm, 0x2A); - regstack[7] = bcm43xx_phy_read(bcm, 0x35); - regstack[8] = bcm43xx_phy_read(bcm, 0x60); - regstack[9] = bcm43xx_radio_read16(bcm, 0x43); - regstack[10] = bcm43xx_radio_read16(bcm, 0x7A); - regstack[11] = bcm43xx_radio_read16(bcm, 0x52); - if (phy->connected) { - regstack[12] = bcm43xx_phy_read(bcm, 0x0811); - regstack[13] = bcm43xx_phy_read(bcm, 0x0812); - regstack[14] = bcm43xx_phy_read(bcm, 0x0814); - regstack[15] = bcm43xx_phy_read(bcm, 0x0815); - } - bcm43xx_radio_selectchannel(bcm, 6, 0); - if (phy->connected) { - bcm43xx_phy_write(bcm, BCM43xx_PHY_G_CRS, regstack[0] & 0x7FFF); - bcm43xx_phy_write(bcm, 0x0802, regstack[1] & 0xFFFC); - bcm43xx_dummy_transmission(bcm); - } - bcm43xx_radio_write16(bcm, 0x0043, 0x0006); - - bcm43xx_phy_set_baseband_attenuation(bcm, 2); - - bcm43xx_write16(bcm, BCM43xx_MMIO_CHANNEL_EXT, 0x0000); - bcm43xx_phy_write(bcm, 0x002E, 0x007F); - bcm43xx_phy_write(bcm, 0x080F, 0x0078); - bcm43xx_phy_write(bcm, 0x0035, regstack[7] & ~(1 << 7)); - bcm43xx_radio_write16(bcm, 0x007A, regstack[10] & 0xFFF0); - bcm43xx_phy_write(bcm, 0x002B, 0x0203); - bcm43xx_phy_write(bcm, 0x002A, 0x08A3); - if (phy->connected) { - bcm43xx_phy_write(bcm, 0x0814, regstack[14] | 0x0003); - bcm43xx_phy_write(bcm, 0x0815, regstack[15] & 0xFFFC); - bcm43xx_phy_write(bcm, 0x0811, 0x01B3); - bcm43xx_phy_write(bcm, 0x0812, 0x00B2); - } - if (is_initializing) - bcm43xx_phy_lo_g_measure_txctl2(bcm); - bcm43xx_phy_write(bcm, 0x080F, 0x8078); - - /* Measure */ - control.low = 0; - control.high = 0; - for (h = 0; h < 10; h++) { - /* Loop over each possible RadioAttenuation (0-9) */ - i = pairorder[h]; - if (is_initializing) { - if (i == 3) { - control.low = 0; - control.high = 0; - } else if (((i % 2 == 1) && (oldi % 2 == 1)) || - ((i % 2 == 0) && (oldi % 2 == 0))) { - tmp_control = bcm43xx_get_lopair(phy, oldi, 0); - memcpy(&control, tmp_control, sizeof(control)); - } else { - tmp_control = bcm43xx_get_lopair(phy, 3, 0); - memcpy(&control, tmp_control, sizeof(control)); - } - } - /* Loop over each possible BasebandAttenuation/2 */ - for (j = 0; j < 4; j++) { - if (is_initializing) { - tmp = i * 2 + j; - r27 = 0; - r31 = 0; - if (tmp > 14) { - r31 = 1; - if (tmp > 17) - r27 = 1; - if (tmp > 19) - r27 = 2; - } - } else { - tmp_control = bcm43xx_get_lopair(phy, i, j * 2); - if (!tmp_control->used) - continue; - memcpy(&control, tmp_control, sizeof(control)); - r27 = 3; - r31 = 0; - } - bcm43xx_radio_write16(bcm, 0x43, i); - bcm43xx_radio_write16(bcm, 0x52, radio->txctl2); - udelay(10); - - bcm43xx_phy_set_baseband_attenuation(bcm, j * 2); - - tmp = (regstack[10] & 0xFFF0); - if (r31) - tmp |= 0x0008; - bcm43xx_radio_write16(bcm, 0x007A, tmp); - - tmp_control = bcm43xx_get_lopair(phy, i, j * 2); - bcm43xx_phy_lo_g_state(bcm, &control, tmp_control, r27); - } - oldi = i; - } - /* Loop over each possible RadioAttenuation (10-13) */ - for (i = 10; i < 14; i++) { - /* Loop over each possible BasebandAttenuation/2 */ - for (j = 0; j < 4; j++) { - if (is_initializing) { - tmp_control = bcm43xx_get_lopair(phy, i - 9, j * 2); - memcpy(&control, tmp_control, sizeof(control)); - tmp = (i - 9) * 2 + j - 5;//FIXME: This is wrong, as the following if statement can never trigger. - r27 = 0; - r31 = 0; - if (tmp > 14) { - r31 = 1; - if (tmp > 17) - r27 = 1; - if (tmp > 19) - r27 = 2; - } - } else { - tmp_control = bcm43xx_get_lopair(phy, i - 9, j * 2); - if (!tmp_control->used) - continue; - memcpy(&control, tmp_control, sizeof(control)); - r27 = 3; - r31 = 0; - } - bcm43xx_radio_write16(bcm, 0x43, i - 9); - bcm43xx_radio_write16(bcm, 0x52, - radio->txctl2 - | (3/*txctl1*/ << 4));//FIXME: shouldn't txctl1 be zero here and 3 in the loop above? - udelay(10); - - bcm43xx_phy_set_baseband_attenuation(bcm, j * 2); - - tmp = (regstack[10] & 0xFFF0); - if (r31) - tmp |= 0x0008; - bcm43xx_radio_write16(bcm, 0x7A, tmp); - - tmp_control = bcm43xx_get_lopair(phy, i, j * 2); - bcm43xx_phy_lo_g_state(bcm, &control, tmp_control, r27); - } - } - - /* Restoration */ - if (phy->connected) { - bcm43xx_phy_write(bcm, 0x0015, 0xE300); - bcm43xx_phy_write(bcm, 0x0812, (r27 << 8) | 0xA0); - udelay(5); - bcm43xx_phy_write(bcm, 0x0812, (r27 << 8) | 0xA2); - udelay(2); - bcm43xx_phy_write(bcm, 0x0812, (r27 << 8) | 0xA3); - } else - bcm43xx_phy_write(bcm, 0x0015, r27 | 0xEFA0); - bcm43xx_phy_lo_adjust(bcm, is_initializing); - bcm43xx_phy_write(bcm, 0x002E, 0x807F); - if (phy->connected) - bcm43xx_phy_write(bcm, 0x002F, 0x0202); - else - bcm43xx_phy_write(bcm, 0x002F, 0x0101); - bcm43xx_write16(bcm, BCM43xx_MMIO_CHANNEL_EXT, regstack[4]); - bcm43xx_phy_write(bcm, 0x0015, regstack[5]); - bcm43xx_phy_write(bcm, 0x002A, regstack[6]); - bcm43xx_phy_write(bcm, 0x0035, regstack[7]); - bcm43xx_phy_write(bcm, 0x0060, regstack[8]); - bcm43xx_radio_write16(bcm, 0x0043, regstack[9]); - bcm43xx_radio_write16(bcm, 0x007A, regstack[10]); - regstack[11] &= 0x00F0; - regstack[11] |= (bcm43xx_radio_read16(bcm, 0x52) & 0x000F); - bcm43xx_radio_write16(bcm, 0x52, regstack[11]); - bcm43xx_write16(bcm, 0x03E2, regstack[3]); - if (phy->connected) { - bcm43xx_phy_write(bcm, 0x0811, regstack[12]); - bcm43xx_phy_write(bcm, 0x0812, regstack[13]); - bcm43xx_phy_write(bcm, 0x0814, regstack[14]); - bcm43xx_phy_write(bcm, 0x0815, regstack[15]); - bcm43xx_phy_write(bcm, BCM43xx_PHY_G_CRS, regstack[0]); - bcm43xx_phy_write(bcm, 0x0802, regstack[1]); - } - bcm43xx_radio_selectchannel(bcm, oldchannel, 1); - -#ifdef CONFIG_BCM43XX_DEBUG - { - /* Sanity check for all lopairs. */ - for (i = 0; i < BCM43xx_LO_COUNT; i++) { - tmp_control = phy->_lo_pairs + i; - if (tmp_control->low < -8 || tmp_control->low > 8 || - tmp_control->high < -8 || tmp_control->high > 8) { - printk(KERN_WARNING PFX - "WARNING: Invalid LOpair (low: %d, high: %d, index: %d)\n", - tmp_control->low, tmp_control->high, i); - } - } - } -#endif /* CONFIG_BCM43XX_DEBUG */ -} - -static -void bcm43xx_phy_lo_mark_current_used(struct bcm43xx_private *bcm) -{ - struct bcm43xx_lopair *pair; - - pair = bcm43xx_current_lopair(bcm); - pair->used = 1; -} - -void bcm43xx_phy_lo_mark_all_unused(struct bcm43xx_private *bcm) -{ - struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm); - struct bcm43xx_lopair *pair; - int i; - - for (i = 0; i < BCM43xx_LO_COUNT; i++) { - pair = phy->_lo_pairs + i; - pair->used = 0; - } -} - -/* http://bcm-specs.sipsolutions.net/EstimatePowerOut - * This function converts a TSSI value to dBm in Q5.2 - */ -static s8 bcm43xx_phy_estimate_power_out(struct bcm43xx_private *bcm, s8 tssi) -{ - struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm); - s8 dbm = 0; - s32 tmp; - - tmp = phy->idle_tssi; - tmp += tssi; - tmp -= phy->savedpctlreg; - - switch (phy->type) { - case BCM43xx_PHYTYPE_A: - tmp += 0x80; - tmp = limit_value(tmp, 0x00, 0xFF); - dbm = phy->tssi2dbm[tmp]; - TODO(); //TODO: There's a FIXME on the specs - break; - case BCM43xx_PHYTYPE_B: - case BCM43xx_PHYTYPE_G: - tmp = limit_value(tmp, 0x00, 0x3F); - dbm = phy->tssi2dbm[tmp]; - break; - default: - assert(0); - } - - return dbm; -} - -/* http://bcm-specs.sipsolutions.net/RecalculateTransmissionPower */ -void bcm43xx_phy_xmitpower(struct bcm43xx_private *bcm) -{ - struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm); - struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm); - - if (phy->savedpctlreg == 0xFFFF) - return; - if ((bcm->board_type == 0x0416) && - (bcm->board_vendor == PCI_VENDOR_ID_BROADCOM)) - return; - - switch (phy->type) { - case BCM43xx_PHYTYPE_A: { - - TODO(); //TODO: Nothing for A PHYs yet :-/ - - break; - } - case BCM43xx_PHYTYPE_B: - case BCM43xx_PHYTYPE_G: { - u16 tmp; - u16 txpower; - s8 v0, v1, v2, v3; - s8 average; - u8 max_pwr; - s16 desired_pwr, estimated_pwr, pwr_adjust; - s16 radio_att_delta, baseband_att_delta; - s16 radio_attenuation, baseband_attenuation; - unsigned long phylock_flags; - - tmp = bcm43xx_shm_read16(bcm, BCM43xx_SHM_SHARED, 0x0058); - v0 = (s8)(tmp & 0x00FF); - v1 = (s8)((tmp & 0xFF00) >> 8); - tmp = bcm43xx_shm_read16(bcm, BCM43xx_SHM_SHARED, 0x005A); - v2 = (s8)(tmp & 0x00FF); - v3 = (s8)((tmp & 0xFF00) >> 8); - tmp = 0; - - if (v0 == 0x7F || v1 == 0x7F || v2 == 0x7F || v3 == 0x7F) { - tmp = bcm43xx_shm_read16(bcm, BCM43xx_SHM_SHARED, 0x0070); - v0 = (s8)(tmp & 0x00FF); - v1 = (s8)((tmp & 0xFF00) >> 8); - tmp = bcm43xx_shm_read16(bcm, BCM43xx_SHM_SHARED, 0x0072); - v2 = (s8)(tmp & 0x00FF); - v3 = (s8)((tmp & 0xFF00) >> 8); - if (v0 == 0x7F || v1 == 0x7F || v2 == 0x7F || v3 == 0x7F) - return; - v0 = (v0 + 0x20) & 0x3F; - v1 = (v1 + 0x20) & 0x3F; - v2 = (v2 + 0x20) & 0x3F; - v3 = (v3 + 0x20) & 0x3F; - tmp = 1; - } - bcm43xx_radio_clear_tssi(bcm); - - average = (v0 + v1 + v2 + v3 + 2) / 4; - - if (tmp && (bcm43xx_shm_read16(bcm, BCM43xx_SHM_SHARED, 0x005E) & 0x8)) - average -= 13; - - estimated_pwr = bcm43xx_phy_estimate_power_out(bcm, average); - - max_pwr = bcm->sprom.maxpower_bgphy; - - if ((bcm->sprom.boardflags & BCM43xx_BFL_PACTRL) && - (phy->type == BCM43xx_PHYTYPE_G)) - max_pwr -= 0x3; - - /*TODO: - max_pwr = min(REG - bcm->sprom.antennagain_bgphy - 0x6, max_pwr) - where REG is the max power as per the regulatory domain - */ - - desired_pwr = limit_value(radio->txpower_desired, 0, max_pwr); - /* Check if we need to adjust the current power. */ - pwr_adjust = desired_pwr - estimated_pwr; - radio_att_delta = -(pwr_adjust + 7) >> 3; - baseband_att_delta = -(pwr_adjust >> 1) - (4 * radio_att_delta); - if ((radio_att_delta == 0) && (baseband_att_delta == 0)) { - bcm43xx_phy_lo_mark_current_used(bcm); - return; - } - - /* Calculate the new attenuation values. */ - baseband_attenuation = radio->baseband_atten; - baseband_attenuation += baseband_att_delta; - radio_attenuation = radio->radio_atten; - radio_attenuation += radio_att_delta; - - /* Get baseband and radio attenuation values into their permitted ranges. - * baseband 0-11, radio 0-9. - * Radio attenuation affects power level 4 times as much as baseband. - */ - if (radio_attenuation < 0) { - baseband_attenuation -= (4 * -radio_attenuation); - radio_attenuation = 0; - } else if (radio_attenuation > 9) { - baseband_attenuation += (4 * (radio_attenuation - 9)); - radio_attenuation = 9; - } else { - while (baseband_attenuation < 0 && radio_attenuation > 0) { - baseband_attenuation += 4; - radio_attenuation--; - } - while (baseband_attenuation > 11 && radio_attenuation < 9) { - baseband_attenuation -= 4; - radio_attenuation++; - } - } - baseband_attenuation = limit_value(baseband_attenuation, 0, 11); - - txpower = radio->txctl1; - if ((radio->version == 0x2050) && (radio->revision == 2)) { - if (radio_attenuation <= 1) { - if (txpower == 0) { - txpower = 3; - radio_attenuation += 2; - baseband_attenuation += 2; - } else if (bcm->sprom.boardflags & BCM43xx_BFL_PACTRL) { - baseband_attenuation += 4 * (radio_attenuation - 2); - radio_attenuation = 2; - } - } else if (radio_attenuation > 4 && txpower != 0) { - txpower = 0; - if (baseband_attenuation < 3) { - radio_attenuation -= 3; - baseband_attenuation += 2; - } else { - radio_attenuation -= 2; - baseband_attenuation -= 2; - } - } - } - radio->txctl1 = txpower; - baseband_attenuation = limit_value(baseband_attenuation, 0, 11); - radio_attenuation = limit_value(radio_attenuation, 0, 9); - - bcm43xx_phy_lock(bcm, phylock_flags); - bcm43xx_radio_lock(bcm); - bcm43xx_radio_set_txpower_bg(bcm, baseband_attenuation, - radio_attenuation, txpower); - bcm43xx_phy_lo_mark_current_used(bcm); - bcm43xx_radio_unlock(bcm); - bcm43xx_phy_unlock(bcm, phylock_flags); - break; - } - default: - assert(0); - } -} - -static inline -s32 bcm43xx_tssi2dbm_ad(s32 num, s32 den) -{ - if (num < 0) - return num/den; - else - return (num+den/2)/den; -} - -static inline -s8 bcm43xx_tssi2dbm_entry(s8 entry [], u8 index, s16 pab0, s16 pab1, s16 pab2) -{ - s32 m1, m2, f = 256, q, delta; - s8 i = 0; - - m1 = bcm43xx_tssi2dbm_ad(16 * pab0 + index * pab1, 32); - m2 = max(bcm43xx_tssi2dbm_ad(32768 + index * pab2, 256), 1); - do { - if (i > 15) - return -EINVAL; - q = bcm43xx_tssi2dbm_ad(f * 4096 - - bcm43xx_tssi2dbm_ad(m2 * f, 16) * f, 2048); - delta = abs(q - f); - f = q; - i++; - } while (delta >= 2); - entry[index] = limit_value(bcm43xx_tssi2dbm_ad(m1 * f, 8192), -127, 128); - return 0; -} - -/* http://bcm-specs.sipsolutions.net/TSSI_to_DBM_Table */ -int bcm43xx_phy_init_tssi2dbm_table(struct bcm43xx_private *bcm) -{ - struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm); - struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm); - s16 pab0, pab1, pab2; - u8 idx; - s8 *dyn_tssi2dbm; - - if (phy->type == BCM43xx_PHYTYPE_A) { - pab0 = (s16)(bcm->sprom.pa1b0); - pab1 = (s16)(bcm->sprom.pa1b1); - pab2 = (s16)(bcm->sprom.pa1b2); - } else { - pab0 = (s16)(bcm->sprom.pa0b0); - pab1 = (s16)(bcm->sprom.pa0b1); - pab2 = (s16)(bcm->sprom.pa0b2); - } - - if ((bcm->chip_id == 0x4301) && (radio->version != 0x2050)) { - phy->idle_tssi = 0x34; - phy->tssi2dbm = bcm43xx_tssi2dbm_b_table; - return 0; - } - - if (pab0 != 0 && pab1 != 0 && pab2 != 0 && - pab0 != -1 && pab1 != -1 && pab2 != -1) { - /* The pabX values are set in SPROM. Use them. */ - if (phy->type == BCM43xx_PHYTYPE_A) { - if ((s8)bcm->sprom.idle_tssi_tgt_aphy != 0 && - (s8)bcm->sprom.idle_tssi_tgt_aphy != -1) - phy->idle_tssi = (s8)(bcm->sprom.idle_tssi_tgt_aphy); - else - phy->idle_tssi = 62; - } else { - if ((s8)bcm->sprom.idle_tssi_tgt_bgphy != 0 && - (s8)bcm->sprom.idle_tssi_tgt_bgphy != -1) - phy->idle_tssi = (s8)(bcm->sprom.idle_tssi_tgt_bgphy); - else - phy->idle_tssi = 62; - } - dyn_tssi2dbm = kmalloc(64, GFP_KERNEL); - if (dyn_tssi2dbm == NULL) { - printk(KERN_ERR PFX "Could not allocate memory" - "for tssi2dbm table\n"); - return -ENOMEM; - } - for (idx = 0; idx < 64; idx++) - if (bcm43xx_tssi2dbm_entry(dyn_tssi2dbm, idx, pab0, pab1, pab2)) { - phy->tssi2dbm = NULL; - printk(KERN_ERR PFX "Could not generate " - "tssi2dBm table\n"); - return -ENODEV; - } - phy->tssi2dbm = dyn_tssi2dbm; - phy->dyn_tssi_tbl = 1; - } else { - /* pabX values not set in SPROM. */ - switch (phy->type) { - case BCM43xx_PHYTYPE_A: - /* APHY needs a generated table. */ - phy->tssi2dbm = NULL; - printk(KERN_ERR PFX "Could not generate tssi2dBm " - "table (wrong SPROM info)!\n"); - return -ENODEV; - case BCM43xx_PHYTYPE_B: - phy->idle_tssi = 0x34; - phy->tssi2dbm = bcm43xx_tssi2dbm_b_table; - break; - case BCM43xx_PHYTYPE_G: - phy->idle_tssi = 0x34; - phy->tssi2dbm = bcm43xx_tssi2dbm_g_table; - break; - } - } - - return 0; -} - -int bcm43xx_phy_init(struct bcm43xx_private *bcm) -{ - struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm); - int err = -ENODEV; - unsigned long flags; - - /* We do not want to be preempted while calibrating - * the hardware. - */ - local_irq_save(flags); - - switch (phy->type) { - case BCM43xx_PHYTYPE_A: - if (phy->rev == 2 || phy->rev == 3) { - bcm43xx_phy_inita(bcm); - err = 0; - } - break; - case BCM43xx_PHYTYPE_B: - switch (phy->rev) { - case 2: - bcm43xx_phy_initb2(bcm); - err = 0; - break; - case 4: - bcm43xx_phy_initb4(bcm); - err = 0; - break; - case 5: - bcm43xx_phy_initb5(bcm); - err = 0; - break; - case 6: - bcm43xx_phy_initb6(bcm); - err = 0; - break; - } - break; - case BCM43xx_PHYTYPE_G: - bcm43xx_phy_initg(bcm); - err = 0; - break; - } - local_irq_restore(flags); - if (err) - printk(KERN_WARNING PFX "Unknown PHYTYPE found!\n"); - - return err; -} - -void bcm43xx_phy_set_antenna_diversity(struct bcm43xx_private *bcm) -{ - struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm); - u16 antennadiv; - u16 offset; - u16 value; - u32 ucodeflags; - - antennadiv = phy->antenna_diversity; - - if (antennadiv == 0xFFFF) - antennadiv = 3; - assert(antennadiv <= 3); - - ucodeflags = bcm43xx_shm_read32(bcm, BCM43xx_SHM_SHARED, - BCM43xx_UCODEFLAGS_OFFSET); - bcm43xx_shm_write32(bcm, BCM43xx_SHM_SHARED, - BCM43xx_UCODEFLAGS_OFFSET, - ucodeflags & ~BCM43xx_UCODEFLAG_AUTODIV); - - switch (phy->type) { - case BCM43xx_PHYTYPE_A: - case BCM43xx_PHYTYPE_G: - if (phy->type == BCM43xx_PHYTYPE_A) - offset = 0x0000; - else - offset = 0x0400; - - if (antennadiv == 2) - value = (3/*automatic*/ << 7); - else - value = (antennadiv << 7); - bcm43xx_phy_write(bcm, offset + 1, - (bcm43xx_phy_read(bcm, offset + 1) - & 0x7E7F) | value); - - if (antennadiv >= 2) { - if (antennadiv == 2) - value = (antennadiv << 7); - else - value = (0/*force0*/ << 7); - bcm43xx_phy_write(bcm, offset + 0x2B, - (bcm43xx_phy_read(bcm, offset + 0x2B) - & 0xFEFF) | value); - } - - if (phy->type == BCM43xx_PHYTYPE_G) { - if (antennadiv >= 2) - bcm43xx_phy_write(bcm, 0x048C, - bcm43xx_phy_read(bcm, 0x048C) - | 0x2000); - else - bcm43xx_phy_write(bcm, 0x048C, - bcm43xx_phy_read(bcm, 0x048C) - & ~0x2000); - if (phy->rev >= 2) { - bcm43xx_phy_write(bcm, 0x0461, - bcm43xx_phy_read(bcm, 0x0461) - | 0x0010); - bcm43xx_phy_write(bcm, 0x04AD, - (bcm43xx_phy_read(bcm, 0x04AD) - & 0x00FF) | 0x0015); - if (phy->rev == 2) - bcm43xx_phy_write(bcm, 0x0427, 0x0008); - else - bcm43xx_phy_write(bcm, 0x0427, - (bcm43xx_phy_read(bcm, 0x0427) - & 0x00FF) | 0x0008); - } - else if (phy->rev >= 6) - bcm43xx_phy_write(bcm, 0x049B, 0x00DC); - } else { - if (phy->rev < 3) - bcm43xx_phy_write(bcm, 0x002B, - (bcm43xx_phy_read(bcm, 0x002B) - & 0x00FF) | 0x0024); - else { - bcm43xx_phy_write(bcm, 0x0061, - bcm43xx_phy_read(bcm, 0x0061) - | 0x0010); - if (phy->rev == 3) { - bcm43xx_phy_write(bcm, 0x0093, 0x001D); - bcm43xx_phy_write(bcm, 0x0027, 0x0008); - } else { - bcm43xx_phy_write(bcm, 0x0093, 0x003A); - bcm43xx_phy_write(bcm, 0x0027, - (bcm43xx_phy_read(bcm, 0x0027) - & 0x00FF) | 0x0008); - } - } - } - break; - case BCM43xx_PHYTYPE_B: - if (bcm->current_core->rev == 2) - value = (3/*automatic*/ << 7); - else - value = (antennadiv << 7); - bcm43xx_phy_write(bcm, 0x03E2, - (bcm43xx_phy_read(bcm, 0x03E2) - & 0xFE7F) | value); - break; - default: - assert(0); - } - - if (antennadiv >= 2) { - ucodeflags = bcm43xx_shm_read32(bcm, BCM43xx_SHM_SHARED, - BCM43xx_UCODEFLAGS_OFFSET); - bcm43xx_shm_write32(bcm, BCM43xx_SHM_SHARED, - BCM43xx_UCODEFLAGS_OFFSET, - ucodeflags | BCM43xx_UCODEFLAG_AUTODIV); - } - - phy->antenna_diversity = antennadiv; -} diff --git a/trunk/drivers/net/wireless/bcm43xx/bcm43xx_phy.h b/trunk/drivers/net/wireless/bcm43xx/bcm43xx_phy.h deleted file mode 100644 index 1f321ef42be8..000000000000 --- a/trunk/drivers/net/wireless/bcm43xx/bcm43xx_phy.h +++ /dev/null @@ -1,74 +0,0 @@ -/* - - Broadcom BCM43xx wireless driver - - Copyright (c) 2005 Martin Langer , - Stefano Brivio - Michael Buesch - Danny van Dyk - Andreas Jaggi - - Some parts of the code in this file are derived from the ipw2200 - driver Copyright(c) 2003 - 2004 Intel Corporation. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; see the file COPYING. If not, write to - the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor, - Boston, MA 02110-1301, USA. - -*/ - -#ifndef BCM43xx_PHY_H_ -#define BCM43xx_PHY_H_ - -#include - -struct bcm43xx_private; - -void bcm43xx_raw_phy_lock(struct bcm43xx_private *bcm); -#define bcm43xx_phy_lock(bcm, flags) \ - do { \ - local_irq_save(flags); \ - bcm43xx_raw_phy_lock(bcm); \ - } while (0) -void bcm43xx_raw_phy_unlock(struct bcm43xx_private *bcm); -#define bcm43xx_phy_unlock(bcm, flags) \ - do { \ - bcm43xx_raw_phy_unlock(bcm); \ - local_irq_restore(flags); \ - } while (0) - -u16 bcm43xx_phy_read(struct bcm43xx_private *bcm, u16 offset); -void bcm43xx_phy_write(struct bcm43xx_private *bcm, u16 offset, u16 val); - -int bcm43xx_phy_init_tssi2dbm_table(struct bcm43xx_private *bcm); -int bcm43xx_phy_init(struct bcm43xx_private *bcm); - -void bcm43xx_phy_set_antenna_diversity(struct bcm43xx_private *bcm); -void bcm43xx_phy_calibrate(struct bcm43xx_private *bcm); -int bcm43xx_phy_connect(struct bcm43xx_private *bcm, int connect); - -void bcm43xx_phy_lo_b_measure(struct bcm43xx_private *bcm); -void bcm43xx_phy_lo_g_measure(struct bcm43xx_private *bcm); -void bcm43xx_phy_xmitpower(struct bcm43xx_private *bcm); - -/* Adjust the LocalOscillator to the saved values. - * "fixed" is only set to 1 once in initialization. Set to 0 otherwise. - */ -void bcm43xx_phy_lo_adjust(struct bcm43xx_private *bcm, int fixed); -void bcm43xx_phy_lo_mark_all_unused(struct bcm43xx_private *bcm); - -void bcm43xx_phy_set_baseband_attenuation(struct bcm43xx_private *bcm, - u16 baseband_attenuation); - -#endif /* BCM43xx_PHY_H_ */ diff --git a/trunk/drivers/net/wireless/bcm43xx/bcm43xx_pio.c b/trunk/drivers/net/wireless/bcm43xx/bcm43xx_pio.c deleted file mode 100644 index c59ddd40680d..000000000000 --- a/trunk/drivers/net/wireless/bcm43xx/bcm43xx_pio.c +++ /dev/null @@ -1,606 +0,0 @@ -/* - - Broadcom BCM43xx wireless driver - - PIO Transmission - - Copyright (c) 2005 Michael Buesch - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; see the file COPYING. If not, write to - the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor, - Boston, MA 02110-1301, USA. - -*/ - -#include "bcm43xx.h" -#include "bcm43xx_pio.h" -#include "bcm43xx_main.h" -#include "bcm43xx_xmit.h" - -#include - - -static void tx_start(struct bcm43xx_pioqueue *queue) -{ - bcm43xx_pio_write(queue, BCM43xx_PIO_TXCTL, - BCM43xx_PIO_TXCTL_INIT); -} - -static void tx_octet(struct bcm43xx_pioqueue *queue, - u8 octet) -{ - if (queue->need_workarounds) { - bcm43xx_pio_write(queue, BCM43xx_PIO_TXDATA, - octet); - bcm43xx_pio_write(queue, BCM43xx_PIO_TXCTL, - BCM43xx_PIO_TXCTL_WRITEHI); - } else { - bcm43xx_pio_write(queue, BCM43xx_PIO_TXCTL, - BCM43xx_PIO_TXCTL_WRITEHI); - bcm43xx_pio_write(queue, BCM43xx_PIO_TXDATA, - octet); - } -} - -static u16 tx_get_next_word(struct bcm43xx_txhdr *txhdr, - const u8 *packet, - unsigned int *pos) -{ - const u8 *source; - unsigned int i = *pos; - u16 ret; - - if (i < sizeof(*txhdr)) { - source = (const u8 *)txhdr; - } else { - source = packet; - i -= sizeof(*txhdr); - } - ret = le16_to_cpu( *((u16 *)(source + i)) ); - *pos += 2; - - return ret; -} - -static void tx_data(struct bcm43xx_pioqueue *queue, - struct bcm43xx_txhdr *txhdr, - const u8 *packet, - unsigned int octets) -{ - u16 data; - unsigned int i = 0; - - if (queue->need_workarounds) { - data = tx_get_next_word(txhdr, packet, &i); - bcm43xx_pio_write(queue, BCM43xx_PIO_TXDATA, data); - } - bcm43xx_pio_write(queue, BCM43xx_PIO_TXCTL, - BCM43xx_PIO_TXCTL_WRITELO | - BCM43xx_PIO_TXCTL_WRITEHI); - while (i < octets - 1) { - data = tx_get_next_word(txhdr, packet, &i); - bcm43xx_pio_write(queue, BCM43xx_PIO_TXDATA, data); - } - if (octets % 2) - tx_octet(queue, packet[octets - sizeof(*txhdr) - 1]); -} - -static void tx_complete(struct bcm43xx_pioqueue *queue, - struct sk_buff *skb) -{ - if (queue->need_workarounds) { - bcm43xx_pio_write(queue, BCM43xx_PIO_TXDATA, - skb->data[skb->len - 1]); - bcm43xx_pio_write(queue, BCM43xx_PIO_TXCTL, - BCM43xx_PIO_TXCTL_WRITEHI | - BCM43xx_PIO_TXCTL_COMPLETE); - } else { - bcm43xx_pio_write(queue, BCM43xx_PIO_TXCTL, - BCM43xx_PIO_TXCTL_COMPLETE); - } -} - -static u16 generate_cookie(struct bcm43xx_pioqueue *queue, - int packetindex) -{ - u16 cookie = 0x0000; - - /* We use the upper 4 bits for the PIO - * controller ID and the lower 12 bits - * for the packet index (in the cache). - */ - switch (queue->mmio_base) { - case BCM43xx_MMIO_PIO1_BASE: - break; - case BCM43xx_MMIO_PIO2_BASE: - cookie = 0x1000; - break; - case BCM43xx_MMIO_PIO3_BASE: - cookie = 0x2000; - break; - case BCM43xx_MMIO_PIO4_BASE: - cookie = 0x3000; - break; - default: - assert(0); - } - assert(((u16)packetindex & 0xF000) == 0x0000); - cookie |= (u16)packetindex; - - return cookie; -} - -static -struct bcm43xx_pioqueue * parse_cookie(struct bcm43xx_private *bcm, - u16 cookie, - struct bcm43xx_pio_txpacket **packet) -{ - struct bcm43xx_pio *pio = bcm43xx_current_pio(bcm); - struct bcm43xx_pioqueue *queue = NULL; - int packetindex; - - switch (cookie & 0xF000) { - case 0x0000: - queue = pio->queue0; - break; - case 0x1000: - queue = pio->queue1; - break; - case 0x2000: - queue = pio->queue2; - break; - case 0x3000: - queue = pio->queue3; - break; - default: - assert(0); - } - packetindex = (cookie & 0x0FFF); - assert(packetindex >= 0 && packetindex < BCM43xx_PIO_MAXTXPACKETS); - *packet = &(queue->tx_packets_cache[packetindex]); - - return queue; -} - -static void pio_tx_write_fragment(struct bcm43xx_pioqueue *queue, - struct sk_buff *skb, - struct bcm43xx_pio_txpacket *packet) -{ - struct bcm43xx_txhdr txhdr; - unsigned int octets; - - assert(skb_shinfo(skb)->nr_frags == 0); - bcm43xx_generate_txhdr(queue->bcm, - &txhdr, skb->data, skb->len, - (packet->xmitted_frags == 0), - generate_cookie(queue, pio_txpacket_getindex(packet))); - - tx_start(queue); - octets = skb->len + sizeof(txhdr); - if (queue->need_workarounds) - octets--; - tx_data(queue, &txhdr, (u8 *)skb->data, octets); - tx_complete(queue, skb); -} - -static void free_txpacket(struct bcm43xx_pio_txpacket *packet, - int irq_context) -{ - struct bcm43xx_pioqueue *queue = packet->queue; - - ieee80211_txb_free(packet->txb); - list_move(&packet->list, &queue->txfree); - queue->nr_txfree++; - - assert(queue->tx_devq_used >= packet->xmitted_octets); - assert(queue->tx_devq_packets >= packet->xmitted_frags); - queue->tx_devq_used -= packet->xmitted_octets; - queue->tx_devq_packets -= packet->xmitted_frags; -} - -static int pio_tx_packet(struct bcm43xx_pio_txpacket *packet) -{ - struct bcm43xx_pioqueue *queue = packet->queue; - struct ieee80211_txb *txb = packet->txb; - struct sk_buff *skb; - u16 octets; - int i; - - for (i = packet->xmitted_frags; i < txb->nr_frags; i++) { - skb = txb->fragments[i]; - - octets = (u16)skb->len + sizeof(struct bcm43xx_txhdr); - assert(queue->tx_devq_size >= octets); - assert(queue->tx_devq_packets <= BCM43xx_PIO_MAXTXDEVQPACKETS); - assert(queue->tx_devq_used <= queue->tx_devq_size); - /* Check if there is sufficient free space on the device - * TX queue. If not, return and let the TX tasklet - * retry later. - */ - if (queue->tx_devq_packets == BCM43xx_PIO_MAXTXDEVQPACKETS) - return -EBUSY; - if (queue->tx_devq_used + octets > queue->tx_devq_size) - return -EBUSY; - /* Now poke the device. */ - pio_tx_write_fragment(queue, skb, packet); - - /* Account for the packet size. - * (We must not overflow the device TX queue) - */ - queue->tx_devq_packets++; - queue->tx_devq_used += octets; - - assert(packet->xmitted_frags <= packet->txb->nr_frags); - packet->xmitted_frags++; - packet->xmitted_octets += octets; - } - list_move_tail(&packet->list, &queue->txrunning); - - return 0; -} - -static void tx_tasklet(unsigned long d) -{ - struct bcm43xx_pioqueue *queue = (struct bcm43xx_pioqueue *)d; - struct bcm43xx_private *bcm = queue->bcm; - unsigned long flags; - struct bcm43xx_pio_txpacket *packet, *tmp_packet; - int err; - - bcm43xx_lock_mmio(bcm, flags); - list_for_each_entry_safe(packet, tmp_packet, &queue->txqueue, list) { - assert(packet->xmitted_frags < packet->txb->nr_frags); - if (packet->xmitted_frags == 0) { - int i; - struct sk_buff *skb; - - /* Check if the device queue is big - * enough for every fragment. If not, drop the - * whole packet. - */ - for (i = 0; i < packet->txb->nr_frags; i++) { - skb = packet->txb->fragments[i]; - if (unlikely(skb->len > queue->tx_devq_size)) { - dprintkl(KERN_ERR PFX "PIO TX device queue too small. " - "Dropping packet.\n"); - free_txpacket(packet, 1); - goto next_packet; - } - } - } - /* Try to transmit the packet. - * This may not completely succeed. - */ - err = pio_tx_packet(packet); - if (err) - break; - next_packet: - continue; - } - bcm43xx_unlock_mmio(bcm, flags); -} - -static void setup_txqueues(struct bcm43xx_pioqueue *queue) -{ - struct bcm43xx_pio_txpacket *packet; - int i; - - queue->nr_txfree = BCM43xx_PIO_MAXTXPACKETS; - for (i = 0; i < BCM43xx_PIO_MAXTXPACKETS; i++) { - packet = &(queue->tx_packets_cache[i]); - - packet->queue = queue; - INIT_LIST_HEAD(&packet->list); - - list_add(&packet->list, &queue->txfree); - } -} - -static -struct bcm43xx_pioqueue * bcm43xx_setup_pioqueue(struct bcm43xx_private *bcm, - u16 pio_mmio_base) -{ - struct bcm43xx_pioqueue *queue; - u32 value; - u16 qsize; - - queue = kzalloc(sizeof(*queue), GFP_KERNEL); - if (!queue) - goto out; - - queue->bcm = bcm; - queue->mmio_base = pio_mmio_base; - queue->need_workarounds = (bcm->current_core->rev < 3); - - INIT_LIST_HEAD(&queue->txfree); - INIT_LIST_HEAD(&queue->txqueue); - INIT_LIST_HEAD(&queue->txrunning); - tasklet_init(&queue->txtask, tx_tasklet, - (unsigned long)queue); - - value = bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD); - value |= BCM43xx_SBF_XFER_REG_BYTESWAP; - bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD, value); - - qsize = bcm43xx_read16(bcm, queue->mmio_base + BCM43xx_PIO_TXQBUFSIZE); - if (qsize <= BCM43xx_PIO_TXQADJUST) { - printk(KERN_ERR PFX "PIO tx device-queue too small (%u)\n", qsize); - goto err_freequeue; - } - qsize -= BCM43xx_PIO_TXQADJUST; - queue->tx_devq_size = qsize; - - setup_txqueues(queue); - -out: - return queue; - -err_freequeue: - kfree(queue); - queue = NULL; - goto out; -} - -static void cancel_transfers(struct bcm43xx_pioqueue *queue) -{ - struct bcm43xx_pio_txpacket *packet, *tmp_packet; - - netif_tx_disable(queue->bcm->net_dev); - assert(queue->bcm->shutting_down); - tasklet_disable(&queue->txtask); - - list_for_each_entry_safe(packet, tmp_packet, &queue->txrunning, list) - free_txpacket(packet, 0); - list_for_each_entry_safe(packet, tmp_packet, &queue->txqueue, list) - free_txpacket(packet, 0); -} - -static void bcm43xx_destroy_pioqueue(struct bcm43xx_pioqueue *queue) -{ - if (!queue) - return; - - cancel_transfers(queue); - kfree(queue); -} - -void bcm43xx_pio_free(struct bcm43xx_private *bcm) -{ - struct bcm43xx_pio *pio; - - if (!bcm43xx_using_pio(bcm)) - return; - pio = bcm43xx_current_pio(bcm); - - bcm43xx_destroy_pioqueue(pio->queue3); - pio->queue3 = NULL; - bcm43xx_destroy_pioqueue(pio->queue2); - pio->queue2 = NULL; - bcm43xx_destroy_pioqueue(pio->queue1); - pio->queue1 = NULL; - bcm43xx_destroy_pioqueue(pio->queue0); - pio->queue0 = NULL; -} - -int bcm43xx_pio_init(struct bcm43xx_private *bcm) -{ - struct bcm43xx_pio *pio = bcm43xx_current_pio(bcm); - struct bcm43xx_pioqueue *queue; - int err = -ENOMEM; - - queue = bcm43xx_setup_pioqueue(bcm, BCM43xx_MMIO_PIO1_BASE); - if (!queue) - goto out; - pio->queue0 = queue; - - queue = bcm43xx_setup_pioqueue(bcm, BCM43xx_MMIO_PIO2_BASE); - if (!queue) - goto err_destroy0; - pio->queue1 = queue; - - queue = bcm43xx_setup_pioqueue(bcm, BCM43xx_MMIO_PIO3_BASE); - if (!queue) - goto err_destroy1; - pio->queue2 = queue; - - queue = bcm43xx_setup_pioqueue(bcm, BCM43xx_MMIO_PIO4_BASE); - if (!queue) - goto err_destroy2; - pio->queue3 = queue; - - if (bcm->current_core->rev < 3) - bcm->irq_savedstate |= BCM43xx_IRQ_PIO_WORKAROUND; - - dprintk(KERN_INFO PFX "PIO initialized\n"); - err = 0; -out: - return err; - -err_destroy2: - bcm43xx_destroy_pioqueue(pio->queue2); - pio->queue2 = NULL; -err_destroy1: - bcm43xx_destroy_pioqueue(pio->queue1); - pio->queue1 = NULL; -err_destroy0: - bcm43xx_destroy_pioqueue(pio->queue0); - pio->queue0 = NULL; - goto out; -} - -int bcm43xx_pio_tx(struct bcm43xx_private *bcm, - struct ieee80211_txb *txb) -{ - struct bcm43xx_pioqueue *queue = bcm43xx_current_pio(bcm)->queue1; - struct bcm43xx_pio_txpacket *packet; - u16 tmp; - - assert(!queue->tx_suspended); - assert(!list_empty(&queue->txfree)); - - tmp = bcm43xx_pio_read(queue, BCM43xx_PIO_TXCTL); - if (tmp & BCM43xx_PIO_TXCTL_SUSPEND) - return -EBUSY; - - packet = list_entry(queue->txfree.next, struct bcm43xx_pio_txpacket, list); - packet->txb = txb; - packet->xmitted_frags = 0; - packet->xmitted_octets = 0; - list_move_tail(&packet->list, &queue->txqueue); - queue->nr_txfree--; - assert(queue->nr_txfree < BCM43xx_PIO_MAXTXPACKETS); - - /* Suspend TX, if we are out of packets in the "free" queue. */ - if (unlikely(list_empty(&queue->txfree))) { - netif_stop_queue(queue->bcm->net_dev); - queue->tx_suspended = 1; - } - - tasklet_schedule(&queue->txtask); - - return 0; -} - -void bcm43xx_pio_handle_xmitstatus(struct bcm43xx_private *bcm, - struct bcm43xx_xmitstatus *status) -{ - struct bcm43xx_pioqueue *queue; - struct bcm43xx_pio_txpacket *packet; - - queue = parse_cookie(bcm, status->cookie, &packet); - assert(queue); -//TODO -if (!queue) -return; - free_txpacket(packet, 1); - if (unlikely(queue->tx_suspended)) { - queue->tx_suspended = 0; - netif_wake_queue(queue->bcm->net_dev); - } - /* If there are packets on the txqueue, poke the tasklet. */ - if (!list_empty(&queue->txqueue)) - tasklet_schedule(&queue->txtask); -} - -static void pio_rx_error(struct bcm43xx_pioqueue *queue, - int clear_buffers, - const char *error) -{ - int i; - - printkl("PIO RX error: %s\n", error); - bcm43xx_pio_write(queue, BCM43xx_PIO_RXCTL, - BCM43xx_PIO_RXCTL_READY); - if (clear_buffers) { - assert(queue->mmio_base == BCM43xx_MMIO_PIO1_BASE); - for (i = 0; i < 15; i++) { - /* Dummy read. */ - bcm43xx_pio_read(queue, BCM43xx_PIO_RXDATA); - } - } -} - -void bcm43xx_pio_rx(struct bcm43xx_pioqueue *queue) -{ - u16 preamble[21] = { 0 }; - struct bcm43xx_rxhdr *rxhdr; - u16 tmp, len, rxflags2; - int i, preamble_readwords; - struct sk_buff *skb; - -return; - tmp = bcm43xx_pio_read(queue, BCM43xx_PIO_RXCTL); - if (!(tmp & BCM43xx_PIO_RXCTL_DATAAVAILABLE)) { - dprintkl(KERN_ERR PFX "PIO RX: No data available\n");//TODO: remove this printk. - return; - } - bcm43xx_pio_write(queue, BCM43xx_PIO_RXCTL, - BCM43xx_PIO_RXCTL_DATAAVAILABLE); - - for (i = 0; i < 10; i++) { - tmp = bcm43xx_pio_read(queue, BCM43xx_PIO_RXCTL); - if (tmp & BCM43xx_PIO_RXCTL_READY) - goto data_ready; - udelay(10); - } - dprintkl(KERN_ERR PFX "PIO RX timed out\n"); - return; -data_ready: - -//FIXME: endianess in this function. - len = le16_to_cpu(bcm43xx_pio_read(queue, BCM43xx_PIO_RXDATA)); - if (unlikely(len > 0x700)) { - pio_rx_error(queue, 0, "len > 0x700"); - return; - } - if (unlikely(len == 0 && queue->mmio_base != BCM43xx_MMIO_PIO4_BASE)) { - pio_rx_error(queue, 0, "len == 0"); - return; - } - preamble[0] = cpu_to_le16(len); - if (queue->mmio_base == BCM43xx_MMIO_PIO4_BASE) - preamble_readwords = 14 / sizeof(u16); - else - preamble_readwords = 18 / sizeof(u16); - for (i = 0; i < preamble_readwords; i++) { - tmp = bcm43xx_pio_read(queue, BCM43xx_PIO_RXDATA); - preamble[i + 1] = cpu_to_be16(tmp);//FIXME? - } - rxhdr = (struct bcm43xx_rxhdr *)preamble; - rxflags2 = le16_to_cpu(rxhdr->flags2); - if (unlikely(rxflags2 & BCM43xx_RXHDR_FLAGS2_INVALIDFRAME)) { - pio_rx_error(queue, - (queue->mmio_base == BCM43xx_MMIO_PIO1_BASE), - "invalid frame"); - return; - } - if (queue->mmio_base == BCM43xx_MMIO_PIO4_BASE) { - /* We received an xmit status. */ - struct bcm43xx_hwxmitstatus *hw; - struct bcm43xx_xmitstatus stat; - - hw = (struct bcm43xx_hwxmitstatus *)(preamble + 1); - stat.cookie = le16_to_cpu(hw->cookie); - stat.flags = hw->flags; - stat.cnt1 = hw->cnt1; - stat.cnt2 = hw->cnt2; - stat.seq = le16_to_cpu(hw->seq); - stat.unknown = le16_to_cpu(hw->unknown); - - bcm43xx_debugfs_log_txstat(queue->bcm, &stat); - bcm43xx_pio_handle_xmitstatus(queue->bcm, &stat); - - return; - } - - skb = dev_alloc_skb(len); - if (unlikely(!skb)) { - pio_rx_error(queue, 1, "OOM"); - return; - } - skb_put(skb, len); - for (i = 0; i < len - 1; i += 2) { - tmp = cpu_to_be16(bcm43xx_pio_read(queue, BCM43xx_PIO_RXDATA)); - *((u16 *)(skb->data + i)) = tmp; - } - if (len % 2) { - tmp = bcm43xx_pio_read(queue, BCM43xx_PIO_RXDATA); - skb->data[len - 1] = (tmp & 0x00FF); - if (rxflags2 & BCM43xx_RXHDR_FLAGS2_TYPE2FRAME) - skb->data[0x20] = (tmp & 0xFF00) >> 8; - else - skb->data[0x1E] = (tmp & 0xFF00) >> 8; - } - bcm43xx_rx(queue->bcm, skb, rxhdr); -} diff --git a/trunk/drivers/net/wireless/bcm43xx/bcm43xx_pio.h b/trunk/drivers/net/wireless/bcm43xx/bcm43xx_pio.h deleted file mode 100644 index 970627bc1769..000000000000 --- a/trunk/drivers/net/wireless/bcm43xx/bcm43xx_pio.h +++ /dev/null @@ -1,138 +0,0 @@ -#ifndef BCM43xx_PIO_H_ -#define BCM43xx_PIO_H_ - -#include "bcm43xx.h" - -#include -#include -#include - - -#define BCM43xx_PIO_TXCTL 0x00 -#define BCM43xx_PIO_TXDATA 0x02 -#define BCM43xx_PIO_TXQBUFSIZE 0x04 -#define BCM43xx_PIO_RXCTL 0x08 -#define BCM43xx_PIO_RXDATA 0x0A - -#define BCM43xx_PIO_TXCTL_WRITEHI (1 << 0) -#define BCM43xx_PIO_TXCTL_WRITELO (1 << 1) -#define BCM43xx_PIO_TXCTL_COMPLETE (1 << 2) -#define BCM43xx_PIO_TXCTL_INIT (1 << 3) -#define BCM43xx_PIO_TXCTL_SUSPEND (1 << 7) - -#define BCM43xx_PIO_RXCTL_DATAAVAILABLE (1 << 0) -#define BCM43xx_PIO_RXCTL_READY (1 << 1) - -/* PIO constants */ -#define BCM43xx_PIO_MAXTXDEVQPACKETS 31 -#define BCM43xx_PIO_TXQADJUST 80 - -/* PIO tuning knobs */ -#define BCM43xx_PIO_MAXTXPACKETS 256 - - - -#ifdef CONFIG_BCM43XX_PIO - - -struct bcm43xx_pioqueue; -struct bcm43xx_xmitstatus; - -struct bcm43xx_pio_txpacket { - struct bcm43xx_pioqueue *queue; - struct ieee80211_txb *txb; - struct list_head list; - - u8 xmitted_frags; - u16 xmitted_octets; -}; - -#define pio_txpacket_getindex(packet) ((int)((packet) - (packet)->queue->tx_packets_cache)) - -struct bcm43xx_pioqueue { - struct bcm43xx_private *bcm; - u16 mmio_base; - - u8 tx_suspended:1, - need_workarounds:1; /* Workarounds needed for core.rev < 3 */ - - /* Adjusted size of the device internal TX buffer. */ - u16 tx_devq_size; - /* Used octets of the device internal TX buffer. */ - u16 tx_devq_used; - /* Used packet slots in the device internal TX buffer. */ - u8 tx_devq_packets; - /* Packets from the txfree list can - * be taken on incoming TX requests. - */ - struct list_head txfree; - unsigned int nr_txfree; - /* Packets on the txqueue are queued, - * but not completely written to the chip, yet. - */ - struct list_head txqueue; - /* Packets on the txrunning queue are completely - * posted to the device. We are waiting for the txstatus. - */ - struct list_head txrunning; - /* Total number or packets sent. - * (This counter can obviously wrap). - */ - unsigned int nr_tx_packets; - struct tasklet_struct txtask; - struct bcm43xx_pio_txpacket tx_packets_cache[BCM43xx_PIO_MAXTXPACKETS]; -}; - -static inline -u16 bcm43xx_pio_read(struct bcm43xx_pioqueue *queue, - u16 offset) -{ - return bcm43xx_read16(queue->bcm, queue->mmio_base + offset); -} - -static inline -void bcm43xx_pio_write(struct bcm43xx_pioqueue *queue, - u16 offset, u16 value) -{ - bcm43xx_write16(queue->bcm, queue->mmio_base + offset, value); -} - - -int bcm43xx_pio_init(struct bcm43xx_private *bcm); -void bcm43xx_pio_free(struct bcm43xx_private *bcm); - -int bcm43xx_pio_tx(struct bcm43xx_private *bcm, - struct ieee80211_txb *txb); -void bcm43xx_pio_handle_xmitstatus(struct bcm43xx_private *bcm, - struct bcm43xx_xmitstatus *status); -void bcm43xx_pio_rx(struct bcm43xx_pioqueue *queue); - -#else /* CONFIG_BCM43XX_PIO */ - -static inline -int bcm43xx_pio_init(struct bcm43xx_private *bcm) -{ - return 0; -} -static inline -void bcm43xx_pio_free(struct bcm43xx_private *bcm) -{ -} -static inline -int bcm43xx_pio_tx(struct bcm43xx_private *bcm, - struct ieee80211_txb *txb) -{ - return 0; -} -static inline -void bcm43xx_pio_handle_xmitstatus(struct bcm43xx_private *bcm, - struct bcm43xx_xmitstatus *status) -{ -} -static inline -void bcm43xx_pio_rx(struct bcm43xx_pioqueue *queue) -{ -} - -#endif /* CONFIG_BCM43XX_PIO */ -#endif /* BCM43xx_PIO_H_ */ diff --git a/trunk/drivers/net/wireless/bcm43xx/bcm43xx_power.c b/trunk/drivers/net/wireless/bcm43xx/bcm43xx_power.c deleted file mode 100644 index 3c92b62807c5..000000000000 --- a/trunk/drivers/net/wireless/bcm43xx/bcm43xx_power.c +++ /dev/null @@ -1,358 +0,0 @@ -/* - - Broadcom BCM43xx wireless driver - - Copyright (c) 2005 Martin Langer , - Stefano Brivio - Michael Buesch - Danny van Dyk - Andreas Jaggi - - Some parts of the code in this file are derived from the ipw2200 - driver Copyright(c) 2003 - 2004 Intel Corporation. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; see the file COPYING. If not, write to - the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor, - Boston, MA 02110-1301, USA. - -*/ - -#include - -#include "bcm43xx.h" -#include "bcm43xx_power.h" -#include "bcm43xx_main.h" - - -/* Get max/min slowclock frequency - * as described in http://bcm-specs.sipsolutions.net/PowerControl - */ -static int bcm43xx_pctl_clockfreqlimit(struct bcm43xx_private *bcm, - int get_max) -{ - int limit = 0; - int divisor; - int selection; - int err; - u32 tmp; - struct bcm43xx_coreinfo *old_core; - - if (!(bcm->chipcommon_capabilities & BCM43xx_CAPABILITIES_PCTL)) - goto out; - old_core = bcm->current_core; - err = bcm43xx_switch_core(bcm, &bcm->core_chipcommon); - if (err) - goto out; - - if (bcm->current_core->rev < 6) { - if ((bcm->bustype == BCM43xx_BUSTYPE_PCMCIA) || - (bcm->bustype == BCM43xx_BUSTYPE_SB)) { - selection = 1; - divisor = 32; - } else { - err = bcm43xx_pci_read_config32(bcm, BCM43xx_PCTL_OUT, &tmp); - if (err) { - printk(KERN_ERR PFX "clockfreqlimit pcicfg read failure\n"); - goto out_switchback; - } - if (tmp & 0x10) { - /* PCI */ - selection = 2; - divisor = 64; - } else { - /* XTAL */ - selection = 1; - divisor = 32; - } - } - } else if (bcm->current_core->rev < 10) { - selection = (tmp & 0x07); - if (selection) { - tmp = bcm43xx_read32(bcm, BCM43xx_CHIPCOMMON_SLOWCLKCTL); - divisor = 4 * (1 + ((tmp & 0xFFFF0000) >> 16)); - } else - divisor = 1; - } else { - tmp = bcm43xx_read32(bcm, BCM43xx_CHIPCOMMON_SYSCLKCTL); - divisor = 4 * (1 + ((tmp & 0xFFFF0000) >> 16)); - selection = 1; - } - - switch (selection) { - case 0: - /* LPO */ - if (get_max) - limit = 43000; - else - limit = 25000; - break; - case 1: - /* XTAL */ - if (get_max) - limit = 20200000; - else - limit = 19800000; - break; - case 2: - /* PCI */ - if (get_max) - limit = 34000000; - else - limit = 25000000; - break; - default: - assert(0); - } - limit /= divisor; - -out_switchback: - err = bcm43xx_switch_core(bcm, old_core); - assert(err == 0); - -out: - return limit; -} - -/* init power control - * as described in http://bcm-specs.sipsolutions.net/PowerControl - */ -int bcm43xx_pctl_init(struct bcm43xx_private *bcm) -{ - int err, maxfreq; - struct bcm43xx_coreinfo *old_core; - - if (!(bcm->chipcommon_capabilities & BCM43xx_CAPABILITIES_PCTL)) - return 0; - old_core = bcm->current_core; - err = bcm43xx_switch_core(bcm, &bcm->core_chipcommon); - if (err == -ENODEV) - return 0; - if (err) - goto out; - - maxfreq = bcm43xx_pctl_clockfreqlimit(bcm, 1); - bcm43xx_write32(bcm, BCM43xx_CHIPCOMMON_PLLONDELAY, - (maxfreq * 150 + 999999) / 1000000); - bcm43xx_write32(bcm, BCM43xx_CHIPCOMMON_FREFSELDELAY, - (maxfreq * 15 + 999999) / 1000000); - - err = bcm43xx_switch_core(bcm, old_core); - assert(err == 0); - -out: - return err; -} - -u16 bcm43xx_pctl_powerup_delay(struct bcm43xx_private *bcm) -{ - u16 delay = 0; - int err; - u32 pll_on_delay; - struct bcm43xx_coreinfo *old_core; - int minfreq; - - if (bcm->bustype != BCM43xx_BUSTYPE_PCI) - goto out; - if (!(bcm->chipcommon_capabilities & BCM43xx_CAPABILITIES_PCTL)) - goto out; - old_core = bcm->current_core; - err = bcm43xx_switch_core(bcm, &bcm->core_chipcommon); - if (err == -ENODEV) - goto out; - - minfreq = bcm43xx_pctl_clockfreqlimit(bcm, 0); - pll_on_delay = bcm43xx_read32(bcm, BCM43xx_CHIPCOMMON_PLLONDELAY); - delay = (((pll_on_delay + 2) * 1000000) + (minfreq - 1)) / minfreq; - - err = bcm43xx_switch_core(bcm, old_core); - assert(err == 0); - -out: - return delay; -} - -/* set the powercontrol clock - * as described in http://bcm-specs.sipsolutions.net/PowerControl - */ -int bcm43xx_pctl_set_clock(struct bcm43xx_private *bcm, u16 mode) -{ - int err; - struct bcm43xx_coreinfo *old_core; - u32 tmp; - - old_core = bcm->current_core; - err = bcm43xx_switch_core(bcm, &bcm->core_chipcommon); - if (err == -ENODEV) - return 0; - if (err) - goto out; - - if (bcm->core_chipcommon.rev < 6) { - if (mode == BCM43xx_PCTL_CLK_FAST) { - err = bcm43xx_pctl_set_crystal(bcm, 1); - if (err) - goto out; - } - } else { - if ((bcm->chipcommon_capabilities & BCM43xx_CAPABILITIES_PCTL) && - (bcm->core_chipcommon.rev < 10)) { - switch (mode) { - case BCM43xx_PCTL_CLK_FAST: - tmp = bcm43xx_read32(bcm, BCM43xx_CHIPCOMMON_SLOWCLKCTL); - tmp = (tmp & ~BCM43xx_PCTL_FORCE_SLOW) | BCM43xx_PCTL_FORCE_PLL; - bcm43xx_write32(bcm, BCM43xx_CHIPCOMMON_SLOWCLKCTL, tmp); - break; - case BCM43xx_PCTL_CLK_SLOW: - tmp = bcm43xx_read32(bcm, BCM43xx_CHIPCOMMON_SLOWCLKCTL); - tmp |= BCM43xx_PCTL_FORCE_SLOW; - bcm43xx_write32(bcm, BCM43xx_CHIPCOMMON_SLOWCLKCTL, tmp); - break; - case BCM43xx_PCTL_CLK_DYNAMIC: - tmp = bcm43xx_read32(bcm, BCM43xx_CHIPCOMMON_SLOWCLKCTL); - tmp &= ~BCM43xx_PCTL_FORCE_SLOW; - tmp |= BCM43xx_PCTL_FORCE_PLL; - tmp &= ~BCM43xx_PCTL_DYN_XTAL; - bcm43xx_write32(bcm, BCM43xx_CHIPCOMMON_SLOWCLKCTL, tmp); - } - } - } - - err = bcm43xx_switch_core(bcm, old_core); - assert(err == 0); - -out: - return err; -} - -int bcm43xx_pctl_set_crystal(struct bcm43xx_private *bcm, int on) -{ - int err; - u32 in, out, outenable; - - err = bcm43xx_pci_read_config32(bcm, BCM43xx_PCTL_IN, &in); - if (err) - goto err_pci; - err = bcm43xx_pci_read_config32(bcm, BCM43xx_PCTL_OUT, &out); - if (err) - goto err_pci; - err = bcm43xx_pci_read_config32(bcm, BCM43xx_PCTL_OUTENABLE, &outenable); - if (err) - goto err_pci; - - outenable |= (BCM43xx_PCTL_XTAL_POWERUP | BCM43xx_PCTL_PLL_POWERDOWN); - - if (on) { - if (in & 0x40) - return 0; - - out |= (BCM43xx_PCTL_XTAL_POWERUP | BCM43xx_PCTL_PLL_POWERDOWN); - - err = bcm43xx_pci_write_config32(bcm, BCM43xx_PCTL_OUT, out); - if (err) - goto err_pci; - err = bcm43xx_pci_write_config32(bcm, BCM43xx_PCTL_OUTENABLE, outenable); - if (err) - goto err_pci; - udelay(1000); - - out &= ~BCM43xx_PCTL_PLL_POWERDOWN; - err = bcm43xx_pci_write_config32(bcm, BCM43xx_PCTL_OUT, out); - if (err) - goto err_pci; - udelay(5000); - } else { - if (bcm->current_core->rev < 5) - return 0; - if (bcm->sprom.boardflags & BCM43xx_BFL_XTAL_NOSLOW) - return 0; - -/* XXX: Why BCM43xx_MMIO_RADIO_HWENABLED_xx can't be read at this time? - * err = bcm43xx_switch_core(bcm, bcm->active_80211_core); - * if (err) - * return err; - * if (((bcm->current_core->rev >= 3) && - * (bcm43xx_read32(bcm, BCM43xx_MMIO_RADIO_HWENABLED_HI) & (1 << 16))) || - * ((bcm->current_core->rev < 3) && - * !(bcm43xx_read16(bcm, BCM43xx_MMIO_RADIO_HWENABLED_LO) & (1 << 4)))) - * return 0; - * err = bcm43xx_switch_core(bcm, &bcm->core_chipcommon); - * if (err) - * return err; - */ - - err = bcm43xx_pctl_set_clock(bcm, BCM43xx_PCTL_CLK_SLOW); - if (err) - goto out; - out &= ~BCM43xx_PCTL_XTAL_POWERUP; - out |= BCM43xx_PCTL_PLL_POWERDOWN; - err = bcm43xx_pci_write_config32(bcm, BCM43xx_PCTL_OUT, out); - if (err) - goto err_pci; - err = bcm43xx_pci_write_config32(bcm, BCM43xx_PCTL_OUTENABLE, outenable); - if (err) - goto err_pci; - } - -out: - return err; - -err_pci: - printk(KERN_ERR PFX "Error: pctl_set_clock() could not access PCI config space!\n"); - err = -EBUSY; - goto out; -} - -/* Set the PowerSavingControlBits. - * Bitvalues: - * 0 => unset the bit - * 1 => set the bit - * -1 => calculate the bit - */ -void bcm43xx_power_saving_ctl_bits(struct bcm43xx_private *bcm, - int bit25, int bit26) -{ - int i; - u32 status; - -//FIXME: Force 25 to off and 26 to on for now: -bit25 = 0; -bit26 = 1; - - if (bit25 == -1) { - //TODO: If powersave is not off and FIXME is not set and we are not in adhoc - // and thus is not an AP and we are associated, set bit 25 - } - if (bit26 == -1) { - //TODO: If the device is awake or this is an AP, or we are scanning, or FIXME, - // or we are associated, or FIXME, or the latest PS-Poll packet sent was - // successful, set bit26 - } - status = bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD); - if (bit25) - status |= BCM43xx_SBF_PS1; - else - status &= ~BCM43xx_SBF_PS1; - if (bit26) - status |= BCM43xx_SBF_PS2; - else - status &= ~BCM43xx_SBF_PS2; - bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD, status); - if (bit26 && bcm->current_core->rev >= 5) { - for (i = 0; i < 100; i++) { - if (bcm43xx_shm_read32(bcm, BCM43xx_SHM_SHARED, 0x0040) != 4) - break; - udelay(10); - } - } -} diff --git a/trunk/drivers/net/wireless/bcm43xx/bcm43xx_power.h b/trunk/drivers/net/wireless/bcm43xx/bcm43xx_power.h deleted file mode 100644 index 5f63640810bd..000000000000 --- a/trunk/drivers/net/wireless/bcm43xx/bcm43xx_power.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - - Broadcom BCM43xx wireless driver - - Copyright (c) 2005 Martin Langer , - Stefano Brivio - Michael Buesch - Danny van Dyk - Andreas Jaggi - - Some parts of the code in this file are derived from the ipw2200 - driver Copyright(c) 2003 - 2004 Intel Corporation. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; see the file COPYING. If not, write to - the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor, - Boston, MA 02110-1301, USA. - -*/ - -#ifndef BCM43xx_POWER_H_ -#define BCM43xx_POWER_H_ - -#include - - -struct bcm43xx_private; - -int bcm43xx_pctl_init(struct bcm43xx_private *bcm); -int bcm43xx_pctl_set_clock(struct bcm43xx_private *bcm, u16 mode); -int bcm43xx_pctl_set_crystal(struct bcm43xx_private *bcm, int on); -u16 bcm43xx_pctl_powerup_delay(struct bcm43xx_private *bcm); - -void bcm43xx_power_saving_ctl_bits(struct bcm43xx_private *bcm, - int bit25, int bit26); - -#endif /* BCM43xx_POWER_H_ */ diff --git a/trunk/drivers/net/wireless/bcm43xx/bcm43xx_radio.c b/trunk/drivers/net/wireless/bcm43xx/bcm43xx_radio.c deleted file mode 100644 index af5c0bff1696..000000000000 --- a/trunk/drivers/net/wireless/bcm43xx/bcm43xx_radio.c +++ /dev/null @@ -1,2026 +0,0 @@ -/* - - Broadcom BCM43xx wireless driver - - Copyright (c) 2005 Martin Langer , - Stefano Brivio - Michael Buesch - Danny van Dyk - Andreas Jaggi - - Some parts of the code in this file are derived from the ipw2200 - driver Copyright(c) 2003 - 2004 Intel Corporation. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; see the file COPYING. If not, write to - the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor, - Boston, MA 02110-1301, USA. - -*/ - -#include - -#include "bcm43xx.h" -#include "bcm43xx_main.h" -#include "bcm43xx_phy.h" -#include "bcm43xx_radio.h" -#include "bcm43xx_ilt.h" - - -/* Table for bcm43xx_radio_calibrationvalue() */ -static const u16 rcc_table[16] = { - 0x0002, 0x0003, 0x0001, 0x000F, - 0x0006, 0x0007, 0x0005, 0x000F, - 0x000A, 0x000B, 0x0009, 0x000F, - 0x000E, 0x000F, 0x000D, 0x000F, -}; - -/* Reverse the bits of a 4bit value. - * Example: 1101 is flipped 1011 - */ -static u16 flip_4bit(u16 value) -{ - u16 flipped = 0x0000; - - assert((value & ~0x000F) == 0x0000); - - flipped |= (value & 0x0001) << 3; - flipped |= (value & 0x0002) << 1; - flipped |= (value & 0x0004) >> 1; - flipped |= (value & 0x0008) >> 3; - - return flipped; -} - -/* Get the freq, as it has to be written to the device. */ -static inline -u16 channel2freq_bg(u8 channel) -{ - /* Frequencies are given as frequencies_bg[index] + 2.4GHz - * Starting with channel 1 - */ - static const u16 frequencies_bg[14] = { - 12, 17, 22, 27, - 32, 37, 42, 47, - 52, 57, 62, 67, - 72, 84, - }; - - assert(channel >= 1 && channel <= 14); - - return frequencies_bg[channel - 1]; -} - -/* Get the freq, as it has to be written to the device. */ -static inline -u16 channel2freq_a(u8 channel) -{ - assert(channel <= 200); - - return (5000 + 5 * channel); -} - -void bcm43xx_radio_lock(struct bcm43xx_private *bcm) -{ - u32 status; - - status = bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD); - status |= BCM43xx_SBF_RADIOREG_LOCK; - bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD, status); - mmiowb(); - udelay(10); -} - -void bcm43xx_radio_unlock(struct bcm43xx_private *bcm) -{ - u32 status; - - bcm43xx_read16(bcm, BCM43xx_MMIO_PHY_VER); /* dummy read */ - status = bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD); - status &= ~BCM43xx_SBF_RADIOREG_LOCK; - bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD, status); - mmiowb(); -} - -u16 bcm43xx_radio_read16(struct bcm43xx_private *bcm, u16 offset) -{ - struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm); - struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm); - - switch (phy->type) { - case BCM43xx_PHYTYPE_A: - offset |= 0x0040; - break; - case BCM43xx_PHYTYPE_B: - if (radio->version == 0x2053) { - if (offset < 0x70) - offset += 0x80; - else if (offset < 0x80) - offset += 0x70; - } else if (radio->version == 0x2050) { - offset |= 0x80; - } else - assert(0); - break; - case BCM43xx_PHYTYPE_G: - offset |= 0x80; - break; - } - - bcm43xx_write16(bcm, BCM43xx_MMIO_RADIO_CONTROL, offset); - return bcm43xx_read16(bcm, BCM43xx_MMIO_RADIO_DATA_LOW); -} - -void bcm43xx_radio_write16(struct bcm43xx_private *bcm, u16 offset, u16 val) -{ - bcm43xx_write16(bcm, BCM43xx_MMIO_RADIO_CONTROL, offset); - mmiowb(); - bcm43xx_write16(bcm, BCM43xx_MMIO_RADIO_DATA_LOW, val); -} - -static void bcm43xx_set_all_gains(struct bcm43xx_private *bcm, - s16 first, s16 second, s16 third) -{ - struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm); - u16 i; - u16 start = 0x08, end = 0x18; - u16 offset = 0x0400; - u16 tmp; - - if (phy->rev <= 1) { - offset = 0x5000; - start = 0x10; - end = 0x20; - } - - for (i = 0; i < 4; i++) - bcm43xx_ilt_write(bcm, offset + i, first); - - for (i = start; i < end; i++) - bcm43xx_ilt_write(bcm, offset + i, second); - - if (third != -1) { - tmp = ((u16)third << 14) | ((u16)third << 6); - bcm43xx_phy_write(bcm, 0x04A0, - (bcm43xx_phy_read(bcm, 0x04A0) & 0xBFBF) | tmp); - bcm43xx_phy_write(bcm, 0x04A1, - (bcm43xx_phy_read(bcm, 0x04A1) & 0xBFBF) | tmp); - bcm43xx_phy_write(bcm, 0x04A2, - (bcm43xx_phy_read(bcm, 0x04A2) & 0xBFBF) | tmp); - } - bcm43xx_dummy_transmission(bcm); -} - -static void bcm43xx_set_original_gains(struct bcm43xx_private *bcm) -{ - struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm); - u16 i, tmp; - u16 offset = 0x0400; - u16 start = 0x0008, end = 0x0018; - - if (phy->rev <= 1) { - offset = 0x5000; - start = 0x0010; - end = 0x0020; - } - - for (i = 0; i < 4; i++) { - tmp = (i & 0xFFFC); - tmp |= (i & 0x0001) << 1; - tmp |= (i & 0x0002) >> 1; - - bcm43xx_ilt_write(bcm, offset + i, tmp); - } - - for (i = start; i < end; i++) - bcm43xx_ilt_write(bcm, offset + i, i - start); - - bcm43xx_phy_write(bcm, 0x04A0, - (bcm43xx_phy_read(bcm, 0x04A0) & 0xBFBF) | 0x4040); - bcm43xx_phy_write(bcm, 0x04A1, - (bcm43xx_phy_read(bcm, 0x04A1) & 0xBFBF) | 0x4040); - bcm43xx_phy_write(bcm, 0x04A2, - (bcm43xx_phy_read(bcm, 0x04A2) & 0xBFBF) | 0x4000); - bcm43xx_dummy_transmission(bcm); -} - -/* Synthetic PU workaround */ -static void bcm43xx_synth_pu_workaround(struct bcm43xx_private *bcm, u8 channel) -{ - struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm); - - if (radio->version != 0x2050 || radio->revision >= 6) { - /* We do not need the workaround. */ - return; - } - - if (channel <= 10) { - bcm43xx_write16(bcm, BCM43xx_MMIO_CHANNEL, - channel2freq_bg(channel + 4)); - } else { - bcm43xx_write16(bcm, BCM43xx_MMIO_CHANNEL, - channel2freq_bg(1)); - } - udelay(100); - bcm43xx_write16(bcm, BCM43xx_MMIO_CHANNEL, - channel2freq_bg(channel)); -} - -u8 bcm43xx_radio_aci_detect(struct bcm43xx_private *bcm, u8 channel) -{ - struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm); - u8 ret = 0; - u16 saved, rssi, temp; - int i, j = 0; - - saved = bcm43xx_phy_read(bcm, 0x0403); - bcm43xx_radio_selectchannel(bcm, channel, 0); - bcm43xx_phy_write(bcm, 0x0403, (saved & 0xFFF8) | 5); - if (radio->aci_hw_rssi) - rssi = bcm43xx_phy_read(bcm, 0x048A) & 0x3F; - else - rssi = saved & 0x3F; - /* clamp temp to signed 5bit */ - if (rssi > 32) - rssi -= 64; - for (i = 0;i < 100; i++) { - temp = (bcm43xx_phy_read(bcm, 0x047F) >> 8) & 0x3F; - if (temp > 32) - temp -= 64; - if (temp < rssi) - j++; - if (j >= 20) - ret = 1; - } - bcm43xx_phy_write(bcm, 0x0403, saved); - - return ret; -} - -u8 bcm43xx_radio_aci_scan(struct bcm43xx_private *bcm) -{ - struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm); - struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm); - u8 ret[13]; - unsigned int channel = radio->channel; - unsigned int i, j, start, end; - unsigned long phylock_flags; - - if (!((phy->type == BCM43xx_PHYTYPE_G) && (phy->rev > 0))) - return 0; - - bcm43xx_phy_lock(bcm, phylock_flags); - bcm43xx_radio_lock(bcm); - bcm43xx_phy_write(bcm, 0x0802, - bcm43xx_phy_read(bcm, 0x0802) & 0xFFFC); - bcm43xx_phy_write(bcm, BCM43xx_PHY_G_CRS, - bcm43xx_phy_read(bcm, BCM43xx_PHY_G_CRS) & 0x7FFF); - bcm43xx_set_all_gains(bcm, 3, 8, 1); - - start = (channel - 5 > 0) ? channel - 5 : 1; - end = (channel + 5 < 14) ? channel + 5 : 13; - - for (i = start; i <= end; i++) { - if (abs(channel - i) > 2) - ret[i-1] = bcm43xx_radio_aci_detect(bcm, i); - } - bcm43xx_radio_selectchannel(bcm, channel, 0); - bcm43xx_phy_write(bcm, 0x0802, - (bcm43xx_phy_read(bcm, 0x0802) & 0xFFFC) | 0x0003); - bcm43xx_phy_write(bcm, 0x0403, - bcm43xx_phy_read(bcm, 0x0403) & 0xFFF8); - bcm43xx_phy_write(bcm, BCM43xx_PHY_G_CRS, - bcm43xx_phy_read(bcm, BCM43xx_PHY_G_CRS) | 0x8000); - bcm43xx_set_original_gains(bcm); - for (i = 0; i < 13; i++) { - if (!ret[i]) - continue; - end = (i + 5 < 13) ? i + 5 : 13; - for (j = i; j < end; j++) - ret[j] = 1; - } - bcm43xx_radio_unlock(bcm); - bcm43xx_phy_unlock(bcm, phylock_flags); - - return ret[channel - 1]; -} - -/* http://bcm-specs.sipsolutions.net/NRSSILookupTable */ -void bcm43xx_nrssi_hw_write(struct bcm43xx_private *bcm, u16 offset, s16 val) -{ - bcm43xx_phy_write(bcm, BCM43xx_PHY_NRSSILT_CTRL, offset); - mmiowb(); - bcm43xx_phy_write(bcm, BCM43xx_PHY_NRSSILT_DATA, (u16)val); -} - -/* http://bcm-specs.sipsolutions.net/NRSSILookupTable */ -s16 bcm43xx_nrssi_hw_read(struct bcm43xx_private *bcm, u16 offset) -{ - u16 val; - - bcm43xx_phy_write(bcm, BCM43xx_PHY_NRSSILT_CTRL, offset); - val = bcm43xx_phy_read(bcm, BCM43xx_PHY_NRSSILT_DATA); - - return (s16)val; -} - -/* http://bcm-specs.sipsolutions.net/NRSSILookupTable */ -void bcm43xx_nrssi_hw_update(struct bcm43xx_private *bcm, u16 val) -{ - u16 i; - s16 tmp; - - for (i = 0; i < 64; i++) { - tmp = bcm43xx_nrssi_hw_read(bcm, i); - tmp -= val; - tmp = limit_value(tmp, -32, 31); - bcm43xx_nrssi_hw_write(bcm, i, tmp); - } -} - -/* http://bcm-specs.sipsolutions.net/NRSSILookupTable */ -void bcm43xx_nrssi_mem_update(struct bcm43xx_private *bcm) -{ - struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm); - s16 i, delta; - s32 tmp; - - delta = 0x1F - radio->nrssi[0]; - for (i = 0; i < 64; i++) { - tmp = (i - delta) * radio->nrssislope; - tmp /= 0x10000; - tmp += 0x3A; - tmp = limit_value(tmp, 0, 0x3F); - radio->nrssi_lt[i] = tmp; - } -} - -static void bcm43xx_calc_nrssi_offset(struct bcm43xx_private *bcm) -{ - struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm); - u16 backup[20] = { 0 }; - s16 v47F; - u16 i; - u16 saved = 0xFFFF; - - backup[0] = bcm43xx_phy_read(bcm, 0x0001); - backup[1] = bcm43xx_phy_read(bcm, 0x0811); - backup[2] = bcm43xx_phy_read(bcm, 0x0812); - backup[3] = bcm43xx_phy_read(bcm, 0x0814); - backup[4] = bcm43xx_phy_read(bcm, 0x0815); - backup[5] = bcm43xx_phy_read(bcm, 0x005A); - backup[6] = bcm43xx_phy_read(bcm, 0x0059); - backup[7] = bcm43xx_phy_read(bcm, 0x0058); - backup[8] = bcm43xx_phy_read(bcm, 0x000A); - backup[9] = bcm43xx_phy_read(bcm, 0x0003); - backup[10] = bcm43xx_radio_read16(bcm, 0x007A); - backup[11] = bcm43xx_radio_read16(bcm, 0x0043); - - bcm43xx_phy_write(bcm, 0x0429, - bcm43xx_phy_read(bcm, 0x0429) & 0x7FFF); - bcm43xx_phy_write(bcm, 0x0001, - (bcm43xx_phy_read(bcm, 0x0001) & 0x3FFF) | 0x4000); - bcm43xx_phy_write(bcm, 0x0811, - bcm43xx_phy_read(bcm, 0x0811) | 0x000C); - bcm43xx_phy_write(bcm, 0x0812, - (bcm43xx_phy_read(bcm, 0x0812) & 0xFFF3) | 0x0004); - bcm43xx_phy_write(bcm, 0x0802, - bcm43xx_phy_read(bcm, 0x0802) & ~(0x1 | 0x2)); - if (phy->rev >= 6) { - backup[12] = bcm43xx_phy_read(bcm, 0x002E); - backup[13] = bcm43xx_phy_read(bcm, 0x002F); - backup[14] = bcm43xx_phy_read(bcm, 0x080F); - backup[15] = bcm43xx_phy_read(bcm, 0x0810); - backup[16] = bcm43xx_phy_read(bcm, 0x0801); - backup[17] = bcm43xx_phy_read(bcm, 0x0060); - backup[18] = bcm43xx_phy_read(bcm, 0x0014); - backup[19] = bcm43xx_phy_read(bcm, 0x0478); - - bcm43xx_phy_write(bcm, 0x002E, 0); - bcm43xx_phy_write(bcm, 0x002F, 0); - bcm43xx_phy_write(bcm, 0x080F, 0); - bcm43xx_phy_write(bcm, 0x0810, 0); - bcm43xx_phy_write(bcm, 0x0478, - bcm43xx_phy_read(bcm, 0x0478) | 0x0100); - bcm43xx_phy_write(bcm, 0x0801, - bcm43xx_phy_read(bcm, 0x0801) | 0x0040); - bcm43xx_phy_write(bcm, 0x0060, - bcm43xx_phy_read(bcm, 0x0060) | 0x0040); - bcm43xx_phy_write(bcm, 0x0014, - bcm43xx_phy_read(bcm, 0x0014) | 0x0200); - } - bcm43xx_radio_write16(bcm, 0x007A, - bcm43xx_radio_read16(bcm, 0x007A) | 0x0070); - bcm43xx_radio_write16(bcm, 0x007A, - bcm43xx_radio_read16(bcm, 0x007A) | 0x0080); - udelay(30); - - v47F = (s16)((bcm43xx_phy_read(bcm, 0x047F) >> 8) & 0x003F); - if (v47F >= 0x20) - v47F -= 0x40; - if (v47F == 31) { - for (i = 7; i >= 4; i--) { - bcm43xx_radio_write16(bcm, 0x007B, i); - udelay(20); - v47F = (s16)((bcm43xx_phy_read(bcm, 0x047F) >> 8) & 0x003F); - if (v47F >= 0x20) - v47F -= 0x40; - if (v47F < 31 && saved == 0xFFFF) - saved = i; - } - if (saved == 0xFFFF) - saved = 4; - } else { - bcm43xx_radio_write16(bcm, 0x007A, - bcm43xx_radio_read16(bcm, 0x007A) & 0x007F); - bcm43xx_phy_write(bcm, 0x0814, - bcm43xx_phy_read(bcm, 0x0814) | 0x0001); - bcm43xx_phy_write(bcm, 0x0815, - bcm43xx_phy_read(bcm, 0x0815) & 0xFFFE); - bcm43xx_phy_write(bcm, 0x0811, - bcm43xx_phy_read(bcm, 0x0811) | 0x000C); - bcm43xx_phy_write(bcm, 0x0812, - bcm43xx_phy_read(bcm, 0x0812) | 0x000C); - bcm43xx_phy_write(bcm, 0x0811, - bcm43xx_phy_read(bcm, 0x0811) | 0x0030); - bcm43xx_phy_write(bcm, 0x0812, - bcm43xx_phy_read(bcm, 0x0812) | 0x0030); - bcm43xx_phy_write(bcm, 0x005A, 0x0480); - bcm43xx_phy_write(bcm, 0x0059, 0x0810); - bcm43xx_phy_write(bcm, 0x0058, 0x000D); - if (phy->rev == 0) { - bcm43xx_phy_write(bcm, 0x0003, 0x0122); - } else { - bcm43xx_phy_write(bcm, 0x000A, - bcm43xx_phy_read(bcm, 0x000A) - | 0x2000); - } - bcm43xx_phy_write(bcm, 0x0814, - bcm43xx_phy_read(bcm, 0x0814) | 0x0004); - bcm43xx_phy_write(bcm, 0x0815, - bcm43xx_phy_read(bcm, 0x0815) & 0xFFFB); - bcm43xx_phy_write(bcm, 0x0003, - (bcm43xx_phy_read(bcm, 0x0003) & 0xFF9F) - | 0x0040); - bcm43xx_radio_write16(bcm, 0x007A, - bcm43xx_radio_read16(bcm, 0x007A) | 0x000F); - bcm43xx_set_all_gains(bcm, 3, 0, 1); - bcm43xx_radio_write16(bcm, 0x0043, - (bcm43xx_radio_read16(bcm, 0x0043) - & 0x00F0) | 0x000F); - udelay(30); - v47F = (s16)((bcm43xx_phy_read(bcm, 0x047F) >> 8) & 0x003F); - if (v47F >= 0x20) - v47F -= 0x40; - if (v47F == -32) { - for (i = 0; i < 4; i++) { - bcm43xx_radio_write16(bcm, 0x007B, i); - udelay(20); - v47F = (s16)((bcm43xx_phy_read(bcm, 0x047F) >> 8) & 0x003F); - if (v47F >= 0x20) - v47F -= 0x40; - if (v47F > -31 && saved == 0xFFFF) - saved = i; - } - if (saved == 0xFFFF) - saved = 3; - } else - saved = 0; - } - bcm43xx_radio_write16(bcm, 0x007B, saved); - - if (phy->rev >= 6) { - bcm43xx_phy_write(bcm, 0x002E, backup[12]); - bcm43xx_phy_write(bcm, 0x002F, backup[13]); - bcm43xx_phy_write(bcm, 0x080F, backup[14]); - bcm43xx_phy_write(bcm, 0x0810, backup[15]); - } - bcm43xx_phy_write(bcm, 0x0814, backup[3]); - bcm43xx_phy_write(bcm, 0x0815, backup[4]); - bcm43xx_phy_write(bcm, 0x005A, backup[5]); - bcm43xx_phy_write(bcm, 0x0059, backup[6]); - bcm43xx_phy_write(bcm, 0x0058, backup[7]); - bcm43xx_phy_write(bcm, 0x000A, backup[8]); - bcm43xx_phy_write(bcm, 0x0003, backup[9]); - bcm43xx_radio_write16(bcm, 0x0043, backup[11]); - bcm43xx_radio_write16(bcm, 0x007A, backup[10]); - bcm43xx_phy_write(bcm, 0x0802, - bcm43xx_phy_read(bcm, 0x0802) | 0x1 | 0x2); - bcm43xx_phy_write(bcm, 0x0429, - bcm43xx_phy_read(bcm, 0x0429) | 0x8000); - bcm43xx_set_original_gains(bcm); - if (phy->rev >= 6) { - bcm43xx_phy_write(bcm, 0x0801, backup[16]); - bcm43xx_phy_write(bcm, 0x0060, backup[17]); - bcm43xx_phy_write(bcm, 0x0014, backup[18]); - bcm43xx_phy_write(bcm, 0x0478, backup[19]); - } - bcm43xx_phy_write(bcm, 0x0001, backup[0]); - bcm43xx_phy_write(bcm, 0x0812, backup[2]); - bcm43xx_phy_write(bcm, 0x0811, backup[1]); -} - -void bcm43xx_calc_nrssi_slope(struct bcm43xx_private *bcm) -{ - struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm); - struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm); - u16 backup[18] = { 0 }; - u16 tmp; - s16 nrssi0, nrssi1; - - switch (phy->type) { - case BCM43xx_PHYTYPE_B: - backup[0] = bcm43xx_radio_read16(bcm, 0x007A); - backup[1] = bcm43xx_radio_read16(bcm, 0x0052); - backup[2] = bcm43xx_radio_read16(bcm, 0x0043); - backup[3] = bcm43xx_phy_read(bcm, 0x0030); - backup[4] = bcm43xx_phy_read(bcm, 0x0026); - backup[5] = bcm43xx_phy_read(bcm, 0x0015); - backup[6] = bcm43xx_phy_read(bcm, 0x002A); - backup[7] = bcm43xx_phy_read(bcm, 0x0020); - backup[8] = bcm43xx_phy_read(bcm, 0x005A); - backup[9] = bcm43xx_phy_read(bcm, 0x0059); - backup[10] = bcm43xx_phy_read(bcm, 0x0058); - backup[11] = bcm43xx_read16(bcm, 0x03E2); - backup[12] = bcm43xx_read16(bcm, 0x03E6); - backup[13] = bcm43xx_read16(bcm, BCM43xx_MMIO_CHANNEL_EXT); - - tmp = bcm43xx_radio_read16(bcm, 0x007A); - tmp &= (phy->rev >= 5) ? 0x007F : 0x000F; - bcm43xx_radio_write16(bcm, 0x007A, tmp); - bcm43xx_phy_write(bcm, 0x0030, 0x00FF); - bcm43xx_write16(bcm, 0x03EC, 0x7F7F); - bcm43xx_phy_write(bcm, 0x0026, 0x0000); - bcm43xx_phy_write(bcm, 0x0015, - bcm43xx_phy_read(bcm, 0x0015) | 0x0020); - bcm43xx_phy_write(bcm, 0x002A, 0x08A3); - bcm43xx_radio_write16(bcm, 0x007A, - bcm43xx_radio_read16(bcm, 0x007A) | 0x0080); - - nrssi0 = (s16)bcm43xx_phy_read(bcm, 0x0027); - bcm43xx_radio_write16(bcm, 0x007A, - bcm43xx_radio_read16(bcm, 0x007A) & 0x007F); - if (phy->rev >= 2) { - bcm43xx_write16(bcm, 0x03E6, 0x0040); - } else if (phy->rev == 0) { - bcm43xx_write16(bcm, 0x03E6, 0x0122); - } else { - bcm43xx_write16(bcm, BCM43xx_MMIO_CHANNEL_EXT, - bcm43xx_read16(bcm, BCM43xx_MMIO_CHANNEL_EXT) & 0x2000); - } - bcm43xx_phy_write(bcm, 0x0020, 0x3F3F); - bcm43xx_phy_write(bcm, 0x0015, 0xF330); - bcm43xx_radio_write16(bcm, 0x005A, 0x0060); - bcm43xx_radio_write16(bcm, 0x0043, - bcm43xx_radio_read16(bcm, 0x0043) & 0x00F0); - bcm43xx_phy_write(bcm, 0x005A, 0x0480); - bcm43xx_phy_write(bcm, 0x0059, 0x0810); - bcm43xx_phy_write(bcm, 0x0058, 0x000D); - udelay(20); - - nrssi1 = (s16)bcm43xx_phy_read(bcm, 0x0027); - bcm43xx_phy_write(bcm, 0x0030, backup[3]); - bcm43xx_radio_write16(bcm, 0x007A, backup[0]); - bcm43xx_write16(bcm, 0x03E2, backup[11]); - bcm43xx_phy_write(bcm, 0x0026, backup[4]); - bcm43xx_phy_write(bcm, 0x0015, backup[5]); - bcm43xx_phy_write(bcm, 0x002A, backup[6]); - bcm43xx_synth_pu_workaround(bcm, radio->channel); - if (phy->rev != 0) - bcm43xx_write16(bcm, 0x03F4, backup[13]); - - bcm43xx_phy_write(bcm, 0x0020, backup[7]); - bcm43xx_phy_write(bcm, 0x005A, backup[8]); - bcm43xx_phy_write(bcm, 0x0059, backup[9]); - bcm43xx_phy_write(bcm, 0x0058, backup[10]); - bcm43xx_radio_write16(bcm, 0x0052, backup[1]); - bcm43xx_radio_write16(bcm, 0x0043, backup[2]); - - if (nrssi0 == nrssi1) - radio->nrssislope = 0x00010000; - else - radio->nrssislope = 0x00400000 / (nrssi0 - nrssi1); - - if (nrssi0 <= -4) { - radio->nrssi[0] = nrssi0; - radio->nrssi[1] = nrssi1; - } - break; - case BCM43xx_PHYTYPE_G: - if (radio->revision >= 9) - return; - if (radio->revision == 8) - bcm43xx_calc_nrssi_offset(bcm); - - bcm43xx_phy_write(bcm, BCM43xx_PHY_G_CRS, - bcm43xx_phy_read(bcm, BCM43xx_PHY_G_CRS) & 0x7FFF); - bcm43xx_phy_write(bcm, 0x0802, - bcm43xx_phy_read(bcm, 0x0802) & 0xFFFC); - backup[7] = bcm43xx_read16(bcm, 0x03E2); - bcm43xx_write16(bcm, 0x03E2, - bcm43xx_read16(bcm, 0x03E2) | 0x8000); - backup[0] = bcm43xx_radio_read16(bcm, 0x007A); - backup[1] = bcm43xx_radio_read16(bcm, 0x0052); - backup[2] = bcm43xx_radio_read16(bcm, 0x0043); - backup[3] = bcm43xx_phy_read(bcm, 0x0015); - backup[4] = bcm43xx_phy_read(bcm, 0x005A); - backup[5] = bcm43xx_phy_read(bcm, 0x0059); - backup[6] = bcm43xx_phy_read(bcm, 0x0058); - backup[8] = bcm43xx_read16(bcm, 0x03E6); - backup[9] = bcm43xx_read16(bcm, BCM43xx_MMIO_CHANNEL_EXT); - if (phy->rev >= 3) { - backup[10] = bcm43xx_phy_read(bcm, 0x002E); - backup[11] = bcm43xx_phy_read(bcm, 0x002F); - backup[12] = bcm43xx_phy_read(bcm, 0x080F); - backup[13] = bcm43xx_phy_read(bcm, BCM43xx_PHY_G_LO_CONTROL); - backup[14] = bcm43xx_phy_read(bcm, 0x0801); - backup[15] = bcm43xx_phy_read(bcm, 0x0060); - backup[16] = bcm43xx_phy_read(bcm, 0x0014); - backup[17] = bcm43xx_phy_read(bcm, 0x0478); - bcm43xx_phy_write(bcm, 0x002E, 0); - bcm43xx_phy_write(bcm, BCM43xx_PHY_G_LO_CONTROL, 0); - switch (phy->rev) { - case 4: case 6: case 7: - bcm43xx_phy_write(bcm, 0x0478, - bcm43xx_phy_read(bcm, 0x0478) - | 0x0100); - bcm43xx_phy_write(bcm, 0x0801, - bcm43xx_phy_read(bcm, 0x0801) - | 0x0040); - break; - case 3: case 5: - bcm43xx_phy_write(bcm, 0x0801, - bcm43xx_phy_read(bcm, 0x0801) - & 0xFFBF); - break; - } - bcm43xx_phy_write(bcm, 0x0060, - bcm43xx_phy_read(bcm, 0x0060) - | 0x0040); - bcm43xx_phy_write(bcm, 0x0014, - bcm43xx_phy_read(bcm, 0x0014) - | 0x0200); - } - bcm43xx_radio_write16(bcm, 0x007A, - bcm43xx_radio_read16(bcm, 0x007A) | 0x0070); - bcm43xx_set_all_gains(bcm, 0, 8, 0); - bcm43xx_radio_write16(bcm, 0x007A, - bcm43xx_radio_read16(bcm, 0x007A) & 0x00F7); - if (phy->rev >= 2) { - bcm43xx_phy_write(bcm, 0x0811, - (bcm43xx_phy_read(bcm, 0x0811) & 0xFFCF) | 0x0030); - bcm43xx_phy_write(bcm, 0x0812, - (bcm43xx_phy_read(bcm, 0x0812) & 0xFFCF) | 0x0010); - } - bcm43xx_radio_write16(bcm, 0x007A, - bcm43xx_radio_read16(bcm, 0x007A) | 0x0080); - udelay(20); - - nrssi0 = (s16)((bcm43xx_phy_read(bcm, 0x047F) >> 8) & 0x003F); - if (nrssi0 >= 0x0020) - nrssi0 -= 0x0040; - - bcm43xx_radio_write16(bcm, 0x007A, - bcm43xx_radio_read16(bcm, 0x007A) & 0x007F); - if (phy->rev >= 2) { - bcm43xx_phy_write(bcm, 0x0003, - (bcm43xx_phy_read(bcm, 0x0003) - & 0xFF9F) | 0x0040); - } - - bcm43xx_write16(bcm, BCM43xx_MMIO_CHANNEL_EXT, - bcm43xx_read16(bcm, BCM43xx_MMIO_CHANNEL_EXT) - | 0x2000); - bcm43xx_radio_write16(bcm, 0x007A, - bcm43xx_radio_read16(bcm, 0x007A) | 0x000F); - bcm43xx_phy_write(bcm, 0x0015, 0xF330); - if (phy->rev >= 2) { - bcm43xx_phy_write(bcm, 0x0812, - (bcm43xx_phy_read(bcm, 0x0812) & 0xFFCF) | 0x0020); - bcm43xx_phy_write(bcm, 0x0811, - (bcm43xx_phy_read(bcm, 0x0811) & 0xFFCF) | 0x0020); - } - - bcm43xx_set_all_gains(bcm, 3, 0, 1); - if (radio->revision == 8) { - bcm43xx_radio_write16(bcm, 0x0043, 0x001F); - } else { - tmp = bcm43xx_radio_read16(bcm, 0x0052) & 0xFF0F; - bcm43xx_radio_write16(bcm, 0x0052, tmp | 0x0060); - tmp = bcm43xx_radio_read16(bcm, 0x0043) & 0xFFF0; - bcm43xx_radio_write16(bcm, 0x0043, tmp | 0x0009); - } - bcm43xx_phy_write(bcm, 0x005A, 0x0480); - bcm43xx_phy_write(bcm, 0x0059, 0x0810); - bcm43xx_phy_write(bcm, 0x0058, 0x000D); - udelay(20); - nrssi1 = (s16)((bcm43xx_phy_read(bcm, 0x047F) >> 8) & 0x003F); - if (nrssi1 >= 0x0020) - nrssi1 -= 0x0040; - if (nrssi0 == nrssi1) - radio->nrssislope = 0x00010000; - else - radio->nrssislope = 0x00400000 / (nrssi0 - nrssi1); - if (nrssi0 >= -4) { - radio->nrssi[0] = nrssi1; - radio->nrssi[1] = nrssi0; - } - if (phy->rev >= 3) { - bcm43xx_phy_write(bcm, 0x002E, backup[10]); - bcm43xx_phy_write(bcm, 0x002F, backup[11]); - bcm43xx_phy_write(bcm, 0x080F, backup[12]); - bcm43xx_phy_write(bcm, BCM43xx_PHY_G_LO_CONTROL, backup[13]); - } - if (phy->rev >= 2) { - bcm43xx_phy_write(bcm, 0x0812, - bcm43xx_phy_read(bcm, 0x0812) & 0xFFCF); - bcm43xx_phy_write(bcm, 0x0811, - bcm43xx_phy_read(bcm, 0x0811) & 0xFFCF); - } - - bcm43xx_radio_write16(bcm, 0x007A, backup[0]); - bcm43xx_radio_write16(bcm, 0x0052, backup[1]); - bcm43xx_radio_write16(bcm, 0x0043, backup[2]); - bcm43xx_write16(bcm, 0x03E2, backup[7]); - bcm43xx_write16(bcm, 0x03E6, backup[8]); - bcm43xx_write16(bcm, BCM43xx_MMIO_CHANNEL_EXT, backup[9]); - bcm43xx_phy_write(bcm, 0x0015, backup[3]); - bcm43xx_phy_write(bcm, 0x005A, backup[4]); - bcm43xx_phy_write(bcm, 0x0059, backup[5]); - bcm43xx_phy_write(bcm, 0x0058, backup[6]); - bcm43xx_synth_pu_workaround(bcm, radio->channel); - bcm43xx_phy_write(bcm, 0x0802, - bcm43xx_phy_read(bcm, 0x0802) | (0x0001 | 0x0002)); - bcm43xx_set_original_gains(bcm); - bcm43xx_phy_write(bcm, BCM43xx_PHY_G_CRS, - bcm43xx_phy_read(bcm, BCM43xx_PHY_G_CRS) | 0x8000); - if (phy->rev >= 3) { - bcm43xx_phy_write(bcm, 0x0801, backup[14]); - bcm43xx_phy_write(bcm, 0x0060, backup[15]); - bcm43xx_phy_write(bcm, 0x0014, backup[16]); - bcm43xx_phy_write(bcm, 0x0478, backup[17]); - } - bcm43xx_nrssi_mem_update(bcm); - bcm43xx_calc_nrssi_threshold(bcm); - break; - default: - assert(0); - } -} - -void bcm43xx_calc_nrssi_threshold(struct bcm43xx_private *bcm) -{ - struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm); - struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm); - s32 threshold; - s32 a, b; - s16 tmp16; - u16 tmp_u16; - - switch (phy->type) { - case BCM43xx_PHYTYPE_B: { - if (radio->version != 0x2050) - return; - if (!(bcm->sprom.boardflags & BCM43xx_BFL_RSSI)) - return; - - if (radio->revision >= 6) { - threshold = (radio->nrssi[1] - radio->nrssi[0]) * 32; - threshold += 20 * (radio->nrssi[0] + 1); - threshold /= 40; - } else - threshold = radio->nrssi[1] - 5; - - threshold = limit_value(threshold, 0, 0x3E); - bcm43xx_phy_read(bcm, 0x0020); /* dummy read */ - bcm43xx_phy_write(bcm, 0x0020, (((u16)threshold) << 8) | 0x001C); - - if (radio->revision >= 6) { - bcm43xx_phy_write(bcm, 0x0087, 0x0E0D); - bcm43xx_phy_write(bcm, 0x0086, 0x0C0B); - bcm43xx_phy_write(bcm, 0x0085, 0x0A09); - bcm43xx_phy_write(bcm, 0x0084, 0x0808); - bcm43xx_phy_write(bcm, 0x0083, 0x0808); - bcm43xx_phy_write(bcm, 0x0082, 0x0604); - bcm43xx_phy_write(bcm, 0x0081, 0x0302); - bcm43xx_phy_write(bcm, 0x0080, 0x0100); - } - break; - } - case BCM43xx_PHYTYPE_G: - if (!phy->connected || - !(bcm->sprom.boardflags & BCM43xx_BFL_RSSI)) { - tmp16 = bcm43xx_nrssi_hw_read(bcm, 0x20); - if (tmp16 >= 0x20) - tmp16 -= 0x40; - if (tmp16 < 3) { - bcm43xx_phy_write(bcm, 0x048A, - (bcm43xx_phy_read(bcm, 0x048A) - & 0xF000) | 0x09EB); - } else { - bcm43xx_phy_write(bcm, 0x048A, - (bcm43xx_phy_read(bcm, 0x048A) - & 0xF000) | 0x0AED); - } - } else { - if (radio->interfmode == BCM43xx_RADIO_INTERFMODE_NONWLAN) { - a = 0xE; - b = 0xA; - } else if (!radio->aci_wlan_automatic && radio->aci_enable) { - a = 0x13; - b = 0x12; - } else { - a = 0xE; - b = 0x11; - } - - a = a * (radio->nrssi[1] - radio->nrssi[0]); - a += (radio->nrssi[0] << 6); - if (a < 32) - a += 31; - else - a += 32; - a = a >> 6; - a = limit_value(a, -31, 31); - - b = b * (radio->nrssi[1] - radio->nrssi[0]); - b += (radio->nrssi[0] << 6); - if (b < 32) - b += 31; - else - b += 32; - b = b >> 6; - b = limit_value(b, -31, 31); - - tmp_u16 = bcm43xx_phy_read(bcm, 0x048A) & 0xF000; - tmp_u16 |= ((u32)b & 0x0000003F); - tmp_u16 |= (((u32)a & 0x0000003F) << 6); - bcm43xx_phy_write(bcm, 0x048A, tmp_u16); - } - break; - default: - assert(0); - } -} - -/* Stack implementation to save/restore values from the - * interference mitigation code. - * It is save to restore values in random order. - */ -static void _stack_save(u32 *_stackptr, size_t *stackidx, - u8 id, u16 offset, u16 value) -{ - u32 *stackptr = &(_stackptr[*stackidx]); - - assert((offset & 0xF000) == 0x0000); - assert((id & 0xF0) == 0x00); - *stackptr = offset; - *stackptr |= ((u32)id) << 12; - *stackptr |= ((u32)value) << 16; - (*stackidx)++; - assert(*stackidx < BCM43xx_INTERFSTACK_SIZE); -} - -static u16 _stack_restore(u32 *stackptr, - u8 id, u16 offset) -{ - size_t i; - - assert((offset & 0xF000) == 0x0000); - assert((id & 0xF0) == 0x00); - for (i = 0; i < BCM43xx_INTERFSTACK_SIZE; i++, stackptr++) { - if ((*stackptr & 0x00000FFF) != offset) - continue; - if (((*stackptr & 0x0000F000) >> 12) != id) - continue; - return ((*stackptr & 0xFFFF0000) >> 16); - } - assert(0); - - return 0; -} - -#define phy_stacksave(offset) \ - do { \ - _stack_save(stack, &stackidx, 0x1, (offset), \ - bcm43xx_phy_read(bcm, (offset))); \ - } while (0) -#define phy_stackrestore(offset) \ - do { \ - bcm43xx_phy_write(bcm, (offset), \ - _stack_restore(stack, 0x1, \ - (offset))); \ - } while (0) -#define radio_stacksave(offset) \ - do { \ - _stack_save(stack, &stackidx, 0x2, (offset), \ - bcm43xx_radio_read16(bcm, (offset))); \ - } while (0) -#define radio_stackrestore(offset) \ - do { \ - bcm43xx_radio_write16(bcm, (offset), \ - _stack_restore(stack, 0x2, \ - (offset))); \ - } while (0) -#define ilt_stacksave(offset) \ - do { \ - _stack_save(stack, &stackidx, 0x3, (offset), \ - bcm43xx_ilt_read(bcm, (offset))); \ - } while (0) -#define ilt_stackrestore(offset) \ - do { \ - bcm43xx_ilt_write(bcm, (offset), \ - _stack_restore(stack, 0x3, \ - (offset))); \ - } while (0) - -static void -bcm43xx_radio_interference_mitigation_enable(struct bcm43xx_private *bcm, - int mode) -{ - struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm); - struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm); - u16 tmp, flipped; - u32 tmp32; - size_t stackidx = 0; - u32 *stack = radio->interfstack; - - switch (mode) { - case BCM43xx_RADIO_INTERFMODE_NONWLAN: - if (phy->rev != 1) { - bcm43xx_phy_write(bcm, 0x042B, - bcm43xx_phy_read(bcm, 0x042B) | 0x0800); - bcm43xx_phy_write(bcm, BCM43xx_PHY_G_CRS, - bcm43xx_phy_read(bcm, BCM43xx_PHY_G_CRS) & ~0x4000); - break; - } - radio_stacksave(0x0078); - tmp = (bcm43xx_radio_read16(bcm, 0x0078) & 0x001E); - flipped = flip_4bit(tmp); - if (flipped < 10 && flipped >= 8) - flipped = 7; - else if (flipped >= 10) - flipped -= 3; - flipped = flip_4bit(flipped); - flipped = (flipped << 1) | 0x0020; - bcm43xx_radio_write16(bcm, 0x0078, flipped); - - bcm43xx_calc_nrssi_threshold(bcm); - - phy_stacksave(0x0406); - bcm43xx_phy_write(bcm, 0x0406, 0x7E28); - - bcm43xx_phy_write(bcm, 0x042B, - bcm43xx_phy_read(bcm, 0x042B) | 0x0800); - bcm43xx_phy_write(bcm, BCM43xx_PHY_RADIO_BITFIELD, - bcm43xx_phy_read(bcm, BCM43xx_PHY_RADIO_BITFIELD) | 0x1000); - - phy_stacksave(0x04A0); - bcm43xx_phy_write(bcm, 0x04A0, - (bcm43xx_phy_read(bcm, 0x04A0) & 0xC0C0) | 0x0008); - phy_stacksave(0x04A1); - bcm43xx_phy_write(bcm, 0x04A1, - (bcm43xx_phy_read(bcm, 0x04A1) & 0xC0C0) | 0x0605); - phy_stacksave(0x04A2); - bcm43xx_phy_write(bcm, 0x04A2, - (bcm43xx_phy_read(bcm, 0x04A2) & 0xC0C0) | 0x0204); - phy_stacksave(0x04A8); - bcm43xx_phy_write(bcm, 0x04A8, - (bcm43xx_phy_read(bcm, 0x04A8) & 0xC0C0) | 0x0803); - phy_stacksave(0x04AB); - bcm43xx_phy_write(bcm, 0x04AB, - (bcm43xx_phy_read(bcm, 0x04AB) & 0xC0C0) | 0x0605); - - phy_stacksave(0x04A7); - bcm43xx_phy_write(bcm, 0x04A7, 0x0002); - phy_stacksave(0x04A3); - bcm43xx_phy_write(bcm, 0x04A3, 0x287A); - phy_stacksave(0x04A9); - bcm43xx_phy_write(bcm, 0x04A9, 0x2027); - phy_stacksave(0x0493); - bcm43xx_phy_write(bcm, 0x0493, 0x32F5); - phy_stacksave(0x04AA); - bcm43xx_phy_write(bcm, 0x04AA, 0x2027); - phy_stacksave(0x04AC); - bcm43xx_phy_write(bcm, 0x04AC, 0x32F5); - break; - case BCM43xx_RADIO_INTERFMODE_MANUALWLAN: - if (bcm43xx_phy_read(bcm, 0x0033) & 0x0800) - break; - - radio->aci_enable = 1; - - phy_stacksave(BCM43xx_PHY_RADIO_BITFIELD); - phy_stacksave(BCM43xx_PHY_G_CRS); - if (phy->rev < 2) { - phy_stacksave(0x0406); - } else { - phy_stacksave(0x04C0); - phy_stacksave(0x04C1); - } - phy_stacksave(0x0033); - phy_stacksave(0x04A7); - phy_stacksave(0x04A3); - phy_stacksave(0x04A9); - phy_stacksave(0x04AA); - phy_stacksave(0x04AC); - phy_stacksave(0x0493); - phy_stacksave(0x04A1); - phy_stacksave(0x04A0); - phy_stacksave(0x04A2); - phy_stacksave(0x048A); - phy_stacksave(0x04A8); - phy_stacksave(0x04AB); - if (phy->rev == 2) { - phy_stacksave(0x04AD); - phy_stacksave(0x04AE); - } else if (phy->rev >= 3) { - phy_stacksave(0x04AD); - phy_stacksave(0x0415); - phy_stacksave(0x0416); - phy_stacksave(0x0417); - ilt_stacksave(0x1A00 + 0x2); - ilt_stacksave(0x1A00 + 0x3); - } - phy_stacksave(0x042B); - phy_stacksave(0x048C); - - bcm43xx_phy_write(bcm, BCM43xx_PHY_RADIO_BITFIELD, - bcm43xx_phy_read(bcm, BCM43xx_PHY_RADIO_BITFIELD) - & ~0x1000); - bcm43xx_phy_write(bcm, BCM43xx_PHY_G_CRS, - (bcm43xx_phy_read(bcm, BCM43xx_PHY_G_CRS) - & 0xFFFC) | 0x0002); - - bcm43xx_phy_write(bcm, 0x0033, 0x0800); - bcm43xx_phy_write(bcm, 0x04A3, 0x2027); - bcm43xx_phy_write(bcm, 0x04A9, 0x1CA8); - bcm43xx_phy_write(bcm, 0x0493, 0x287A); - bcm43xx_phy_write(bcm, 0x04AA, 0x1CA8); - bcm43xx_phy_write(bcm, 0x04AC, 0x287A); - - bcm43xx_phy_write(bcm, 0x04A0, - (bcm43xx_phy_read(bcm, 0x04A0) - & 0xFFC0) | 0x001A); - bcm43xx_phy_write(bcm, 0x04A7, 0x000D); - - if (phy->rev < 2) { - bcm43xx_phy_write(bcm, 0x0406, 0xFF0D); - } else if (phy->rev == 2) { - bcm43xx_phy_write(bcm, 0x04C0, 0xFFFF); - bcm43xx_phy_write(bcm, 0x04C1, 0x00A9); - } else { - bcm43xx_phy_write(bcm, 0x04C0, 0x00C1); - bcm43xx_phy_write(bcm, 0x04C1, 0x0059); - } - - bcm43xx_phy_write(bcm, 0x04A1, - (bcm43xx_phy_read(bcm, 0x04A1) - & 0xC0FF) | 0x1800); - bcm43xx_phy_write(bcm, 0x04A1, - (bcm43xx_phy_read(bcm, 0x04A1) - & 0xFFC0) | 0x0015); - bcm43xx_phy_write(bcm, 0x04A8, - (bcm43xx_phy_read(bcm, 0x04A8) - & 0xCFFF) | 0x1000); - bcm43xx_phy_write(bcm, 0x04A8, - (bcm43xx_phy_read(bcm, 0x04A8) - & 0xF0FF) | 0x0A00); - bcm43xx_phy_write(bcm, 0x04AB, - (bcm43xx_phy_read(bcm, 0x04AB) - & 0xCFFF) | 0x1000); - bcm43xx_phy_write(bcm, 0x04AB, - (bcm43xx_phy_read(bcm, 0x04AB) - & 0xF0FF) | 0x0800); - bcm43xx_phy_write(bcm, 0x04AB, - (bcm43xx_phy_read(bcm, 0x04AB) - & 0xFFCF) | 0x0010); - bcm43xx_phy_write(bcm, 0x04AB, - (bcm43xx_phy_read(bcm, 0x04AB) - & 0xFFF0) | 0x0005); - bcm43xx_phy_write(bcm, 0x04A8, - (bcm43xx_phy_read(bcm, 0x04A8) - & 0xFFCF) | 0x0010); - bcm43xx_phy_write(bcm, 0x04A8, - (bcm43xx_phy_read(bcm, 0x04A8) - & 0xFFF0) | 0x0006); - bcm43xx_phy_write(bcm, 0x04A2, - (bcm43xx_phy_read(bcm, 0x04A2) - & 0xF0FF) | 0x0800); - bcm43xx_phy_write(bcm, 0x04A0, - (bcm43xx_phy_read(bcm, 0x04A0) - & 0xF0FF) | 0x0500); - bcm43xx_phy_write(bcm, 0x04A2, - (bcm43xx_phy_read(bcm, 0x04A2) - & 0xFFF0) | 0x000B); - - if (phy->rev >= 3) { - bcm43xx_phy_write(bcm, 0x048A, - bcm43xx_phy_read(bcm, 0x048A) - & ~0x8000); - bcm43xx_phy_write(bcm, 0x0415, - (bcm43xx_phy_read(bcm, 0x0415) - & 0x8000) | 0x36D8); - bcm43xx_phy_write(bcm, 0x0416, - (bcm43xx_phy_read(bcm, 0x0416) - & 0x8000) | 0x36D8); - bcm43xx_phy_write(bcm, 0x0417, - (bcm43xx_phy_read(bcm, 0x0417) - & 0xFE00) | 0x016D); - } else { - bcm43xx_phy_write(bcm, 0x048A, - bcm43xx_phy_read(bcm, 0x048A) - | 0x1000); - bcm43xx_phy_write(bcm, 0x048A, - (bcm43xx_phy_read(bcm, 0x048A) - & 0x9FFF) | 0x2000); - tmp32 = bcm43xx_shm_read32(bcm, BCM43xx_SHM_SHARED, - BCM43xx_UCODEFLAGS_OFFSET); - if (!(tmp32 & 0x800)) { - tmp32 |= 0x800; - bcm43xx_shm_write32(bcm, BCM43xx_SHM_SHARED, - BCM43xx_UCODEFLAGS_OFFSET, - tmp32); - } - } - if (phy->rev >= 2) { - bcm43xx_phy_write(bcm, 0x042B, - bcm43xx_phy_read(bcm, 0x042B) - | 0x0800); - } - bcm43xx_phy_write(bcm, 0x048C, - (bcm43xx_phy_read(bcm, 0x048C) - & 0xF0FF) | 0x0200); - if (phy->rev == 2) { - bcm43xx_phy_write(bcm, 0x04AE, - (bcm43xx_phy_read(bcm, 0x04AE) - & 0xFF00) | 0x007F); - bcm43xx_phy_write(bcm, 0x04AD, - (bcm43xx_phy_read(bcm, 0x04AD) - & 0x00FF) | 0x1300); - } else if (phy->rev >= 6) { - bcm43xx_ilt_write(bcm, 0x1A00 + 0x3, 0x007F); - bcm43xx_ilt_write(bcm, 0x1A00 + 0x2, 0x007F); - bcm43xx_phy_write(bcm, 0x04AD, - bcm43xx_phy_read(bcm, 0x04AD) - & 0x00FF); - } - bcm43xx_calc_nrssi_slope(bcm); - break; - default: - assert(0); - } -} - -static void -bcm43xx_radio_interference_mitigation_disable(struct bcm43xx_private *bcm, - int mode) -{ - struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm); - struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm); - u32 tmp32; - u32 *stack = radio->interfstack; - - switch (mode) { - case BCM43xx_RADIO_INTERFMODE_NONWLAN: - if (phy->rev != 1) { - bcm43xx_phy_write(bcm, 0x042B, - bcm43xx_phy_read(bcm, 0x042B) & ~0x0800); - bcm43xx_phy_write(bcm, BCM43xx_PHY_G_CRS, - bcm43xx_phy_read(bcm, BCM43xx_PHY_G_CRS) | 0x4000); - break; - } - phy_stackrestore(0x0078); - bcm43xx_calc_nrssi_threshold(bcm); - phy_stackrestore(0x0406); - bcm43xx_phy_write(bcm, 0x042B, - bcm43xx_phy_read(bcm, 0x042B) & ~0x0800); - if (!bcm->bad_frames_preempt) { - bcm43xx_phy_write(bcm, BCM43xx_PHY_RADIO_BITFIELD, - bcm43xx_phy_read(bcm, BCM43xx_PHY_RADIO_BITFIELD) - & ~(1 << 11)); - } - bcm43xx_phy_write(bcm, BCM43xx_PHY_G_CRS, - bcm43xx_phy_read(bcm, BCM43xx_PHY_G_CRS) | 0x4000); - phy_stackrestore(0x04A0); - phy_stackrestore(0x04A1); - phy_stackrestore(0x04A2); - phy_stackrestore(0x04A8); - phy_stackrestore(0x04AB); - phy_stackrestore(0x04A7); - phy_stackrestore(0x04A3); - phy_stackrestore(0x04A9); - phy_stackrestore(0x0493); - phy_stackrestore(0x04AA); - phy_stackrestore(0x04AC); - break; - case BCM43xx_RADIO_INTERFMODE_MANUALWLAN: - if (!(bcm43xx_phy_read(bcm, 0x0033) & 0x0800)) - break; - - radio->aci_enable = 0; - - phy_stackrestore(BCM43xx_PHY_RADIO_BITFIELD); - phy_stackrestore(BCM43xx_PHY_G_CRS); - phy_stackrestore(0x0033); - phy_stackrestore(0x04A3); - phy_stackrestore(0x04A9); - phy_stackrestore(0x0493); - phy_stackrestore(0x04AA); - phy_stackrestore(0x04AC); - phy_stackrestore(0x04A0); - phy_stackrestore(0x04A7); - if (phy->rev >= 2) { - phy_stackrestore(0x04C0); - phy_stackrestore(0x04C1); - } else - phy_stackrestore(0x0406); - phy_stackrestore(0x04A1); - phy_stackrestore(0x04AB); - phy_stackrestore(0x04A8); - if (phy->rev == 2) { - phy_stackrestore(0x04AD); - phy_stackrestore(0x04AE); - } else if (phy->rev >= 3) { - phy_stackrestore(0x04AD); - phy_stackrestore(0x0415); - phy_stackrestore(0x0416); - phy_stackrestore(0x0417); - ilt_stackrestore(0x1A00 + 0x2); - ilt_stackrestore(0x1A00 + 0x3); - } - phy_stackrestore(0x04A2); - phy_stackrestore(0x04A8); - phy_stackrestore(0x042B); - phy_stackrestore(0x048C); - tmp32 = bcm43xx_shm_read32(bcm, BCM43xx_SHM_SHARED, - BCM43xx_UCODEFLAGS_OFFSET); - if (tmp32 & 0x800) { - tmp32 &= ~0x800; - bcm43xx_shm_write32(bcm, BCM43xx_SHM_SHARED, - BCM43xx_UCODEFLAGS_OFFSET, - tmp32); - } - bcm43xx_calc_nrssi_slope(bcm); - break; - default: - assert(0); - } -} - -#undef phy_stacksave -#undef phy_stackrestore -#undef radio_stacksave -#undef radio_stackrestore -#undef ilt_stacksave -#undef ilt_stackrestore - -int bcm43xx_radio_set_interference_mitigation(struct bcm43xx_private *bcm, - int mode) -{ - struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm); - struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm); - int currentmode; - - if ((phy->type != BCM43xx_PHYTYPE_G) || - (phy->rev == 0) || - (!phy->connected)) - return -ENODEV; - - radio->aci_wlan_automatic = 0; - switch (mode) { - case BCM43xx_RADIO_INTERFMODE_AUTOWLAN: - radio->aci_wlan_automatic = 1; - if (radio->aci_enable) - mode = BCM43xx_RADIO_INTERFMODE_MANUALWLAN; - else - mode = BCM43xx_RADIO_INTERFMODE_NONE; - break; - case BCM43xx_RADIO_INTERFMODE_NONE: - case BCM43xx_RADIO_INTERFMODE_NONWLAN: - case BCM43xx_RADIO_INTERFMODE_MANUALWLAN: - break; - default: - return -EINVAL; - } - - currentmode = radio->interfmode; - if (currentmode == mode) - return 0; - if (currentmode != BCM43xx_RADIO_INTERFMODE_NONE) - bcm43xx_radio_interference_mitigation_disable(bcm, currentmode); - - if (mode == BCM43xx_RADIO_INTERFMODE_NONE) { - radio->aci_enable = 0; - radio->aci_hw_rssi = 0; - } else - bcm43xx_radio_interference_mitigation_enable(bcm, mode); - radio->interfmode = mode; - - return 0; -} - -u16 bcm43xx_radio_calibrationvalue(struct bcm43xx_private *bcm) -{ - u16 reg, index, ret; - - reg = bcm43xx_radio_read16(bcm, 0x0060); - index = (reg & 0x001E) >> 1; - ret = rcc_table[index] << 1; - ret |= (reg & 0x0001); - ret |= 0x0020; - - return ret; -} - -u16 bcm43xx_radio_init2050(struct bcm43xx_private *bcm) -{ - struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm); - struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm); - u16 backup[19] = { 0 }; - u16 ret; - u16 i, j; - u32 tmp1 = 0, tmp2 = 0; - - backup[0] = bcm43xx_radio_read16(bcm, 0x0043); - backup[14] = bcm43xx_radio_read16(bcm, 0x0051); - backup[15] = bcm43xx_radio_read16(bcm, 0x0052); - backup[1] = bcm43xx_phy_read(bcm, 0x0015); - backup[16] = bcm43xx_phy_read(bcm, 0x005A); - backup[17] = bcm43xx_phy_read(bcm, 0x0059); - backup[18] = bcm43xx_phy_read(bcm, 0x0058); - if (phy->type == BCM43xx_PHYTYPE_B) { - backup[2] = bcm43xx_phy_read(bcm, 0x0030); - backup[3] = bcm43xx_read16(bcm, 0x03EC); - bcm43xx_phy_write(bcm, 0x0030, 0x00FF); - bcm43xx_write16(bcm, 0x03EC, 0x3F3F); - } else { - if (phy->connected) { - backup[4] = bcm43xx_phy_read(bcm, 0x0811); - backup[5] = bcm43xx_phy_read(bcm, 0x0812); - backup[6] = bcm43xx_phy_read(bcm, 0x0814); - backup[7] = bcm43xx_phy_read(bcm, 0x0815); - backup[8] = bcm43xx_phy_read(bcm, BCM43xx_PHY_G_CRS); - backup[9] = bcm43xx_phy_read(bcm, 0x0802); - bcm43xx_phy_write(bcm, 0x0814, - (bcm43xx_phy_read(bcm, 0x0814) | 0x0003)); - bcm43xx_phy_write(bcm, 0x0815, - (bcm43xx_phy_read(bcm, 0x0815) & 0xFFFC)); - bcm43xx_phy_write(bcm, BCM43xx_PHY_G_CRS, - (bcm43xx_phy_read(bcm, BCM43xx_PHY_G_CRS) & 0x7FFF)); - bcm43xx_phy_write(bcm, 0x0802, - (bcm43xx_phy_read(bcm, 0x0802) & 0xFFFC)); - bcm43xx_phy_write(bcm, 0x0811, 0x01B3); - bcm43xx_phy_write(bcm, 0x0812, 0x0FB2); - } - bcm43xx_write16(bcm, BCM43xx_MMIO_PHY_RADIO, - (bcm43xx_read16(bcm, BCM43xx_MMIO_PHY_RADIO) | 0x8000)); - } - backup[10] = bcm43xx_phy_read(bcm, 0x0035); - bcm43xx_phy_write(bcm, 0x0035, - (bcm43xx_phy_read(bcm, 0x0035) & 0xFF7F)); - backup[11] = bcm43xx_read16(bcm, 0x03E6); - backup[12] = bcm43xx_read16(bcm, BCM43xx_MMIO_CHANNEL_EXT); - - // Initialization - if (phy->version == 0) { - bcm43xx_write16(bcm, 0x03E6, 0x0122); - } else { - if (phy->version >= 2) - bcm43xx_write16(bcm, 0x03E6, 0x0040); - bcm43xx_write16(bcm, BCM43xx_MMIO_CHANNEL_EXT, - (bcm43xx_read16(bcm, BCM43xx_MMIO_CHANNEL_EXT) | 0x2000)); - } - - ret = bcm43xx_radio_calibrationvalue(bcm); - - if (phy->type == BCM43xx_PHYTYPE_B) - bcm43xx_radio_write16(bcm, 0x0078, 0x0003); - - bcm43xx_phy_write(bcm, 0x0015, 0xBFAF); - bcm43xx_phy_write(bcm, 0x002B, 0x1403); - if (phy->connected) - bcm43xx_phy_write(bcm, 0x0812, 0x00B2); - bcm43xx_phy_write(bcm, 0x0015, 0xBFA0); - bcm43xx_radio_write16(bcm, 0x0051, - (bcm43xx_radio_read16(bcm, 0x0051) | 0x0004)); - bcm43xx_radio_write16(bcm, 0x0052, 0x0000); - bcm43xx_radio_write16(bcm, 0x0043, - bcm43xx_radio_read16(bcm, 0x0043) | 0x0009); - bcm43xx_phy_write(bcm, 0x0058, 0x0000); - - for (i = 0; i < 16; i++) { - bcm43xx_phy_write(bcm, 0x005A, 0x0480); - bcm43xx_phy_write(bcm, 0x0059, 0xC810); - bcm43xx_phy_write(bcm, 0x0058, 0x000D); - if (phy->connected) - bcm43xx_phy_write(bcm, 0x0812, 0x30B2); - bcm43xx_phy_write(bcm, 0x0015, 0xAFB0); - udelay(10); - if (phy->connected) - bcm43xx_phy_write(bcm, 0x0812, 0x30B2); - bcm43xx_phy_write(bcm, 0x0015, 0xEFB0); - udelay(10); - if (phy->connected) - bcm43xx_phy_write(bcm, 0x0812, 0x30B2); - bcm43xx_phy_write(bcm, 0x0015, 0xFFF0); - udelay(10); - tmp1 += bcm43xx_phy_read(bcm, 0x002D); - bcm43xx_phy_write(bcm, 0x0058, 0x0000); - if (phy->connected) - bcm43xx_phy_write(bcm, 0x0812, 0x30B2); - bcm43xx_phy_write(bcm, 0x0015, 0xAFB0); - } - - tmp1++; - tmp1 >>= 9; - udelay(10); - bcm43xx_phy_write(bcm, 0x0058, 0x0000); - - for (i = 0; i < 16; i++) { - bcm43xx_radio_write16(bcm, 0x0078, (flip_4bit(i) << 1) | 0x0020); - backup[13] = bcm43xx_radio_read16(bcm, 0x0078); - udelay(10); - for (j = 0; j < 16; j++) { - bcm43xx_phy_write(bcm, 0x005A, 0x0D80); - bcm43xx_phy_write(bcm, 0x0059, 0xC810); - bcm43xx_phy_write(bcm, 0x0058, 0x000D); - if (phy->connected) - bcm43xx_phy_write(bcm, 0x0812, 0x30B2); - bcm43xx_phy_write(bcm, 0x0015, 0xAFB0); - udelay(10); - if (phy->connected) - bcm43xx_phy_write(bcm, 0x0812, 0x30B2); - bcm43xx_phy_write(bcm, 0x0015, 0xEFB0); - udelay(10); - if (phy->connected) - bcm43xx_phy_write(bcm, 0x0812, 0x30B3); /* 0x30B3 is not a typo */ - bcm43xx_phy_write(bcm, 0x0015, 0xFFF0); - udelay(10); - tmp2 += bcm43xx_phy_read(bcm, 0x002D); - bcm43xx_phy_write(bcm, 0x0058, 0x0000); - if (phy->connected) - bcm43xx_phy_write(bcm, 0x0812, 0x30B2); - bcm43xx_phy_write(bcm, 0x0015, 0xAFB0); - } - tmp2++; - tmp2 >>= 8; - if (tmp1 < tmp2) - break; - } - - /* Restore the registers */ - bcm43xx_phy_write(bcm, 0x0015, backup[1]); - bcm43xx_radio_write16(bcm, 0x0051, backup[14]); - bcm43xx_radio_write16(bcm, 0x0052, backup[15]); - bcm43xx_radio_write16(bcm, 0x0043, backup[0]); - bcm43xx_phy_write(bcm, 0x005A, backup[16]); - bcm43xx_phy_write(bcm, 0x0059, backup[17]); - bcm43xx_phy_write(bcm, 0x0058, backup[18]); - bcm43xx_write16(bcm, 0x03E6, backup[11]); - if (phy->version != 0) - bcm43xx_write16(bcm, BCM43xx_MMIO_CHANNEL_EXT, backup[12]); - bcm43xx_phy_write(bcm, 0x0035, backup[10]); - bcm43xx_radio_selectchannel(bcm, radio->channel, 1); - if (phy->type == BCM43xx_PHYTYPE_B) { - bcm43xx_phy_write(bcm, 0x0030, backup[2]); - bcm43xx_write16(bcm, 0x03EC, backup[3]); - } else { - bcm43xx_write16(bcm, BCM43xx_MMIO_PHY_RADIO, - (bcm43xx_read16(bcm, BCM43xx_MMIO_PHY_RADIO) & 0x7FFF)); - if (phy->connected) { - bcm43xx_phy_write(bcm, 0x0811, backup[4]); - bcm43xx_phy_write(bcm, 0x0812, backup[5]); - bcm43xx_phy_write(bcm, 0x0814, backup[6]); - bcm43xx_phy_write(bcm, 0x0815, backup[7]); - bcm43xx_phy_write(bcm, BCM43xx_PHY_G_CRS, backup[8]); - bcm43xx_phy_write(bcm, 0x0802, backup[9]); - } - } - if (i >= 15) - ret = backup[13]; - - return ret; -} - -void bcm43xx_radio_init2060(struct bcm43xx_private *bcm) -{ - int err; - - bcm43xx_radio_write16(bcm, 0x0004, 0x00C0); - bcm43xx_radio_write16(bcm, 0x0005, 0x0008); - bcm43xx_radio_write16(bcm, 0x0009, 0x0040); - bcm43xx_radio_write16(bcm, 0x0005, 0x00AA); - bcm43xx_radio_write16(bcm, 0x0032, 0x008F); - bcm43xx_radio_write16(bcm, 0x0006, 0x008F); - bcm43xx_radio_write16(bcm, 0x0034, 0x008F); - bcm43xx_radio_write16(bcm, 0x002C, 0x0007); - bcm43xx_radio_write16(bcm, 0x0082, 0x0080); - bcm43xx_radio_write16(bcm, 0x0080, 0x0000); - bcm43xx_radio_write16(bcm, 0x003F, 0x00DA); - bcm43xx_radio_write16(bcm, 0x0005, bcm43xx_radio_read16(bcm, 0x0005) & ~0x0008); - bcm43xx_radio_write16(bcm, 0x0081, bcm43xx_radio_read16(bcm, 0x0081) & ~0x0010); - bcm43xx_radio_write16(bcm, 0x0081, bcm43xx_radio_read16(bcm, 0x0081) & ~0x0020); - bcm43xx_radio_write16(bcm, 0x0081, bcm43xx_radio_read16(bcm, 0x0081) & ~0x0020); - udelay(400); - - bcm43xx_radio_write16(bcm, 0x0081, (bcm43xx_radio_read16(bcm, 0x0081) & ~0x0020) | 0x0010); - udelay(400); - - bcm43xx_radio_write16(bcm, 0x0005, (bcm43xx_radio_read16(bcm, 0x0005) & ~0x0008) | 0x0008); - bcm43xx_radio_write16(bcm, 0x0085, bcm43xx_radio_read16(bcm, 0x0085) & ~0x0010); - bcm43xx_radio_write16(bcm, 0x0005, bcm43xx_radio_read16(bcm, 0x0005) & ~0x0008); - bcm43xx_radio_write16(bcm, 0x0081, bcm43xx_radio_read16(bcm, 0x0081) & ~0x0040); - bcm43xx_radio_write16(bcm, 0x0081, (bcm43xx_radio_read16(bcm, 0x0081) & ~0x0040) | 0x0040); - bcm43xx_radio_write16(bcm, 0x0005, (bcm43xx_radio_read16(bcm, 0x0081) & ~0x0008) | 0x0008); - bcm43xx_phy_write(bcm, 0x0063, 0xDDC6); - bcm43xx_phy_write(bcm, 0x0069, 0x07BE); - bcm43xx_phy_write(bcm, 0x006A, 0x0000); - - err = bcm43xx_radio_selectchannel(bcm, BCM43xx_RADIO_DEFAULT_CHANNEL_A, 0); - assert(err == 0); - udelay(1000); -} - -static inline -u16 freq_r3A_value(u16 frequency) -{ - u16 value; - - if (frequency < 5091) - value = 0x0040; - else if (frequency < 5321) - value = 0x0000; - else if (frequency < 5806) - value = 0x0080; - else - value = 0x0040; - - return value; -} - -void bcm43xx_radio_set_tx_iq(struct bcm43xx_private *bcm) -{ - static const u8 data_high[5] = { 0x00, 0x40, 0x80, 0x90, 0xD0 }; - static const u8 data_low[5] = { 0x00, 0x01, 0x05, 0x06, 0x0A }; - u16 tmp = bcm43xx_radio_read16(bcm, 0x001E); - int i, j; - - for (i = 0; i < 5; i++) { - for (j = 0; j < 5; j++) { - if (tmp == (data_high[i] << 4 | data_low[j])) { - bcm43xx_phy_write(bcm, 0x0069, (i - j) << 8 | 0x00C0); - return; - } - } - } -} - -int bcm43xx_radio_selectchannel(struct bcm43xx_private *bcm, - u8 channel, - int synthetic_pu_workaround) -{ - struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm); - u16 r8, tmp; - u16 freq; - - if ((radio->manufact == 0x17F) && - (radio->version == 0x2060) && - (radio->revision == 1)) { - if (channel > 200) - return -EINVAL; - freq = channel2freq_a(channel); - - r8 = bcm43xx_radio_read16(bcm, 0x0008); - bcm43xx_write16(bcm, 0x03F0, freq); - bcm43xx_radio_write16(bcm, 0x0008, r8); - - TODO();//TODO: write max channel TX power? to Radio 0x2D - tmp = bcm43xx_radio_read16(bcm, 0x002E); - tmp &= 0x0080; - TODO();//TODO: OR tmp with the Power out estimation for this channel? - bcm43xx_radio_write16(bcm, 0x002E, tmp); - - if (freq >= 4920 && freq <= 5500) { - /* - * r8 = (((freq * 15 * 0xE1FC780F) >> 32) / 29) & 0x0F; - * = (freq * 0.025862069 - */ - r8 = 3 * freq / 116; /* is equal to r8 = freq * 0.025862 */ - } - bcm43xx_radio_write16(bcm, 0x0007, (r8 << 4) | r8); - bcm43xx_radio_write16(bcm, 0x0020, (r8 << 4) | r8); - bcm43xx_radio_write16(bcm, 0x0021, (r8 << 4) | r8); - bcm43xx_radio_write16(bcm, 0x0022, - (bcm43xx_radio_read16(bcm, 0x0022) - & 0x000F) | (r8 << 4)); - bcm43xx_radio_write16(bcm, 0x002A, (r8 << 4)); - bcm43xx_radio_write16(bcm, 0x002B, (r8 << 4)); - bcm43xx_radio_write16(bcm, 0x0008, - (bcm43xx_radio_read16(bcm, 0x0008) - & 0x00F0) | (r8 << 4)); - bcm43xx_radio_write16(bcm, 0x0029, - (bcm43xx_radio_read16(bcm, 0x0029) - & 0xFF0F) | 0x00B0); - bcm43xx_radio_write16(bcm, 0x0035, 0x00AA); - bcm43xx_radio_write16(bcm, 0x0036, 0x0085); - bcm43xx_radio_write16(bcm, 0x003A, - (bcm43xx_radio_read16(bcm, 0x003A) - & 0xFF20) | freq_r3A_value(freq)); - bcm43xx_radio_write16(bcm, 0x003D, - bcm43xx_radio_read16(bcm, 0x003D) & 0x00FF); - bcm43xx_radio_write16(bcm, 0x0081, - (bcm43xx_radio_read16(bcm, 0x0081) - & 0xFF7F) | 0x0080); - bcm43xx_radio_write16(bcm, 0x0035, - bcm43xx_radio_read16(bcm, 0x0035) & 0xFFEF); - bcm43xx_radio_write16(bcm, 0x0035, - (bcm43xx_radio_read16(bcm, 0x0035) - & 0xFFEF) | 0x0010); - bcm43xx_radio_set_tx_iq(bcm); - TODO(); //TODO: TSSI2dbm workaround - bcm43xx_phy_xmitpower(bcm);//FIXME correct? - } else { - if ((channel < 1) || (channel > 14)) - return -EINVAL; - - if (synthetic_pu_workaround) - bcm43xx_synth_pu_workaround(bcm, channel); - - bcm43xx_write16(bcm, BCM43xx_MMIO_CHANNEL, - channel2freq_bg(channel)); - - if (channel == 14) { - if (bcm->sprom.locale == BCM43xx_LOCALE_JAPAN) { - bcm43xx_shm_write32(bcm, BCM43xx_SHM_SHARED, - BCM43xx_UCODEFLAGS_OFFSET, - bcm43xx_shm_read32(bcm, BCM43xx_SHM_SHARED, - BCM43xx_UCODEFLAGS_OFFSET) - & ~(1 << 7)); - } else { - bcm43xx_shm_write32(bcm, BCM43xx_SHM_SHARED, - BCM43xx_UCODEFLAGS_OFFSET, - bcm43xx_shm_read32(bcm, BCM43xx_SHM_SHARED, - BCM43xx_UCODEFLAGS_OFFSET) - | (1 << 7)); - } - bcm43xx_write16(bcm, BCM43xx_MMIO_CHANNEL_EXT, - bcm43xx_read16(bcm, BCM43xx_MMIO_CHANNEL_EXT) - | (1 << 11)); - } else { - bcm43xx_write16(bcm, BCM43xx_MMIO_CHANNEL_EXT, - bcm43xx_read16(bcm, BCM43xx_MMIO_CHANNEL_EXT) - & 0xF7BF); - } - } - - radio->channel = channel; - //XXX: Using the longer of 2 timeouts (8000 vs 2000 usecs). Specs states - // that 2000 usecs might suffice. - udelay(8000); - - return 0; -} - -void bcm43xx_radio_set_txantenna(struct bcm43xx_private *bcm, u32 val) -{ - u16 tmp; - - val <<= 8; - tmp = bcm43xx_shm_read16(bcm, BCM43xx_SHM_SHARED, 0x0022) & 0xFCFF; - bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, 0x0022, tmp | val); - tmp = bcm43xx_shm_read16(bcm, BCM43xx_SHM_SHARED, 0x03A8) & 0xFCFF; - bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, 0x03A8, tmp | val); - tmp = bcm43xx_shm_read16(bcm, BCM43xx_SHM_SHARED, 0x0054) & 0xFCFF; - bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, 0x0054, tmp | val); -} - -/* http://bcm-specs.sipsolutions.net/TX_Gain_Base_Band */ -static u16 bcm43xx_get_txgain_base_band(u16 txpower) -{ - u16 ret; - - assert(txpower <= 63); - - if (txpower >= 54) - ret = 2; - else if (txpower >= 49) - ret = 4; - else if (txpower >= 44) - ret = 5; - else - ret = 6; - - return ret; -} - -/* http://bcm-specs.sipsolutions.net/TX_Gain_Radio_Frequency_Power_Amplifier */ -static u16 bcm43xx_get_txgain_freq_power_amp(u16 txpower) -{ - u16 ret; - - assert(txpower <= 63); - - if (txpower >= 32) - ret = 0; - else if (txpower >= 25) - ret = 1; - else if (txpower >= 20) - ret = 2; - else if (txpower >= 12) - ret = 3; - else - ret = 4; - - return ret; -} - -/* http://bcm-specs.sipsolutions.net/TX_Gain_Digital_Analog_Converter */ -static u16 bcm43xx_get_txgain_dac(u16 txpower) -{ - u16 ret; - - assert(txpower <= 63); - - if (txpower >= 54) - ret = txpower - 53; - else if (txpower >= 49) - ret = txpower - 42; - else if (txpower >= 44) - ret = txpower - 37; - else if (txpower >= 32) - ret = txpower - 32; - else if (txpower >= 25) - ret = txpower - 20; - else if (txpower >= 20) - ret = txpower - 13; - else if (txpower >= 12) - ret = txpower - 8; - else - ret = txpower; - - return ret; -} - -void bcm43xx_radio_set_txpower_a(struct bcm43xx_private *bcm, u16 txpower) -{ - struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm); - u16 pamp, base, dac, ilt; - - txpower = limit_value(txpower, 0, 63); - - pamp = bcm43xx_get_txgain_freq_power_amp(txpower); - pamp <<= 5; - pamp &= 0x00E0; - bcm43xx_phy_write(bcm, 0x0019, pamp); - - base = bcm43xx_get_txgain_base_band(txpower); - base &= 0x000F; - bcm43xx_phy_write(bcm, 0x0017, base | 0x0020); - - ilt = bcm43xx_ilt_read(bcm, 0x3001); - ilt &= 0x0007; - - dac = bcm43xx_get_txgain_dac(txpower); - dac <<= 3; - dac |= ilt; - - bcm43xx_ilt_write(bcm, 0x3001, dac); - - radio->txpwr_offset = txpower; - - TODO(); - //TODO: FuncPlaceholder (Adjust BB loft cancel) -} - -void bcm43xx_radio_set_txpower_bg(struct bcm43xx_private *bcm, - u16 baseband_attenuation, u16 radio_attenuation, - u16 txpower) -{ - struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm); - struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm); - - if (baseband_attenuation == 0xFFFF) - baseband_attenuation = radio->baseband_atten; - if (radio_attenuation == 0xFFFF) - radio_attenuation = radio->radio_atten; - if (txpower == 0xFFFF) - txpower = radio->txctl1; - radio->baseband_atten = baseband_attenuation; - radio->radio_atten = radio_attenuation; - radio->txctl1 = txpower; - - assert(/*baseband_attenuation >= 0 &&*/ baseband_attenuation <= 11); - if (radio->revision < 6) - assert(/*radio_attenuation >= 0 &&*/ radio_attenuation <= 9); - else - assert(/* radio_attenuation >= 0 &&*/ radio_attenuation <= 31); - assert(/*txpower >= 0 &&*/ txpower <= 7); - - bcm43xx_phy_set_baseband_attenuation(bcm, baseband_attenuation); - bcm43xx_radio_write16(bcm, 0x0043, radio_attenuation); - bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, 0x0064, radio_attenuation); - if (radio->version == 0x2050) { - bcm43xx_radio_write16(bcm, 0x0052, - (bcm43xx_radio_read16(bcm, 0x0052) & ~0x0070) - | ((txpower << 4) & 0x0070)); - } - //FIXME: The spec is very weird and unclear here. - if (phy->type == BCM43xx_PHYTYPE_G) - bcm43xx_phy_lo_adjust(bcm, 0); -} - -u16 bcm43xx_default_baseband_attenuation(struct bcm43xx_private *bcm) -{ - struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm); - - if (radio->version == 0x2050 && radio->revision < 6) - return 0; - return 2; -} - -u16 bcm43xx_default_radio_attenuation(struct bcm43xx_private *bcm) -{ - struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm); - struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm); - u16 att = 0xFFFF; - - if (phy->type == BCM43xx_PHYTYPE_A) - return 0x60; - - switch (radio->version) { - case 0x2053: - switch (radio->revision) { - case 1: - att = 6; - break; - } - break; - case 0x2050: - switch (radio->revision) { - case 0: - att = 5; - break; - case 1: - if (phy->type == BCM43xx_PHYTYPE_G) { - if (bcm->board_vendor == PCI_VENDOR_ID_BROADCOM && - bcm->board_type == 0x421 && - bcm->board_revision >= 30) - att = 3; - else if (bcm->board_vendor == PCI_VENDOR_ID_BROADCOM && - bcm->board_type == 0x416) - att = 3; - else - att = 1; - } else { - if (bcm->board_vendor == PCI_VENDOR_ID_BROADCOM && - bcm->board_type == 0x421 && - bcm->board_revision >= 30) - att = 7; - else - att = 6; - } - break; - case 2: - if (phy->type == BCM43xx_PHYTYPE_G) { - if (bcm->board_vendor == PCI_VENDOR_ID_BROADCOM && - bcm->board_type == 0x421 && - bcm->board_revision >= 30) - att = 3; - else if (bcm->board_vendor == PCI_VENDOR_ID_BROADCOM && - bcm->board_type == 0x416) - att = 5; - else if (bcm->chip_id == 0x4320) - att = 4; - else - att = 3; - } else - att = 6; - break; - case 3: - att = 5; - break; - case 4: - case 5: - att = 1; - break; - case 6: - case 7: - att = 5; - break; - case 8: - att = 0x1A; - break; - case 9: - default: - att = 5; - } - } - if (bcm->board_vendor == PCI_VENDOR_ID_BROADCOM && - bcm->board_type == 0x421) { - if (bcm->board_revision < 0x43) - att = 2; - else if (bcm->board_revision < 0x51) - att = 3; - } - if (att == 0xFFFF) - att = 5; - - return att; -} - -u16 bcm43xx_default_txctl1(struct bcm43xx_private *bcm) -{ - struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm); - - if (radio->version != 0x2050) - return 0; - if (radio->revision == 1) - return 3; - if (radio->revision < 6) - return 2; - if (radio->revision == 8) - return 1; - return 0; -} - -void bcm43xx_radio_turn_on(struct bcm43xx_private *bcm) -{ - struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm); - struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm); - int err; - - if (radio->enabled) - return; - - switch (phy->type) { - case BCM43xx_PHYTYPE_A: - bcm43xx_radio_write16(bcm, 0x0004, 0x00C0); - bcm43xx_radio_write16(bcm, 0x0005, 0x0008); - bcm43xx_phy_write(bcm, 0x0010, bcm43xx_phy_read(bcm, 0x0010) & 0xFFF7); - bcm43xx_phy_write(bcm, 0x0011, bcm43xx_phy_read(bcm, 0x0011) & 0xFFF7); - bcm43xx_radio_init2060(bcm); - break; - case BCM43xx_PHYTYPE_B: - case BCM43xx_PHYTYPE_G: - bcm43xx_phy_write(bcm, 0x0015, 0x8000); - bcm43xx_phy_write(bcm, 0x0015, 0xCC00); - bcm43xx_phy_write(bcm, 0x0015, (phy->connected ? 0x00C0 : 0x0000)); - err = bcm43xx_radio_selectchannel(bcm, BCM43xx_RADIO_DEFAULT_CHANNEL_BG, 1); - assert(err == 0); - break; - default: - assert(0); - } - radio->enabled = 1; - dprintk(KERN_INFO PFX "Radio turned on\n"); -} - -void bcm43xx_radio_turn_off(struct bcm43xx_private *bcm) -{ - struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm); - struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm); - - if (phy->type == BCM43xx_PHYTYPE_A) { - bcm43xx_radio_write16(bcm, 0x0004, 0x00FF); - bcm43xx_radio_write16(bcm, 0x0005, 0x00FB); - bcm43xx_phy_write(bcm, 0x0010, bcm43xx_phy_read(bcm, 0x0010) | 0x0008); - bcm43xx_phy_write(bcm, 0x0011, bcm43xx_phy_read(bcm, 0x0011) | 0x0008); - } - if (phy->type == BCM43xx_PHYTYPE_G && bcm->current_core->rev >= 5) { - bcm43xx_phy_write(bcm, 0x0811, bcm43xx_phy_read(bcm, 0x0811) | 0x008C); - bcm43xx_phy_write(bcm, 0x0812, bcm43xx_phy_read(bcm, 0x0812) & 0xFF73); - } else - bcm43xx_phy_write(bcm, 0x0015, 0xAA00); - radio->enabled = 0; - dprintk(KERN_INFO PFX "Radio turned off\n"); -} - -void bcm43xx_radio_clear_tssi(struct bcm43xx_private *bcm) -{ - struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm); - - switch (phy->type) { - case BCM43xx_PHYTYPE_A: - bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, 0x0068, 0x7F7F); - bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, 0x006a, 0x7F7F); - break; - case BCM43xx_PHYTYPE_B: - case BCM43xx_PHYTYPE_G: - bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, 0x0058, 0x7F7F); - bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, 0x005a, 0x7F7F); - bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, 0x0070, 0x7F7F); - bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, 0x0072, 0x7F7F); - break; - } -} diff --git a/trunk/drivers/net/wireless/bcm43xx/bcm43xx_radio.h b/trunk/drivers/net/wireless/bcm43xx/bcm43xx_radio.h deleted file mode 100644 index 9ed18039fa3e..000000000000 --- a/trunk/drivers/net/wireless/bcm43xx/bcm43xx_radio.h +++ /dev/null @@ -1,99 +0,0 @@ -/* - - Broadcom BCM43xx wireless driver - - Copyright (c) 2005 Martin Langer , - Stefano Brivio - Michael Buesch - Danny van Dyk - Andreas Jaggi - - Some parts of the code in this file are derived from the ipw2200 - driver Copyright(c) 2003 - 2004 Intel Corporation. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; see the file COPYING. If not, write to - the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor, - Boston, MA 02110-1301, USA. - -*/ - -#ifndef BCM43xx_RADIO_H_ -#define BCM43xx_RADIO_H_ - -#include "bcm43xx.h" - - -#define BCM43xx_RADIO_DEFAULT_CHANNEL_A 36 -#define BCM43xx_RADIO_DEFAULT_CHANNEL_BG 6 - -/* Force antenna 0. */ -#define BCM43xx_RADIO_TXANTENNA_0 0 -/* Force antenna 1. */ -#define BCM43xx_RADIO_TXANTENNA_1 1 -/* Use the RX antenna, that was selected for the most recently - * received good PLCP header. - */ -#define BCM43xx_RADIO_TXANTENNA_LASTPLCP 3 -#define BCM43xx_RADIO_TXANTENNA_DEFAULT BCM43xx_RADIO_TXANTENNA_LASTPLCP - -#define BCM43xx_RADIO_INTERFMODE_NONE 0 -#define BCM43xx_RADIO_INTERFMODE_NONWLAN 1 -#define BCM43xx_RADIO_INTERFMODE_MANUALWLAN 2 -#define BCM43xx_RADIO_INTERFMODE_AUTOWLAN 3 - - -void bcm43xx_radio_lock(struct bcm43xx_private *bcm); -void bcm43xx_radio_unlock(struct bcm43xx_private *bcm); - -u16 bcm43xx_radio_read16(struct bcm43xx_private *bcm, u16 offset); -void bcm43xx_radio_write16(struct bcm43xx_private *bcm, u16 offset, u16 val); - -u16 bcm43xx_radio_init2050(struct bcm43xx_private *bcm); -void bcm43xx_radio_init2060(struct bcm43xx_private *bcm); - -void bcm43xx_radio_turn_on(struct bcm43xx_private *bcm); -void bcm43xx_radio_turn_off(struct bcm43xx_private *bcm); - -int bcm43xx_radio_selectchannel(struct bcm43xx_private *bcm, u8 channel, - int synthetic_pu_workaround); - -void bcm43xx_radio_set_txpower_a(struct bcm43xx_private *bcm, u16 txpower); -void bcm43xx_radio_set_txpower_bg(struct bcm43xx_private *bcm, - u16 baseband_attenuation, u16 attenuation, - u16 txpower); - -u16 bcm43xx_default_baseband_attenuation(struct bcm43xx_private *bcm); -u16 bcm43xx_default_radio_attenuation(struct bcm43xx_private *bcm); -u16 bcm43xx_default_txctl1(struct bcm43xx_private *bcm); - -void bcm43xx_radio_set_txantenna(struct bcm43xx_private *bcm, u32 val); - -void bcm43xx_radio_clear_tssi(struct bcm43xx_private *bcm); - -u8 bcm43xx_radio_aci_detect(struct bcm43xx_private *bcm, u8 channel); -u8 bcm43xx_radio_aci_scan(struct bcm43xx_private *bcm); - -int bcm43xx_radio_set_interference_mitigation(struct bcm43xx_private *bcm, int mode); - -void bcm43xx_calc_nrssi_slope(struct bcm43xx_private *bcm); -void bcm43xx_calc_nrssi_threshold(struct bcm43xx_private *bcm); -s16 bcm43xx_nrssi_hw_read(struct bcm43xx_private *bcm, u16 offset); -void bcm43xx_nrssi_hw_write(struct bcm43xx_private *bcm, u16 offset, s16 val); -void bcm43xx_nrssi_hw_update(struct bcm43xx_private *bcm, u16 val); -void bcm43xx_nrssi_mem_update(struct bcm43xx_private *bcm); - -void bcm43xx_radio_set_tx_iq(struct bcm43xx_private *bcm); -u16 bcm43xx_radio_calibrationvalue(struct bcm43xx_private *bcm); - -#endif /* BCM43xx_RADIO_H_ */ diff --git a/trunk/drivers/net/wireless/bcm43xx/bcm43xx_sysfs.c b/trunk/drivers/net/wireless/bcm43xx/bcm43xx_sysfs.c deleted file mode 100644 index c44d890b949b..000000000000 --- a/trunk/drivers/net/wireless/bcm43xx/bcm43xx_sysfs.c +++ /dev/null @@ -1,322 +0,0 @@ -/* - - Broadcom BCM43xx wireless driver - - SYSFS support routines - - Copyright (c) 2006 Michael Buesch - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; see the file COPYING. If not, write to - the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor, - Boston, MA 02110-1301, USA. - -*/ - -#include "bcm43xx_sysfs.h" -#include "bcm43xx.h" -#include "bcm43xx_main.h" -#include "bcm43xx_radio.h" - -#include - - -#define GENERIC_FILESIZE 64 - - -static int get_integer(const char *buf, size_t count) -{ - char tmp[10 + 1] = { 0 }; - int ret = -EINVAL; - - if (count == 0) - goto out; - count = min(count, (size_t)10); - memcpy(tmp, buf, count); - ret = simple_strtol(tmp, NULL, 10); -out: - return ret; -} - -static int get_boolean(const char *buf, size_t count) -{ - if (count != 0) { - if (buf[0] == '1') - return 1; - if (buf[0] == '0') - return 0; - if (count >= 4 && memcmp(buf, "true", 4) == 0) - return 1; - if (count >= 5 && memcmp(buf, "false", 5) == 0) - return 0; - if (count >= 3 && memcmp(buf, "yes", 3) == 0) - return 1; - if (count >= 2 && memcmp(buf, "no", 2) == 0) - return 0; - if (count >= 2 && memcmp(buf, "on", 2) == 0) - return 1; - if (count >= 3 && memcmp(buf, "off", 3) == 0) - return 0; - } - return -EINVAL; -} - -static ssize_t bcm43xx_attr_sprom_show(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct bcm43xx_private *bcm = devattr_to_bcm(attr, attr_sprom); - u16 *sprom; - unsigned long flags; - int i, err; - - if (!capable(CAP_NET_ADMIN)) - return -EPERM; - - assert(BCM43xx_SPROM_SIZE * sizeof(u16) <= PAGE_SIZE); - sprom = kmalloc(BCM43xx_SPROM_SIZE * sizeof(*sprom), - GFP_KERNEL); - if (!sprom) - return -ENOMEM; - bcm43xx_lock_mmio(bcm, flags); - assert(bcm->initialized); - err = bcm43xx_sprom_read(bcm, sprom); - if (!err) { - for (i = 0; i < BCM43xx_SPROM_SIZE; i++) { - buf[i * 2] = sprom[i] & 0x00FF; - buf[i * 2 + 1] = (sprom[i] & 0xFF00) >> 8; - } - } - bcm43xx_unlock_mmio(bcm, flags); - kfree(sprom); - - return err ? err : BCM43xx_SPROM_SIZE * sizeof(u16); -} - -static ssize_t bcm43xx_attr_sprom_store(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) -{ - struct bcm43xx_private *bcm = devattr_to_bcm(attr, attr_sprom); - u16 *sprom; - unsigned long flags; - int i, err; - - if (!capable(CAP_NET_ADMIN)) - return -EPERM; - - if (count != BCM43xx_SPROM_SIZE * sizeof(u16)) - return -EINVAL; - sprom = kmalloc(BCM43xx_SPROM_SIZE * sizeof(*sprom), - GFP_KERNEL); - if (!sprom) - return -ENOMEM; - for (i = 0; i < BCM43xx_SPROM_SIZE; i++) { - sprom[i] = buf[i * 2] & 0xFF; - sprom[i] |= ((u16)(buf[i * 2 + 1] & 0xFF)) << 8; - } - bcm43xx_lock_mmio(bcm, flags); - assert(bcm->initialized); - err = bcm43xx_sprom_write(bcm, sprom); - bcm43xx_unlock_mmio(bcm, flags); - kfree(sprom); - - return err ? err : count; - -} - -static ssize_t bcm43xx_attr_interfmode_show(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct bcm43xx_private *bcm = devattr_to_bcm(attr, attr_interfmode); - unsigned long flags; - int err; - ssize_t count = 0; - - if (!capable(CAP_NET_ADMIN)) - return -EPERM; - - bcm43xx_lock(bcm, flags); - assert(bcm->initialized); - - switch (bcm43xx_current_radio(bcm)->interfmode) { - case BCM43xx_RADIO_INTERFMODE_NONE: - count = snprintf(buf, PAGE_SIZE, "0 (No Interference Mitigation)\n"); - break; - case BCM43xx_RADIO_INTERFMODE_NONWLAN: - count = snprintf(buf, PAGE_SIZE, "1 (Non-WLAN Interference Mitigation)\n"); - break; - case BCM43xx_RADIO_INTERFMODE_MANUALWLAN: - count = snprintf(buf, PAGE_SIZE, "2 (WLAN Interference Mitigation)\n"); - break; - default: - assert(0); - } - err = 0; - - bcm43xx_unlock(bcm, flags); - - return err ? err : count; - -} - -static ssize_t bcm43xx_attr_interfmode_store(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) -{ - struct bcm43xx_private *bcm = devattr_to_bcm(attr, attr_interfmode); - unsigned long flags; - int err; - int mode; - - if (!capable(CAP_NET_ADMIN)) - return -EPERM; - - mode = get_integer(buf, count); - switch (mode) { - case 0: - mode = BCM43xx_RADIO_INTERFMODE_NONE; - break; - case 1: - mode = BCM43xx_RADIO_INTERFMODE_NONWLAN; - break; - case 2: - mode = BCM43xx_RADIO_INTERFMODE_MANUALWLAN; - break; - case 3: - mode = BCM43xx_RADIO_INTERFMODE_AUTOWLAN; - break; - default: - return -EINVAL; - } - - bcm43xx_lock_mmio(bcm, flags); - assert(bcm->initialized); - - err = bcm43xx_radio_set_interference_mitigation(bcm, mode); - if (err) { - printk(KERN_ERR PFX "Interference Mitigation not " - "supported by device\n"); - } - - bcm43xx_unlock_mmio(bcm, flags); - - return err ? err : count; -} - -static ssize_t bcm43xx_attr_preamble_show(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct bcm43xx_private *bcm = devattr_to_bcm(attr, attr_preamble); - unsigned long flags; - int err; - ssize_t count; - - if (!capable(CAP_NET_ADMIN)) - return -EPERM; - - bcm43xx_lock(bcm, flags); - assert(bcm->initialized); - - if (bcm->short_preamble) - count = snprintf(buf, PAGE_SIZE, "1 (Short Preamble enabled)\n"); - else - count = snprintf(buf, PAGE_SIZE, "0 (Short Preamble disabled)\n"); - - err = 0; - bcm43xx_unlock(bcm, flags); - - return err ? err : count; -} - -static ssize_t bcm43xx_attr_preamble_store(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) -{ - struct bcm43xx_private *bcm = devattr_to_bcm(attr, attr_preamble); - unsigned long flags; - int err; - int value; - - if (!capable(CAP_NET_ADMIN)) - return -EPERM; - - value = get_boolean(buf, count); - if (value < 0) - return value; - bcm43xx_lock(bcm, flags); - assert(bcm->initialized); - - bcm->short_preamble = !!value; - - err = 0; - bcm43xx_unlock(bcm, flags); - - return err ? err : count; -} - -int bcm43xx_sysfs_register(struct bcm43xx_private *bcm) -{ - struct device *dev = &bcm->pci_dev->dev; - struct bcm43xx_sysfs *sysfs = &bcm->sysfs; - int err; - - assert(bcm->initialized); - - sysfs->attr_sprom.attr.name = "sprom"; - sysfs->attr_sprom.attr.owner = THIS_MODULE; - sysfs->attr_sprom.attr.mode = 0600; - sysfs->attr_sprom.show = bcm43xx_attr_sprom_show; - sysfs->attr_sprom.store = bcm43xx_attr_sprom_store; - err = device_create_file(dev, &sysfs->attr_sprom); - if (err) - goto out; - - sysfs->attr_interfmode.attr.name = "interference"; - sysfs->attr_interfmode.attr.owner = THIS_MODULE; - sysfs->attr_interfmode.attr.mode = 0600; - sysfs->attr_interfmode.show = bcm43xx_attr_interfmode_show; - sysfs->attr_interfmode.store = bcm43xx_attr_interfmode_store; - err = device_create_file(dev, &sysfs->attr_interfmode); - if (err) - goto err_remove_sprom; - - sysfs->attr_preamble.attr.name = "shortpreamble"; - sysfs->attr_preamble.attr.owner = THIS_MODULE; - sysfs->attr_preamble.attr.mode = 0600; - sysfs->attr_preamble.show = bcm43xx_attr_preamble_show; - sysfs->attr_preamble.store = bcm43xx_attr_preamble_store; - err = device_create_file(dev, &sysfs->attr_preamble); - if (err) - goto err_remove_interfmode; - -out: - return err; -err_remove_interfmode: - device_remove_file(dev, &sysfs->attr_interfmode); -err_remove_sprom: - device_remove_file(dev, &sysfs->attr_sprom); - goto out; -} - -void bcm43xx_sysfs_unregister(struct bcm43xx_private *bcm) -{ - struct device *dev = &bcm->pci_dev->dev; - struct bcm43xx_sysfs *sysfs = &bcm->sysfs; - - device_remove_file(dev, &sysfs->attr_preamble); - device_remove_file(dev, &sysfs->attr_interfmode); - device_remove_file(dev, &sysfs->attr_sprom); -} diff --git a/trunk/drivers/net/wireless/bcm43xx/bcm43xx_sysfs.h b/trunk/drivers/net/wireless/bcm43xx/bcm43xx_sysfs.h deleted file mode 100644 index 57f14514e3e0..000000000000 --- a/trunk/drivers/net/wireless/bcm43xx/bcm43xx_sysfs.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef BCM43xx_SYSFS_H_ -#define BCM43xx_SYSFS_H_ - -#include - - -struct bcm43xx_sysfs { - struct device_attribute attr_sprom; - struct device_attribute attr_interfmode; - struct device_attribute attr_preamble; -}; - -#define devattr_to_bcm(attr, attr_name) ({ \ - struct bcm43xx_sysfs *__s; struct bcm43xx_private *__p; \ - __s = container_of((attr), struct bcm43xx_sysfs, attr_name); \ - __p = container_of(__s, struct bcm43xx_private, sysfs); \ - __p; \ - }) - -struct bcm43xx_private; - -int bcm43xx_sysfs_register(struct bcm43xx_private *bcm); -void bcm43xx_sysfs_unregister(struct bcm43xx_private *bcm); - -#endif /* BCM43xx_SYSFS_H_ */ diff --git a/trunk/drivers/net/wireless/bcm43xx/bcm43xx_wx.c b/trunk/drivers/net/wireless/bcm43xx/bcm43xx_wx.c deleted file mode 100644 index 3daee828ef4b..000000000000 --- a/trunk/drivers/net/wireless/bcm43xx/bcm43xx_wx.c +++ /dev/null @@ -1,1002 +0,0 @@ -/* - - Broadcom BCM43xx wireless driver - - Copyright (c) 2005 Martin Langer , - Stefano Brivio - Michael Buesch - Danny van Dyk - Andreas Jaggi - - Some parts of the code in this file are derived from the ipw2200 - driver Copyright(c) 2003 - 2004 Intel Corporation. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; see the file COPYING. If not, write to - the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor, - Boston, MA 02110-1301, USA. - -*/ - -#include -#include -#include -#include -#include -#include /* for capable() */ -#include - -#include "bcm43xx.h" -#include "bcm43xx_wx.h" -#include "bcm43xx_main.h" -#include "bcm43xx_radio.h" -#include "bcm43xx_phy.h" - - -/* The WIRELESS_EXT version, which is implemented by this driver. */ -#define BCM43xx_WX_VERSION 18 - -#define MAX_WX_STRING 80 - - -static int bcm43xx_wx_get_name(struct net_device *net_dev, - struct iw_request_info *info, - union iwreq_data *data, - char *extra) -{ - struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); - unsigned long flags; - int i; - struct bcm43xx_phyinfo *phy; - char suffix[7] = { 0 }; - int have_a = 0, have_b = 0, have_g = 0; - - bcm43xx_lock(bcm, flags); - for (i = 0; i < bcm->nr_80211_available; i++) { - phy = &(bcm->core_80211_ext[i].phy); - switch (phy->type) { - case BCM43xx_PHYTYPE_A: - have_a = 1; - break; - case BCM43xx_PHYTYPE_G: - have_g = 1; - case BCM43xx_PHYTYPE_B: - have_b = 1; - break; - default: - assert(0); - } - } - bcm43xx_unlock(bcm, flags); - - i = 0; - if (have_a) { - suffix[i++] = 'a'; - suffix[i++] = '/'; - } - if (have_b) { - suffix[i++] = 'b'; - suffix[i++] = '/'; - } - if (have_g) { - suffix[i++] = 'g'; - suffix[i++] = '/'; - } - if (i != 0) - suffix[i - 1] = '\0'; - - snprintf(data->name, IFNAMSIZ, "IEEE 802.11%s", suffix); - - return 0; -} - -static int bcm43xx_wx_set_channelfreq(struct net_device *net_dev, - struct iw_request_info *info, - union iwreq_data *data, - char *extra) -{ - struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); - unsigned long flags; - u8 channel; - int freq; - int err = -EINVAL; - - bcm43xx_lock_mmio(bcm, flags); - if ((data->freq.m >= 0) && (data->freq.m <= 1000)) { - channel = data->freq.m; - freq = bcm43xx_channel_to_freq(bcm, channel); - } else { - channel = bcm43xx_freq_to_channel(bcm, data->freq.m); - freq = data->freq.m; - } - if (!bcm43xx_is_valid_channel(bcm, channel)) - goto out_unlock; - if (bcm->initialized) { - //ieee80211softmac_disassoc(softmac, $REASON); - bcm43xx_mac_suspend(bcm); - err = bcm43xx_radio_selectchannel(bcm, channel, 0); - bcm43xx_mac_enable(bcm); - } else { - bcm43xx_current_radio(bcm)->initial_channel = channel; - err = 0; - } -out_unlock: - bcm43xx_unlock_mmio(bcm, flags); - - return err; -} - -static int bcm43xx_wx_get_channelfreq(struct net_device *net_dev, - struct iw_request_info *info, - union iwreq_data *data, - char *extra) -{ - struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); - struct bcm43xx_radioinfo *radio; - unsigned long flags; - int err = -ENODEV; - u16 channel; - - bcm43xx_lock(bcm, flags); - radio = bcm43xx_current_radio(bcm); - channel = radio->channel; - if (channel == 0xFF) { - assert(!bcm->initialized); - channel = radio->initial_channel; - if (channel == 0xFF) - goto out_unlock; - } - assert(channel > 0 && channel <= 1000); - data->freq.e = 1; - data->freq.m = bcm43xx_channel_to_freq(bcm, channel) * 100000; - data->freq.flags = 1; - - err = 0; -out_unlock: - bcm43xx_unlock(bcm, flags); - - return err; -} - -static int bcm43xx_wx_set_mode(struct net_device *net_dev, - struct iw_request_info *info, - union iwreq_data *data, - char *extra) -{ - struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); - unsigned long flags; - int mode; - - mode = data->mode; - if (mode == IW_MODE_AUTO) - mode = BCM43xx_INITIAL_IWMODE; - - bcm43xx_lock_mmio(bcm, flags); - if (bcm->ieee->iw_mode != mode) - bcm43xx_set_iwmode(bcm, mode); - bcm43xx_unlock_mmio(bcm, flags); - - return 0; -} - -static int bcm43xx_wx_get_mode(struct net_device *net_dev, - struct iw_request_info *info, - union iwreq_data *data, - char *extra) -{ - struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); - unsigned long flags; - - bcm43xx_lock(bcm, flags); - data->mode = bcm->ieee->iw_mode; - bcm43xx_unlock(bcm, flags); - - return 0; -} - -static int bcm43xx_wx_get_rangeparams(struct net_device *net_dev, - struct iw_request_info *info, - union iwreq_data *data, - char *extra) -{ - struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); - struct iw_range *range = (struct iw_range *)extra; - const struct ieee80211_geo *geo; - unsigned long flags; - int i, j; - struct bcm43xx_phyinfo *phy; - - data->data.length = sizeof(*range); - memset(range, 0, sizeof(*range)); - - //TODO: What about 802.11b? - /* 54Mb/s == ~27Mb/s payload throughput (802.11g) */ - range->throughput = 27 * 1000 * 1000; - - range->max_qual.qual = 100; - /* TODO: Real max RSSI */ - range->max_qual.level = 3; - range->max_qual.noise = 100; - range->max_qual.updated = 7; - - range->avg_qual.qual = 70; - range->avg_qual.level = 2; - range->avg_qual.noise = 40; - range->avg_qual.updated = 7; - - range->min_rts = BCM43xx_MIN_RTS_THRESHOLD; - range->max_rts = BCM43xx_MAX_RTS_THRESHOLD; - range->min_frag = MIN_FRAG_THRESHOLD; - range->max_frag = MAX_FRAG_THRESHOLD; - - range->encoding_size[0] = 5; - range->encoding_size[1] = 13; - range->num_encoding_sizes = 2; - range->max_encoding_tokens = WEP_KEYS; - - range->we_version_compiled = WIRELESS_EXT; - range->we_version_source = BCM43xx_WX_VERSION; - - range->enc_capa = IW_ENC_CAPA_WPA | - IW_ENC_CAPA_WPA2 | - IW_ENC_CAPA_CIPHER_TKIP | - IW_ENC_CAPA_CIPHER_CCMP; - - bcm43xx_lock(bcm, flags); - phy = bcm43xx_current_phy(bcm); - - range->num_bitrates = 0; - i = 0; - if (phy->type == BCM43xx_PHYTYPE_A || - phy->type == BCM43xx_PHYTYPE_G) { - range->num_bitrates = 8; - range->bitrate[i++] = IEEE80211_OFDM_RATE_6MB; - range->bitrate[i++] = IEEE80211_OFDM_RATE_9MB; - range->bitrate[i++] = IEEE80211_OFDM_RATE_12MB; - range->bitrate[i++] = IEEE80211_OFDM_RATE_18MB; - range->bitrate[i++] = IEEE80211_OFDM_RATE_24MB; - range->bitrate[i++] = IEEE80211_OFDM_RATE_36MB; - range->bitrate[i++] = IEEE80211_OFDM_RATE_48MB; - range->bitrate[i++] = IEEE80211_OFDM_RATE_54MB; - } - if (phy->type == BCM43xx_PHYTYPE_B || - phy->type == BCM43xx_PHYTYPE_G) { - range->num_bitrates += 4; - range->bitrate[i++] = IEEE80211_CCK_RATE_1MB; - range->bitrate[i++] = IEEE80211_CCK_RATE_2MB; - range->bitrate[i++] = IEEE80211_CCK_RATE_5MB; - range->bitrate[i++] = IEEE80211_CCK_RATE_11MB; - } - - geo = ieee80211_get_geo(bcm->ieee); - range->num_channels = geo->a_channels + geo->bg_channels; - j = 0; - for (i = 0; i < geo->a_channels; i++) { - if (j == IW_MAX_FREQUENCIES) - break; - range->freq[j].i = j + 1; - range->freq[j].m = geo->a[i].freq;//FIXME? - range->freq[j].e = 1; - j++; - } - for (i = 0; i < geo->bg_channels; i++) { - if (j == IW_MAX_FREQUENCIES) - break; - range->freq[j].i = j + 1; - range->freq[j].m = geo->bg[i].freq;//FIXME? - range->freq[j].e = 1; - j++; - } - range->num_frequency = j; - - bcm43xx_unlock(bcm, flags); - - return 0; -} - -static int bcm43xx_wx_set_nick(struct net_device *net_dev, - struct iw_request_info *info, - union iwreq_data *data, - char *extra) -{ - struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); - unsigned long flags; - size_t len; - - bcm43xx_lock(bcm, flags); - len = min((size_t)data->data.length, (size_t)IW_ESSID_MAX_SIZE); - memcpy(bcm->nick, extra, len); - bcm->nick[len] = '\0'; - bcm43xx_unlock(bcm, flags); - - return 0; -} - -static int bcm43xx_wx_get_nick(struct net_device *net_dev, - struct iw_request_info *info, - union iwreq_data *data, - char *extra) -{ - struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); - unsigned long flags; - size_t len; - - bcm43xx_lock(bcm, flags); - len = strlen(bcm->nick) + 1; - memcpy(extra, bcm->nick, len); - data->data.length = (__u16)len; - data->data.flags = 1; - bcm43xx_unlock(bcm, flags); - - return 0; -} - -static int bcm43xx_wx_set_rts(struct net_device *net_dev, - struct iw_request_info *info, - union iwreq_data *data, - char *extra) -{ - struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); - unsigned long flags; - int err = -EINVAL; - - bcm43xx_lock(bcm, flags); - if (data->rts.disabled) { - bcm->rts_threshold = BCM43xx_MAX_RTS_THRESHOLD; - err = 0; - } else { - if (data->rts.value >= BCM43xx_MIN_RTS_THRESHOLD && - data->rts.value <= BCM43xx_MAX_RTS_THRESHOLD) { - bcm->rts_threshold = data->rts.value; - err = 0; - } - } - bcm43xx_unlock(bcm, flags); - - return err; -} - -static int bcm43xx_wx_get_rts(struct net_device *net_dev, - struct iw_request_info *info, - union iwreq_data *data, - char *extra) -{ - struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); - unsigned long flags; - - bcm43xx_lock(bcm, flags); - data->rts.value = bcm->rts_threshold; - data->rts.fixed = 0; - data->rts.disabled = (bcm->rts_threshold == BCM43xx_MAX_RTS_THRESHOLD); - bcm43xx_unlock(bcm, flags); - - return 0; -} - -static int bcm43xx_wx_set_frag(struct net_device *net_dev, - struct iw_request_info *info, - union iwreq_data *data, - char *extra) -{ - struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); - unsigned long flags; - int err = -EINVAL; - - bcm43xx_lock(bcm, flags); - if (data->frag.disabled) { - bcm->ieee->fts = MAX_FRAG_THRESHOLD; - err = 0; - } else { - if (data->frag.value >= MIN_FRAG_THRESHOLD && - data->frag.value <= MAX_FRAG_THRESHOLD) { - bcm->ieee->fts = data->frag.value & ~0x1; - err = 0; - } - } - bcm43xx_unlock(bcm, flags); - - return err; -} - -static int bcm43xx_wx_get_frag(struct net_device *net_dev, - struct iw_request_info *info, - union iwreq_data *data, - char *extra) -{ - struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); - unsigned long flags; - - bcm43xx_lock(bcm, flags); - data->frag.value = bcm->ieee->fts; - data->frag.fixed = 0; - data->frag.disabled = (bcm->ieee->fts == MAX_FRAG_THRESHOLD); - bcm43xx_unlock(bcm, flags); - - return 0; -} - -static int bcm43xx_wx_set_xmitpower(struct net_device *net_dev, - struct iw_request_info *info, - union iwreq_data *data, - char *extra) -{ - struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); - struct bcm43xx_radioinfo *radio; - struct bcm43xx_phyinfo *phy; - unsigned long flags; - int err = -ENODEV; - u16 maxpower; - - if ((data->txpower.flags & IW_TXPOW_TYPE) != IW_TXPOW_DBM) { - printk(PFX KERN_ERR "TX power not in dBm.\n"); - return -EOPNOTSUPP; - } - - bcm43xx_lock_mmio(bcm, flags); - if (!bcm->initialized) - goto out_unlock; - radio = bcm43xx_current_radio(bcm); - phy = bcm43xx_current_phy(bcm); - if (data->txpower.disabled != (!(radio->enabled))) { - if (data->txpower.disabled) - bcm43xx_radio_turn_off(bcm); - else - bcm43xx_radio_turn_on(bcm); - } - if (data->txpower.value > 0) { - /* desired and maxpower dBm values are in Q5.2 */ - if (phy->type == BCM43xx_PHYTYPE_A) - maxpower = bcm->sprom.maxpower_aphy; - else - maxpower = bcm->sprom.maxpower_bgphy; - radio->txpower_desired = limit_value(data->txpower.value << 2, - 0, maxpower); - bcm43xx_phy_xmitpower(bcm); - } - err = 0; - -out_unlock: - bcm43xx_unlock_mmio(bcm, flags); - - return err; -} - -static int bcm43xx_wx_get_xmitpower(struct net_device *net_dev, - struct iw_request_info *info, - union iwreq_data *data, - char *extra) -{ - struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); - struct bcm43xx_radioinfo *radio; - unsigned long flags; - int err = -ENODEV; - - bcm43xx_lock(bcm, flags); - if (!bcm->initialized) - goto out_unlock; - radio = bcm43xx_current_radio(bcm); - /* desired dBm value is in Q5.2 */ - data->txpower.value = radio->txpower_desired >> 2; - data->txpower.fixed = 1; - data->txpower.flags = IW_TXPOW_DBM; - data->txpower.disabled = !(radio->enabled); - - err = 0; -out_unlock: - bcm43xx_unlock(bcm, flags); - - return err; -} - -static int bcm43xx_wx_set_encoding(struct net_device *net_dev, - struct iw_request_info *info, - union iwreq_data *data, - char *extra) -{ - struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); - int err; - - err = ieee80211_wx_set_encode(bcm->ieee, info, data, extra); - - return err; -} - -static int bcm43xx_wx_set_encodingext(struct net_device *net_dev, - struct iw_request_info *info, - union iwreq_data *data, - char *extra) -{ - struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); - int err; - - err = ieee80211_wx_set_encodeext(bcm->ieee, info, data, extra); - - return err; -} - -static int bcm43xx_wx_get_encoding(struct net_device *net_dev, - struct iw_request_info *info, - union iwreq_data *data, - char *extra) -{ - struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); - int err; - - err = ieee80211_wx_get_encode(bcm->ieee, info, data, extra); - - return err; -} - -static int bcm43xx_wx_get_encodingext(struct net_device *net_dev, - struct iw_request_info *info, - union iwreq_data *data, - char *extra) -{ - struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); - int err; - - err = ieee80211_wx_get_encodeext(bcm->ieee, info, data, extra); - - return err; -} - -static int bcm43xx_wx_set_interfmode(struct net_device *net_dev, - struct iw_request_info *info, - union iwreq_data *data, - char *extra) -{ - struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); - unsigned long flags; - int mode, err = 0; - - mode = *((int *)extra); - switch (mode) { - case 0: - mode = BCM43xx_RADIO_INTERFMODE_NONE; - break; - case 1: - mode = BCM43xx_RADIO_INTERFMODE_NONWLAN; - break; - case 2: - mode = BCM43xx_RADIO_INTERFMODE_MANUALWLAN; - break; - case 3: - mode = BCM43xx_RADIO_INTERFMODE_AUTOWLAN; - break; - default: - printk(KERN_ERR PFX "set_interfmode allowed parameters are: " - "0 => None, 1 => Non-WLAN, 2 => WLAN, " - "3 => Auto-WLAN\n"); - return -EINVAL; - } - - bcm43xx_lock_mmio(bcm, flags); - if (bcm->initialized) { - err = bcm43xx_radio_set_interference_mitigation(bcm, mode); - if (err) { - printk(KERN_ERR PFX "Interference Mitigation not " - "supported by device\n"); - } - } else { - if (mode == BCM43xx_RADIO_INTERFMODE_AUTOWLAN) { - printk(KERN_ERR PFX "Interference Mitigation mode Auto-WLAN " - "not supported while the interface is down.\n"); - err = -ENODEV; - } else - bcm43xx_current_radio(bcm)->interfmode = mode; - } - bcm43xx_unlock_mmio(bcm, flags); - - return err; -} - -static int bcm43xx_wx_get_interfmode(struct net_device *net_dev, - struct iw_request_info *info, - union iwreq_data *data, - char *extra) -{ - struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); - unsigned long flags; - int mode; - - bcm43xx_lock(bcm, flags); - mode = bcm43xx_current_radio(bcm)->interfmode; - bcm43xx_unlock(bcm, flags); - - switch (mode) { - case BCM43xx_RADIO_INTERFMODE_NONE: - strncpy(extra, "0 (No Interference Mitigation)", MAX_WX_STRING); - break; - case BCM43xx_RADIO_INTERFMODE_NONWLAN: - strncpy(extra, "1 (Non-WLAN Interference Mitigation)", MAX_WX_STRING); - break; - case BCM43xx_RADIO_INTERFMODE_MANUALWLAN: - strncpy(extra, "2 (WLAN Interference Mitigation)", MAX_WX_STRING); - break; - default: - assert(0); - } - data->data.length = strlen(extra) + 1; - - return 0; -} - -static int bcm43xx_wx_set_shortpreamble(struct net_device *net_dev, - struct iw_request_info *info, - union iwreq_data *data, - char *extra) -{ - struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); - unsigned long flags; - int on; - - on = *((int *)extra); - bcm43xx_lock(bcm, flags); - bcm->short_preamble = !!on; - bcm43xx_unlock(bcm, flags); - - return 0; -} - -static int bcm43xx_wx_get_shortpreamble(struct net_device *net_dev, - struct iw_request_info *info, - union iwreq_data *data, - char *extra) -{ - struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); - unsigned long flags; - int on; - - bcm43xx_lock(bcm, flags); - on = bcm->short_preamble; - bcm43xx_unlock(bcm, flags); - - if (on) - strncpy(extra, "1 (Short Preamble enabled)", MAX_WX_STRING); - else - strncpy(extra, "0 (Short Preamble disabled)", MAX_WX_STRING); - data->data.length = strlen(extra) + 1; - - return 0; -} - -static int bcm43xx_wx_set_swencryption(struct net_device *net_dev, - struct iw_request_info *info, - union iwreq_data *data, - char *extra) -{ - struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); - unsigned long flags; - int on; - - on = *((int *)extra); - - bcm43xx_lock(bcm, flags); - bcm->ieee->host_encrypt = !!on; - bcm->ieee->host_decrypt = !!on; - bcm->ieee->host_build_iv = !on; - bcm43xx_unlock(bcm, flags); - - return 0; -} - -static int bcm43xx_wx_get_swencryption(struct net_device *net_dev, - struct iw_request_info *info, - union iwreq_data *data, - char *extra) -{ - struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); - unsigned long flags; - int on; - - bcm43xx_lock(bcm, flags); - on = bcm->ieee->host_encrypt; - bcm43xx_unlock(bcm, flags); - - if (on) - strncpy(extra, "1 (SW encryption enabled) ", MAX_WX_STRING); - else - strncpy(extra, "0 (SW encryption disabled) ", MAX_WX_STRING); - data->data.length = strlen(extra + 1); - - return 0; -} - -/* Enough buffer to hold a hexdump of the sprom data. */ -#define SPROM_BUFFERSIZE 512 - -static int sprom2hex(const u16 *sprom, char *dump) -{ - int i, pos = 0; - - for (i = 0; i < BCM43xx_SPROM_SIZE; i++) { - pos += snprintf(dump + pos, SPROM_BUFFERSIZE - pos - 1, - "%04X", swab16(sprom[i]) & 0xFFFF); - } - - return pos + 1; -} - -static int hex2sprom(u16 *sprom, const char *dump, unsigned int len) -{ - char tmp[5] = { 0 }; - int cnt = 0; - unsigned long parsed; - - if (len < BCM43xx_SPROM_SIZE * sizeof(u16) * 2) - return -EINVAL; - while (cnt < BCM43xx_SPROM_SIZE) { - memcpy(tmp, dump, 4); - dump += 4; - parsed = simple_strtoul(tmp, NULL, 16); - sprom[cnt++] = swab16((u16)parsed); - } - - return 0; -} - -static int bcm43xx_wx_sprom_read(struct net_device *net_dev, - struct iw_request_info *info, - union iwreq_data *data, - char *extra) -{ - struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); - int err = -EPERM; - u16 *sprom; - unsigned long flags; - - if (!capable(CAP_SYS_RAWIO)) - goto out; - - err = -ENOMEM; - sprom = kmalloc(BCM43xx_SPROM_SIZE * sizeof(*sprom), - GFP_KERNEL); - if (!sprom) - goto out; - - bcm43xx_lock_mmio(bcm, flags); - err = -ENODEV; - if (bcm->initialized) - err = bcm43xx_sprom_read(bcm, sprom); - bcm43xx_unlock_mmio(bcm, flags); - if (!err) - data->data.length = sprom2hex(sprom, extra); - kfree(sprom); -out: - return err; -} - -static int bcm43xx_wx_sprom_write(struct net_device *net_dev, - struct iw_request_info *info, - union iwreq_data *data, - char *extra) -{ - struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); - int err = -EPERM; - u16 *sprom; - unsigned long flags; - char *input; - unsigned int len; - - if (!capable(CAP_SYS_RAWIO)) - goto out; - - err = -ENOMEM; - sprom = kmalloc(BCM43xx_SPROM_SIZE * sizeof(*sprom), - GFP_KERNEL); - if (!sprom) - goto out; - - len = data->data.length; - extra[len - 1] = '\0'; - input = strchr(extra, ':'); - if (input) { - input++; - len -= input - extra; - } else - input = extra; - err = hex2sprom(sprom, input, len); - if (err) - goto out_kfree; - - bcm43xx_lock_mmio(bcm, flags); - err = -ENODEV; - if (bcm->initialized) - err = bcm43xx_sprom_write(bcm, sprom); - bcm43xx_unlock_mmio(bcm, flags); -out_kfree: - kfree(sprom); -out: - return err; -} - -/* Get wireless statistics. Called by /proc/net/wireless and by SIOCGIWSTATS */ - -static struct iw_statistics *bcm43xx_get_wireless_stats(struct net_device *net_dev) -{ - struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); - struct ieee80211softmac_device *mac = ieee80211_priv(net_dev); - struct iw_statistics *wstats; - - wstats = &bcm->stats.wstats; - if (!mac->associated) { - wstats->miss.beacon = 0; -// bcm->ieee->ieee_stats.tx_retry_limit_exceeded = 0; // FIXME: should this be cleared here? - wstats->discard.retries = 0; -// bcm->ieee->ieee_stats.tx_discards_wrong_sa = 0; // FIXME: same question - wstats->discard.nwid = 0; -// bcm->ieee->ieee_stats.rx_discards_undecryptable = 0; // FIXME: ditto - wstats->discard.code = 0; -// bcm->ieee->ieee_stats.rx_fragments = 0; // FIXME: same here - wstats->discard.fragment = 0; - wstats->discard.misc = 0; - wstats->qual.qual = 0; - wstats->qual.level = 0; - wstats->qual.noise = 0; - wstats->qual.updated = 7; - wstats->qual.updated |= IW_QUAL_NOISE_INVALID | - IW_QUAL_QUAL_INVALID | IW_QUAL_LEVEL_INVALID; - return wstats; - } - /* fill in the real statistics when iface associated */ - wstats->qual.qual = 100; // TODO: get the real signal quality - wstats->qual.level = 3 - bcm->stats.link_quality; - wstats->qual.noise = bcm->stats.noise; - wstats->qual.updated = IW_QUAL_QUAL_UPDATED | IW_QUAL_LEVEL_UPDATED | - IW_QUAL_NOISE_UPDATED; - wstats->discard.code = bcm->ieee->ieee_stats.rx_discards_undecryptable; - wstats->discard.retries = bcm->ieee->ieee_stats.tx_retry_limit_exceeded; - wstats->discard.nwid = bcm->ieee->ieee_stats.tx_discards_wrong_sa; - wstats->discard.fragment = bcm->ieee->ieee_stats.rx_fragments; - wstats->discard.misc = 0; // FIXME - wstats->miss.beacon = 0; // FIXME - return wstats; -} - - -#ifdef WX -# undef WX -#endif -#define WX(ioctl) [(ioctl) - SIOCSIWCOMMIT] -static const iw_handler bcm43xx_wx_handlers[] = { - /* Wireless Identification */ - WX(SIOCGIWNAME) = bcm43xx_wx_get_name, - /* Basic operations */ - WX(SIOCSIWFREQ) = bcm43xx_wx_set_channelfreq, - WX(SIOCGIWFREQ) = bcm43xx_wx_get_channelfreq, - WX(SIOCSIWMODE) = bcm43xx_wx_set_mode, - WX(SIOCGIWMODE) = bcm43xx_wx_get_mode, - /* Informative stuff */ - WX(SIOCGIWRANGE) = bcm43xx_wx_get_rangeparams, - /* Access Point manipulation */ - WX(SIOCSIWAP) = ieee80211softmac_wx_set_wap, - WX(SIOCGIWAP) = ieee80211softmac_wx_get_wap, - WX(SIOCSIWSCAN) = ieee80211softmac_wx_trigger_scan, - WX(SIOCGIWSCAN) = ieee80211softmac_wx_get_scan_results, - /* 802.11 specific support */ - WX(SIOCSIWESSID) = ieee80211softmac_wx_set_essid, - WX(SIOCGIWESSID) = ieee80211softmac_wx_get_essid, - WX(SIOCSIWNICKN) = bcm43xx_wx_set_nick, - WX(SIOCGIWNICKN) = bcm43xx_wx_get_nick, - /* Other parameters */ - WX(SIOCSIWRATE) = ieee80211softmac_wx_set_rate, - WX(SIOCGIWRATE) = ieee80211softmac_wx_get_rate, - WX(SIOCSIWRTS) = bcm43xx_wx_set_rts, - WX(SIOCGIWRTS) = bcm43xx_wx_get_rts, - WX(SIOCSIWFRAG) = bcm43xx_wx_set_frag, - WX(SIOCGIWFRAG) = bcm43xx_wx_get_frag, - WX(SIOCSIWTXPOW) = bcm43xx_wx_set_xmitpower, - WX(SIOCGIWTXPOW) = bcm43xx_wx_get_xmitpower, -//TODO WX(SIOCSIWRETRY) = bcm43xx_wx_set_retry, -//TODO WX(SIOCGIWRETRY) = bcm43xx_wx_get_retry, - /* Encoding */ - WX(SIOCSIWENCODE) = bcm43xx_wx_set_encoding, - WX(SIOCGIWENCODE) = bcm43xx_wx_get_encoding, - WX(SIOCSIWENCODEEXT) = bcm43xx_wx_set_encodingext, - WX(SIOCGIWENCODEEXT) = bcm43xx_wx_get_encodingext, - /* Power saving */ -//TODO WX(SIOCSIWPOWER) = bcm43xx_wx_set_power, -//TODO WX(SIOCGIWPOWER) = bcm43xx_wx_get_power, - WX(SIOCSIWGENIE) = ieee80211softmac_wx_set_genie, - WX(SIOCGIWGENIE) = ieee80211softmac_wx_get_genie, - WX(SIOCSIWAUTH) = ieee80211_wx_set_auth, - WX(SIOCGIWAUTH) = ieee80211_wx_get_auth, -}; -#undef WX - -static const iw_handler bcm43xx_priv_wx_handlers[] = { - /* Set Interference Mitigation Mode. */ - bcm43xx_wx_set_interfmode, - /* Get Interference Mitigation Mode. */ - bcm43xx_wx_get_interfmode, - /* Enable/Disable Short Preamble mode. */ - bcm43xx_wx_set_shortpreamble, - /* Get Short Preamble mode. */ - bcm43xx_wx_get_shortpreamble, - /* Enable/Disable Software Encryption mode */ - bcm43xx_wx_set_swencryption, - /* Get Software Encryption mode */ - bcm43xx_wx_get_swencryption, - /* Write SRPROM data. */ - bcm43xx_wx_sprom_write, - /* Read SPROM data. */ - bcm43xx_wx_sprom_read, -}; - -#define PRIV_WX_SET_INTERFMODE (SIOCIWFIRSTPRIV + 0) -#define PRIV_WX_GET_INTERFMODE (SIOCIWFIRSTPRIV + 1) -#define PRIV_WX_SET_SHORTPREAMBLE (SIOCIWFIRSTPRIV + 2) -#define PRIV_WX_GET_SHORTPREAMBLE (SIOCIWFIRSTPRIV + 3) -#define PRIV_WX_SET_SWENCRYPTION (SIOCIWFIRSTPRIV + 4) -#define PRIV_WX_GET_SWENCRYPTION (SIOCIWFIRSTPRIV + 5) -#define PRIV_WX_SPROM_WRITE (SIOCIWFIRSTPRIV + 6) -#define PRIV_WX_SPROM_READ (SIOCIWFIRSTPRIV + 7) - -#define PRIV_WX_DUMMY(ioctl) \ - { \ - .cmd = (ioctl), \ - .name = "__unused" \ - } - -static const struct iw_priv_args bcm43xx_priv_wx_args[] = { - { - .cmd = PRIV_WX_SET_INTERFMODE, - .set_args = IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, - .name = "set_interfmode", - }, - { - .cmd = PRIV_WX_GET_INTERFMODE, - .get_args = IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | MAX_WX_STRING, - .name = "get_interfmode", - }, - { - .cmd = PRIV_WX_SET_SHORTPREAMBLE, - .set_args = IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, - .name = "set_shortpreambl", - }, - { - .cmd = PRIV_WX_GET_SHORTPREAMBLE, - .get_args = IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | MAX_WX_STRING, - .name = "get_shortpreambl", - }, - { - .cmd = PRIV_WX_SET_SWENCRYPTION, - .set_args = IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, - .name = "set_swencryption", - }, - { - .cmd = PRIV_WX_GET_SWENCRYPTION, - .get_args = IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | MAX_WX_STRING, - .name = "get_swencryption", - }, - { - .cmd = PRIV_WX_SPROM_WRITE, - .set_args = IW_PRIV_TYPE_CHAR | SPROM_BUFFERSIZE, - .name = "write_sprom", - }, - { - .cmd = PRIV_WX_SPROM_READ, - .get_args = IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | SPROM_BUFFERSIZE, - .name = "read_sprom", - }, -}; - -const struct iw_handler_def bcm43xx_wx_handlers_def = { - .standard = bcm43xx_wx_handlers, - .num_standard = ARRAY_SIZE(bcm43xx_wx_handlers), - .num_private = ARRAY_SIZE(bcm43xx_priv_wx_handlers), - .num_private_args = ARRAY_SIZE(bcm43xx_priv_wx_args), - .private = bcm43xx_priv_wx_handlers, - .private_args = bcm43xx_priv_wx_args, - .get_wireless_stats = bcm43xx_get_wireless_stats, -}; diff --git a/trunk/drivers/net/wireless/bcm43xx/bcm43xx_wx.h b/trunk/drivers/net/wireless/bcm43xx/bcm43xx_wx.h deleted file mode 100644 index 1f29ff3aa4c3..000000000000 --- a/trunk/drivers/net/wireless/bcm43xx/bcm43xx_wx.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - - Broadcom BCM43xx wireless driver - - Copyright (c) 2005 Martin Langer , - Stefano Brivio - Michael Buesch - Danny van Dyk - Andreas Jaggi - - Some parts of the code in this file are derived from the ipw2200 - driver Copyright(c) 2003 - 2004 Intel Corporation. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; see the file COPYING. If not, write to - the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor, - Boston, MA 02110-1301, USA. - -*/ - -#ifndef BCM43xx_WX_H_ -#define BCM43xx_WX_H_ - -extern const struct iw_handler_def bcm43xx_wx_handlers_def; - -#endif /* BCM43xx_WX_H_ */ diff --git a/trunk/drivers/net/wireless/bcm43xx/bcm43xx_xmit.c b/trunk/drivers/net/wireless/bcm43xx/bcm43xx_xmit.c deleted file mode 100644 index d8ece28c079f..000000000000 --- a/trunk/drivers/net/wireless/bcm43xx/bcm43xx_xmit.c +++ /dev/null @@ -1,582 +0,0 @@ -/* - - Broadcom BCM43xx wireless driver - - Transmission (TX/RX) related functions. - - Copyright (c) 2005 Martin Langer , - Stefano Brivio - Michael Buesch - Danny van Dyk - Andreas Jaggi - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; see the file COPYING. If not, write to - the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor, - Boston, MA 02110-1301, USA. - -*/ - -#include "bcm43xx_xmit.h" - -#include - - -/* Extract the bitrate out of a CCK PLCP header. */ -static u8 bcm43xx_plcp_get_bitrate_cck(struct bcm43xx_plcp_hdr4 *plcp) -{ - switch (plcp->raw[0]) { - case 0x0A: - return IEEE80211_CCK_RATE_1MB; - case 0x14: - return IEEE80211_CCK_RATE_2MB; - case 0x37: - return IEEE80211_CCK_RATE_5MB; - case 0x6E: - return IEEE80211_CCK_RATE_11MB; - } - assert(0); - return 0; -} - -/* Extract the bitrate out of an OFDM PLCP header. */ -static u8 bcm43xx_plcp_get_bitrate_ofdm(struct bcm43xx_plcp_hdr4 *plcp) -{ - switch (plcp->raw[0] & 0xF) { - case 0xB: - return IEEE80211_OFDM_RATE_6MB; - case 0xF: - return IEEE80211_OFDM_RATE_9MB; - case 0xA: - return IEEE80211_OFDM_RATE_12MB; - case 0xE: - return IEEE80211_OFDM_RATE_18MB; - case 0x9: - return IEEE80211_OFDM_RATE_24MB; - case 0xD: - return IEEE80211_OFDM_RATE_36MB; - case 0x8: - return IEEE80211_OFDM_RATE_48MB; - case 0xC: - return IEEE80211_OFDM_RATE_54MB; - } - assert(0); - return 0; -} - -u8 bcm43xx_plcp_get_ratecode_cck(const u8 bitrate) -{ - switch (bitrate) { - case IEEE80211_CCK_RATE_1MB: - return 0x0A; - case IEEE80211_CCK_RATE_2MB: - return 0x14; - case IEEE80211_CCK_RATE_5MB: - return 0x37; - case IEEE80211_CCK_RATE_11MB: - return 0x6E; - } - assert(0); - return 0; -} - -u8 bcm43xx_plcp_get_ratecode_ofdm(const u8 bitrate) -{ - switch (bitrate) { - case IEEE80211_OFDM_RATE_6MB: - return 0xB; - case IEEE80211_OFDM_RATE_9MB: - return 0xF; - case IEEE80211_OFDM_RATE_12MB: - return 0xA; - case IEEE80211_OFDM_RATE_18MB: - return 0xE; - case IEEE80211_OFDM_RATE_24MB: - return 0x9; - case IEEE80211_OFDM_RATE_36MB: - return 0xD; - case IEEE80211_OFDM_RATE_48MB: - return 0x8; - case IEEE80211_OFDM_RATE_54MB: - return 0xC; - } - assert(0); - return 0; -} - -static void bcm43xx_generate_plcp_hdr(struct bcm43xx_plcp_hdr4 *plcp, - const u16 octets, const u8 bitrate, - const int ofdm_modulation) -{ - __le32 *data = &(plcp->data); - __u8 *raw = plcp->raw; - - if (ofdm_modulation) { - *data = bcm43xx_plcp_get_ratecode_ofdm(bitrate); - assert(!(octets & 0xF000)); - *data |= (octets << 5); - *data = cpu_to_le32(*data); - } else { - u32 plen; - - plen = octets * 16 / bitrate; - if ((octets * 16 % bitrate) > 0) { - plen++; - if ((bitrate == IEEE80211_CCK_RATE_11MB) - && ((octets * 8 % 11) < 4)) { - raw[1] = 0x84; - } else - raw[1] = 0x04; - } else - raw[1] = 0x04; - *data |= cpu_to_le32(plen << 16); - raw[0] = bcm43xx_plcp_get_ratecode_cck(bitrate); - } -} - -static u8 bcm43xx_calc_fallback_rate(u8 bitrate) -{ - switch (bitrate) { - case IEEE80211_CCK_RATE_1MB: - return IEEE80211_CCK_RATE_1MB; - case IEEE80211_CCK_RATE_2MB: - return IEEE80211_CCK_RATE_1MB; - case IEEE80211_CCK_RATE_5MB: - return IEEE80211_CCK_RATE_2MB; - case IEEE80211_CCK_RATE_11MB: - return IEEE80211_CCK_RATE_5MB; - case IEEE80211_OFDM_RATE_6MB: - return IEEE80211_CCK_RATE_5MB; - case IEEE80211_OFDM_RATE_9MB: - return IEEE80211_OFDM_RATE_6MB; - case IEEE80211_OFDM_RATE_12MB: - return IEEE80211_OFDM_RATE_9MB; - case IEEE80211_OFDM_RATE_18MB: - return IEEE80211_OFDM_RATE_12MB; - case IEEE80211_OFDM_RATE_24MB: - return IEEE80211_OFDM_RATE_18MB; - case IEEE80211_OFDM_RATE_36MB: - return IEEE80211_OFDM_RATE_24MB; - case IEEE80211_OFDM_RATE_48MB: - return IEEE80211_OFDM_RATE_36MB; - case IEEE80211_OFDM_RATE_54MB: - return IEEE80211_OFDM_RATE_48MB; - } - assert(0); - return 0; -} - -static -__le16 bcm43xx_calc_duration_id(const struct ieee80211_hdr *wireless_header, - u8 bitrate) -{ - const u16 frame_ctl = le16_to_cpu(wireless_header->frame_ctl); - __le16 duration_id = wireless_header->duration_id; - - switch (WLAN_FC_GET_TYPE(frame_ctl)) { - case IEEE80211_FTYPE_DATA: - case IEEE80211_FTYPE_MGMT: - //TODO: Steal the code from ieee80211, once it is completed there. - break; - case IEEE80211_FTYPE_CTL: - /* Use the original duration/id. */ - break; - default: - assert(0); - } - - return duration_id; -} - -static inline -u16 ceiling_div(u16 dividend, u16 divisor) -{ - return ((dividend + divisor - 1) / divisor); -} - -static void bcm43xx_generate_rts(const struct bcm43xx_phyinfo *phy, - struct bcm43xx_txhdr *txhdr, - u16 *flags, - u8 bitrate, - const struct ieee80211_hdr_4addr *wlhdr) -{ - u16 fctl; - u16 dur; - u8 fallback_bitrate; - int ofdm_modulation; - int fallback_ofdm_modulation; -// u8 *sa, *da; - u16 flen; - -//FIXME sa = ieee80211_get_SA((struct ieee80211_hdr *)wlhdr); -//FIXME da = ieee80211_get_DA((struct ieee80211_hdr *)wlhdr); - fallback_bitrate = bcm43xx_calc_fallback_rate(bitrate); - ofdm_modulation = !(ieee80211_is_cck_rate(bitrate)); - fallback_ofdm_modulation = !(ieee80211_is_cck_rate(fallback_bitrate)); - - flen = sizeof(u16) + sizeof(u16) + ETH_ALEN + ETH_ALEN + IEEE80211_FCS_LEN, - bcm43xx_generate_plcp_hdr((struct bcm43xx_plcp_hdr4 *)(&txhdr->rts_cts_plcp), - flen, bitrate, - !ieee80211_is_cck_rate(bitrate)); - bcm43xx_generate_plcp_hdr((struct bcm43xx_plcp_hdr4 *)(&txhdr->rts_cts_fallback_plcp), - flen, fallback_bitrate, - !ieee80211_is_cck_rate(fallback_bitrate)); - fctl = IEEE80211_FTYPE_CTL; - fctl |= IEEE80211_STYPE_RTS; - dur = le16_to_cpu(wlhdr->duration_id); -/*FIXME: should we test for dur==0 here and let it unmodified in this case? - * The following assert checks for this case... - */ -assert(dur); -/*FIXME: The duration calculation is not really correct. - * I am not 100% sure which bitrate to use. We use the RTS rate here, - * but this is likely to be wrong. - */ - if (phy->type == BCM43xx_PHYTYPE_A) { - /* Three times SIFS */ - dur += 16 * 3; - /* Add ACK duration. */ - dur += ceiling_div((16 + 8 * (14 /*bytes*/) + 6) * 10, - bitrate * 4); - /* Add CTS duration. */ - dur += ceiling_div((16 + 8 * (14 /*bytes*/) + 6) * 10, - bitrate * 4); - } else { - /* Three times SIFS */ - dur += 10 * 3; - /* Add ACK duration. */ - dur += ceiling_div(8 * (14 /*bytes*/) * 10, - bitrate); - /* Add CTS duration. */ - dur += ceiling_div(8 * (14 /*bytes*/) * 10, - bitrate); - } - - txhdr->rts_cts_frame_control = cpu_to_le16(fctl); - txhdr->rts_cts_dur = cpu_to_le16(dur); -//printk(BCM43xx_MACFMT " " BCM43xx_MACFMT " " BCM43xx_MACFMT "\n", BCM43xx_MACARG(wlhdr->addr1), BCM43xx_MACARG(wlhdr->addr2), BCM43xx_MACARG(wlhdr->addr3)); -//printk(BCM43xx_MACFMT " " BCM43xx_MACFMT "\n", BCM43xx_MACARG(sa), BCM43xx_MACARG(da)); - memcpy(txhdr->rts_cts_mac1, wlhdr->addr1, ETH_ALEN);//FIXME! -// memcpy(txhdr->rts_cts_mac2, sa, ETH_ALEN); - - *flags |= BCM43xx_TXHDRFLAG_RTSCTS; - *flags |= BCM43xx_TXHDRFLAG_RTS; - if (ofdm_modulation) - *flags |= BCM43xx_TXHDRFLAG_RTSCTS_OFDM; - if (fallback_ofdm_modulation) - *flags |= BCM43xx_TXHDRFLAG_RTSCTSFALLBACK_OFDM; -} - -void bcm43xx_generate_txhdr(struct bcm43xx_private *bcm, - struct bcm43xx_txhdr *txhdr, - const unsigned char *fragment_data, - const unsigned int fragment_len, - const int is_first_fragment, - const u16 cookie) -{ - const struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm); - const struct ieee80211_hdr_4addr *wireless_header = (const struct ieee80211_hdr_4addr *)fragment_data; - const struct ieee80211_security *secinfo = &bcm->ieee->sec; - u8 bitrate; - u8 fallback_bitrate; - int ofdm_modulation; - int fallback_ofdm_modulation; - u16 plcp_fragment_len = fragment_len; - u16 flags = 0; - u16 control = 0; - u16 wsec_rate = 0; - u16 encrypt_frame; - - /* Now construct the TX header. */ - memset(txhdr, 0, sizeof(*txhdr)); - - bitrate = bcm->softmac->txrates.default_rate; - ofdm_modulation = !(ieee80211_is_cck_rate(bitrate)); - fallback_bitrate = bcm43xx_calc_fallback_rate(bitrate); - fallback_ofdm_modulation = !(ieee80211_is_cck_rate(fallback_bitrate)); - - /* Set Frame Control from 80211 header. */ - txhdr->frame_control = wireless_header->frame_ctl; - /* Copy address1 from 80211 header. */ - memcpy(txhdr->mac1, wireless_header->addr1, 6); - /* Set the fallback duration ID. */ - txhdr->fallback_dur_id = bcm43xx_calc_duration_id((const struct ieee80211_hdr *)wireless_header, - fallback_bitrate); - /* Set the cookie (used as driver internal ID for the frame) */ - txhdr->cookie = cpu_to_le16(cookie); - - /* Hardware appends FCS. */ - plcp_fragment_len += IEEE80211_FCS_LEN; - - /* Hardware encryption. */ - encrypt_frame = le16_to_cpup(&wireless_header->frame_ctl) & IEEE80211_FCTL_PROTECTED; - if (encrypt_frame && !bcm->ieee->host_encrypt) { - const struct ieee80211_hdr_3addr *hdr = (struct ieee80211_hdr_3addr *)wireless_header; - memcpy(txhdr->wep_iv, hdr->payload, 4); - /* Hardware appends ICV. */ - plcp_fragment_len += 4; - - wsec_rate |= (bcm->key[secinfo->active_key].algorithm << BCM43xx_TXHDR_WSEC_ALGO_SHIFT) - & BCM43xx_TXHDR_WSEC_ALGO_MASK; - wsec_rate |= (secinfo->active_key << BCM43xx_TXHDR_WSEC_KEYINDEX_SHIFT) - & BCM43xx_TXHDR_WSEC_KEYINDEX_MASK; - } - - /* Generate the PLCP header and the fallback PLCP header. */ - bcm43xx_generate_plcp_hdr((struct bcm43xx_plcp_hdr4 *)(&txhdr->plcp), - plcp_fragment_len, - bitrate, ofdm_modulation); - bcm43xx_generate_plcp_hdr(&txhdr->fallback_plcp, plcp_fragment_len, - fallback_bitrate, fallback_ofdm_modulation); - - /* Set the CONTROL field */ - if (ofdm_modulation) - control |= BCM43xx_TXHDRCTL_OFDM; - if (bcm->short_preamble) //FIXME: could be the other way around, please test - control |= BCM43xx_TXHDRCTL_SHORT_PREAMBLE; - control |= (phy->antenna_diversity << BCM43xx_TXHDRCTL_ANTENNADIV_SHIFT) - & BCM43xx_TXHDRCTL_ANTENNADIV_MASK; - - /* Set the FLAGS field */ - if (!is_multicast_ether_addr(wireless_header->addr1) && - !is_broadcast_ether_addr(wireless_header->addr1)) - flags |= BCM43xx_TXHDRFLAG_EXPECTACK; - if (1 /* FIXME: PS poll?? */) - flags |= 0x10; // FIXME: unknown meaning. - if (fallback_ofdm_modulation) - flags |= BCM43xx_TXHDRFLAG_FALLBACKOFDM; - if (is_first_fragment) - flags |= BCM43xx_TXHDRFLAG_FIRSTFRAGMENT; - - /* Set WSEC/RATE field */ - wsec_rate |= (txhdr->plcp.raw[0] << BCM43xx_TXHDR_RATE_SHIFT) - & BCM43xx_TXHDR_RATE_MASK; - - /* Generate the RTS/CTS packet, if required. */ - /* FIXME: We should first try with CTS-to-self, - * if we are on 80211g. If we get too many - * failures (hidden nodes), we should switch back to RTS/CTS. - */ - if (0/*FIXME txctl->use_rts_cts*/) { - bcm43xx_generate_rts(phy, txhdr, &flags, - 0/*FIXME txctl->rts_cts_rate*/, - wireless_header); - } - - txhdr->flags = cpu_to_le16(flags); - txhdr->control = cpu_to_le16(control); - txhdr->wsec_rate = cpu_to_le16(wsec_rate); -} - -static s8 bcm43xx_rssi_postprocess(struct bcm43xx_private *bcm, - u8 in_rssi, int ofdm, - int adjust_2053, int adjust_2050) -{ - struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm); - struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm); - s32 tmp; - - switch (radio->version) { - case 0x2050: - if (ofdm) { - tmp = in_rssi; - if (tmp > 127) - tmp -= 256; - tmp *= 73; - tmp /= 64; - if (adjust_2050) - tmp += 25; - else - tmp -= 3; - } else { - if (bcm->sprom.boardflags & BCM43xx_BFL_RSSI) { - if (in_rssi > 63) - in_rssi = 63; - tmp = radio->nrssi_lt[in_rssi]; - tmp = 31 - tmp; - tmp *= -131; - tmp /= 128; - tmp -= 57; - } else { - tmp = in_rssi; - tmp = 31 - tmp; - tmp *= -149; - tmp /= 128; - tmp -= 68; - } - if (phy->type == BCM43xx_PHYTYPE_G && - adjust_2050) - tmp += 25; - } - break; - case 0x2060: - if (in_rssi > 127) - tmp = in_rssi - 256; - else - tmp = in_rssi; - break; - default: - tmp = in_rssi; - tmp -= 11; - tmp *= 103; - tmp /= 64; - if (adjust_2053) - tmp -= 109; - else - tmp -= 83; - } - - return (s8)tmp; -} - -//TODO -#if 0 -static s8 bcm43xx_rssinoise_postprocess(struct bcm43xx_private *bcm, - u8 in_rssi) -{ - struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm); - s8 ret; - - if (phy->type == BCM43xx_PHYTYPE_A) { - //TODO: Incomplete specs. - ret = 0; - } else - ret = bcm43xx_rssi_postprocess(bcm, in_rssi, 0, 1, 1); - - return ret; -} -#endif - -int bcm43xx_rx(struct bcm43xx_private *bcm, - struct sk_buff *skb, - struct bcm43xx_rxhdr *rxhdr) -{ - struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm); - struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm); - struct bcm43xx_plcp_hdr4 *plcp; - struct ieee80211_rx_stats stats; - struct ieee80211_hdr_4addr *wlhdr; - u16 frame_ctl; - int is_packet_for_us = 0; - int err = -EINVAL; - const u16 rxflags1 = le16_to_cpu(rxhdr->flags1); - const u16 rxflags2 = le16_to_cpu(rxhdr->flags2); - const u16 rxflags3 = le16_to_cpu(rxhdr->flags3); - const int is_ofdm = !!(rxflags1 & BCM43xx_RXHDR_FLAGS1_OFDM); - - if (rxflags2 & BCM43xx_RXHDR_FLAGS2_TYPE2FRAME) { - plcp = (struct bcm43xx_plcp_hdr4 *)(skb->data + 2); - /* Skip two unknown bytes and the PLCP header. */ - skb_pull(skb, 2 + sizeof(struct bcm43xx_plcp_hdr6)); - } else { - plcp = (struct bcm43xx_plcp_hdr4 *)(skb->data); - /* Skip the PLCP header. */ - skb_pull(skb, sizeof(struct bcm43xx_plcp_hdr6)); - } - /* The SKB contains the PAYLOAD (wireless header + data) - * at this point. The FCS at the end is stripped. - */ - - memset(&stats, 0, sizeof(stats)); - stats.mac_time = le16_to_cpu(rxhdr->mactime); - stats.rssi = bcm43xx_rssi_postprocess(bcm, rxhdr->rssi, is_ofdm, - !!(rxflags1 & BCM43xx_RXHDR_FLAGS1_2053RSSIADJ), - !!(rxflags3 & BCM43xx_RXHDR_FLAGS3_2050RSSIADJ)); - stats.signal = rxhdr->signal_quality; //FIXME -//TODO stats.noise = - if (is_ofdm) - stats.rate = bcm43xx_plcp_get_bitrate_ofdm(plcp); - else - stats.rate = bcm43xx_plcp_get_bitrate_cck(plcp); -//printk("RX ofdm %d, rate == %u\n", is_ofdm, stats.rate); - stats.received_channel = radio->channel; -//TODO stats.control = - stats.mask = IEEE80211_STATMASK_SIGNAL | -//TODO IEEE80211_STATMASK_NOISE | - IEEE80211_STATMASK_RATE | - IEEE80211_STATMASK_RSSI; - if (phy->type == BCM43xx_PHYTYPE_A) - stats.freq = IEEE80211_52GHZ_BAND; - else - stats.freq = IEEE80211_24GHZ_BAND; - stats.len = skb->len; - - bcm->stats.last_rx = jiffies; - if (bcm->ieee->iw_mode == IW_MODE_MONITOR) { - err = ieee80211_rx(bcm->ieee, skb, &stats); - return (err == 0) ? -EINVAL : 0; - } - - wlhdr = (struct ieee80211_hdr_4addr *)(skb->data); - - switch (bcm->ieee->iw_mode) { - case IW_MODE_ADHOC: - if (memcmp(wlhdr->addr1, bcm->net_dev->dev_addr, ETH_ALEN) == 0 || - memcmp(wlhdr->addr3, bcm->ieee->bssid, ETH_ALEN) == 0 || - is_broadcast_ether_addr(wlhdr->addr1) || - is_multicast_ether_addr(wlhdr->addr1) || - bcm->net_dev->flags & IFF_PROMISC) - is_packet_for_us = 1; - break; - case IW_MODE_INFRA: - default: - /* When receiving multicast or broadcast packets, filter out - the packets we send ourself; we shouldn't see those */ - if (memcmp(wlhdr->addr3, bcm->ieee->bssid, ETH_ALEN) == 0 || - memcmp(wlhdr->addr1, bcm->net_dev->dev_addr, ETH_ALEN) == 0 || - (memcmp(wlhdr->addr3, bcm->net_dev->dev_addr, ETH_ALEN) && - (is_broadcast_ether_addr(wlhdr->addr1) || - is_multicast_ether_addr(wlhdr->addr1) || - bcm->net_dev->flags & IFF_PROMISC))) - is_packet_for_us = 1; - break; - } - - frame_ctl = le16_to_cpu(wlhdr->frame_ctl); - if ((frame_ctl & IEEE80211_FCTL_PROTECTED) && !bcm->ieee->host_decrypt) { - frame_ctl &= ~IEEE80211_FCTL_PROTECTED; - wlhdr->frame_ctl = cpu_to_le16(frame_ctl); - /* trim IV and ICV */ - /* FIXME: this must be done only for WEP encrypted packets */ - if (skb->len < 32) { - dprintkl(KERN_ERR PFX "RX packet dropped (PROTECTED flag " - "set and length < 32)\n"); - return -EINVAL; - } else { - memmove(skb->data + 4, skb->data, 24); - skb_pull(skb, 4); - skb_trim(skb, skb->len - 4); - stats.len -= 8; - } - wlhdr = (struct ieee80211_hdr_4addr *)(skb->data); - } - - switch (WLAN_FC_GET_TYPE(frame_ctl)) { - case IEEE80211_FTYPE_MGMT: - ieee80211_rx_mgt(bcm->ieee, wlhdr, &stats); - break; - case IEEE80211_FTYPE_DATA: - if (is_packet_for_us) { - err = ieee80211_rx(bcm->ieee, skb, &stats); - err = (err == 0) ? -EINVAL : 0; - } - break; - case IEEE80211_FTYPE_CTL: - break; - default: - assert(0); - return -EINVAL; - } - - return err; -} diff --git a/trunk/drivers/net/wireless/bcm43xx/bcm43xx_xmit.h b/trunk/drivers/net/wireless/bcm43xx/bcm43xx_xmit.h deleted file mode 100644 index 2aed19e35c77..000000000000 --- a/trunk/drivers/net/wireless/bcm43xx/bcm43xx_xmit.h +++ /dev/null @@ -1,156 +0,0 @@ -#ifndef BCM43xx_XMIT_H_ -#define BCM43xx_XMIT_H_ - -#include "bcm43xx_main.h" - - -#define _bcm43xx_declare_plcp_hdr(size) \ - struct bcm43xx_plcp_hdr##size { \ - union { \ - __le32 data; \ - __u8 raw[size]; \ - } __attribute__((__packed__)); \ - } __attribute__((__packed__)) - -/* struct bcm43xx_plcp_hdr4 */ -_bcm43xx_declare_plcp_hdr(4); -/* struct bcm43xx_plcp_hdr6 */ -_bcm43xx_declare_plcp_hdr(6); - -#undef _bcm43xx_declare_plcp_hdr - -/* Device specific TX header. To be prepended to TX frames. */ -struct bcm43xx_txhdr { - union { - struct { - __le16 flags; - __le16 wsec_rate; - __le16 frame_control; - u16 unknown_zeroed_0; - __le16 control; - u8 wep_iv[10]; - u8 unknown_wsec_tkip_data[3]; //FIXME - PAD_BYTES(3); - u8 mac1[6]; - u16 unknown_zeroed_1; - struct bcm43xx_plcp_hdr4 rts_cts_fallback_plcp; - __le16 rts_cts_dur_fallback; - struct bcm43xx_plcp_hdr4 fallback_plcp; - __le16 fallback_dur_id; - PAD_BYTES(2); - __le16 cookie; - __le16 unknown_scb_stuff; //FIXME - struct bcm43xx_plcp_hdr6 rts_cts_plcp; - __le16 rts_cts_frame_control; - __le16 rts_cts_dur; - u8 rts_cts_mac1[6]; - u8 rts_cts_mac2[6]; - PAD_BYTES(2); - struct bcm43xx_plcp_hdr6 plcp; - } __attribute__((__packed__)); - u8 raw[82]; - } __attribute__((__packed__)); -} __attribute__((__packed__)); - -/* Values/Masks for the device TX header */ -#define BCM43xx_TXHDRFLAG_EXPECTACK 0x0001 -#define BCM43xx_TXHDRFLAG_RTSCTS 0x0002 -#define BCM43xx_TXHDRFLAG_RTS 0x0004 -#define BCM43xx_TXHDRFLAG_FIRSTFRAGMENT 0x0008 -#define BCM43xx_TXHDRFLAG_DESTPSMODE 0x0020 -#define BCM43xx_TXHDRFLAG_RTSCTS_OFDM 0x0080 -#define BCM43xx_TXHDRFLAG_FALLBACKOFDM 0x0100 -#define BCM43xx_TXHDRFLAG_RTSCTSFALLBACK_OFDM 0x0200 -#define BCM43xx_TXHDRFLAG_CTS 0x0400 -#define BCM43xx_TXHDRFLAG_FRAMEBURST 0x0800 - -#define BCM43xx_TXHDRCTL_OFDM 0x0001 -#define BCM43xx_TXHDRCTL_SHORT_PREAMBLE 0x0010 -#define BCM43xx_TXHDRCTL_ANTENNADIV_MASK 0x0030 -#define BCM43xx_TXHDRCTL_ANTENNADIV_SHIFT 8 - -#define BCM43xx_TXHDR_RATE_MASK 0x0F00 -#define BCM43xx_TXHDR_RATE_SHIFT 8 -#define BCM43xx_TXHDR_RTSRATE_MASK 0xF000 -#define BCM43xx_TXHDR_RTSRATE_SHIFT 12 -#define BCM43xx_TXHDR_WSEC_KEYINDEX_MASK 0x00F0 -#define BCM43xx_TXHDR_WSEC_KEYINDEX_SHIFT 4 -#define BCM43xx_TXHDR_WSEC_ALGO_MASK 0x0003 -#define BCM43xx_TXHDR_WSEC_ALGO_SHIFT 0 - -void bcm43xx_generate_txhdr(struct bcm43xx_private *bcm, - struct bcm43xx_txhdr *txhdr, - const unsigned char *fragment_data, - const unsigned int fragment_len, - const int is_first_fragment, - const u16 cookie); - -/* RX header as received from the hardware. */ -struct bcm43xx_rxhdr { - /* Frame Length. Must be generated explicitely in PIO mode. */ - __le16 frame_length; - PAD_BYTES(2); - /* Flags field 1 */ - __le16 flags1; - u8 rssi; - u8 signal_quality; - PAD_BYTES(2); - /* Flags field 3 */ - __le16 flags3; - /* Flags field 2 */ - __le16 flags2; - /* Lower 16bits of the TSF at the time the frame started. */ - __le16 mactime; - PAD_BYTES(14); -} __attribute__((__packed__)); - -#define BCM43xx_RXHDR_FLAGS1_OFDM (1 << 0) -/*#define BCM43xx_RXHDR_FLAGS1_SIGNAL??? (1 << 3) FIXME */ -#define BCM43xx_RXHDR_FLAGS1_SHORTPREAMBLE (1 << 7) -#define BCM43xx_RXHDR_FLAGS1_2053RSSIADJ (1 << 14) - -#define BCM43xx_RXHDR_FLAGS2_INVALIDFRAME (1 << 0) -#define BCM43xx_RXHDR_FLAGS2_TYPE2FRAME (1 << 2) -/*FIXME: WEP related flags */ - -#define BCM43xx_RXHDR_FLAGS3_2050RSSIADJ (1 << 10) - -/* Transmit Status as received from the hardware. */ -struct bcm43xx_hwxmitstatus { - PAD_BYTES(4); - __le16 cookie; - u8 flags; - u8 cnt1:4, - cnt2:4; - PAD_BYTES(2); - __le16 seq; - __le16 unknown; //FIXME -} __attribute__((__packed__)); - -/* Transmit Status in CPU byteorder. */ -struct bcm43xx_xmitstatus { - u16 cookie; - u8 flags; - u8 cnt1:4, - cnt2:4; - u16 seq; - u16 unknown; //FIXME -}; - -#define BCM43xx_TXSTAT_FLAG_ACK 0x01 -//TODO #define BCM43xx_TXSTAT_FLAG_??? 0x02 -//TODO #define BCM43xx_TXSTAT_FLAG_??? 0x04 -//TODO #define BCM43xx_TXSTAT_FLAG_??? 0x08 -//TODO #define BCM43xx_TXSTAT_FLAG_??? 0x10 -#define BCM43xx_TXSTAT_FLAG_IGNORE 0x20 -//TODO #define BCM43xx_TXSTAT_FLAG_??? 0x40 -//TODO #define BCM43xx_TXSTAT_FLAG_??? 0x80 - -u8 bcm43xx_plcp_get_ratecode_cck(const u8 bitrate); -u8 bcm43xx_plcp_get_ratecode_ofdm(const u8 bitrate); - -int bcm43xx_rx(struct bcm43xx_private *bcm, - struct sk_buff *skb, - struct bcm43xx_rxhdr *rxhdr); - -#endif /* BCM43xx_XMIT_H_ */ diff --git a/trunk/drivers/net/wireless/hostap/hostap_80211.h b/trunk/drivers/net/wireless/hostap/hostap_80211.h index cc1ee7f4f5f8..1fc72fe511e9 100644 --- a/trunk/drivers/net/wireless/hostap/hostap_80211.h +++ b/trunk/drivers/net/wireless/hostap/hostap_80211.h @@ -92,6 +92,8 @@ void hostap_dump_rx_80211(const char *name, struct sk_buff *skb, void hostap_dump_tx_80211(const char *name, struct sk_buff *skb); int hostap_data_start_xmit(struct sk_buff *skb, struct net_device *dev); int hostap_mgmt_start_xmit(struct sk_buff *skb, struct net_device *dev); +struct sk_buff * hostap_tx_encrypt(struct sk_buff *skb, + struct ieee80211_crypt_data *crypt); int hostap_master_start_xmit(struct sk_buff *skb, struct net_device *dev); #endif /* HOSTAP_80211_H */ diff --git a/trunk/drivers/net/wireless/hostap/hostap_80211_tx.c b/trunk/drivers/net/wireless/hostap/hostap_80211_tx.c index 06a5214145e3..4a85e63906f1 100644 --- a/trunk/drivers/net/wireless/hostap/hostap_80211_tx.c +++ b/trunk/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) /* Called only from software IRQ */ -static struct sk_buff * hostap_tx_encrypt(struct sk_buff *skb, - struct ieee80211_crypt_data *crypt) +struct sk_buff * hostap_tx_encrypt(struct sk_buff *skb, + struct ieee80211_crypt_data *crypt) { struct hostap_interface *iface; local_info_t *local; @@ -317,7 +317,7 @@ static struct sk_buff * hostap_tx_encrypt(struct sk_buff *skb, } if (local->tkip_countermeasures && - strcmp(crypt->ops->name, "TKIP") == 0) { + crypt && crypt->ops && strcmp(crypt->ops->name, "TKIP") == 0) { hdr = (struct ieee80211_hdr_4addr *) skb->data; if (net_ratelimit()) { printk(KERN_DEBUG "%s: TKIP countermeasures: dropped " @@ -469,7 +469,7 @@ int hostap_master_start_xmit(struct sk_buff *skb, struct net_device *dev) } if (local->ieee_802_1x && meta->ethertype == ETH_P_PAE && tx.crypt && - !(fc & IEEE80211_FCTL_PROTECTED)) { + !(fc & IEEE80211_FCTL_VERS)) { no_encrypt = 1; PDEBUG(DEBUG_EXTRA2, "%s: TX: IEEE 802.1X - passing " "unencrypted EAPOL frame\n", dev->name); @@ -535,4 +535,5 @@ int hostap_master_start_xmit(struct sk_buff *skb, struct net_device *dev) EXPORT_SYMBOL(hostap_dump_tx_80211); +EXPORT_SYMBOL(hostap_tx_encrypt); EXPORT_SYMBOL(hostap_master_start_xmit); diff --git a/trunk/drivers/parisc/ccio-dma.c b/trunk/drivers/parisc/ccio-dma.c index a5d826237b26..93f8a8fa8890 100644 --- a/trunk/drivers/parisc/ccio-dma.c +++ b/trunk/drivers/parisc/ccio-dma.c @@ -1560,7 +1560,7 @@ static int ccio_probe(struct parisc_device *dev) *ioc_p = ioc; ioc->hw_path = dev->hw_path; - ioc->ioc_regs = ioremap_nocache(dev->hpa.start, 4096); + ioc->ioc_regs = ioremap(dev->hpa.start, 4096); ccio_ioc_init(ioc); ccio_init_resources(ioc); hppa_dma_ops = &ccio_ops; diff --git a/trunk/drivers/parisc/dino.c b/trunk/drivers/parisc/dino.c index 6e8ed0c81a6c..3d1a7f98c676 100644 --- a/trunk/drivers/parisc/dino.c +++ b/trunk/drivers/parisc/dino.c @@ -5,7 +5,6 @@ ** (c) Copyright 1999 SuSE GmbH ** (c) Copyright 1999,2000 Hewlett-Packard Company ** (c) Copyright 2000 Grant Grundler -** (c) Copyright 2006 Helge Deller ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by @@ -786,7 +785,7 @@ dino_bridge_init(struct dino_device *dino_dev, const char *name) if((io_addr & (1 << i)) == 0) continue; - start = F_EXTEND(0xf0000000UL) | (i << 23); + start = (unsigned long)(signed int)(0xf0000000 | (i << 23)); end = start + 8 * 1024 * 1024 - 1; DBG("DINO RANGE %d is at 0x%lx-0x%lx\n", count, @@ -997,7 +996,7 @@ static int __init dino_probe(struct parisc_device *dev) } dino_dev->hba.dev = dev; - dino_dev->hba.base_addr = ioremap_nocache(hpa, 4096); + dino_dev->hba.base_addr = ioremap(hpa, 4096); dino_dev->hba.lmmio_space_offset = 0; /* CPU addrs == bus addrs */ spin_lock_init(&dino_dev->dinosaur_pen); dino_dev->hba.iommu = ccio_get_iommu(dev); diff --git a/trunk/drivers/parisc/eisa.c b/trunk/drivers/parisc/eisa.c index 9d3bd15bf53b..3d94d86c1c9f 100644 --- a/trunk/drivers/parisc/eisa.c +++ b/trunk/drivers/parisc/eisa.c @@ -366,7 +366,7 @@ static int __devinit eisa_probe(struct parisc_device *dev) eisa_dev.eeprom_addr = MIRAGE_EEPROM_BASE_ADDR; } } - eisa_eeprom_addr = ioremap_nocache(eisa_dev.eeprom_addr, HPEE_MAX_LENGTH); + eisa_eeprom_addr = ioremap(eisa_dev.eeprom_addr, HPEE_MAX_LENGTH); result = eisa_enumerator(eisa_dev.eeprom_addr, &eisa_dev.hba.io_space, &eisa_dev.hba.lmmio_space); init_eisa_pic(); diff --git a/trunk/drivers/parisc/iosapic.c b/trunk/drivers/parisc/iosapic.c index 7a458d5bc751..8d7a36392eb8 100644 --- a/trunk/drivers/parisc/iosapic.c +++ b/trunk/drivers/parisc/iosapic.c @@ -879,7 +879,7 @@ void *iosapic_register(unsigned long hpa) return NULL; } - isi->addr = ioremap_nocache(hpa, 4096); + isi->addr = ioremap(hpa, 4096); isi->isi_hpa = hpa; isi->isi_version = iosapic_rd_version(isi); isi->isi_num_vectors = IOSAPIC_IRDT_MAX_ENTRY(isi->isi_version) + 1; diff --git a/trunk/drivers/parisc/lba_pci.c b/trunk/drivers/parisc/lba_pci.c index 3fe4a77fa16a..e8a2a4a852f5 100644 --- a/trunk/drivers/parisc/lba_pci.c +++ b/trunk/drivers/parisc/lba_pci.c @@ -1213,7 +1213,7 @@ lba_pat_resources(struct parisc_device *pa_dev, struct lba_device *lba_dev) ** Postable I/O port space is per PCI host adapter. ** base of 64MB PIOP region */ - lba_dev->iop_base = ioremap_nocache(p->start, 64 * 1024 * 1024); + lba_dev->iop_base = ioremap(p->start, 64 * 1024 * 1024); sprintf(lba_dev->hba.io_name, "PCI%02lx Ports", lba_dev->hba.bus_num.start); @@ -1525,7 +1525,7 @@ lba_driver_probe(struct parisc_device *dev) u32 func_class; void *tmp_obj; char *version; - void __iomem *addr = ioremap_nocache(dev->hpa.start, 4096); + void __iomem *addr = ioremap(dev->hpa.start, 4096); /* Read HW Rev First */ func_class = READ_REG32(addr + LBA_FCLASS); @@ -1619,7 +1619,7 @@ lba_driver_probe(struct parisc_device *dev) } else { if (!astro_iop_base) { /* Sprockets PDC uses NPIOP region */ - astro_iop_base = ioremap_nocache(LBA_PORT_BASE, 64 * 1024); + astro_iop_base = ioremap(LBA_PORT_BASE, 64 * 1024); pci_port = &lba_astro_port_ops; } @@ -1700,7 +1700,7 @@ void __init lba_init(void) */ void lba_set_iregs(struct parisc_device *lba, u32 ibase, u32 imask) { - void __iomem * base_addr = ioremap_nocache(lba->hpa.start, 4096); + void __iomem * base_addr = ioremap(lba->hpa.start, 4096); imask <<= 2; /* adjust for hints - 2 more bits */ diff --git a/trunk/drivers/parisc/pdc_stable.c b/trunk/drivers/parisc/pdc_stable.c index 4e53be9c03ab..a28e17898fbd 100644 --- a/trunk/drivers/parisc/pdc_stable.c +++ b/trunk/drivers/parisc/pdc_stable.c @@ -4,8 +4,9 @@ * Copyright (C) 2005-2006 Thibaut VARENE * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License, version 2, as - * published by the Free Software Foundation. + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/trunk/drivers/parisc/sba_iommu.c b/trunk/drivers/parisc/sba_iommu.c index 42b32ff2fca6..0821747e44cf 100644 --- a/trunk/drivers/parisc/sba_iommu.c +++ b/trunk/drivers/parisc/sba_iommu.c @@ -1642,9 +1642,9 @@ sba_ioc_init(struct parisc_device *sba, struct ioc *ioc, int ioc_num) ** **************************************************************************/ -static void __iomem *ioc_remap(struct sba_device *sba_dev, unsigned int offset) +static void __iomem *ioc_remap(struct sba_device *sba_dev, int offset) { - return ioremap_nocache(sba_dev->dev->hpa.start + offset, SBA_FUNC_SIZE); + return ioremap(sba_dev->dev->hpa.start + offset, SBA_FUNC_SIZE); } static void sba_hw_init(struct sba_device *sba_dev) @@ -2040,7 +2040,7 @@ sba_driver_callback(struct parisc_device *dev) u32 func_class; int i; char *version; - void __iomem *sba_addr = ioremap_nocache(dev->hpa.start, SBA_FUNC_SIZE); + void __iomem *sba_addr = ioremap(dev->hpa.start, SBA_FUNC_SIZE); struct proc_dir_entry *info_entry, *bitmap_entry, *root; sba_dump_ranges(sba_addr); diff --git a/trunk/drivers/parisc/superio.c b/trunk/drivers/parisc/superio.c index 719b863bc20e..ad6d3b28a3a6 100644 --- a/trunk/drivers/parisc/superio.c +++ b/trunk/drivers/parisc/superio.c @@ -12,7 +12,6 @@ * (C) Copyright 2001 John Marvin * (C) Copyright 2003 Grant Grundler * (C) Copyright 2005 Kyle McMartin - * (C) Copyright 2006 Helge Deller * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -389,34 +388,43 @@ int superio_fixup_irq(struct pci_dev *pcidev) return local_irq; } +static struct uart_port serial[] = { + { + .iotype = UPIO_PORT, + .line = 0, + .type = PORT_16550A, + .uartclk = 115200*16, + .fifosize = 16, + }, + { + .iotype = UPIO_PORT, + .line = 1, + .type = PORT_16550A, + .uartclk = 115200*16, + .fifosize = 16, + } +}; + static void __devinit superio_serial_init(void) { #ifdef CONFIG_SERIAL_8250 int retval; - struct uart_port serial_port; - - memset(&serial_port, 0, sizeof(serial_port)); - serial_port.iotype = UPIO_PORT; - serial_port.type = PORT_16550A; - serial_port.uartclk = 115200*16; - serial_port.fifosize = 16; - spin_lock_init(&serial_port.lock); - - /* serial port #1 */ - serial_port.iobase = sio_dev.sp1_base; - serial_port.irq = SP1_IRQ; - serial_port.line = 0; - retval = early_serial_setup(&serial_port); + + serial[0].iobase = sio_dev.sp1_base; + serial[0].irq = SP1_IRQ; + spin_lock_init(&serial[0].lock); + + retval = early_serial_setup(&serial[0]); if (retval < 0) { printk(KERN_WARNING PFX "Register Serial #0 failed.\n"); return; } - /* serial port #2 */ - serial_port.iobase = sio_dev.sp2_base; - serial_port.irq = SP2_IRQ; - serial_port.line = 1; - retval = early_serial_setup(&serial_port); + serial[1].iobase = sio_dev.sp2_base; + serial[1].irq = SP2_IRQ; + spin_lock_init(&serial[1].lock); + retval = early_serial_setup(&serial[1]); + if (retval < 0) printk(KERN_WARNING PFX "Register Serial #1 failed.\n"); #endif /* CONFIG_SERIAL_8250 */ diff --git a/trunk/drivers/pcmcia/vrc4171_card.c b/trunk/drivers/pcmcia/vrc4171_card.c index 459e6e1946fd..0574efd7828a 100644 --- a/trunk/drivers/pcmcia/vrc4171_card.c +++ b/trunk/drivers/pcmcia/vrc4171_card.c @@ -634,7 +634,7 @@ static void vrc4171_remove_sockets(void) static int __devinit vrc4171_card_setup(char *options) { if (options == NULL || *options == '\0') - return 1; + return 0; if (strncmp(options, "irq:", 4) == 0) { int irq; @@ -644,7 +644,7 @@ static int __devinit vrc4171_card_setup(char *options) vrc4171_irq = irq; if (*options != ',') - return 1; + return 0; options++; } @@ -663,10 +663,10 @@ static int __devinit vrc4171_card_setup(char *options) } if (*options != ',') - return 1; + return 0; options++; } else - return 1; + return 0; } @@ -688,7 +688,7 @@ static int __devinit vrc4171_card_setup(char *options) } if (*options != ',') - return 1; + return 0; options++; if (strncmp(options, "memnoprobe", 10) == 0) @@ -700,7 +700,7 @@ static int __devinit vrc4171_card_setup(char *options) } } - return 1; + return 0; } __setup("vrc4171_card=", vrc4171_card_setup); diff --git a/trunk/drivers/pcmcia/vrc4173_cardu.c b/trunk/drivers/pcmcia/vrc4173_cardu.c index 6004196f7cc1..57f38dba0a48 100644 --- a/trunk/drivers/pcmcia/vrc4173_cardu.c +++ b/trunk/drivers/pcmcia/vrc4173_cardu.c @@ -516,7 +516,7 @@ static int __devinit vrc4173_cardu_probe(struct pci_dev *dev, static int __devinit vrc4173_cardu_setup(char *options) { if (options == NULL || *options == '\0') - return 1; + return 0; if (strncmp(options, "cardu1:", 7) == 0) { options += 7; @@ -527,9 +527,9 @@ static int __devinit vrc4173_cardu_setup(char *options) } if (*options != ',') - return 1; + return 0; } else - return 1; + return 0; } if (strncmp(options, "cardu2:", 7) == 0) { @@ -538,7 +538,7 @@ static int __devinit vrc4173_cardu_setup(char *options) cardu_sockets[CARDU2].noprobe = 1; } - return 1; + return 0; } __setup("vrc4173_cardu=", vrc4173_cardu_setup); diff --git a/trunk/drivers/scsi/ahci.c b/trunk/drivers/scsi/ahci.c index 1bd82c4e52a0..ffba65656a83 100644 --- a/trunk/drivers/scsi/ahci.c +++ b/trunk/drivers/scsi/ahci.c @@ -293,10 +293,6 @@ static const struct pci_device_id ahci_pci_tbl[] = { board_ahci }, /* JMicron JMB360 */ { 0x197b, 0x2363, PCI_ANY_ID, PCI_ANY_ID, 0, 0, board_ahci }, /* JMicron JMB363 */ - { PCI_VENDOR_ID_ATI, 0x4380, PCI_ANY_ID, PCI_ANY_ID, 0, 0, - board_ahci }, /* ATI SB600 non-raid */ - { PCI_VENDOR_ID_ATI, 0x4381, PCI_ANY_ID, PCI_ANY_ID, 0, 0, - board_ahci }, /* ATI SB600 raid */ { } /* terminate list */ }; diff --git a/trunk/drivers/scsi/ata_piix.c b/trunk/drivers/scsi/ata_piix.c index 24e71b555172..2d5be84d8bd4 100644 --- a/trunk/drivers/scsi/ata_piix.c +++ b/trunk/drivers/scsi/ata_piix.c @@ -301,7 +301,7 @@ static struct piix_map_db ich6_map_db = { .mask = 0x3, .map = { /* PM PS SM SS MAP */ - { P0, P2, P1, P3 }, /* 00b */ + { P0, P1, P2, P3 }, /* 00b */ { IDE, IDE, P1, P3 }, /* 01b */ { P0, P2, IDE, IDE }, /* 10b */ { RV, RV, RV, RV }, @@ -312,7 +312,7 @@ static struct piix_map_db ich6m_map_db = { .mask = 0x3, .map = { /* PM PS SM SS MAP */ - { P0, P2, RV, RV }, /* 00b */ + { P0, P1, P2, P3 }, /* 00b */ { RV, RV, RV, RV }, { P0, P2, IDE, IDE }, /* 10b */ { RV, RV, RV, RV }, diff --git a/trunk/drivers/scsi/ibmmca.c b/trunk/drivers/scsi/ibmmca.c index 24eb59e143a9..3a8462e8d063 100644 --- a/trunk/drivers/scsi/ibmmca.c +++ b/trunk/drivers/scsi/ibmmca.c @@ -2488,7 +2488,7 @@ static int option_setup(char *str) } ints[0] = i - 1; internal_ibmmca_scsi_setup(cur, ints); - return 1; + return 0; } __setup("ibmmcascsi=", option_setup); diff --git a/trunk/drivers/scsi/lasi700.c b/trunk/drivers/scsi/lasi700.c index eb7bd310cc82..459a4daebece 100644 --- a/trunk/drivers/scsi/lasi700.c +++ b/trunk/drivers/scsi/lasi700.c @@ -112,7 +112,7 @@ lasi700_probe(struct parisc_device *dev) hostdata->dev = &dev->dev; dma_set_mask(&dev->dev, DMA_32BIT_MASK); - hostdata->base = ioremap_nocache(base, 0x100); + hostdata->base = ioremap(base, 0x100); hostdata->differential = 0; if (dev->id.sversion == LASI_700_SVERSION) { diff --git a/trunk/drivers/scsi/libata-bmdma.c b/trunk/drivers/scsi/libata-bmdma.c index 835dff0bafdc..95d81d86d8b7 100644 --- a/trunk/drivers/scsi/libata-bmdma.c +++ b/trunk/drivers/scsi/libata-bmdma.c @@ -703,7 +703,6 @@ ata_pci_init_native_mode(struct pci_dev *pdev, struct ata_port_info **port, int struct ata_probe_ent *probe_ent = ata_probe_ent_alloc(pci_dev_to_dev(pdev), port[0]); int p = 0; - unsigned long bmdma; if (!probe_ent) return NULL; @@ -717,12 +716,7 @@ ata_pci_init_native_mode(struct pci_dev *pdev, struct ata_port_info **port, int probe_ent->port[p].altstatus_addr = probe_ent->port[p].ctl_addr = pci_resource_start(pdev, 1) | ATA_PCI_CTL_OFS; - bmdma = pci_resource_start(pdev, 4); - if (bmdma) { - if (inb(bmdma + 2) & 0x80) - probe_ent->host_set_flags |= ATA_HOST_SIMPLEX; - probe_ent->port[p].bmdma_addr = bmdma; - } + probe_ent->port[p].bmdma_addr = pci_resource_start(pdev, 4); ata_std_ports(&probe_ent->port[p]); p++; } @@ -732,13 +726,7 @@ ata_pci_init_native_mode(struct pci_dev *pdev, struct ata_port_info **port, int probe_ent->port[p].altstatus_addr = probe_ent->port[p].ctl_addr = pci_resource_start(pdev, 3) | ATA_PCI_CTL_OFS; - bmdma = pci_resource_start(pdev, 4); - if (bmdma) { - bmdma += 8; - if(inb(bmdma + 2) & 0x80) - probe_ent->host_set_flags |= ATA_HOST_SIMPLEX; - probe_ent->port[p].bmdma_addr = bmdma; - } + probe_ent->port[p].bmdma_addr = pci_resource_start(pdev, 4) + 8; ata_std_ports(&probe_ent->port[p]); p++; } @@ -752,7 +740,6 @@ static struct ata_probe_ent *ata_pci_init_legacy_port(struct pci_dev *pdev, struct ata_port_info *port, int port_num) { struct ata_probe_ent *probe_ent; - unsigned long bmdma; probe_ent = ata_probe_ent_alloc(pci_dev_to_dev(pdev), port); if (!probe_ent) @@ -779,13 +766,8 @@ static struct ata_probe_ent *ata_pci_init_legacy_port(struct pci_dev *pdev, break; } - bmdma = pci_resource_start(pdev, 4); - if (bmdma != 0) { - bmdma += 8 * port_num; - probe_ent->port[0].bmdma_addr = bmdma; - if (inb(bmdma + 2) & 0x80) - probe_ent->host_set_flags |= ATA_HOST_SIMPLEX; - } + probe_ent->port[0].bmdma_addr = + pci_resource_start(pdev, 4) + 8 * port_num; ata_std_ports(&probe_ent->port[0]); return probe_ent; diff --git a/trunk/drivers/scsi/libata-core.c b/trunk/drivers/scsi/libata-core.c index e63c1ff1e102..d279666dcb38 100644 --- a/trunk/drivers/scsi/libata-core.c +++ b/trunk/drivers/scsi/libata-core.c @@ -62,9 +62,7 @@ #include "libata.h" static unsigned int ata_dev_init_params(struct ata_port *ap, - struct ata_device *dev, - u16 heads, - u16 sectors); + struct ata_device *dev); static void ata_set_mode(struct ata_port *ap); static unsigned int ata_dev_set_xfermode(struct ata_port *ap, struct ata_device *dev); @@ -278,7 +276,7 @@ static void ata_unpack_xfermask(unsigned int xfer_mask, } static const struct ata_xfer_ent { - int shift, bits; + unsigned int shift, bits; u8 base; } ata_xfer_tbl[] = { { ATA_SHIFT_PIO, ATA_BITS_PIO, XFER_PIO_0 }, @@ -989,7 +987,9 @@ ata_exec_internal(struct ata_port *ap, struct ata_device *dev, qc->private_data = &wait; qc->complete_fn = ata_qc_complete_internal; - ata_qc_issue(qc); + qc->err_mask = ata_qc_issue(qc); + if (qc->err_mask) + ata_qc_complete(qc); spin_unlock_irqrestore(&ap->host_set->lock, flags); @@ -1081,8 +1081,9 @@ unsigned int ata_pio_need_iordy(const struct ata_device *adev) * * Read ID data from the specified device. ATA_CMD_ID_ATA is * performed on ATA devices and ATA_CMD_ID_ATAPI on ATAPI - * devices. This function also issues ATA_CMD_INIT_DEV_PARAMS - * for pre-ATA4 drives. + * devices. This function also takes care of EDD signature + * misreporting (to be removed once EDD support is gone) and + * issues ATA_CMD_INIT_DEV_PARAMS for pre-ATA4 drives. * * LOCKING: * Kernel thread context (may sleep) @@ -1094,6 +1095,7 @@ static int ata_dev_read_id(struct ata_port *ap, struct ata_device *dev, unsigned int *p_class, int post_reset, u16 **p_id) { unsigned int class = *p_class; + unsigned int using_edd; struct ata_taskfile tf; unsigned int err_mask = 0; u16 *id; @@ -1102,6 +1104,12 @@ static int ata_dev_read_id(struct ata_port *ap, struct ata_device *dev, DPRINTK("ENTER, host %u, dev %u\n", ap->id, dev->devno); + if (ap->ops->probe_reset || + ap->flags & (ATA_FLAG_SRST | ATA_FLAG_SATA_RESET)) + using_edd = 0; + else + using_edd = 1; + ata_dev_select(ap, dev->devno, 1, 1); /* select device 0/1 */ id = kmalloc(sizeof(id[0]) * ATA_ID_WORDS, GFP_KERNEL); @@ -1131,16 +1139,39 @@ static int ata_dev_read_id(struct ata_port *ap, struct ata_device *dev, err_mask = ata_exec_internal(ap, dev, &tf, DMA_FROM_DEVICE, id, sizeof(id[0]) * ATA_ID_WORDS); + if (err_mask) { rc = -EIO; reason = "I/O error"; + + if (err_mask & ~AC_ERR_DEV) + goto err_out; + + /* + * arg! EDD works for all test cases, but seems to return + * the ATA signature for some ATAPI devices. Until the + * reason for this is found and fixed, we fix up the mess + * here. If IDENTIFY DEVICE returns command aborted + * (as ATAPI devices do), then we issue an + * IDENTIFY PACKET DEVICE. + * + * ATA software reset (SRST, the default) does not appear + * to have this problem. + */ + if ((using_edd) && (class == ATA_DEV_ATA)) { + u8 err = tf.feature; + if (err & ATA_ABORTED) { + class = ATA_DEV_ATAPI; + goto retry; + } + } goto err_out; } swap_buf_le16(id, ATA_ID_WORDS); /* sanity check */ - if ((class == ATA_DEV_ATA) != (ata_id_is_ata(id) | ata_id_is_cfa(id))) { + if ((class == ATA_DEV_ATA) != ata_id_is_ata(id)) { rc = -EINVAL; reason = "device reports illegal type"; goto err_out; @@ -1156,7 +1187,7 @@ static int ata_dev_read_id(struct ata_port *ap, struct ata_device *dev, * Some drives were very specific about that exact sequence. */ if (ata_id_major_version(id) < 4 || !ata_id_has_lba(id)) { - err_mask = ata_dev_init_params(ap, dev, id[3], id[6]); + err_mask = ata_dev_init_params(ap, dev); if (err_mask) { rc = -EIO; reason = "INIT_DEV_PARAMS failed"; @@ -1409,11 +1440,7 @@ static int ata_bus_probe(struct ata_port *ap) if (!found) goto err_out_disable; - if (ap->ops->set_mode) - ap->ops->set_mode(ap); - else - ata_set_mode(ap); - + ata_set_mode(ap); if (ap->flags & ATA_FLAG_PORT_DISABLED) goto err_out_disable; @@ -1818,7 +1845,7 @@ static void ata_host_set_dma(struct ata_port *ap) */ static void ata_set_mode(struct ata_port *ap) { - int i, rc, used_dma = 0; + int i, rc; /* step 1: calculate xfer_mask */ for (i = 0; i < ATA_MAX_DEVICES; i++) { @@ -1836,9 +1863,6 @@ static void ata_set_mode(struct ata_port *ap) dma_mask = ata_pack_xfermask(0, dev->mwdma_mask, dev->udma_mask); dev->pio_mode = ata_xfer_mask2mode(pio_mask); dev->dma_mode = ata_xfer_mask2mode(dma_mask); - - if (dev->dma_mode) - used_dma = 1; } /* step 2: always set host PIO timings */ @@ -1860,17 +1884,6 @@ static void ata_set_mode(struct ata_port *ap) goto err_out; } - /* - * Record simplex status. If we selected DMA then the other - * host channels are not permitted to do so. - */ - - if (used_dma && (ap->host_set->flags & ATA_HOST_SIMPLEX)) - ap->host_set->simplex_claimed = 1; - - /* - * Chip specific finalisation - */ if (ap->ops->post_set_mode) ap->ops->post_set_mode(ap); @@ -1992,6 +2005,45 @@ static void ata_bus_post_reset(struct ata_port *ap, unsigned int devmask) ap->ops->dev_select(ap, 0); } +/** + * ata_bus_edd - Issue EXECUTE DEVICE DIAGNOSTIC command. + * @ap: Port to reset and probe + * + * Use the EXECUTE DEVICE DIAGNOSTIC command to reset and + * probe the bus. Not often used these days. + * + * LOCKING: + * PCI/etc. bus probe sem. + * Obtains host_set lock. + * + */ + +static unsigned int ata_bus_edd(struct ata_port *ap) +{ + struct ata_taskfile tf; + unsigned long flags; + + /* set up execute-device-diag (bus reset) taskfile */ + /* also, take interrupts to a known state (disabled) */ + DPRINTK("execute-device-diag\n"); + ata_tf_init(ap, &tf, 0); + tf.ctl |= ATA_NIEN; + tf.command = ATA_CMD_EDD; + tf.protocol = ATA_PROT_NODATA; + + /* do bus reset */ + spin_lock_irqsave(&ap->host_set->lock, flags); + ata_tf_to_host(ap, &tf); + spin_unlock_irqrestore(&ap->host_set->lock, flags); + + /* spec says at least 2ms. but who knows with those + * crazy ATAPI devices... + */ + msleep(150); + + return ata_busy_sleep(ap, ATA_TMOUT_BOOT_QUICK, ATA_TMOUT_BOOT); +} + static unsigned int ata_bus_softreset(struct ata_port *ap, unsigned int devmask) { @@ -2026,12 +2078,13 @@ static unsigned int ata_bus_softreset(struct ata_port *ap, */ msleep(150); + /* Before we perform post reset processing we want to see if - * the bus shows 0xFF because the odd clown forgets the D7 - * pulldown resistor. - */ + the bus shows 0xFF because the odd clown forgets the D7 pulldown + resistor */ + if (ata_check_status(ap) == 0xFF) - return AC_ERR_OTHER; + return 1; /* Positive is failure for some reason */ ata_bus_post_reset(ap, devmask); @@ -2063,7 +2116,7 @@ void ata_bus_reset(struct ata_port *ap) struct ata_ioports *ioaddr = &ap->ioaddr; unsigned int slave_possible = ap->flags & ATA_FLAG_SLAVE_POSS; u8 err; - unsigned int dev0, dev1 = 0, devmask = 0; + unsigned int dev0, dev1 = 0, rc = 0, devmask = 0; DPRINTK("ENTER, host %u, port %u\n", ap->id, ap->port_no); @@ -2086,8 +2139,18 @@ void ata_bus_reset(struct ata_port *ap) /* issue bus reset */ if (ap->flags & ATA_FLAG_SRST) - if (ata_bus_softreset(ap, devmask)) - goto err_out; + rc = ata_bus_softreset(ap, devmask); + else if ((ap->flags & ATA_FLAG_SATA_RESET) == 0) { + /* set up device control */ + if (ap->flags & ATA_FLAG_MMIO) + writeb(ap->ctl, (void __iomem *) ioaddr->ctl_addr); + else + outb(ap->ctl, ioaddr->ctl_addr); + rc = ata_bus_edd(ap); + } + + if (rc) + goto err_out; /* * determine by signature whether we have ATA or ATAPI devices @@ -2160,9 +2223,9 @@ static int sata_phy_resume(struct ata_port *ap) * so makes reset sequence different from the original * ->phy_reset implementation and Jeff nervous. :-P */ -void ata_std_probeinit(struct ata_port *ap) +extern void ata_std_probeinit(struct ata_port *ap) { - if ((ap->flags & ATA_FLAG_SATA) && ap->ops->scr_read) { + if (ap->flags & ATA_FLAG_SATA && ap->ops->scr_read) { sata_phy_resume(ap); if (sata_dev_present(ap)) ata_busy_sleep(ap, ATA_TMOUT_BOOT_QUICK, ATA_TMOUT_BOOT); @@ -2651,23 +2714,18 @@ static int ata_dma_blacklisted(const struct ata_device *dev) * known limits including host controller limits, device * blacklist, etc... * - * FIXME: The current implementation limits all transfer modes to - * the fastest of the lowested device on the port. This is not - * required on most controllers. - * * LOCKING: * None. */ static void ata_dev_xfermask(struct ata_port *ap, struct ata_device *dev) { - struct ata_host_set *hs = ap->host_set; unsigned long xfer_mask; int i; xfer_mask = ata_pack_xfermask(ap->pio_mask, ap->mwdma_mask, ap->udma_mask); - /* FIXME: Use port-wide xfermask for now */ + /* use port-wide xfermask for now */ for (i = 0; i < ATA_MAX_DEVICES; i++) { struct ata_device *d = &ap->device[i]; if (!ata_dev_present(d)) @@ -2677,23 +2735,12 @@ static void ata_dev_xfermask(struct ata_port *ap, struct ata_device *dev) xfer_mask &= ata_id_xfermask(d->id); if (ata_dma_blacklisted(d)) xfer_mask &= ~(ATA_MASK_MWDMA | ATA_MASK_UDMA); - /* Apply cable rule here. Don't apply it early because when - we handle hot plug the cable type can itself change */ - if (ap->cbl == ATA_CBL_PATA40) - xfer_mask &= ~(0xF8 << ATA_SHIFT_UDMA); } if (ata_dma_blacklisted(dev)) printk(KERN_WARNING "ata%u: dev %u is on DMA blacklist, " "disabling DMA\n", ap->id, dev->devno); - if (hs->flags & ATA_HOST_SIMPLEX) { - if (hs->simplex_claimed) - xfer_mask &= ~(ATA_MASK_MWDMA | ATA_MASK_UDMA); - } - if (ap->ops->mode_filter) - xfer_mask = ap->ops->mode_filter(ap, dev, xfer_mask); - ata_unpack_xfermask(xfer_mask, &dev->pio_mask, &dev->mwdma_mask, &dev->udma_mask); } @@ -2748,16 +2795,16 @@ static unsigned int ata_dev_set_xfermode(struct ata_port *ap, */ static unsigned int ata_dev_init_params(struct ata_port *ap, - struct ata_device *dev, - u16 heads, - u16 sectors) + struct ata_device *dev) { struct ata_taskfile tf; unsigned int err_mask; + u16 sectors = dev->id[6]; + u16 heads = dev->id[3]; /* Number of sectors per track 1-255. Number of heads 1-16 */ if (sectors < 1 || sectors > 255 || heads < 1 || heads > 16) - return AC_ERR_INVALID; + return 0; /* set up init dev params taskfile */ DPRINTK("init dev params \n"); @@ -3995,14 +4042,15 @@ static inline int ata_should_dma_map(struct ata_queued_cmd *qc) * * LOCKING: * spin_lock_irqsave(host_set lock) + * + * RETURNS: + * Zero on success, AC_ERR_* mask on failure */ -void ata_qc_issue(struct ata_queued_cmd *qc) + +unsigned int ata_qc_issue(struct ata_queued_cmd *qc) { struct ata_port *ap = qc->ap; - qc->ap->active_tag = qc->tag; - qc->flags |= ATA_QCFLAG_ACTIVE; - if (ata_should_dma_map(qc)) { if (qc->flags & ATA_QCFLAG_SG) { if (ata_sg_setup(qc)) @@ -4017,18 +4065,17 @@ void ata_qc_issue(struct ata_queued_cmd *qc) ap->ops->qc_prep(qc); - qc->err_mask |= ap->ops->qc_issue(qc); - if (unlikely(qc->err_mask)) - goto err; - return; + qc->ap->active_tag = qc->tag; + qc->flags |= ATA_QCFLAG_ACTIVE; + + return ap->ops->qc_issue(qc); sg_err: qc->flags &= ~ATA_QCFLAG_DMAMAP; - qc->err_mask |= AC_ERR_SYSTEM; -err: - ata_qc_complete(qc); + return AC_ERR_SYSTEM; } + /** * ata_qc_issue_prot - issue taskfile to device in proto-dependent manner * @qc: command to issue to device @@ -4489,14 +4536,6 @@ static struct ata_port * ata_host_add(const struct ata_probe_ent *ent, int rc; DPRINTK("ENTER\n"); - - if (!ent->port_ops->probe_reset && - !(ent->host_flags & (ATA_FLAG_SATA_RESET | ATA_FLAG_SRST))) { - printk(KERN_ERR "ata%u: no reset mechanism available\n", - port_no); - return NULL; - } - host = scsi_host_alloc(ent->sht, sizeof(struct ata_port)); if (!host) return NULL; @@ -4557,7 +4596,6 @@ int ata_device_add(const struct ata_probe_ent *ent) host_set->mmio_base = ent->mmio_base; host_set->private_data = ent->private_data; host_set->ops = ent->port_ops; - host_set->flags = ent->host_set_flags; /* register each port bound to this device */ for (i = 0; i < ent->n_ports; i++) { diff --git a/trunk/drivers/scsi/libata-scsi.c b/trunk/drivers/scsi/libata-scsi.c index 53f5b0d9161c..628191bfd990 100644 --- a/trunk/drivers/scsi/libata-scsi.c +++ b/trunk/drivers/scsi/libata-scsi.c @@ -1431,7 +1431,9 @@ static void ata_scsi_translate(struct ata_port *ap, struct ata_device *dev, goto early_finish; /* select device, send command to hardware */ - ata_qc_issue(qc); + qc->err_mask = ata_qc_issue(qc); + if (qc->err_mask) + ata_qc_complete(qc); VPRINTK("EXIT\n"); return; @@ -2197,7 +2199,9 @@ static void atapi_request_sense(struct ata_queued_cmd *qc) qc->complete_fn = atapi_sense_complete; - ata_qc_issue(qc); + qc->err_mask = ata_qc_issue(qc); + if (qc->err_mask) + ata_qc_complete(qc); DPRINTK("EXIT\n"); } diff --git a/trunk/drivers/scsi/libata.h b/trunk/drivers/scsi/libata.h index 1c755b14521a..65f52beea884 100644 --- a/trunk/drivers/scsi/libata.h +++ b/trunk/drivers/scsi/libata.h @@ -47,7 +47,7 @@ extern struct ata_queued_cmd *ata_qc_new_init(struct ata_port *ap, extern int ata_rwcmd_protocol(struct ata_queued_cmd *qc); extern void ata_port_flush_task(struct ata_port *ap); extern void ata_qc_free(struct ata_queued_cmd *qc); -extern void ata_qc_issue(struct ata_queued_cmd *qc); +extern unsigned int ata_qc_issue(struct ata_queued_cmd *qc); extern int ata_check_atapi_dma(struct ata_queued_cmd *qc); extern void ata_dev_select(struct ata_port *ap, unsigned int device, unsigned int wait, unsigned int can_sleep); diff --git a/trunk/drivers/scsi/mesh.c b/trunk/drivers/scsi/mesh.c index f852421002ef..d6d2125f9044 100644 --- a/trunk/drivers/scsi/mesh.c +++ b/trunk/drivers/scsi/mesh.c @@ -1748,7 +1748,7 @@ static int mesh_host_reset(struct scsi_cmnd *cmd) static void set_mesh_power(struct mesh_state *ms, int state) { - if (!machine_is(powermac)) + if (_machine != _MACH_Pmac) return; if (state) { pmac_call_feature(PMAC_FTR_MESH_ENABLE, macio_get_of_node(ms->mdev), 0, 1); diff --git a/trunk/drivers/scsi/sata_mv.c b/trunk/drivers/scsi/sata_mv.c index fa901fd65085..275ed9bd898c 100644 --- a/trunk/drivers/scsi/sata_mv.c +++ b/trunk/drivers/scsi/sata_mv.c @@ -1010,7 +1010,7 @@ static void mv_fill_sg(struct ata_queued_cmd *qc) pp->sg_tbl[i].addr = cpu_to_le32(addr & 0xffffffff); pp->sg_tbl[i].addr_hi = cpu_to_le32((addr >> 16) >> 16); - pp->sg_tbl[i].flags_size = cpu_to_le32(len & 0xffff); + pp->sg_tbl[i].flags_size = cpu_to_le32(len); sg_len -= len; addr += len; @@ -1350,6 +1350,7 @@ static void mv_host_intr(struct ata_host_set *host_set, u32 relevant, { void __iomem *mmio = host_set->mmio_base; void __iomem *hc_mmio = mv_hc_base(mmio, hc); + struct ata_port *ap; struct ata_queued_cmd *qc; u32 hc_irq_cause; int shift, port, port0, hard_port, handled; @@ -1372,32 +1373,25 @@ static void mv_host_intr(struct ata_host_set *host_set, u32 relevant, for (port = port0; port < port0 + MV_PORTS_PER_HC; port++) { u8 ata_status = 0; - struct ata_port *ap = host_set->ports[port]; - struct mv_port_priv *pp = ap->private_data; - + ap = host_set->ports[port]; hard_port = port & MV_PORT_MASK; /* range 0-3 */ handled = 0; /* ensure ata_status is set if handled++ */ - /* Note that DEV_IRQ might happen spuriously during EDMA, - * and should be ignored in such cases. We could mask it, - * but it's pretty rare and may not be worth the overhead. - */ - if (pp->pp_flags & MV_PP_FLAG_EDMA_EN) { - /* EDMA: check for response queue interrupt */ - if ((CRPB_DMA_DONE << hard_port) & hc_irq_cause) { - ata_status = mv_get_crpb_status(ap); - handled = 1; - } - } else { - /* PIO: check for device (drive) interrupt */ - if ((DEV_IRQ << hard_port) & hc_irq_cause) { - ata_status = readb((void __iomem *) + if ((CRPB_DMA_DONE << hard_port) & hc_irq_cause) { + /* new CRPB on the queue; just one at a time until NCQ + */ + ata_status = mv_get_crpb_status(ap); + handled++; + } else if ((DEV_IRQ << hard_port) & hc_irq_cause) { + /* received ATA IRQ; read the status reg to clear INTRQ + */ + ata_status = readb((void __iomem *) ap->ioaddr.status_addr); - handled = 1; - } + handled++; } - if (ap->flags & (ATA_FLAG_PORT_DISABLED | ATA_FLAG_NOINTR)) + if (ap && + (ap->flags & (ATA_FLAG_PORT_DISABLED | ATA_FLAG_NOINTR))) continue; err_mask = ac_err_mask(ata_status); @@ -1409,12 +1403,12 @@ static void mv_host_intr(struct ata_host_set *host_set, u32 relevant, if ((PORT0_ERR << shift) & relevant) { mv_err_intr(ap); err_mask |= AC_ERR_OTHER; - handled = 1; + handled++; } - if (handled) { + if (handled && ap) { qc = ata_qc_from_tag(ap, ap->active_tag); - if (qc && (qc->flags & ATA_QCFLAG_ACTIVE)) { + if (NULL != qc) { VPRINTK("port %u IRQ found for qc, " "ata_status 0x%x\n", port,ata_status); /* mark qc status appropriately */ diff --git a/trunk/drivers/scsi/zalon.c b/trunk/drivers/scsi/zalon.c index a6cfbb3b361c..b131432c677d 100644 --- a/trunk/drivers/scsi/zalon.c +++ b/trunk/drivers/scsi/zalon.c @@ -88,7 +88,7 @@ zalon_probe(struct parisc_device *dev) struct gsc_irq gsc_irq; u32 zalon_vers; int error = -ENODEV; - void __iomem *zalon = ioremap_nocache(dev->hpa.start, 4096); + void __iomem *zalon = ioremap(dev->hpa.start, 4096); void __iomem *io_port = zalon + GSC_SCSI_ZALON_OFFSET; static int unit = 0; struct Scsi_Host *host; diff --git a/trunk/drivers/serial/8250_gsc.c b/trunk/drivers/serial/8250_gsc.c index 913c71cc0569..8b4947933d9b 100644 --- a/trunk/drivers/serial/8250_gsc.c +++ b/trunk/drivers/serial/8250_gsc.c @@ -52,14 +52,13 @@ serial_init_chip(struct parisc_device *dev) address += 0x800; } - memset(&port, 0, sizeof(port)); - port.iotype = UPIO_MEM; - port.uartclk = LASI_BASE_BAUD * 16; - port.mapbase = address; - port.membase = ioremap_nocache(address, 16); - port.irq = dev->irq; - port.flags = UPF_BOOT_AUTOCONF; - port.dev = &dev->dev; + memset(&port, 0, sizeof(struct uart_port)); + port.mapbase = address; + port.irq = dev->irq; + port.iotype = UPIO_MEM; + port.flags = UPF_IOREMAP | UPF_BOOT_AUTOCONF; + port.uartclk = LASI_BASE_BAUD * 16; + port.dev = &dev->dev; err = serial8250_register_port(&port); if (err < 0) { diff --git a/trunk/drivers/serial/Kconfig b/trunk/drivers/serial/Kconfig index fe0d8b8e91c8..7d22dc0478d3 100644 --- a/trunk/drivers/serial/Kconfig +++ b/trunk/drivers/serial/Kconfig @@ -63,6 +63,33 @@ config SERIAL_8250_CONSOLE If unsure, say N. +config SERIAL_8250_GSC + tristate + depends on SERIAL_8250 && GSC + default SERIAL_8250 + +config SERIAL_8250_PCI + tristate "8250/16550 PCI device support" if EMBEDDED + depends on SERIAL_8250 && PCI + default SERIAL_8250 + help + This builds standard PCI serial support. You may be able to + disable this feature if you only need legacy serial support. + Saves about 9K. + +config SERIAL_8250_PNP + tristate "8250/16550 PNP device support" if EMBEDDED + depends on SERIAL_8250 && PNP + default SERIAL_8250 + help + This builds standard PNP serial support. You may be able to + disable this feature if you only need legacy serial support. + +config SERIAL_8250_HP300 + tristate + depends on SERIAL_8250 && HP300 + default SERIAL_8250 + config SERIAL_8250_CS tristate "8250/16550 PCMCIA device support" depends on PCMCIA && SERIAL_8250 diff --git a/trunk/drivers/serial/Makefile b/trunk/drivers/serial/Makefile index d2b4c214876b..0a71bf68a03f 100644 --- a/trunk/drivers/serial/Makefile +++ b/trunk/drivers/serial/Makefile @@ -4,15 +4,13 @@ # $Id: Makefile,v 1.8 2002/07/21 21:32:30 rmk Exp $ # -serial-8250-y := -serial-8250-$(CONFIG_PNP) += 8250_pnp.o -serial-8250-$(CONFIG_GSC) += 8250_gsc.o -serial-8250-$(CONFIG_PCI) += 8250_pci.o -serial-8250-$(CONFIG_HP300) += 8250_hp300.o - obj-$(CONFIG_SERIAL_CORE) += serial_core.o obj-$(CONFIG_SERIAL_21285) += 21285.o -obj-$(CONFIG_SERIAL_8250) += 8250.o $(serial-8250-y) +obj-$(CONFIG_SERIAL_8250) += 8250.o +obj-$(CONFIG_SERIAL_8250_PNP) += 8250_pnp.o +obj-$(CONFIG_SERIAL_8250_GSC) += 8250_gsc.o +obj-$(CONFIG_SERIAL_8250_PCI) += 8250_pci.o +obj-$(CONFIG_SERIAL_8250_HP300) += 8250_hp300.o obj-$(CONFIG_SERIAL_8250_CS) += serial_cs.o obj-$(CONFIG_SERIAL_8250_ACORN) += 8250_acorn.o obj-$(CONFIG_SERIAL_8250_CONSOLE) += 8250_early.o diff --git a/trunk/drivers/serial/jsm/jsm_tty.c b/trunk/drivers/serial/jsm/jsm_tty.c index 7d823705193c..4d48b625cd3d 100644 --- a/trunk/drivers/serial/jsm/jsm_tty.c +++ b/trunk/drivers/serial/jsm/jsm_tty.c @@ -142,14 +142,12 @@ static void jsm_tty_send_xchar(struct uart_port *port, char ch) { unsigned long lock_flags; struct jsm_channel *channel = (struct jsm_channel *)port; - struct termios *termios; spin_lock_irqsave(&port->lock, lock_flags); - termios = port->info->tty->termios; - if (ch == termios->c_cc[VSTART]) + if (ch == port->info->tty->termios->c_cc[VSTART]) channel->ch_bd->bd_ops->send_start_character(channel); - if (ch == termios->c_cc[VSTOP]) + if (ch == port->info->tty->termios->c_cc[VSTOP]) channel->ch_bd->bd_ops->send_stop_character(channel); spin_unlock_irqrestore(&port->lock, lock_flags); } @@ -180,7 +178,6 @@ static int jsm_tty_open(struct uart_port *port) struct jsm_board *brd; int rc = 0; struct jsm_channel *channel = (struct jsm_channel *)port; - struct termios *termios; /* Get board pointer from our array of majors we have allocated */ brd = channel->ch_bd; @@ -242,13 +239,12 @@ static int jsm_tty_open(struct uart_port *port) channel->ch_cached_lsr = 0; channel->ch_stops_sent = 0; - termios = port->info->tty->termios; - channel->ch_c_cflag = termios->c_cflag; - channel->ch_c_iflag = termios->c_iflag; - channel->ch_c_oflag = termios->c_oflag; - channel->ch_c_lflag = termios->c_lflag; - channel->ch_startc = termios->c_cc[VSTART]; - channel->ch_stopc = termios->c_cc[VSTOP]; + channel->ch_c_cflag = port->info->tty->termios->c_cflag; + channel->ch_c_iflag = port->info->tty->termios->c_iflag; + channel->ch_c_oflag = port->info->tty->termios->c_oflag; + channel->ch_c_lflag = port->info->tty->termios->c_lflag; + channel->ch_startc = port->info->tty->termios->c_cc[VSTART]; + channel->ch_stopc = port->info->tty->termios->c_cc[VSTOP]; /* Tell UART to init itself */ brd->bd_ops->uart_init(channel); @@ -788,7 +784,6 @@ static void jsm_carrier(struct jsm_channel *ch) void jsm_check_queue_flow_control(struct jsm_channel *ch) { - struct board_ops *bd_ops = ch->ch_bd->bd_ops; int qleft = 0; /* Store how much space we have left in the queue */ @@ -814,7 +809,7 @@ void jsm_check_queue_flow_control(struct jsm_channel *ch) /* HWFLOW */ if (ch->ch_c_cflag & CRTSCTS) { if(!(ch->ch_flags & CH_RECEIVER_OFF)) { - bd_ops->disable_receiver(ch); + ch->ch_bd->bd_ops->disable_receiver(ch); ch->ch_flags |= (CH_RECEIVER_OFF); jsm_printk(READ, INFO, &ch->ch_bd->pci_dev, "Internal queue hit hilevel mark (%d)! Turning off interrupts.\n", @@ -824,7 +819,7 @@ void jsm_check_queue_flow_control(struct jsm_channel *ch) /* SWFLOW */ else if (ch->ch_c_iflag & IXOFF) { if (ch->ch_stops_sent <= MAX_STOPS_SENT) { - bd_ops->send_stop_character(ch); + ch->ch_bd->bd_ops->send_stop_character(ch); ch->ch_stops_sent++; jsm_printk(READ, INFO, &ch->ch_bd->pci_dev, "Sending stop char! Times sent: %x\n", ch->ch_stops_sent); @@ -851,7 +846,7 @@ void jsm_check_queue_flow_control(struct jsm_channel *ch) /* HWFLOW */ if (ch->ch_c_cflag & CRTSCTS) { if (ch->ch_flags & CH_RECEIVER_OFF) { - bd_ops->enable_receiver(ch); + ch->ch_bd->bd_ops->enable_receiver(ch); ch->ch_flags &= ~(CH_RECEIVER_OFF); jsm_printk(READ, INFO, &ch->ch_bd->pci_dev, "Internal queue hit lowlevel mark (%d)! Turning on interrupts.\n", @@ -861,7 +856,7 @@ void jsm_check_queue_flow_control(struct jsm_channel *ch) /* SWFLOW */ else if (ch->ch_c_iflag & IXOFF && ch->ch_stops_sent) { ch->ch_stops_sent = 0; - bd_ops->send_start_character(ch); + ch->ch_bd->bd_ops->send_start_character(ch); jsm_printk(READ, INFO, &ch->ch_bd->pci_dev, "Sending start char!\n"); } } diff --git a/trunk/drivers/serial/mux.c b/trunk/drivers/serial/mux.c index 64c0e89124c9..868eaf4a1a68 100644 --- a/trunk/drivers/serial/mux.c +++ b/trunk/drivers/serial/mux.c @@ -51,7 +51,7 @@ #define MUX_BREAK(status) ((status & 0xF000) == 0x2000) #define MUX_NR 256 -static unsigned int port_cnt __read_mostly; +static unsigned int port_cnt = 0; static struct uart_port mux_ports[MUX_NR]; static struct uart_driver mux_driver = { @@ -461,7 +461,7 @@ static int __init mux_probe(struct parisc_device *dev) port->iobase = 0; port->mapbase = dev->hpa.start + MUX_OFFSET + (i * MUX_LINE_OFFSET); - port->membase = ioremap_nocache(port->mapbase, MUX_LINE_OFFSET); + port->membase = ioremap(port->mapbase, MUX_LINE_OFFSET); port->iotype = UPIO_MEM; port->type = PORT_MUX; port->irq = NO_IRQ; diff --git a/trunk/drivers/usb/core/hcd-pci.c b/trunk/drivers/usb/core/hcd-pci.c index 0d2193b69235..e0afb5ad29e5 100644 --- a/trunk/drivers/usb/core/hcd-pci.c +++ b/trunk/drivers/usb/core/hcd-pci.c @@ -296,7 +296,7 @@ int usb_hcd_pci_suspend (struct pci_dev *dev, pm_message_t message) #ifdef CONFIG_PPC_PMAC /* Disable ASIC clocks for USB */ - if (machine_is(powermac)) { + if (_machine == _MACH_Pmac) { struct device_node *of_node; of_node = pci_device_to_OF_node (dev); @@ -331,7 +331,7 @@ int usb_hcd_pci_resume (struct pci_dev *dev) #ifdef CONFIG_PPC_PMAC /* Reenable ASIC clocks for USB */ - if (machine_is(powermac)) { + if (_machine == _MACH_Pmac) { struct device_node *of_node; of_node = pci_device_to_OF_node (dev); diff --git a/trunk/drivers/usb/net/zd1201.c b/trunk/drivers/usb/net/zd1201.c index 9b1e4ed1d07e..fe9b60cd8d95 100644 --- a/trunk/drivers/usb/net/zd1201.c +++ b/trunk/drivers/usb/net/zd1201.c @@ -1736,7 +1736,6 @@ static const struct iw_handler_def zd1201_iw_handlers = { .standard = (iw_handler *)zd1201_iw_handler, .private = (iw_handler *)zd1201_private_handler, .private_args = (struct iw_priv_args *) zd1201_private_args, - .get_wireless_stats = zd1201_get_wireless_stats, }; static int zd1201_probe(struct usb_interface *interface, @@ -1797,6 +1796,7 @@ static int zd1201_probe(struct usb_interface *interface, zd->dev->open = zd1201_net_open; zd->dev->stop = zd1201_net_stop; zd->dev->get_stats = zd1201_get_stats; + zd->dev->get_wireless_stats = zd1201_get_wireless_stats; zd->dev->wireless_handlers = (struct iw_handler_def *)&zd1201_iw_handlers; zd->dev->hard_start_xmit = zd1201_hard_start_xmit; diff --git a/trunk/drivers/video/Kconfig b/trunk/drivers/video/Kconfig index f87c0171f4ec..22e9d696fdd2 100644 --- a/trunk/drivers/video/Kconfig +++ b/trunk/drivers/video/Kconfig @@ -904,6 +904,18 @@ config FB_MATROX_MULTIHEAD There is no need for enabling 'Matrox multihead support' if you have only one Matrox card in the box. +config FB_RADEON_OLD + tristate "ATI Radeon display support (Old driver)" + depends on FB && PCI + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + select FB_MACMODES if PPC + help + Choose this option if you want to use an ATI Radeon graphics card as + a framebuffer device. There are both PCI and AGP versions. You + don't need to choose this to run the Radeon in plain VGA mode. + config FB_RADEON tristate "ATI Radeon display support" depends on FB && PCI diff --git a/trunk/drivers/video/Makefile b/trunk/drivers/video/Makefile index 23de3b2c7856..cb90218515ac 100644 --- a/trunk/drivers/video/Makefile +++ b/trunk/drivers/video/Makefile @@ -39,6 +39,7 @@ obj-$(CONFIG_FB_KYRO) += kyro/ obj-$(CONFIG_FB_SAVAGE) += savage/ obj-$(CONFIG_FB_GEODE) += geode/ obj-$(CONFIG_FB_I810) += vgastate.o +obj-$(CONFIG_FB_RADEON_OLD) += radeonfb.o obj-$(CONFIG_FB_NEOMAGIC) += neofb.o vgastate.o obj-$(CONFIG_FB_VIRGE) += virgefb.o obj-$(CONFIG_FB_3DFX) += tdfxfb.o diff --git a/trunk/drivers/video/aty/aty128fb.c b/trunk/drivers/video/aty/aty128fb.c index f7bbff4ddc6a..821c6da8e42c 100644 --- a/trunk/drivers/video/aty/aty128fb.c +++ b/trunk/drivers/video/aty/aty128fb.c @@ -67,7 +67,6 @@ #include #ifdef CONFIG_PPC_PMAC -#include #include #include #include @@ -1749,7 +1748,7 @@ static int __init aty128_init(struct pci_dev *pdev, const struct pci_device_id * var = default_var; #ifdef CONFIG_PPC_PMAC - if (machine_is(powermac)) { + if (_machine == _MACH_Pmac) { /* Indicate sleep capability */ if (par->chip_gen == rage_M3) { pmac_call_feature(PMAC_FTR_DEVICE_CAN_WAKE, NULL, 0, 1); @@ -2012,7 +2011,7 @@ static int aty128fb_blank(int blank, struct fb_info *fb) return 0; #ifdef CONFIG_PMAC_BACKLIGHT - if (machine_is(powermac) && blank) + if ((_machine == _MACH_Pmac) && blank) set_backlight_enable(0); #endif /* CONFIG_PMAC_BACKLIGHT */ @@ -2030,7 +2029,7 @@ static int aty128fb_blank(int blank, struct fb_info *fb) aty128_set_lcd_enable(par, par->lcd_on && !blank); } #ifdef CONFIG_PMAC_BACKLIGHT - if (machine_is(powermac) && !blank) + if ((_machine == _MACH_Pmac) && !blank) set_backlight_enable(1); #endif /* CONFIG_PMAC_BACKLIGHT */ return 0; diff --git a/trunk/drivers/video/aty/atyfb_base.c b/trunk/drivers/video/aty/atyfb_base.c index b39e72d5413b..e799fcca365a 100644 --- a/trunk/drivers/video/aty/atyfb_base.c +++ b/trunk/drivers/video/aty/atyfb_base.c @@ -75,7 +75,6 @@ #include "ati_ids.h" #ifdef __powerpc__ -#include #include #include "../macmodes.h" #endif @@ -2519,7 +2518,7 @@ static int __init aty_init(struct fb_info *info, const char *name) memset(&var, 0, sizeof(var)); #ifdef CONFIG_PPC - if (machine_is(powermac)) { + if (_machine == _MACH_Pmac) { /* * FIXME: The NVRAM stuff should be put in a Mac-specific file, as it * applies to all Mac video cards @@ -2674,7 +2673,7 @@ static int atyfb_blank(int blank, struct fb_info *info) return 0; #ifdef CONFIG_PMAC_BACKLIGHT - if (machine_is(powermac) && blank > FB_BLANK_NORMAL) + if ((_machine == _MACH_Pmac) && blank > FB_BLANK_NORMAL) set_backlight_enable(0); #elif defined(CONFIG_FB_ATY_GENERIC_LCD) if (par->lcd_table && blank > FB_BLANK_NORMAL && @@ -2706,7 +2705,7 @@ static int atyfb_blank(int blank, struct fb_info *info) aty_st_le32(CRTC_GEN_CNTL, gen_cntl, par); #ifdef CONFIG_PMAC_BACKLIGHT - if (machine_is(powermac) && blank <= FB_BLANK_NORMAL) + if ((_machine == _MACH_Pmac) && blank <= FB_BLANK_NORMAL) set_backlight_enable(1); #elif defined(CONFIG_FB_ATY_GENERIC_LCD) if (par->lcd_table && blank <= FB_BLANK_NORMAL && diff --git a/trunk/drivers/video/aty/radeon_pm.c b/trunk/drivers/video/aty/radeon_pm.c index c7091761cef4..5886a2f1323e 100644 --- a/trunk/drivers/video/aty/radeon_pm.c +++ b/trunk/drivers/video/aty/radeon_pm.c @@ -20,7 +20,7 @@ #include #ifdef CONFIG_PPC_PMAC -#include +#include #include #include #endif @@ -2745,7 +2745,7 @@ void radeonfb_pm_init(struct radeonfb_info *rinfo, int dynclk) rinfo->pm_mode |= radeon_pm_off; } #if defined(CONFIG_PPC_PMAC) - if (machine_is(powermac) && rinfo->of_node) { + if (_machine == _MACH_Pmac && rinfo->of_node) { if (rinfo->is_mobility && rinfo->pm_reg && rinfo->family <= CHIP_FAMILY_RV250) rinfo->pm_mode |= radeon_pm_d2; diff --git a/trunk/drivers/video/backlight/Kconfig b/trunk/drivers/video/backlight/Kconfig index b895eaaa73fd..9d996f2c10d5 100644 --- a/trunk/drivers/video/backlight/Kconfig +++ b/trunk/drivers/video/backlight/Kconfig @@ -43,11 +43,11 @@ config LCD_DEVICE default y config BACKLIGHT_CORGI - tristate "Sharp Corgi Backlight Driver (SL Series)" + tristate "Sharp Corgi Backlight Driver (SL-C7xx Series)" depends on BACKLIGHT_DEVICE && PXA_SHARPSL default y help - If you have a Sharp Zaurus SL-C7xx, SL-Cxx00 or SL-6000x say y to enable the + If you have a Sharp Zaurus SL-C7xx, say y to enable the backlight driver. config BACKLIGHT_HP680 diff --git a/trunk/drivers/video/backlight/backlight.c b/trunk/drivers/video/backlight/backlight.c index 334b1db1bd7c..151fda8dded0 100644 --- a/trunk/drivers/video/backlight/backlight.c +++ b/trunk/drivers/video/backlight/backlight.c @@ -16,12 +16,14 @@ static ssize_t backlight_show_power(struct class_device *cdev, char *buf) { - int rc = -ENXIO; + int rc; struct backlight_device *bd = to_backlight_device(cdev); down(&bd->sem); - if (likely(bd->props)) - rc = sprintf(buf, "%d\n", bd->props->power); + if (likely(bd->props && bd->props->get_power)) + rc = sprintf(buf, "%d\n", bd->props->get_power(bd)); + else + rc = -ENXIO; up(&bd->sem); return rc; @@ -29,7 +31,7 @@ static ssize_t backlight_show_power(struct class_device *cdev, char *buf) static ssize_t backlight_store_power(struct class_device *cdev, const char *buf, size_t count) { - int rc = -ENXIO, power; + int rc, power; char *endp; struct backlight_device *bd = to_backlight_device(cdev); @@ -38,13 +40,12 @@ static ssize_t backlight_store_power(struct class_device *cdev, const char *buf, return -EINVAL; down(&bd->sem); - if (likely(bd->props)) { + if (likely(bd->props && bd->props->set_power)) { pr_debug("backlight: set power to %d\n", power); - bd->props->power = power; - if (likely(bd->props->update_status)) - bd->props->update_status(bd); + bd->props->set_power(bd, power); rc = count; - } + } else + rc = -ENXIO; up(&bd->sem); return rc; @@ -52,12 +53,14 @@ static ssize_t backlight_store_power(struct class_device *cdev, const char *buf, static ssize_t backlight_show_brightness(struct class_device *cdev, char *buf) { - int rc = -ENXIO; + int rc; struct backlight_device *bd = to_backlight_device(cdev); down(&bd->sem); - if (likely(bd->props)) - rc = sprintf(buf, "%d\n", bd->props->brightness); + if (likely(bd->props && bd->props->get_brightness)) + rc = sprintf(buf, "%d\n", bd->props->get_brightness(bd)); + else + rc = -ENXIO; up(&bd->sem); return rc; @@ -65,7 +68,7 @@ static ssize_t backlight_show_brightness(struct class_device *cdev, char *buf) static ssize_t backlight_store_brightness(struct class_device *cdev, const char *buf, size_t count) { - int rc = -ENXIO, brightness; + int rc, brightness; char *endp; struct backlight_device *bd = to_backlight_device(cdev); @@ -74,18 +77,12 @@ static ssize_t backlight_store_brightness(struct class_device *cdev, const char return -EINVAL; down(&bd->sem); - if (likely(bd->props)) { - if (brightness > bd->props->max_brightness) - rc = -EINVAL; - else { - pr_debug("backlight: set brightness to %d\n", - brightness); - bd->props->brightness = brightness; - if (likely(bd->props->update_status)) - bd->props->update_status(bd); - rc = count; - } - } + if (likely(bd->props && bd->props->set_brightness)) { + pr_debug("backlight: set brightness to %d\n", brightness); + bd->props->set_brightness(bd, brightness); + rc = count; + } else + rc = -ENXIO; up(&bd->sem); return rc; @@ -93,26 +90,14 @@ static ssize_t backlight_store_brightness(struct class_device *cdev, const char static ssize_t backlight_show_max_brightness(struct class_device *cdev, char *buf) { - int rc = -ENXIO; + int rc; struct backlight_device *bd = to_backlight_device(cdev); down(&bd->sem); if (likely(bd->props)) rc = sprintf(buf, "%d\n", bd->props->max_brightness); - up(&bd->sem); - - return rc; -} - -static ssize_t backlight_show_actual_brightness(struct class_device *cdev, - char *buf) -{ - int rc = -ENXIO; - struct backlight_device *bd = to_backlight_device(cdev); - - down(&bd->sem); - if (likely(bd->props && bd->props->get_brightness)) - rc = sprintf(buf, "%d\n", bd->props->get_brightness(bd)); + else + rc = -ENXIO; up(&bd->sem); return rc; @@ -138,10 +123,7 @@ static struct class backlight_class = { static struct class_device_attribute bl_class_device_attributes[] = { DECLARE_ATTR(power, 0644, backlight_show_power, backlight_store_power), - DECLARE_ATTR(brightness, 0644, backlight_show_brightness, - backlight_store_brightness), - DECLARE_ATTR(actual_brightness, 0444, backlight_show_actual_brightness, - NULL), + DECLARE_ATTR(brightness, 0644, backlight_show_brightness, backlight_store_brightness), DECLARE_ATTR(max_brightness, 0444, backlight_show_max_brightness, NULL), }; @@ -162,12 +144,8 @@ static int fb_notifier_callback(struct notifier_block *self, bd = container_of(self, struct backlight_device, fb_notif); down(&bd->sem); if (bd->props) - if (!bd->props->check_fb || - bd->props->check_fb(evdata->info)) { - bd->props->fb_blank = *(int *)evdata->data; - if (likely(bd->props && bd->props->update_status)) - bd->props->update_status(bd); - } + if (!bd->props->check_fb || bd->props->check_fb(evdata->info)) + bd->props->set_power(bd, *(int *)evdata->data); up(&bd->sem); return 0; } @@ -253,12 +231,6 @@ void backlight_device_unregister(struct backlight_device *bd) &bl_class_device_attributes[i]); down(&bd->sem); - if (likely(bd->props && bd->props->update_status)) { - bd->props->brightness = 0; - bd->props->power = 0; - bd->props->update_status(bd); - } - bd->props = NULL; up(&bd->sem); diff --git a/trunk/drivers/video/backlight/corgi_bl.c b/trunk/drivers/video/backlight/corgi_bl.c index 2ebbfd95145f..d0aaf450e8c7 100644 --- a/trunk/drivers/video/backlight/corgi_bl.c +++ b/trunk/drivers/video/backlight/corgi_bl.c @@ -1,7 +1,7 @@ /* - * Backlight Driver for Sharp Zaurus Handhelds (various models) + * Backlight Driver for Sharp Corgi * - * Copyright (c) 2004-2006 Richard Purdie + * Copyright (c) 2004-2005 Richard Purdie * * Based on Sharp's 2.4 Backlight Driver * @@ -15,63 +15,80 @@ #include #include #include -#include +#include #include #include + #include #include -static int corgibl_intensity; -static DEFINE_MUTEX(bl_mutex); -static struct backlight_properties corgibl_data; -static struct backlight_device *corgi_backlight_device; -static struct corgibl_machinfo *bl_machinfo; +#define CORGI_DEFAULT_INTENSITY 0x1f +#define CORGI_LIMIT_MASK 0x0b -static unsigned long corgibl_flags; -#define CORGIBL_SUSPENDED 0x01 -#define CORGIBL_BATTLOW 0x02 +static int corgibl_powermode = FB_BLANK_UNBLANK; +static int current_intensity = 0; +static int corgibl_limit = 0; +static void (*corgibl_mach_set_intensity)(int intensity); +static spinlock_t bl_lock = SPIN_LOCK_UNLOCKED; +static struct backlight_properties corgibl_data; -static int corgibl_send_intensity(struct backlight_device *bd) +static void corgibl_send_intensity(int intensity) { + unsigned long flags; void (*corgi_kick_batt)(void); - int intensity = bd->props->brightness; - if (bd->props->power != FB_BLANK_UNBLANK) - intensity = 0; - if (bd->props->fb_blank != FB_BLANK_UNBLANK) - intensity = 0; - if (corgibl_flags & CORGIBL_SUSPENDED) + if (corgibl_powermode != FB_BLANK_UNBLANK) { intensity = 0; - if (corgibl_flags & CORGIBL_BATTLOW) - intensity &= bl_machinfo->limit_mask; + } else { + if (corgibl_limit) + intensity &= CORGI_LIMIT_MASK; + } - mutex_lock(&bl_mutex); - bl_machinfo->set_bl_intensity(intensity); - mutex_unlock(&bl_mutex); + spin_lock_irqsave(&bl_lock, flags); - corgibl_intensity = intensity; + corgibl_mach_set_intensity(intensity); + + spin_unlock_irqrestore(&bl_lock, flags); corgi_kick_batt = symbol_get(sharpsl_battery_kick); if (corgi_kick_batt) { corgi_kick_batt(); symbol_put(sharpsl_battery_kick); } +} - return 0; +static void corgibl_blank(int blank) +{ + switch(blank) { + + case FB_BLANK_NORMAL: + case FB_BLANK_VSYNC_SUSPEND: + case FB_BLANK_HSYNC_SUSPEND: + case FB_BLANK_POWERDOWN: + if (corgibl_powermode == FB_BLANK_UNBLANK) { + corgibl_send_intensity(0); + corgibl_powermode = blank; + } + break; + case FB_BLANK_UNBLANK: + if (corgibl_powermode != FB_BLANK_UNBLANK) { + corgibl_powermode = blank; + corgibl_send_intensity(current_intensity); + } + break; + } } #ifdef CONFIG_PM static int corgibl_suspend(struct platform_device *dev, pm_message_t state) { - corgibl_flags |= CORGIBL_SUSPENDED; - corgibl_send_intensity(corgi_backlight_device); + corgibl_blank(FB_BLANK_POWERDOWN); return 0; } static int corgibl_resume(struct platform_device *dev) { - corgibl_flags &= ~CORGIBL_SUSPENDED; - corgibl_send_intensity(corgi_backlight_device); + corgibl_blank(FB_BLANK_UNBLANK); return 0; } #else @@ -79,55 +96,68 @@ static int corgibl_resume(struct platform_device *dev) #define corgibl_resume NULL #endif -static int corgibl_get_intensity(struct backlight_device *bd) + +static int corgibl_set_power(struct backlight_device *bd, int state) { - return corgibl_intensity; + corgibl_blank(state); + return 0; +} + +static int corgibl_get_power(struct backlight_device *bd) +{ + return corgibl_powermode; } -static int corgibl_set_intensity(struct backlight_device *bd) +static int corgibl_set_intensity(struct backlight_device *bd, int intensity) { - corgibl_send_intensity(corgi_backlight_device); + if (intensity > corgibl_data.max_brightness) + intensity = corgibl_data.max_brightness; + corgibl_send_intensity(intensity); + current_intensity=intensity; return 0; } +static int corgibl_get_intensity(struct backlight_device *bd) +{ + return current_intensity; +} + /* * Called when the battery is low to limit the backlight intensity. * If limit==0 clear any limit, otherwise limit the intensity */ void corgibl_limit_intensity(int limit) { - if (limit) - corgibl_flags |= CORGIBL_BATTLOW; - else - corgibl_flags &= ~CORGIBL_BATTLOW; - corgibl_send_intensity(corgi_backlight_device); + corgibl_limit = (limit ? 1 : 0); + corgibl_send_intensity(current_intensity); } EXPORT_SYMBOL(corgibl_limit_intensity); static struct backlight_properties corgibl_data = { - .owner = THIS_MODULE, + .owner = THIS_MODULE, + .get_power = corgibl_get_power, + .set_power = corgibl_set_power, .get_brightness = corgibl_get_intensity, - .update_status = corgibl_set_intensity, + .set_brightness = corgibl_set_intensity, }; +static struct backlight_device *corgi_backlight_device; + static int __init corgibl_probe(struct platform_device *pdev) { struct corgibl_machinfo *machinfo = pdev->dev.platform_data; - bl_machinfo = machinfo; corgibl_data.max_brightness = machinfo->max_intensity; - if (!machinfo->limit_mask) - machinfo->limit_mask = -1; + corgibl_mach_set_intensity = machinfo->set_bl_intensity; corgi_backlight_device = backlight_device_register ("corgi-bl", NULL, &corgibl_data); if (IS_ERR (corgi_backlight_device)) return PTR_ERR (corgi_backlight_device); - corgibl_data.power = FB_BLANK_UNBLANK; - corgibl_data.brightness = machinfo->default_intensity; - corgibl_send_intensity(corgi_backlight_device); + corgibl_set_intensity(NULL, CORGI_DEFAULT_INTENSITY); + corgibl_limit_intensity(0); printk("Corgi Backlight Driver Initialized.\n"); return 0; @@ -137,6 +167,8 @@ static int corgibl_remove(struct platform_device *dev) { backlight_device_unregister(corgi_backlight_device); + corgibl_set_intensity(NULL, 0); + printk("Corgi Backlight Driver Unloaded\n"); return 0; } diff --git a/trunk/drivers/video/backlight/hp680_bl.c b/trunk/drivers/video/backlight/hp680_bl.c index a71e984c93d4..95da4c9ed1f1 100644 --- a/trunk/drivers/video/backlight/hp680_bl.c +++ b/trunk/drivers/video/backlight/hp680_bl.c @@ -13,7 +13,7 @@ #include #include #include -#include +#include #include #include #include @@ -25,58 +25,66 @@ #define HP680_MAX_INTENSITY 255 #define HP680_DEFAULT_INTENSITY 10 -static int hp680bl_suspended; +static int hp680bl_powermode = FB_BLANK_UNBLANK; static int current_intensity = 0; static spinlock_t bl_lock = SPIN_LOCK_UNLOCKED; -static struct backlight_device *hp680_backlight_device; -static void hp680bl_send_intensity(struct backlight_device *bd) +static void hp680bl_send_intensity(int intensity) { unsigned long flags; - u16 v; - int intensity = bd->props->brightness; - if (bd->props->power != FB_BLANK_UNBLANK) - intensity = 0; - if (bd->props->fb_blank != FB_BLANK_UNBLANK) - intensity = 0; - if (hp680bl_suspended) + if (hp680bl_powermode != FB_BLANK_UNBLANK) intensity = 0; spin_lock_irqsave(&bl_lock, flags); - if (intensity && current_intensity == 0) { - sh_dac_enable(DAC_LCD_BRIGHTNESS); - v = inw(HD64461_GPBDR); - v &= ~HD64461_GPBDR_LCDOFF; - outw(v, HD64461_GPBDR); - sh_dac_output(255-(u8)intensity, DAC_LCD_BRIGHTNESS); - } else if (intensity == 0 && current_intensity != 0) { - sh_dac_output(255-(u8)intensity, DAC_LCD_BRIGHTNESS); - sh_dac_disable(DAC_LCD_BRIGHTNESS); - v = inw(HD64461_GPBDR); - v |= HD64461_GPBDR_LCDOFF; - outw(v, HD64461_GPBDR); - } else if (intensity) { - sh_dac_output(255-(u8)intensity, DAC_LCD_BRIGHTNESS); - } + sh_dac_output(255-(u8)intensity, DAC_LCD_BRIGHTNESS); spin_unlock_irqrestore(&bl_lock, flags); - - current_intensity = intensity; } +static void hp680bl_blank(int blank) +{ + u16 v; + + switch(blank) { + + case FB_BLANK_NORMAL: + case FB_BLANK_VSYNC_SUSPEND: + case FB_BLANK_HSYNC_SUSPEND: + case FB_BLANK_POWERDOWN: + if (hp680bl_powermode == FB_BLANK_UNBLANK) { + hp680bl_send_intensity(0); + hp680bl_powermode = blank; + sh_dac_disable(DAC_LCD_BRIGHTNESS); + v = inw(HD64461_GPBDR); + v |= HD64461_GPBDR_LCDOFF; + outw(v, HD64461_GPBDR); + } + break; + case FB_BLANK_UNBLANK: + if (hp680bl_powermode != FB_BLANK_UNBLANK) { + sh_dac_enable(DAC_LCD_BRIGHTNESS); + v = inw(HD64461_GPBDR); + v &= ~HD64461_GPBDR_LCDOFF; + outw(v, HD64461_GPBDR); + hp680bl_powermode = blank; + hp680bl_send_intensity(current_intensity); + } + break; + } +} #ifdef CONFIG_PM -static int hp680bl_suspend(struct platform_device *dev, pm_message_t state) +static int hp680bl_suspend(struct device *dev, pm_message_t state, u32 level) { - hp680bl_suspended = 1; - hp680bl_send_intensity(hp680_backlight_device); + if (level == SUSPEND_POWER_DOWN) + hp680bl_blank(FB_BLANK_POWERDOWN); return 0; } -static int hp680bl_resume(struct platform_device *dev) +static int hp680bl_resume(struct device *dev, u32 level) { - hp680bl_suspended = 0; - hp680bl_send_intensity(hp680_backlight_device); + if (level == RESUME_POWER_ON) + hp680bl_blank(FB_BLANK_UNBLANK); return 0; } #else @@ -84,9 +92,24 @@ static int hp680bl_resume(struct platform_device *dev) #define hp680bl_resume NULL #endif -static int hp680bl_set_intensity(struct backlight_device *bd) + +static int hp680bl_set_power(struct backlight_device *bd, int state) { - hp680bl_send_intensity(bd); + hp680bl_blank(state); + return 0; +} + +static int hp680bl_get_power(struct backlight_device *bd) +{ + return hp680bl_powermode; +} + +static int hp680bl_set_intensity(struct backlight_device *bd, int intensity) +{ + if (intensity > HP680_MAX_INTENSITY) + intensity = HP680_MAX_INTENSITY; + hp680bl_send_intensity(intensity); + current_intensity = intensity; return 0; } @@ -97,67 +120,65 @@ static int hp680bl_get_intensity(struct backlight_device *bd) static struct backlight_properties hp680bl_data = { .owner = THIS_MODULE, + .get_power = hp680bl_get_power, + .set_power = hp680bl_set_power, .max_brightness = HP680_MAX_INTENSITY, .get_brightness = hp680bl_get_intensity, - .update_status = hp680bl_set_intensity, + .set_brightness = hp680bl_set_intensity, }; -static int __init hp680bl_probe(struct platform_device *dev) +static struct backlight_device *hp680_backlight_device; + +static int __init hp680bl_probe(struct device *dev) { hp680_backlight_device = backlight_device_register ("hp680-bl", NULL, &hp680bl_data); if (IS_ERR (hp680_backlight_device)) return PTR_ERR (hp680_backlight_device); - hp680_backlight_device->props->brightness = HP680_DEFAULT_INTENSITY; - hp680bl_send_intensity(hp680_backlight_device); + hp680bl_set_intensity(NULL, HP680_DEFAULT_INTENSITY); return 0; } -static int hp680bl_remove(struct platform_device *dev) +static int hp680bl_remove(struct device *dev) { backlight_device_unregister(hp680_backlight_device); return 0; } -static struct platform_driver hp680bl_driver = { +static struct device_driver hp680bl_driver = { + .name = "hp680-bl", + .bus = &platform_bus_type, .probe = hp680bl_probe, .remove = hp680bl_remove, .suspend = hp680bl_suspend, .resume = hp680bl_resume, - .driver = { - .name = "hp680-bl", - }, }; -static struct platform_device *hp680bl_device; +static struct platform_device hp680bl_device = { + .name = "hp680-bl", + .id = -1, +}; static int __init hp680bl_init(void) { int ret; - ret = platform_driver_register(&hp680bl_driver); + ret=driver_register(&hp680bl_driver); if (!ret) { - hp680bl_device = platform_device_alloc("hp680-bl", -1); - if (!hp680bl_device) - return -ENOMEM; - - ret = platform_device_add(hp680bl_device); - - if (ret) { - platform_device_put(hp680bl_device); - platform_driver_unregister(&hp680bl_driver); - } + ret = platform_device_register(&hp680bl_device); + if (ret) + driver_unregister(&hp680bl_driver); } return ret; } static void __exit hp680bl_exit(void) { - platform_device_unregister(hp680bl_device); - platform_driver_unregister(&hp680bl_driver); + platform_device_unregister(&hp680bl_device); + driver_unregister(&hp680bl_driver); } module_init(hp680bl_init); diff --git a/trunk/drivers/video/cfbimgblt.c b/trunk/drivers/video/cfbimgblt.c index 8ba6152db2fd..910e2338a27e 100644 --- a/trunk/drivers/video/cfbimgblt.c +++ b/trunk/drivers/video/cfbimgblt.c @@ -169,7 +169,7 @@ static inline void slow_imageblit(const struct fb_image *image, struct fb_info * while (j--) { l--; - color = (*s & (1 << l)) ? fgcolor : bgcolor; + color = (*s & 1 << (FB_BIT_NR(l))) ? fgcolor : bgcolor; val |= FB_SHIFT_HIGH(color, shift); /* Did the bitshift spill bits to the next long? */ diff --git a/trunk/drivers/video/cirrusfb.c b/trunk/drivers/video/cirrusfb.c index 1103010af54a..66d6f2f0a219 100644 --- a/trunk/drivers/video/cirrusfb.c +++ b/trunk/drivers/video/cirrusfb.c @@ -60,8 +60,8 @@ #include #endif #ifdef CONFIG_PPC_PREP -#include -#define isPReP (machine_is(prep)) +#include +#define isPReP (_machine == _MACH_prep) #else #define isPReP 0 #endif diff --git a/trunk/drivers/video/console/fbcon.c b/trunk/drivers/video/console/fbcon.c index ca020719d20b..041d06987861 100644 --- a/trunk/drivers/video/console/fbcon.c +++ b/trunk/drivers/video/console/fbcon.c @@ -466,7 +466,7 @@ static int __init fb_console_setup(char *this_opt) int i, j; if (!this_opt || !*this_opt) - return 1; + return 0; while ((options = strsep(&this_opt, ",")) != NULL) { if (!strncmp(options, "font:", 5)) @@ -481,10 +481,10 @@ static int __init fb_console_setup(char *this_opt) options++; } if (*options != ',') - return 1; + return 0; options++; } else - return 1; + return 0; } if (!strncmp(options, "map:", 4)) { @@ -496,7 +496,7 @@ static int __init fb_console_setup(char *this_opt) con2fb_map_boot[i] = (options[j++]-'0') % FB_MAX; } - return 1; + return 0; } if (!strncmp(options, "vc:", 3)) { @@ -518,7 +518,7 @@ static int __init fb_console_setup(char *this_opt) rotate = 0; } } - return 1; + return 0; } __setup("fbcon=", fb_console_setup); @@ -1142,7 +1142,6 @@ static void fbcon_init(struct vc_data *vc, int init) set_blitting_type(vc, info); } - ops->p = &fb_display[fg_console]; } static void fbcon_deinit(struct vc_data *vc) diff --git a/trunk/drivers/video/console/sticore.c b/trunk/drivers/video/console/sticore.c index 74ac2acaf72c..0339f5640a78 100644 --- a/trunk/drivers/video/console/sticore.c +++ b/trunk/drivers/video/console/sticore.c @@ -275,7 +275,7 @@ static int __init sti_setup(char *str) if (str) strlcpy (default_sti_path, str, sizeof (default_sti_path)); - return 1; + return 0; } /* Assuming the machine has multiple STI consoles (=graphic cards) which @@ -321,7 +321,7 @@ static int __init sti_font_setup(char *str) i++; } - return 1; + return 0; } /* 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) glob_cfg->save_addr)); /* dump extended cfg */ - cfg = PTR_STI((unsigned long)glob_cfg->ext_ptr); + cfg = PTR_STI(glob_cfg->ext_ptr); DPRINTK(( KERN_INFO "monitor %d\n" "in friendly mode: %d\n" @@ -453,11 +453,25 @@ sti_init_glob_cfg(struct sti_struct *sti, sti->regions_phys[i] = REGION_OFFSET_TO_PHYS(sti->regions[i], newhpa); + /* remap virtually */ + /* FIXME: add BTLB support if btlb==1 */ len = sti->regions[i].region_desc.length * 4096; + +/* XXX: Enabling IOREMAP debugging causes a crash, so we must be passing + * a virtual address to something expecting a physical address that doesn't + * go through a readX macro */ +#if 0 + if (len) + glob_cfg->region_ptrs[i] = (unsigned long) ( + sti->regions[i].region_desc.cache ? + ioremap(sti->regions_phys[i], len) : + ioremap_nocache(sti->regions_phys[i], len) ); +#else if (len) glob_cfg->region_ptrs[i] = sti->regions_phys[i]; +#endif - DPRINTK(("region #%d: phys %08lx, region_ptr %08x, len=%lukB, " + DPRINTK(("region #%d: phys %08lx, virt %08x, len=%lukB, " "btlb=%d, sysonly=%d, cache=%d, last=%d\n", i, sti->regions_phys[i], glob_cfg->region_ptrs[i], len/1024, diff --git a/trunk/drivers/video/fbmem.c b/trunk/drivers/video/fbmem.c index 944855b3e4af..b1a8dca76430 100644 --- a/trunk/drivers/video/fbmem.c +++ b/trunk/drivers/video/fbmem.c @@ -1588,7 +1588,7 @@ static int __init video_setup(char *options) } } - return 1; + return 0; } __setup("video=", video_setup); #endif diff --git a/trunk/drivers/video/matrox/matroxfb_base.c b/trunk/drivers/video/matrox/matroxfb_base.c index 23c1827b2d0b..951c9974a1d3 100644 --- a/trunk/drivers/video/matrox/matroxfb_base.c +++ b/trunk/drivers/video/matrox/matroxfb_base.c @@ -115,7 +115,6 @@ #include #ifdef CONFIG_PPC_PMAC -#include unsigned char nvram_read_byte(int); static int default_vmode = VMODE_NVRAM; static int default_cmode = CMODE_NVRAM; @@ -1834,7 +1833,7 @@ static int initMatrox2(WPMINFO struct board* b){ /* FIXME: Where to move this?! */ #if defined(CONFIG_PPC_PMAC) #ifndef MODULE - if (machine_is(powermac)) { + if (_machine == _MACH_Pmac) { struct fb_var_screeninfo var; if (default_vmode <= 0 || default_vmode > VMODE_MAX) default_vmode = VMODE_640_480_60; diff --git a/trunk/drivers/video/nvidia/nvidia.c b/trunk/drivers/video/nvidia/nvidia.c index 093ab9977c7c..6d3e4890cb43 100644 --- a/trunk/drivers/video/nvidia/nvidia.c +++ b/trunk/drivers/video/nvidia/nvidia.c @@ -30,7 +30,6 @@ #include #endif #ifdef CONFIG_PMAC_BACKLIGHT -#include #include #endif @@ -1356,7 +1355,7 @@ static int nvidiafb_blank(int blank, struct fb_info *info) NVWriteCrtc(par, 0x1a, vesa); #ifdef CONFIG_PMAC_BACKLIGHT - if (par->FlatPanel && machine_is(powermac)) { + if (par->FlatPanel && _machine == _MACH_Pmac) { set_backlight_enable(!blank); } #endif @@ -1742,7 +1741,7 @@ static int __devinit nvidiafb_probe(struct pci_dev *pd, info->fix.id, par->FbMapSize / (1024 * 1024), info->fix.smem_start); #ifdef CONFIG_PMAC_BACKLIGHT - if (par->FlatPanel && machine_is(powermac)) + if (par->FlatPanel && _machine == _MACH_Pmac) register_backlight_controller(&nvidia_backlight_controller, par, "mnca"); #endif diff --git a/trunk/drivers/video/pxafb.c b/trunk/drivers/video/pxafb.c index 809fc5eefc15..53ad61f1038c 100644 --- a/trunk/drivers/video/pxafb.c +++ b/trunk/drivers/video/pxafb.c @@ -232,9 +232,9 @@ static int pxafb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) if (var->yres < MIN_YRES) var->yres = MIN_YRES; if (var->xres > fbi->max_xres) - return -EINVAL; + var->xres = fbi->max_xres; if (var->yres > fbi->max_yres) - return -EINVAL; + var->yres = fbi->max_yres; var->xres_virtual = max(var->xres_virtual, var->xres); var->yres_virtual = @@ -781,7 +781,7 @@ static void pxafb_disable_controller(struct pxafb_info *fbi) LCCR0 &= ~LCCR0_LDM; /* Enable LCD Disable Done Interrupt */ LCCR0 |= LCCR0_DIS; /* Disable LCD Controller */ - schedule_timeout(200 * HZ / 1000); + schedule_timeout(20 * HZ / 1000); remove_wait_queue(&fbi->ctrlr_wait, &wait); /* disable LCD controller clock */ @@ -1274,7 +1274,7 @@ int __init pxafb_probe(struct platform_device *dev) struct pxafb_mach_info *inf; int ret; - dev_dbg(&dev->dev, "pxafb_probe\n"); + dev_dbg(dev, "pxafb_probe\n"); inf = dev->dev.platform_data; ret = -ENOMEM; diff --git a/trunk/drivers/video/radeonfb.c b/trunk/drivers/video/radeonfb.c new file mode 100644 index 000000000000..24982adb3aa2 --- /dev/null +++ b/trunk/drivers/video/radeonfb.c @@ -0,0 +1,3167 @@ +/* + * drivers/video/radeonfb.c + * framebuffer driver for ATI Radeon chipset video boards + * + * Copyright 2000 Ani Joshi + * + * + * ChangeLog: + * 2000-08-03 initial version 0.0.1 + * 2000-09-10 more bug fixes, public release 0.0.5 + * 2001-02-19 mode bug fixes, 0.0.7 + * 2001-07-05 fixed scrolling issues, engine initialization, + * and minor mode tweaking, 0.0.9 + * 2001-09-07 Radeon VE support, Nick Kurshev + * blanking, pan_display, and cmap fixes, 0.1.0 + * 2001-10-10 Radeon 7500 and 8500 support, and experimental + * flat panel support, 0.1.1 + * 2001-11-17 Radeon M6 (ppc) support, Daniel Berlin, 0.1.2 + * 2001-11-18 DFP fixes, Kevin Hendricks, 0.1.3 + * 2001-11-29 more cmap, backlight fixes, Benjamin Herrenschmidt + * 2002-01-18 DFP panel detection via BIOS, Michael Clark, 0.1.4 + * 2002-06-02 console switching, mode set fixes, accel fixes + * 2002-06-03 MTRR support, Peter Horton, 0.1.5 + * 2002-09-21 rv250, r300, m9 initial support, + * added mirror option, 0.1.6 + * + * Special thanks to ATI DevRel team for their hardware donations. + * + */ + + +#define RADEON_VERSION "0.1.6" + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#if defined(__powerpc__) +#include +#include +#include "macmodes.h" + +#ifdef CONFIG_NVRAM +#include +#endif + +#ifdef CONFIG_PMAC_BACKLIGHT +#include +#endif + +#ifdef CONFIG_BOOTX_TEXT +#include +#endif + +#ifdef CONFIG_ADB_PMU +#include +#include +#endif + +#endif /* __powerpc__ */ + +#ifdef CONFIG_MTRR +#include +#endif + +#include