]> git.karo-electronics.de Git - linux-beck.git/commitdiff
Automatic merge with /usr/src/ntfs-2.6.git.
authorAnton Altaparmakov <aia21@cantab.net>
Sun, 26 Jun 2005 21:19:40 +0000 (22:19 +0100)
committerAnton Altaparmakov <aia21@cantab.net>
Sun, 26 Jun 2005 21:19:40 +0000 (22:19 +0100)
637 files changed:
Documentation/00-INDEX
Documentation/SubmittingPatches
Documentation/cdrom/sbpcd
Documentation/cpu-freq/governors.txt
Documentation/cpusets.txt
Documentation/devices.txt
Documentation/dvb/bt8xx.txt
Documentation/feature-removal-schedule.txt
Documentation/kdump/gdbmacros.txt [new file with mode: 0644]
Documentation/kdump/kdump.txt [new file with mode: 0644]
Documentation/kernel-parameters.txt
Documentation/networking/00-INDEX
Documentation/networking/wanpipe.txt [deleted file]
Documentation/power/kernel_threads.txt
Documentation/power/pci.txt
Documentation/power/swsusp.txt
Documentation/power/video.txt
Documentation/power/video_extension.txt
Documentation/s390/s390dbf.txt
Documentation/sysrq.txt
MAINTAINERS
Makefile
arch/arm/Kconfig
arch/arm/configs/enp2611_defconfig
arch/arm/configs/ixdp2400_defconfig
arch/arm/configs/ixdp2401_defconfig
arch/arm/configs/ixdp2800_defconfig
arch/arm/configs/ixdp2801_defconfig
arch/arm/kernel/irq.c
arch/arm/kernel/signal.c
arch/arm/kernel/time.c
arch/arm/mach-clps711x/Kconfig
arch/arm/mach-ixp2000/Kconfig
arch/arm/mach-ixp2000/enp2611.c
arch/arm/mach-ixp2000/ixdp2x00.c
arch/arm/mach-ixp2000/pci.c
arch/frv/kernel/setup.c
arch/frv/kernel/signal.c
arch/h8300/kernel/signal.c
arch/i386/Kconfig
arch/i386/boot/Makefile
arch/i386/boot/compressed/head.S
arch/i386/boot/compressed/misc.c
arch/i386/boot/edd.S
arch/i386/boot/setup.S
arch/i386/boot/tools/build.c
arch/i386/crypto/aes.c
arch/i386/defconfig
arch/i386/kernel/Makefile
arch/i386/kernel/acpi/boot.c
arch/i386/kernel/acpi/sleep.c
arch/i386/kernel/apic.c
arch/i386/kernel/apm.c
arch/i386/kernel/cpu/common.c
arch/i386/kernel/cpu/cpufreq/powernow-k7.c
arch/i386/kernel/cpu/intel.c
arch/i386/kernel/cpu/intel_cacheinfo.c
arch/i386/kernel/cpu/mcheck/k7.c
arch/i386/kernel/cpu/mcheck/mce.c
arch/i386/kernel/cpu/mcheck/p4.c
arch/i386/kernel/cpu/mcheck/p5.c
arch/i386/kernel/cpu/mcheck/p6.c
arch/i386/kernel/cpu/mcheck/winchip.c
arch/i386/kernel/cpu/mtrr/generic.c
arch/i386/kernel/crash.c [new file with mode: 0644]
arch/i386/kernel/dmi_scan.c
arch/i386/kernel/efi.c
arch/i386/kernel/head.S
arch/i386/kernel/i8259.c
arch/i386/kernel/io_apic.c
arch/i386/kernel/irq.c
arch/i386/kernel/machine_kexec.c [new file with mode: 0644]
arch/i386/kernel/mpparse.c
arch/i386/kernel/process.c
arch/i386/kernel/reboot.c
arch/i386/kernel/relocate_kernel.S [new file with mode: 0644]
arch/i386/kernel/setup.c
arch/i386/kernel/signal.c
arch/i386/kernel/smp.c
arch/i386/kernel/smpboot.c
arch/i386/kernel/syscall_table.S
arch/i386/kernel/sysenter.c
arch/i386/kernel/time_hpet.c
arch/i386/kernel/timers/common.c
arch/i386/kernel/timers/timer_tsc.c
arch/i386/kernel/traps.c
arch/i386/kernel/vmlinux.lds.S
arch/i386/mach-default/setup.c
arch/i386/mach-default/topology.c
arch/i386/mach-visws/mpparse.c
arch/i386/mm/discontig.c
arch/i386/mm/fault.c
arch/i386/mm/highmem.c
arch/i386/mm/init.c
arch/i386/mm/ioremap.c
arch/i386/mm/pgtable.c
arch/i386/power/cpu.c
arch/ia64/kernel/domain.c
arch/ia64/kernel/smpboot.c
arch/ia64/sn/kernel/xpc.h
arch/ia64/sn/kernel/xpc_channel.c
arch/ia64/sn/kernel/xpc_partition.c
arch/m32r/kernel/signal.c
arch/mips/Kconfig
arch/mips/kernel/setup.c
arch/mips/mm/init.c
arch/mips/mm/pgtable.c
arch/ppc/Kconfig
arch/ppc/Kconfig.debug
arch/ppc/Makefile
arch/ppc/boot/openfirmware/chrpmain.c
arch/ppc/kernel/Makefile
arch/ppc/kernel/cputable.c
arch/ppc/kernel/entry.S
arch/ppc/kernel/head_booke.h
arch/ppc/kernel/head_fsl_booke.S
arch/ppc/kernel/machine_kexec.c [new file with mode: 0644]
arch/ppc/kernel/misc.S
arch/ppc/kernel/perfmon.c
arch/ppc/kernel/relocate_kernel.S [new file with mode: 0644]
arch/ppc/kernel/signal.c
arch/ppc/kernel/traps.c
arch/ppc/mm/44x_mmu.c
arch/ppc/mm/4xx_mmu.c
arch/ppc/mm/fsl_booke_mmu.c
arch/ppc/platforms/83xx/mpc834x_sys.c
arch/ppc/platforms/85xx/mpc8540_ads.c
arch/ppc/platforms/85xx/mpc8560_ads.c
arch/ppc/platforms/85xx/sbc8560.c
arch/ppc/platforms/85xx/stx_gp3.c
arch/ppc/platforms/chrp_pci.c
arch/ppc/platforms/katana.c
arch/ppc/platforms/pmac_pci.c
arch/ppc/syslib/cpm2_common.c
arch/ppc/syslib/indirect_pci.c
arch/ppc/syslib/ipic.c
arch/ppc/syslib/mv64x60.c
arch/ppc/syslib/mv64x60_win.c
arch/ppc64/Kconfig
arch/ppc64/kernel/Makefile
arch/ppc64/kernel/head.S
arch/ppc64/kernel/lparcfg.c
arch/ppc64/kernel/machine_kexec.c [new file with mode: 0644]
arch/ppc64/kernel/misc.S
arch/ppc64/kernel/mpic.c
arch/ppc64/kernel/mpic.h
arch/ppc64/kernel/pSeries_setup.c
arch/ppc64/kernel/pSeries_smp.c
arch/ppc64/kernel/setup.c
arch/ppc64/kernel/xics.c
arch/ppc64/mm/hash_native.c
arch/s390/Kconfig
arch/s390/defconfig
arch/s390/kernel/Makefile
arch/s390/kernel/compat_wrapper.S
arch/s390/kernel/cpcmd.c
arch/s390/kernel/crash.c [new file with mode: 0644]
arch/s390/kernel/debug.c
arch/s390/kernel/entry.S
arch/s390/kernel/entry64.S
arch/s390/kernel/machine_kexec.c [new file with mode: 0644]
arch/s390/kernel/process.c
arch/s390/kernel/relocate_kernel.S [new file with mode: 0644]
arch/s390/kernel/relocate_kernel64.S [new file with mode: 0644]
arch/s390/kernel/setup.c
arch/s390/kernel/smp.c
arch/s390/kernel/syscalls.S
arch/s390/kernel/traps.c
arch/s390/mm/extmem.c
arch/um/drivers/daemon_user.c
arch/um/drivers/line.c
arch/um/drivers/mconsole_kern.c
arch/um/drivers/net_kern.c
arch/um/drivers/ssl.c
arch/um/drivers/stdio_console.c
arch/um/drivers/ubd_kern.c
arch/um/include/line.h
arch/um/include/mconsole_kern.h
arch/um/include/time_user.h
arch/um/kernel/main.c
arch/um/kernel/process_kern.c
arch/um/kernel/reboot.c
arch/um/kernel/skas/Makefile
arch/um/kernel/skas/include/mode-skas.h
arch/um/kernel/skas/process_kern.c
arch/um/kernel/skas/time.c [deleted file]
arch/um/kernel/syscall_kern.c
arch/um/kernel/time.c
arch/um/kernel/time_kern.c
arch/um/kernel/tt/Makefile
arch/um/kernel/tt/gdb.c
arch/um/kernel/tt/gdb_kern.c
arch/um/kernel/tt/include/debug.h
arch/um/kernel/tt/include/mode-tt.h
arch/um/kernel/tt/process_kern.c
arch/um/kernel/tt/time.c [deleted file]
arch/um/sys-i386/signal.c
arch/um/sys-i386/syscalls.c
arch/um/sys-x86_64/syscalls.c
arch/x86_64/Kconfig
arch/x86_64/Makefile
arch/x86_64/boot/compressed/head.S
arch/x86_64/boot/compressed/misc.c
arch/x86_64/boot/install.sh
arch/x86_64/boot/setup.S
arch/x86_64/boot/tools/build.c
arch/x86_64/ia32/ia32entry.S
arch/x86_64/kernel/Makefile
arch/x86_64/kernel/acpi/wakeup.S
arch/x86_64/kernel/apic.c
arch/x86_64/kernel/crash.c [new file with mode: 0644]
arch/x86_64/kernel/e820.c
arch/x86_64/kernel/genapic_flat.c
arch/x86_64/kernel/head.S
arch/x86_64/kernel/i387.c
arch/x86_64/kernel/i8259.c
arch/x86_64/kernel/io_apic.c
arch/x86_64/kernel/irq.c
arch/x86_64/kernel/machine_kexec.c [new file with mode: 0644]
arch/x86_64/kernel/mce.c
arch/x86_64/kernel/mce_intel.c
arch/x86_64/kernel/nmi.c
arch/x86_64/kernel/process.c
arch/x86_64/kernel/reboot.c
arch/x86_64/kernel/relocate_kernel.S [new file with mode: 0644]
arch/x86_64/kernel/setup.c
arch/x86_64/kernel/setup64.c
arch/x86_64/kernel/signal.c
arch/x86_64/kernel/smp.c
arch/x86_64/kernel/smpboot.c
arch/x86_64/kernel/suspend.c
arch/x86_64/kernel/traps.c
arch/x86_64/kernel/vmlinux.lds.S
arch/x86_64/mm/numa.c
arch/xtensa/platform-iss/console.c
drivers/acpi/Kconfig
drivers/acpi/pci_irq.c
drivers/base/cpu.c
drivers/block/ll_rw_blk.c
drivers/block/pktcdvd.c
drivers/cdrom/cm206.c
drivers/cdrom/sonycd535.c
drivers/char/Kconfig
drivers/char/amiserial.c
drivers/char/applicom.c
drivers/char/drm/Kconfig
drivers/char/drm/Makefile
drivers/char/drm/drmP.h
drivers/char/drm/drm_bufs.c
drivers/char/drm/drm_context.c
drivers/char/drm/drm_ioc32.c [new file with mode: 0644]
drivers/char/drm/i915_dma.c
drivers/char/drm/i915_drm.h
drivers/char/drm/i915_drv.c
drivers/char/drm/i915_drv.h
drivers/char/drm/i915_irq.c
drivers/char/drm/i915_mem.c
drivers/char/drm/radeon_drv.c
drivers/char/drm/radeon_drv.h
drivers/char/drm/radeon_ioc32.c [new file with mode: 0644]
drivers/char/drm/radeon_irq.c
drivers/char/ds1620.c
drivers/char/ftape/compressor/zftape-compress.c
drivers/char/hpet.c
drivers/char/i8k.c
drivers/char/ip2/i2cmd.c
drivers/char/ip2/i2cmd.h
drivers/char/ip2main.c
drivers/char/isicom.c
drivers/char/istallion.c
drivers/char/mem.c
drivers/char/misc.c
drivers/char/mwave/3780i.c
drivers/char/mwave/3780i.h
drivers/char/mwave/tp3780i.c
drivers/char/nvram.c
drivers/char/rio/func.h
drivers/char/rio/rio_linux.c
drivers/char/rio/rioinit.c
drivers/char/rio/riotty.c
drivers/char/rocket.c
drivers/char/rocket_int.h
drivers/char/sysrq.c
drivers/char/toshiba.c
drivers/char/tpm/tpm.c
drivers/char/tpm/tpm.h
drivers/char/tpm/tpm_atmel.c
drivers/char/tpm/tpm_nsc.c
drivers/char/tty_io.c
drivers/firmware/efivars.c
drivers/i2c/busses/i2c-mpc.c
drivers/ieee1394/ieee1394_core.c
drivers/ieee1394/nodemgr.c
drivers/input/gameport/gameport.c
drivers/input/serio/i8042.c
drivers/input/serio/serio.c
drivers/isdn/act2000/capi.c
drivers/isdn/act2000/capi.h
drivers/isdn/hardware/avm/b1dma.c
drivers/isdn/hardware/avm/c4.c
drivers/isdn/hardware/avm/t1isa.c
drivers/isdn/hisax/Makefile
drivers/isdn/hisax/amd7930_fn.c
drivers/isdn/hisax/asuscom.c
drivers/isdn/hisax/avm_pci.c
drivers/isdn/hisax/bkm_a4t.c
drivers/isdn/hisax/bkm_a8.c
drivers/isdn/hisax/callc.c
drivers/isdn/hisax/config.c
drivers/isdn/hisax/diva.c
drivers/isdn/hisax/elsa.c
drivers/isdn/hisax/elsa_ser.c
drivers/isdn/hisax/enternow.h [deleted file]
drivers/isdn/hisax/enternow_pci.c
drivers/isdn/hisax/gazel.c
drivers/isdn/hisax/hfc4s8s_l1.c
drivers/isdn/hisax/hfc_2bds0.c
drivers/isdn/hisax/hfc_2bs0.c
drivers/isdn/hisax/hfc_pci.c
drivers/isdn/hisax/hfc_pci.h
drivers/isdn/hisax/hfc_sx.c
drivers/isdn/hisax/hfc_sx.h
drivers/isdn/hisax/hfc_usb.c
drivers/isdn/hisax/hfc_usb.h
drivers/isdn/hisax/hfcscard.c
drivers/isdn/hisax/hisax.h
drivers/isdn/hisax/hscx.c
drivers/isdn/hisax/icc.c
drivers/isdn/hisax/ipacx.c
drivers/isdn/hisax/isac.c
drivers/isdn/hisax/isar.c
drivers/isdn/hisax/isdnl1.c
drivers/isdn/hisax/isdnl2.c
drivers/isdn/hisax/isdnl3.c
drivers/isdn/hisax/isurf.c
drivers/isdn/hisax/ix1_micro.c
drivers/isdn/hisax/jade.c
drivers/isdn/hisax/jade.h
drivers/isdn/hisax/l3_1tr6.c
drivers/isdn/hisax/l3dss1.c
drivers/isdn/hisax/l3ni1.c
drivers/isdn/hisax/mic.c
drivers/isdn/hisax/netjet.c
drivers/isdn/hisax/niccy.c
drivers/isdn/hisax/nj_s.c
drivers/isdn/hisax/nj_u.c
drivers/isdn/hisax/q931.c
drivers/isdn/hisax/s0box.c
drivers/isdn/hisax/saphir.c
drivers/isdn/hisax/sedlbauer.c
drivers/isdn/hisax/sportster.c
drivers/isdn/hisax/st5481.h
drivers/isdn/hisax/st5481_hdlc.c [deleted file]
drivers/isdn/hisax/st5481_hdlc.h [deleted file]
drivers/isdn/hisax/st5481_usb.c
drivers/isdn/hisax/tei.c
drivers/isdn/hisax/teleint.c
drivers/isdn/hisax/teles0.c
drivers/isdn/hisax/teles3.c
drivers/isdn/hisax/telespci.c
drivers/isdn/hisax/w6692.c
drivers/isdn/i4l/isdn_audio.c
drivers/isdn/i4l/isdn_audio.h
drivers/isdn/i4l/isdn_common.c
drivers/isdn/i4l/isdn_common.h
drivers/isdn/i4l/isdn_concap.c
drivers/isdn/i4l/isdn_concap.h
drivers/isdn/i4l/isdn_net.c
drivers/isdn/i4l/isdn_tty.c
drivers/isdn/i4l/isdn_tty.h
drivers/isdn/i4l/isdn_ttyfax.c
drivers/isdn/i4l/isdn_x25iface.c
drivers/isdn/pcbit/callbacks.c
drivers/isdn/pcbit/callbacks.h
drivers/isdn/pcbit/capi.c
drivers/isdn/pcbit/capi.h
drivers/isdn/pcbit/drv.c
drivers/isdn/sc/Makefile
drivers/isdn/sc/command.c
drivers/isdn/sc/debug.c [deleted file]
drivers/isdn/sc/init.c
drivers/isdn/sc/interrupt.c
drivers/isdn/sc/ioctl.c
drivers/isdn/sc/packet.c
drivers/isdn/sc/shmem.c
drivers/isdn/sc/timer.c
drivers/macintosh/therm_adt746x.c
drivers/mca/mca-legacy.c
drivers/md/md.c
drivers/media/dvb/dvb-core/dvb_frontend.c
drivers/media/video/cx88/cx88.h
drivers/media/video/msp3400.c
drivers/media/video/video-buf-dvb.c
drivers/net/8139too.c
drivers/net/irda/sir_kthread.c
drivers/net/irda/stir4200.c
drivers/net/tg3.c
drivers/net/tg3.h
drivers/net/wan/Kconfig
drivers/net/wireless/airo.c
drivers/pcmcia/cs.c
drivers/pnp/pnpbios/core.c
drivers/s390/Kconfig
drivers/s390/block/dasd.c
drivers/s390/block/dasd_proc.c
drivers/s390/block/dcssblk.c
drivers/s390/char/Makefile
drivers/s390/char/con3215.c
drivers/s390/char/con3270.c
drivers/s390/char/tape_34xx.c
drivers/s390/char/tape_core.c
drivers/s390/char/tape_proc.c
drivers/s390/char/vmcp.c [new file with mode: 0644]
drivers/s390/char/vmcp.h [new file with mode: 0644]
drivers/s390/char/vmlogrdr.c
drivers/s390/cio/ccwgroup.c
drivers/s390/cio/cio.c
drivers/s390/cio/css.c
drivers/s390/cio/device.c
drivers/s390/cio/qdio.c
drivers/s390/cio/qdio.h
drivers/s390/net/claw.c
drivers/s390/net/ctcdbug.c
drivers/s390/net/ctcdbug.h
drivers/s390/net/iucv.h
drivers/s390/net/lcs.c
drivers/s390/net/netiucv.c
drivers/s390/net/qeth.h
drivers/s390/net/qeth_main.c
drivers/s390/net/smsgiucv.c
drivers/s390/s390mach.c
drivers/s390/s390mach.h
drivers/scsi/dpt_i2o.c
drivers/scsi/dpti.h
drivers/scsi/initio.c
drivers/scsi/initio.h
drivers/serial/68328serial.c
drivers/serial/68360serial.c
drivers/serial/icom.h
drivers/serial/mpsc.c
drivers/serial/sunzilog.c
drivers/telephony/ixj.c
drivers/usb/core/hub.c
drivers/usb/gadget/file_storage.c
drivers/usb/storage/usb.c
drivers/video/au1100fb.c
drivers/video/console/Kconfig
drivers/video/fbsysfs.c
drivers/video/matrox/matroxfb_misc.c
drivers/video/vesafb.c
drivers/w1/w1.c
fs/Kconfig
fs/afs/kafsasyncd.c
fs/afs/kafstimod.c
fs/dquot.c
fs/jbd/journal.c
fs/jffs/intrep.c
fs/jffs/intrep.h
fs/jffs/jffs_fm.c
fs/jffs/jffs_fm.h
fs/jffs2/background.c
fs/jfs/jfs_logmgr.c
fs/jfs/jfs_txnmgr.c
fs/libfs.c
fs/lockd/clntproc.c
fs/ncpfs/dir.c
fs/ncpfs/ncplib_kernel.c
fs/ncpfs/ncplib_kernel.h
fs/partitions/Makefile
fs/partitions/check.c
fs/partitions/check.h
fs/partitions/msdos.c
fs/proc/Makefile
fs/proc/proc_misc.c
fs/proc/vmcore.c [new file with mode: 0644]
fs/reiserfs/inode.c
fs/xfs/linux-2.6/xfs_buf.c
fs/xfs/linux-2.6/xfs_super.c
include/asm-arm/arch-ixp2000/io.h
include/asm-arm/arch-ixp2000/ixp2000-regs.h
include/asm-arm/mach/time.h
include/asm-arm/signal.h
include/asm-arm/system.h
include/asm-generic/vmlinux.lds.h
include/asm-i386/apic.h
include/asm-i386/apicdef.h
include/asm-i386/cpu.h
include/asm-i386/highmem.h
include/asm-i386/irq.h
include/asm-i386/kdebug.h
include/asm-i386/kexec.h [new file with mode: 0644]
include/asm-i386/mach-default/mach_ipi.h
include/asm-i386/page.h
include/asm-i386/processor.h
include/asm-i386/smp.h
include/asm-i386/topology.h
include/asm-ia64/system.h
include/asm-ia64/topology.h
include/asm-mips/mmzone.h
include/asm-mips/page.h
include/asm-mips/pgtable.h
include/asm-mips/system.h
include/asm-ppc/fsl_ocp.h [deleted file]
include/asm-ppc/kexec.h [new file with mode: 0644]
include/asm-ppc/machdep.h
include/asm-ppc/mmu.h
include/asm-ppc/mmu_context.h
include/asm-ppc/ocp.h
include/asm-ppc/ppc_asm.h
include/asm-ppc/reg.h
include/asm-ppc/reg_booke.h
include/asm-ppc64/kdebug.h
include/asm-ppc64/kexec.h [new file with mode: 0644]
include/asm-ppc64/machdep.h
include/asm-ppc64/mmu.h
include/asm-ppc64/xics.h
include/asm-s390/cpcmd.h
include/asm-s390/debug.h
include/asm-s390/kexec.h [new file with mode: 0644]
include/asm-s390/lowcore.h
include/asm-s390/processor.h
include/asm-s390/ptrace.h
include/asm-s390/system.h
include/asm-s390/thread_info.h
include/asm-s390/unistd.h
include/asm-sparc/system.h
include/asm-sparc64/kdebug.h
include/asm-sparc64/system.h
include/asm-sparc64/termios.h
include/asm-um/ptrace-i386.h
include/asm-x86_64/apic.h
include/asm-x86_64/apicdef.h
include/asm-x86_64/irq.h
include/asm-x86_64/kdebug.h
include/asm-x86_64/kexec.h [new file with mode: 0644]
include/asm-x86_64/page.h
include/asm-x86_64/smp.h
include/asm-x86_64/suspend.h
include/asm-x86_64/topology.h
include/asm-x86_64/unistd.h
include/linux/a.out.h
include/linux/blkdev.h
include/linux/bootmem.h
include/linux/cpu.h
include/linux/crash_dump.h [new file with mode: 0644]
include/linux/dmi.h
include/linux/highmem.h
include/linux/init.h
include/linux/init_task.h
include/linux/kernel.h
include/linux/kexec.h [new file with mode: 0644]
include/linux/list.h
include/linux/nvram.h
include/linux/pm.h
include/linux/proc_fs.h
include/linux/reboot.h
include/linux/sched.h
include/linux/suspend.h
include/linux/syscalls.h
include/linux/topology.h
init/do_mounts_initrd.c
kernel/Kconfig.preempt [new file with mode: 0644]
kernel/Makefile
kernel/cpu.c
kernel/cpuset.c
kernel/crash_dump.c [new file with mode: 0644]
kernel/fork.c
kernel/kexec.c [new file with mode: 0644]
kernel/ksysfs.c
kernel/panic.c
kernel/power/Kconfig
kernel/power/Makefile
kernel/power/disk.c
kernel/power/main.c
kernel/power/process.c
kernel/power/smp.c
kernel/power/swsusp.c
kernel/printk.c
kernel/resource.c
kernel/sched.c
kernel/signal.c
kernel/sys.c
kernel/sys_ni.c
kernel/sysctl.c
kernel/timer.c
lib/Kconfig
lib/bitmap.c
lib/sha1.c
mm/bootmem.c
mm/filemap.c
mm/memory.c
mm/page_io.c
mm/pdflush.c
mm/vmscan.c
net/ipv4/Kconfig
net/rxrpc/krxiod.c
net/rxrpc/krxsecd.c
net/rxrpc/krxtimod.c
net/sched/Kconfig
net/sunrpc/svcsock.c
net/sunrpc/xprt.c
scripts/basic/docproc.c
scripts/basic/fixdep.c
scripts/basic/split-include.c
scripts/kconfig/conf.c
scripts/kconfig/confdata.c
scripts/kconfig/mconf.c
security/keys/key.c
security/keys/process_keys.c
security/selinux/hooks.c
security/selinux/include/av_perm_to_string.h
security/selinux/include/av_permissions.h
security/selinux/selinuxfs.c
security/selinux/ss/conditional.c
security/selinux/ss/policydb.c
security/selinux/ss/services.c
sound/oss/Kconfig
sound/oss/ad1816.c
sound/oss/ad1848.c
sound/oss/ad1889.c
sound/oss/cmpci.c
sound/oss/dmasound/dmasound_awacs.c
sound/oss/emu10k1/midi.c
sound/oss/emu10k1/passthrough.c
sound/oss/es1370.c
sound/oss/es1371.c
sound/oss/esssolo1.c
sound/oss/maestro.c
sound/oss/mpu401.c
sound/oss/nm256.h
sound/oss/nm256_audio.c
sound/oss/nm256_coeff.h
sound/oss/rme96xx.c
sound/oss/sb_common.c
sound/oss/sscape.c
sound/oss/v_midi.c
sound/oss/wavfront.c

index 8de8a01a2474bc4ab429e6d97225a1f61af957c0..f28a24e0279b4c01aa8596e3f296ec50ef0ad70a 100644 (file)
@@ -138,6 +138,8 @@ java.txt
        - info on the in-kernel binary support for Java(tm).
 kbuild/
        - directory with info about the kernel build process.
+kdumpt.txt
+       - mini HowTo on getting the crash dump code to work.
 kernel-doc-nano-HOWTO.txt
        - mini HowTo on generation and location of kernel documentation files.
 kernel-docs.txt
index 4d35562b1cf976d7f63f7f555440686e44ae5db4..4d1f41b84ebca707ffdb5da8211da04091ee078d 100644 (file)
@@ -132,21 +132,6 @@ which require discussion or do not have a clear advantage should
 usually be sent first to linux-kernel.  Only after the patch is
 discussed should the patch then be submitted to Linus.
 
-For small patches you may want to CC the Trivial Patch Monkey
-trivial@rustcorp.com.au set up by Rusty Russell; which collects "trivial"
-patches. Trivial patches must qualify for one of the following rules:
- Spelling fixes in documentation
- Spelling fixes which could break grep(1).
- Warning fixes (cluttering with useless warnings is bad)
- Compilation fixes (only if they are actually correct)
- Runtime fixes (only if they actually fix things)
- Removing use of deprecated functions/macros (eg. check_region).
- Contact detail and documentation fixes
- Non-portable code replaced by portable code (even in arch-specific,
- since people copy, as long as it's trivial)
- Any fix by the author/maintainer of the file. (ie. patch monkey
- in re-transmission mode)
-
 
 
 5) Select your CC (e-mail carbon copy) list.
@@ -299,7 +284,7 @@ can certify the below:
 
 then you just add a line saying
 
-       Signed-off-by: Random J Developer <random@developer.org>
+       Signed-off-by: Random J Developer <random@developer.example.org>
 
 Some people also put extra tags at the end.  They'll just be ignored for
 now, but you can do this to mark internal company procedures or just
index d1825dffca34ed600b7a1b216355b3bbca60eca6..b3ba63f4ce3e9cf00f41fd38a17fae94ba05d046 100644 (file)
@@ -419,6 +419,7 @@ into the file "track01":
  */
 #include <stdio.h>
 #include <sys/ioctl.h>
+#include <sys/types.h>
 #include <linux/cdrom.h>
 
 static struct cdrom_tochdr hdr;
@@ -429,7 +430,7 @@ static int datafile, drive;
 static int i, j, limit, track, err;
 static char filename[32];
 
-main(int argc, char *argv[])
+int main(int argc, char *argv[])
 {
 /*
  * open /dev/cdrom
@@ -516,6 +517,7 @@ entry[track+1].cdte_addr.lba=entry[track].cdte_addr.lba+300;
        }
       arg.addr.lba++;
     }
+    return 0;
 }
 /*===================== end program ========================================*/
 
@@ -564,15 +566,16 @@ Appendix -- the "cdtester" utility:
 #include <stdio.h>
 #include <malloc.h>
 #include <sys/ioctl.h>
+#include <sys/types.h>
 #include <linux/cdrom.h>
 
 #ifdef AZT_PRIVATE_IOCTLS
 #include <linux/../../drivers/cdrom/aztcd.h>
-#endif AZT_PRIVATE_IOCTLS
+#endif /* AZT_PRIVATE_IOCTLS */
 #ifdef SBP_PRIVATE_IOCTLS
 #include <linux/../../drivers/cdrom/sbpcd.h>
 #include <linux/fs.h>
-#endif SBP_PRIVATE_IOCTLS
+#endif /* SBP_PRIVATE_IOCTLS */
 
 struct cdrom_tochdr hdr;
 struct cdrom_tochdr tocHdr;
@@ -590,7 +593,7 @@ union
        struct cdrom_msf msf;
        unsigned char buf[CD_FRAMESIZE_RAW];
 } azt;
-#endif AZT_PRIVATE_IOCTLS
+#endif /* AZT_PRIVATE_IOCTLS */
 int i, i1, i2, i3, j, k;
 unsigned char sequence=0;
 unsigned char command[80];
@@ -738,7 +741,7 @@ void display(int size,unsigned char *buffer)
        } 
 } 
 
-main(int argc, char *argv[])
+int main(int argc, char *argv[])
 {
        printf("\nTesting tool for a CDROM driver's audio functions V0.1\n");
        printf("(C) 1995 Eberhard Moenkeberg <emoenke@gwdg.de>\n");
@@ -1046,12 +1049,13 @@ main(int argc, char *argv[])
                        rc=ioctl(drive,CDROMAUDIOBUFSIZ,j);
                        printf("%d frames granted.\n",rc);
                        break;
-#endif SBP_PRIVATE_IOCTLS
+#endif /* SBP_PRIVATE_IOCTLS */
                default:
                        printf("unknown command: \"%s\".\n",command);
                        break;
                }
        }
+       return 0;
 }
 /*==========================================================================*/
 
index b85481acd0ca49fdb6625faaae44293cc213d3ea..933fae74c3379cba1fd7d066a2ab7f6daead76a3 100644 (file)
@@ -9,6 +9,7 @@
 
 
                    Dominik Brodowski  <linux@brodo.de>
+            some additions and corrections by Nico Golde <nico@ngolde.de>
 
 
 
@@ -25,6 +26,7 @@ Contents:
 2.1  Performance
 2.2  Powersave
 2.3  Userspace
+2.4  Ondemand
 
 3.   The Governor Interface in the CPUfreq Core
 
@@ -86,7 +88,7 @@ highest frequency within the borders of scaling_min_freq and
 scaling_max_freq.
 
 
-2.1 Powersave
+2.2 Powersave
 -------------
 
 The CPUfreq governor "powersave" sets the CPU statically to the
@@ -94,7 +96,7 @@ lowest frequency within the borders of scaling_min_freq and
 scaling_max_freq.
 
 
-2.2 Userspace
+2.3 Userspace
 -------------
 
 The CPUfreq governor "userspace" allows the user, or any userspace
@@ -103,6 +105,14 @@ by making a sysfs file "scaling_setspeed" available in the CPU-device
 directory.
 
 
+2.4 Ondemand
+------------
+
+The CPUfreq govenor "ondemand" sets the CPU depending on the
+current usage. To do this the CPU must have the capability to
+switch the frequency very fast.
+
+
 
 3. The Governor Interface in the CPUfreq Core
 =============================================
index 2f8f24eaefd9ac746f8a1e98b6e2c99abcc23b58..ad944c06031294cc35265d82ecf2a8fcc12586de 100644 (file)
@@ -51,6 +51,14 @@ mems_allowed vector.
 
 If a cpuset is cpu or mem exclusive, no other cpuset, other than a direct
 ancestor or descendent, may share any of the same CPUs or Memory Nodes.
+A cpuset that is cpu exclusive has a sched domain associated with it.
+The sched domain consists of all cpus in the current cpuset that are not
+part of any exclusive child cpusets.
+This ensures that the scheduler load balacing code only balances
+against the cpus that are in the sched domain as defined above and not
+all of the cpus in the system. This removes any overhead due to
+load balancing code trying to pull tasks outside of the cpu exclusive
+cpuset only to be prevented by the tasks' cpus_allowed mask.
 
 User level code may create and destroy cpusets by name in the cpuset
 virtual file system, manage the attributes and permissions of these
@@ -84,6 +92,9 @@ This can be especially valuable on:
       and a database), or
     * NUMA systems running large HPC applications with demanding
       performance characteristics.
+    * Also cpu_exclusive cpusets are useful for servers running orthogonal
+      workloads such as RT applications requiring low latency and HPC
+      applications that are throughput sensitive
 
 These subsets, or "soft partitions" must be able to be dynamically
 adjusted, as the job mix changes, without impacting other concurrently
@@ -125,6 +136,8 @@ Cpusets extends these two mechanisms as follows:
  - A cpuset may be marked exclusive, which ensures that no other
    cpuset (except direct ancestors and descendents) may contain
    any overlapping CPUs or Memory Nodes.
+   Also a cpu_exclusive cpuset would be associated with a sched
+   domain.
  - You can list all the tasks (by pid) attached to any cpuset.
 
 The implementation of cpusets requires a few, simple hooks
@@ -136,6 +149,9 @@ into the rest of the kernel, none in performance critical paths:
    allowed in that tasks cpuset.
  - in sched.c migrate_all_tasks(), to keep migrating tasks within
    the CPUs allowed by their cpuset, if possible.
+ - in sched.c, a new API partition_sched_domains for handling
+   sched domain changes associated with cpu_exclusive cpusets
+   and related changes in both sched.c and arch/ia64/kernel/domain.c
  - in the mbind and set_mempolicy system calls, to mask the requested
    Memory Nodes by what's allowed in that tasks cpuset.
  - in page_alloc, to restrict memory to allowed nodes.
index bb67cf25010ed4ceb64b2157f3db4b299bf597c9..0f515175c72a889959ad5258379a602f31495767 100644 (file)
@@ -94,6 +94,7 @@ Your cooperation is appreciated.
                  9 = /dev/urandom      Faster, less secure random number gen.
                 10 = /dev/aio          Asyncronous I/O notification interface
                 11 = /dev/kmsg         Writes to this come out as printk's
+                12 = /dev/oldmem       Access to crash dump from kexec kernel
   1 block      RAM disk
                  0 = /dev/ram0         First RAM disk
                  1 = /dev/ram1         Second RAM disk
index d64430bf4bb6ec5d681c2f7c30cc71905a72bd67..3a326079475864fa8637ab7e998fbbec89fd9416 100644 (file)
@@ -44,26 +44,23 @@ TwinHan (dst) are loaded automatically by the dvb-bt8xx device driver.
    $ modprobe dst
 
 The value 0x71 will override the PCI type detection for dvb-bt8xx,
-which  is necessary for TwinHan cards.
+which is necessary for TwinHan cards.
 
 If you're having an older card (blue color circuit) and card=0x71 locks
 your machine, try using 0x68, too. If that does not work, ask on the
 mailing list.
 
-The DST module takes a couple of useful parameters.
+The DST module takes a couple of useful parameters:
 
-verbose takes values 0 to 5. These values control the verbosity level.
-
-debug takes values 0 and 1. You can either disable or enable debugging.
-
-dst_addons takes values 0 and 0x20. A value of 0 means it is a FTA card.
-0x20 means it has a Conditional Access slot.
-
-The autodected values are determined bythe cards 'response
-string' which you can see in your logs e.g.
-
-dst_get_device_id: Recognise [DSTMCI]
+a. verbose takes values 0 to 5. These values control the verbosity level.
+b. debug takes values 0 and 1. You can either disable or enable debugging.
+c. dst_addons takes values 0 and 0x20:
+- A value of 0 means it is a FTA card.
+- A value of 0x20 means it has a Conditional Access slot.
 
+The autodetected values are determined by the "response string"
+of the card, which you can see in your logs:
+e.g.: dst_get_device_id: Recognize [DSTMCI]
 
 --
-Authors: Richard Walker, Jamie Honan, Michael Hunold, Manu Abraham
+Authors: Richard Walker, Jamie Honan, Michael Hunold, Manu Abraham, Uwe Bugla
index 77511af453625bb959c132f5723f718b8e94c41c..1d227ee3792a1f704c7b505486e50985cf7fd8b5 100644 (file)
@@ -43,6 +43,14 @@ Who: Randy Dunlap <rddunlap@osdl.org>
 
 ---------------------------
 
+What:  RAW driver (CONFIG_RAW_DRIVER)
+When:  December 2005
+Why:   declared obsolete since kernel 2.6.3
+       O_DIRECT can be used instead
+Who:   Adrian Bunk <bunk@stusta.de>
+
+---------------------------
+
 What:  register_ioctl32_conversion() / unregister_ioctl32_conversion()
 When:  April 2005
 Why:   Replaced by ->compat_ioctl in file_operations and other method
diff --git a/Documentation/kdump/gdbmacros.txt b/Documentation/kdump/gdbmacros.txt
new file mode 100644 (file)
index 0000000..bc1b9eb
--- /dev/null
@@ -0,0 +1,179 @@
+#
+# This file contains a few gdb macros (user defined commands) to extract
+# useful information from kernel crashdump (kdump) like stack traces of
+# all the processes or a particular process and trapinfo.
+#
+# These macros can be used by copying this file in .gdbinit (put in home
+# directory or current directory) or by invoking gdb command with
+# --command=<command-file-name> option
+#
+# Credits:
+# Alexander Nyberg <alexn@telia.com>
+# V Srivatsa <vatsa@in.ibm.com>
+# Maneesh Soni <maneesh@in.ibm.com>
+#
+
+define bttnobp
+       set $tasks_off=((size_t)&((struct task_struct *)0)->tasks)
+       set $pid_off=((size_t)&((struct task_struct *)0)->pids[1].pid_list.next)
+       set $init_t=&init_task
+       set $next_t=(((char *)($init_t->tasks).next) - $tasks_off)
+       while ($next_t != $init_t)
+               set $next_t=(struct task_struct *)$next_t
+               printf "\npid %d; comm %s:\n", $next_t.pid, $next_t.comm
+               printf "===================\n"
+               set var $stackp = $next_t.thread.esp
+               set var $stack_top = ($stackp & ~4095) + 4096
+
+               while ($stackp < $stack_top)
+                       if (*($stackp) > _stext && *($stackp) < _sinittext)
+                               info symbol *($stackp)
+                       end
+                       set $stackp += 4
+               end
+               set $next_th=(((char *)$next_t->pids[1].pid_list.next) - $pid_off)
+               while ($next_th != $next_t)
+                       set $next_th=(struct task_struct *)$next_th
+                       printf "\npid %d; comm %s:\n", $next_t.pid, $next_t.comm
+                       printf "===================\n"
+                       set var $stackp = $next_t.thread.esp
+                       set var $stack_top = ($stackp & ~4095) + 4096
+
+                       while ($stackp < $stack_top)
+                               if (*($stackp) > _stext && *($stackp) < _sinittext)
+                                       info symbol *($stackp)
+                               end
+                               set $stackp += 4
+                       end
+                       set $next_th=(((char *)$next_th->pids[1].pid_list.next) - $pid_off)
+               end
+               set $next_t=(char *)($next_t->tasks.next) - $tasks_off
+       end
+end
+document bttnobp
+       dump all thread stack traces on a kernel compiled with !CONFIG_FRAME_POINTER
+end
+
+define btt
+       set $tasks_off=((size_t)&((struct task_struct *)0)->tasks)
+       set $pid_off=((size_t)&((struct task_struct *)0)->pids[1].pid_list.next)
+       set $init_t=&init_task
+       set $next_t=(((char *)($init_t->tasks).next) - $tasks_off)
+       while ($next_t != $init_t)
+               set $next_t=(struct task_struct *)$next_t
+               printf "\npid %d; comm %s:\n", $next_t.pid, $next_t.comm
+               printf "===================\n"
+               set var $stackp = $next_t.thread.esp
+               set var $stack_top = ($stackp & ~4095) + 4096
+               set var $stack_bot = ($stackp & ~4095)
+
+               set $stackp = *($stackp)
+               while (($stackp < $stack_top) && ($stackp > $stack_bot))
+                       set var $addr = *($stackp + 4)
+                       info symbol $addr
+                       set $stackp = *($stackp)
+               end
+
+               set $next_th=(((char *)$next_t->pids[1].pid_list.next) - $pid_off)
+               while ($next_th != $next_t)
+                       set $next_th=(struct task_struct *)$next_th
+                       printf "\npid %d; comm %s:\n", $next_t.pid, $next_t.comm
+                       printf "===================\n"
+                       set var $stackp = $next_t.thread.esp
+                       set var $stack_top = ($stackp & ~4095) + 4096
+                       set var $stack_bot = ($stackp & ~4095)
+
+                       set $stackp = *($stackp)
+                       while (($stackp < $stack_top) && ($stackp > $stack_bot))
+                               set var $addr = *($stackp + 4)
+                               info symbol $addr
+                               set $stackp = *($stackp)
+                       end
+                       set $next_th=(((char *)$next_th->pids[1].pid_list.next) - $pid_off)
+               end
+               set $next_t=(char *)($next_t->tasks.next) - $tasks_off
+       end
+end
+document btt
+       dump all thread stack traces on a kernel compiled with CONFIG_FRAME_POINTER
+end
+
+define btpid
+       set var $pid = $arg0
+       set $tasks_off=((size_t)&((struct task_struct *)0)->tasks)
+       set $pid_off=((size_t)&((struct task_struct *)0)->pids[1].pid_list.next)
+       set $init_t=&init_task
+       set $next_t=(((char *)($init_t->tasks).next) - $tasks_off)
+       set var $pid_task = 0
+
+       while ($next_t != $init_t)
+               set $next_t=(struct task_struct *)$next_t
+
+               if ($next_t.pid == $pid)
+                       set $pid_task = $next_t
+               end
+
+               set $next_th=(((char *)$next_t->pids[1].pid_list.next) - $pid_off)
+               while ($next_th != $next_t)
+                       set $next_th=(struct task_struct *)$next_th
+                       if ($next_th.pid == $pid)
+                               set $pid_task = $next_th
+                       end
+                       set $next_th=(((char *)$next_th->pids[1].pid_list.next) - $pid_off)
+               end
+               set $next_t=(char *)($next_t->tasks.next) - $tasks_off
+       end
+
+       printf "\npid %d; comm %s:\n", $pid_task.pid, $pid_task.comm
+       printf "===================\n"
+       set var $stackp = $pid_task.thread.esp
+       set var $stack_top = ($stackp & ~4095) + 4096
+       set var $stack_bot = ($stackp & ~4095)
+
+       set $stackp = *($stackp)
+       while (($stackp < $stack_top) && ($stackp > $stack_bot))
+               set var $addr = *($stackp + 4)
+               info symbol $addr
+               set $stackp = *($stackp)
+       end
+end
+document btpid
+       backtrace of pid
+end
+
+
+define trapinfo
+       set var $pid = $arg0
+       set $tasks_off=((size_t)&((struct task_struct *)0)->tasks)
+       set $pid_off=((size_t)&((struct task_struct *)0)->pids[1].pid_list.next)
+       set $init_t=&init_task
+       set $next_t=(((char *)($init_t->tasks).next) - $tasks_off)
+       set var $pid_task = 0
+
+       while ($next_t != $init_t)
+               set $next_t=(struct task_struct *)$next_t
+
+               if ($next_t.pid == $pid)
+                       set $pid_task = $next_t
+               end
+
+               set $next_th=(((char *)$next_t->pids[1].pid_list.next) - $pid_off)
+               while ($next_th != $next_t)
+                       set $next_th=(struct task_struct *)$next_th
+                       if ($next_th.pid == $pid)
+                               set $pid_task = $next_th
+                       end
+                       set $next_th=(((char *)$next_th->pids[1].pid_list.next) - $pid_off)
+               end
+               set $next_t=(char *)($next_t->tasks.next) - $tasks_off
+       end
+
+       printf "Trapno %ld, cr2 0x%lx, error_code %ld\n", $pid_task.thread.trap_no, \
+                               $pid_task.thread.cr2, $pid_task.thread.error_code
+
+end
+document trapinfo
+       Run info threads and lookup pid of thread #1
+       'trapinfo <pid>' will tell you by which trap & possibly
+       addresthe kernel paniced.
+end
diff --git a/Documentation/kdump/kdump.txt b/Documentation/kdump/kdump.txt
new file mode 100644 (file)
index 0000000..7ff213f
--- /dev/null
@@ -0,0 +1,141 @@
+Documentation for kdump - the kexec-based crash dumping solution
+================================================================
+
+DESIGN
+======
+
+Kdump uses kexec to reboot to a second kernel whenever a dump needs to be taken.
+This second kernel is booted with very little memory. The first kernel reserves
+the section of memory that the second kernel uses. This ensures that on-going
+DMA from the first kernel does not corrupt the second kernel.
+
+All the necessary information about Core image is encoded in ELF format and
+stored in reserved area of memory before crash. Physical address of start of
+ELF header is passed to new kernel through command line parameter elfcorehdr=.
+
+On i386, the first 640 KB of physical memory is needed to boot, irrespective
+of where the kernel loads. Hence, this region is backed up by kexec just before
+rebooting into the new kernel.
+
+In the second kernel, "old memory" can be accessed in two ways.
+
+- The first one is through a /dev/oldmem device interface. A capture utility
+  can read the device file and write out the memory in raw format. This is raw
+  dump of memory and analysis/capture tool should be intelligent enough to
+  determine where to look for the right information. ELF headers (elfcorehdr=)
+  can become handy here.
+
+- The second interface is through /proc/vmcore. This exports the dump as an ELF
+  format file which can be written out using any file copy command
+  (cp, scp, etc). Further, gdb can be used to perform limited debugging on
+  the dump file. This method ensures methods ensure that there is correct
+  ordering of the dump pages (corresponding to the first 640 KB that has been
+  relocated).
+
+SETUP
+=====
+
+1) Download http://www.xmission.com/~ebiederm/files/kexec/kexec-tools-1.101.tar.gz
+   and apply http://lse.sourceforge.net/kdump/patches/kexec-tools-1.101-kdump.patch
+   and after that build the source.
+
+2) Download and build the appropriate (latest) kexec/kdump (-mm) kernel
+   patchset and apply it to the vanilla kernel tree.
+
+   Two kernels need to be built in order to get this feature working.
+
+  A) First kernel:
+   a) Enable "kexec system call" feature (in Processor type and features).
+       CONFIG_KEXEC=y
+   b) This kernel's physical load address should be the default value of
+      0x100000 (0x100000, 1 MB) (in Processor type and features).
+       CONFIG_PHYSICAL_START=0x100000
+   c) Enable "sysfs file system support" (in Pseudo filesystems).
+       CONFIG_SYSFS=y
+   d) Boot into first kernel with the command line parameter "crashkernel=Y@X".
+      Use appropriate values for X and Y. Y denotes how much memory to reserve
+      for the second kernel, and X denotes at what physical address the reserved
+      memory section starts. For example: "crashkernel=64M@16M".
+
+  B) Second kernel:
+   a) Enable "kernel crash dumps" feature (in Processor type and features).
+       CONFIG_CRASH_DUMP=y
+   b) Specify a suitable value for "Physical address where the kernel is
+      loaded" (in Processor type and features). Typically this value
+      should be same as X (See option d) above, e.g., 16 MB or 0x1000000.
+       CONFIG_PHYSICAL_START=0x1000000
+   c) Enable "/proc/vmcore support" (Optional, in Pseudo filesystems).
+       CONFIG_PROC_VMCORE=y
+   d) Disable SMP support and build a UP kernel (Until it is fixed).
+       CONFIG_SMP=n
+   e) Enable "Local APIC support on uniprocessors".
+       CONFIG_X86_UP_APIC=y
+   f) Enable "IO-APIC support on uniprocessors"
+       CONFIG_X86_UP_IOAPIC=y
+
+  Note:   i) Options a) and b) depend upon "Configure standard kernel features
+            (for small systems)" (under General setup).
+        ii) Option a) also depends on CONFIG_HIGHMEM (under Processor
+               type and features).
+       iii) Both option a) and b) are under "Processor type and features".
+
+3) Boot into the first kernel. You are now ready to try out kexec-based crash
+   dumps.
+
+4) Load the second kernel to be booted using:
+
+   kexec -p <second-kernel> --crash-dump --args-linux --append="root=<root-dev>
+   init 1 irqpoll"
+
+   Note: i) <second-kernel> has to be a vmlinux image. bzImage will not work,
+           as of now.
+       ii) By default ELF headers are stored in ELF32 format (for i386). This
+           is sufficient to represent the physical memory up to 4GB. To store
+           headers in ELF64 format, specifiy "--elf64-core-headers" on the
+           kexec command line additionally.
+       iii) Specify "irqpoll" as command line parameter. This reduces driver
+            initialization failures in second kernel due to shared interrupts.
+
+5) System reboots into the second kernel when a panic occurs. A module can be
+   written to force the panic or "ALT-SysRq-c" can be used initiate a crash
+   dump for testing purposes.
+
+6) Write out the dump file using
+
+   cp /proc/vmcore <dump-file>
+
+   Dump memory can also be accessed as a /dev/oldmem device for a linear/raw
+   view.  To create the device, type:
+
+   mknod /dev/oldmem c 1 12
+
+   Use "dd" with suitable options for count, bs and skip to access specific
+   portions of the dump.
+
+   Entire memory:  dd if=/dev/oldmem of=oldmem.001
+
+ANALYSIS
+========
+
+Limited analysis can be done using gdb on the dump file copied out of
+/proc/vmcore. Use vmlinux built with -g and run
+
+  gdb vmlinux <dump-file>
+
+Stack trace for the task on processor 0, register display, memory display
+work fine.
+
+Note: gdb cannot analyse core files generated in ELF64 format for i386.
+
+TODO
+====
+
+1) Provide a kernel pages filtering mechanism so that core file size is not
+   insane on systems having huge memory banks.
+2) Modify "crash" tool to make it recognize this dump.
+
+CONTACT
+=======
+
+Vivek Goyal (vgoyal@in.ibm.com)
+Maneesh Soni (maneesh@in.ibm.com)
index 4924d387a6573223e9877b56d4d28219f9f650b2..f44bb5567c5bc1816ed8dc30442fdb09a17ce3f2 100644 (file)
@@ -358,6 +358,10 @@ running once the system is up.
        cpia_pp=        [HW,PPT]
                        Format: { parport<nr> | auto | none }
 
+       crashkernel=nn[KMG]@ss[KMG]
+                       [KNL] Reserve a chunk of physical memory to
+                       hold a kernel to switch to with kexec on panic.
+
        cs4232=         [HW,OSS]
                        Format: <io>,<irq>,<dma>,<dma2>,<mpuio>,<mpuirq>
 
@@ -447,6 +451,10 @@ running once the system is up.
                        Format: {"as"|"cfq"|"deadline"|"noop"}
                        See Documentation/block/as-iosched.txt
                        and Documentation/block/deadline-iosched.txt for details.
+       elfcorehdr=     [IA-32]
+                       Specifies physical address of start of kernel core image
+                       elf header.
+                       See Documentation/kdump.txt for details.
 
        enforcing       [SELINUX] Set initial enforcing status.
                        Format: {"0" | "1"}
@@ -548,6 +556,9 @@ running once the system is up.
 
        i810=           [HW,DRM]
 
+       i8k.ignore_dmi  [HW] Continue probing hardware even if DMI data
+                       indicates that the driver is running on unsupported
+                       hardware.
        i8k.force       [HW] Activate i8k driver even if SMM BIOS signature
                        does not match list of supported models.
        i8k.power_status
index 834993d267303d30e53817aafb0ffe4894afb608..5b01d5cc4e95b8d2087d3dc1039094bfab34f56f 100644 (file)
@@ -114,9 +114,7 @@ tuntap.txt
 vortex.txt
        - info on using 3Com Vortex (3c590, 3c592, 3c595, 3c597) Ethernet cards.
 wan-router.txt
-       - Wan router documentation
-wanpipe.txt
-       - WANPIPE(tm) Multiprotocol WAN Driver for Linux WAN Router
+       - WAN router documentation
 wavelan.txt
        - AT&T GIS (nee NCR) WaveLAN card: An Ethernet-like radio transceiver
 x25.txt
diff --git a/Documentation/networking/wanpipe.txt b/Documentation/networking/wanpipe.txt
deleted file mode 100644 (file)
index aea20cd..0000000
+++ /dev/null
@@ -1,622 +0,0 @@
-------------------------------------------------------------------------------
-Linux WAN Router Utilities Package
-------------------------------------------------------------------------------
-Version 2.2.1 
-Mar 28, 2001
-Author: Nenad Corbic <ncorbic@sangoma.com>
-Copyright (c) 1995-2001 Sangoma Technologies Inc.
-------------------------------------------------------------------------------
-
-INTRODUCTION
-
-Wide Area Networks (WANs) are used to interconnect Local Area Networks (LANs)
-and/or stand-alone hosts over vast distances with data transfer rates
-significantly higher than those achievable with commonly used dial-up
-connections.
-
-Usually an external device called `WAN router' sitting on your local network
-or connected to your machine's serial port provides physical connection to
-WAN.  Although router's job may be as simple as taking your local network
-traffic, converting it to WAN format and piping it through the WAN link, these
-devices are notoriously expensive, with prices as much as 2 - 5 times higher
-then the price of a typical PC box.
-
-Alternatively, considering robustness and multitasking capabilities of Linux,
-an internal router can be built (most routers use some sort of stripped down
-Unix-like operating system anyway). With a number of relatively inexpensive WAN
-interface cards available on the market, a perfectly usable router can be
-built for less than half a price of an external router.  Yet a Linux box
-acting as a router can still be used for other purposes, such as fire-walling,
-running FTP, WWW or DNS server, etc.
-
-This kernel module introduces the notion of a WAN Link Driver (WLD) to Linux
-operating system and provides generic hardware-independent services for such
-drivers.  Why can existing Linux network device interface not be used for
-this purpose?  Well, it can.  However, there are a few key differences between
-a typical network interface (e.g. Ethernet) and a WAN link.
-
-Many WAN protocols, such as X.25 and frame relay, allow for multiple logical
-connections (known as `virtual circuits' in X.25 terminology) over a single
-physical link.  Each such virtual circuit may (and almost always does) lead
-to a different geographical location and, therefore, different network.  As a
-result, it is the virtual circuit, not the physical link, that represents a
-route and, therefore, a network interface in Linux terms.
-
-To further complicate things, virtual circuits are usually volatile in nature
-(excluding so called `permanent' virtual circuits or PVCs).  With almost no
-time required to set up and tear down a virtual circuit, it is highly desirable
-to implement on-demand connections in order to minimize network charges.  So
-unlike a typical network driver, the WAN driver must be able to handle multiple
-network interfaces and cope as multiple virtual circuits come into existence
-and go away dynamically.
-Last, but not least, WAN configuration is much more complex than that of say
-Ethernet and may well amount to several dozens of parameters.  Some of them
-are "link-wide"  while others are virtual circuit-specific.  The same holds
-true for WAN statistics which is by far more extensive and extremely useful
-when troubleshooting WAN connections.  Extending the ifconfig utility to suit
-these needs may be possible, but does not seem quite reasonable.  Therefore, a
-WAN configuration utility and corresponding application programmer's interface
-is needed for this purpose.
-
-Most of these problems are taken care of by this module.  Its goal is to
-provide a user with more-or-less standard look and feel for all WAN devices and
-assist a WAN device driver writer by providing common services, such as:
-
- o User-level interface via /proc file system
- o Centralized configuration
- o Device management (setup, shutdown, etc.)
- o Network interface management (dynamic creation/destruction)
- o Protocol encapsulation/decapsulation
-
-To ba able to use the Linux WAN Router you will also need a WAN Tools package
-available from
-
-       ftp.sangoma.com/pub/linux/current_wanpipe/wanpipe-X.Y.Z.tgz
-
-where vX.Y.Z represent the wanpipe version number.
-
-For technical questions and/or comments please e-mail to ncorbic@sangoma.com.
-For general inquiries please contact Sangoma Technologies Inc. by
-
-       Hotline:        1-800-388-2475  (USA and Canada, toll free)
-       Phone:          (905) 474-1990  ext: 106
-       Fax:            (905) 474-9223
-       E-mail:         dm@sangoma.com  (David Mandelstam)
-       WWW:            http://www.sangoma.com
-
-
-INSTALLATION
-
-Please read the WanpipeForLinux.pdf manual on how to 
-install the WANPIPE tools and drivers properly. 
-
-
-After installing wanpipe package: /usr/local/wanrouter/doc. 
-On the ftp.sangoma.com : /linux/current_wanpipe/doc
-
-
-COPYRIGHT AND LICENSING INFORMATION
-
-This program is free software; you can redistribute it and/or modify it under
-the terms of the GNU General Public License as published by the Free Software
-Foundation; either version 2, or (at your option) any later version.
-
-This program is distributed in the hope that it will be useful, but WITHOUT
-ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License along with
-this program; if not, write to the Free Software Foundation, Inc., 675 Mass
-Ave, Cambridge, MA 02139, USA.
-
-
-
-ACKNOWLEDGEMENTS
-
-This product is based on the WANPIPE(tm) Multiprotocol WAN Router developed
-by Sangoma Technologies Inc. for Linux 2.0.x and 2.2.x.  Success of the WANPIPE
-together with the next major release of Linux kernel in summer 1996 commanded
-adequate changes to the WANPIPE code to take full advantage of new Linux
-features.
-
-Instead of continuing developing proprietary interface tied to Sangoma WAN
-cards, we decided to separate all hardware-independent code into a separate
-module and defined two levels of interfaces - one for user-level applications
-and another for kernel-level WAN drivers.  WANPIPE is now implemented as a
-WAN driver compliant with the WAN Link Driver interface.  Also a general
-purpose WAN configuration utility and a set of shell scripts was developed to 
-support WAN router at the user level.
-
-Many useful ideas concerning hardware-independent interface implementation
-were given by Mike McLagan <mike.mclagan@linux.org> and his implementation
-of the Frame Relay router and drivers for Sangoma cards (dlci/sdla).
-
-With the new implementation of the APIs being incorporated into the WANPIPE,
-a special thank goes to Alan Cox in providing insight into BSD sockets.
-
-Special thanks to all the WANPIPE users who performed field-testing, reported
-bugs and made valuable comments and suggestions that help us to improve this
-product.
-
-
-
-NEW IN THIS RELEASE
-
-       o Updated the WANCFG utility
-               Calls the pppconfig to configure the PPPD
-               for async connections.
-
-       o Added the PPPCONFIG utility
-               Used to configure the PPPD dameon for the
-               WANPIPE Async PPP and standard serial port.
-               The wancfg calls the pppconfig to configure
-               the pppd.
-
-       o Fixed the PCI autodetect feature.  
-               The SLOT 0 was used as an autodetect option
-               however, some high end PC's slot numbers start
-               from 0. 
-
-       o This release has been tested with the new backupd
-         daemon release.
-       
-
-PRODUCT COMPONENTS AND RELATED FILES
-
-/etc: (or user defined)
-       wanpipe1.conf   default router configuration file
-
-/lib/modules/X.Y.Z/misc:
-       wanrouter.o     router kernel loadable module
-       af_wanpipe.o    wanpipe api socket module
-
-/lib/modules/X.Y.Z/net:
-       sdladrv.o       Sangoma SDLA support module
-       wanpipe.o       Sangoma WANPIPE(tm) driver module
-
-/proc/net/wanrouter
-       Config          reads current router configuration
-       Status          reads current router status
-       {name}          reads WAN driver statistics
-
-/usr/sbin:
-       wanrouter       wanrouter start-up script
-       wanconfig       wanrouter configuration utility
-       sdladump        WANPIPE adapter memory dump utility
-        fpipemon        Monitor for Frame Relay
-        cpipemon        Monitor for Cisco HDLC
-       ppipemon        Monitor for PPP
-       xpipemon        Monitor for X25
-       wpkbdmon        WANPIPE keyboard led monitor/debugger
-
-/usr/local/wanrouter:
-       README          this file
-       COPYING         GNU General Public License
-       Setup           installation script
-       Filelist        distribution definition file
-       wanrouter.rc    meta-configuration file 
-                       (used by the Setup and wanrouter script)
-
-/usr/local/wanrouter/doc:
-       wanpipeForLinux.pdf     WAN Router User's Manual
-
-/usr/local/wanrouter/patches:
-       wanrouter-v2213.gz      patch for Linux kernels 2.2.11 up to 2.2.13.
-       wanrouter-v2214.gz      patch for Linux kernel 2.2.14. 
-       wanrouter-v2215.gz      patch for Linux kernels 2.2.15 to 2.2.17.
-       wanrouter-v2218.gz      patch for Linux kernels 2.2.18 and up.
-       wanrouter-v240.gz       patch for Linux kernel 2.4.0.  
-       wanrouter-v242.gz       patch for Linux kernel 2.4.2 and up.
-       wanrouter-v2034.gz      patch for Linux kernel 2.0.34
-       wanrouter-v2036.gz      patch for Linux kernel 2.0.36 and up. 
-
-/usr/local/wanrouter/patches/kdrivers:
-       Sources of the latest WANPIPE device drivers.
-       These are used to UPGRADE the linux kernel to the newest
-       version if the kernel source has already been pathced with
-       WANPIPE drivers.
-
-/usr/local/wanrouter/samples:
-       interface       sample interface configuration file
-       wanpipe1.cpri   CHDLC primary port
-       wanpipe2.csec   CHDLC secondary port
-       wanpipe1.fr     Frame Relay protocol
-       wanpipe1.ppp    PPP protocol ) 
-       wanpipe1.asy    CHDLC ASYNC protocol
-       wanpipe1.x25    X25 protocol
-       wanpipe1.stty   Sync TTY driver (Used by Kernel PPPD daemon)
-       wanpipe1.atty   Async TTY driver (Used by Kernel PPPD daemon)
-       wanrouter.rc    sample meta-configuration file
-
-/usr/local/wanrouter/util:
-       *               wan-tools utilities source code
-
-/usr/local/wanrouter/api/x25:
-       *               x25 api sample programs.
-/usr/local/wanrouter/api/chdlc:
-       *               chdlc api sample programs.
-/usr/local/wanrouter/api/fr:
-       *               fr api sample programs.
-/usr/local/wanrouter/config/wancfg:
-       wancfg          WANPIPE GUI configuration program.
-                        Creates wanpipe#.conf files. 
-/usr/local/wanrouter/config/cfgft1:
-       cfgft1          GUI CSU/DSU configuration program.
-
-/usr/include/linux:
-       wanrouter.h     router API definitions
-       wanpipe.h       WANPIPE API definitions
-       sdladrv.h       SDLA support module API definitions
-       sdlasfm.h       SDLA firmware module definitions
-       if_wanpipe.h    WANPIPE Socket definitions
-       if_wanpipe_common.h     WANPIPE Socket/Driver common definitions.
-       sdlapci.h       WANPIPE PCI definitions
-       
-
-/usr/src/linux/net/wanrouter:
-       *               wanrouter source code
-
-/var/log:
-       wanrouter       wanrouter start-up log (created by the Setup script)
-
-/var/lock:  (or /var/lock/subsys for RedHat)
-       wanrouter       wanrouter lock file (created by the Setup script)
-
-/usr/local/wanrouter/firmware:
-       fr514.sfm       Frame relay firmware for Sangoma S508/S514 card
-       cdual514.sfm    Dual Port Cisco HDLC firmware for Sangoma S508/S514 card
-       ppp514.sfm      PPP Firmware for Sangoma S508 and S514 cards
-       x25_508.sfm     X25 Firmware for Sangoma S508 card.
-
-
-REVISION HISTORY
-
-1.0.0  December 31, 1996       Initial version
-
-1.0.1  January 30, 1997        Status and statistics can be read via /proc
-                               filesystem entries.
-
-1.0.2   April 30, 1997          Added UDP management via monitors.
-
-1.0.3  June 3, 1997            UDP management for multiple boards using Frame
-                               Relay and PPP
-                               Enabled continuous transmission of Configure 
-                               Request Packet for PPP (for 508 only)
-                               Connection Timeout for PPP changed from 900 to 0
-                               Flow Control Problem fixed for Frame Relay
-
-1.0.4  July 10, 1997           S508/FT1 monitoring capability in fpipemon and
-                               ppipemon utilities.
-                               Configurable TTL for UDP packets.
-                               Multicast and Broadcast IP source addresses are
-                               silently discarded.
-
-1.0.5  July 28, 1997           Configurable T391,T392,N391,N392,N393 for Frame
-                               Relay in router.conf.
-                               Configurable Memory Address through router.conf 
-                               for Frame Relay, PPP and X.25. (commenting this
-                               out enables auto-detection).
-                               Fixed freeing up received buffers using kfree()
-                               for Frame Relay and X.25.
-                               Protect sdla_peek() by calling save_flags(),
-                               cli() and restore_flags().
-                               Changed number of Trace elements from 32 to 20
-                               Added DLCI specific data monitoring in FPIPEMON. 
-2.0.0  Nov 07, 1997            Implemented protection of RACE conditions by 
-                               critical flags for FRAME RELAY and PPP.
-                               DLCI List interrupt mode implemented.
-                               IPX support in FRAME RELAY and PPP.
-                               IPX Server Support (MARS)
-                               More driver specific stats included in FPIPEMON
-                               and PIPEMON.
-
-2.0.1  Nov 28, 1997            Bug Fixes for version 2.0.0.
-                               Protection of "enable_irq()" while 
-                               "disable_irq()" has been enabled from any other
-                               routine (for Frame Relay, PPP and X25).
-                               Added additional Stats for Fpipemon and Ppipemon
-                               Improved Load Sharing for multiple boards
-
-2.0.2  Dec 09, 1997            Support for PAP and CHAP for ppp has been
-                               implemented.
-
-2.0.3  Aug 15, 1998            New release supporting Cisco HDLC, CIR for Frame
-                               relay, Dynamic IP assignment for PPP and Inverse
-                               Arp support for Frame-relay.  Man Pages are 
-                               included for better support and a new utility
-                               for configuring FT1 cards.
-
-2.0.4  Dec 09, 1998            Dual Port support for Cisco HDLC.
-                               Support for HDLC (LAPB) API.
-                               Supports BiSync Streaming code for S502E 
-                               and S503 cards.
-                               Support for Streaming HDLC API.
-                               Provides a BSD socket interface for 
-                               creating applications using BiSync
-                               streaming.        
-
-2.0.5   Aug 04, 1999           CHDLC initializatin bug fix.
-                               PPP interrupt driven driver: 
-                               Fix to the PPP line hangup problem.
-                               New PPP firmware
-                               Added comments to the startup SYSTEM ERROR messages
-                               Xpipemon debugging application for the X25 protocol
-                               New USER_MANUAL.txt
-                               Fixed the odd boundary 4byte writes to the board.
-                               BiSync Streaming code has been taken out.  
-                                Available as a patch.
-                               Streaming HDLC API has been taken out.  
-                                Available as a patch.                 
-
-2.0.6   Aug 17, 1999           Increased debugging in statup scripts
-                               Fixed insallation bugs from 2.0.5
-                               Kernel patch works for both 2.2.10 and 2.2.11 kernels.
-                               There is no functional difference between the two packages         
-
-2.0.7   Aug 26, 1999           o  Merged X25API code into WANPIPE.
-                               o  Fixed a memeory leak for X25API
-                               o  Updated the X25API code for 2.2.X kernels.
-                               o  Improved NEM handling.   
-
-2.1.0  Oct 25, 1999            o New code for S514 PCI Card
-                               o New CHDLC and Frame Relay drivers
-                               o PPP and X25 are not supported in this release    
-
-2.1.1  Nov 30, 1999            o PPP support for S514 PCI Cards
-
-2.1.3   Apr 06, 2000           o Socket based x25api 
-                               o Socket based chdlc api
-                               o Socket based fr api
-                               o Dual Port Receive only CHDLC support.
-                               o Asynchronous CHDLC support (Secondary Port)
-                               o cfgft1 GUI csu/dsu configurator
-                               o wancfg GUI configuration file 
-                                 configurator.
-                               o Architectual directory changes.
-
-beta-2.1.4 Jul 2000            o Dynamic interface configuration:
-                                       Network interfaces reflect the state
-                                       of protocol layer.  If the protocol becomes
-                                       disconnected, driver will bring down
-                                       the interface.  Once the protocol reconnects
-                                       the interface will be brought up. 
-                                       
-                                       Note: This option is turned off by default.
-
-                               o Dynamic wanrouter setup using 'wanconfig':
-                                       wanconfig utility can be used to
-                                       shutdown,restart,start or reconfigure 
-                                       a virtual circuit dynamically.
-                                    
-                                       Frame Relay:  Each DLCI can be: 
-                                                     created,stopped,restarted and reconfigured
-                                                     dynamically using wanconfig.
-                                       
-                                                     ex: wanconfig card wanpipe1 dev wp1_fr16 up
-                                 
-                               o Wanrouter startup via command line arguments:
-                                       wanconfig also supports wanrouter startup via command line
-                                       arguments.  Thus, there is no need to create a wanpipe#.conf
-                                       configuration file.  
-
-                               o Socket based x25api update/bug fixes.
-                                       Added support for LCN numbers greater than 255.
-                                       Option to pass up modem messages.
-                                       Provided a PCI IRQ check, so a single S514
-                                       card is guaranteed to have a non-sharing interrupt.
-
-                               o Fixes to the wancfg utility.
-                               o New FT1 debugging support via *pipemon utilities.
-                               o Frame Relay ARP support Enabled.
-
-beta3-2.1.4 Jul 2000           o X25 M_BIT Problem fix.
-                               o Added the Multi-Port PPP
-                                 Updated utilites for the Multi-Port PPP.
-
-2.1.4  Aut 2000
-                               o In X25API:
-                                       Maximum packet an application can send
-                                       to the driver has been extended to 4096 bytes.
-
-                                       Fixed the x25 startup bug. Enable 
-                                       communications only after all interfaces
-                                       come up.  HIGH SVC/PVC is used to calculate
-                                       the number of channels.
-                                       Enable protocol only after all interfaces
-                                       are enabled.
-
-                               o Added an extra state to the FT1 config, kernel module.
-                               o Updated the pipemon debuggers.
-
-                               o Blocked the Multi-Port PPP from running on kernels
-                                 2.2.16 or greater, due to syncppp kernel module
-                                 change. 
-         
-beta1-2.1.5    Nov 15 2000
-                               o Fixed the MulitPort PPP Support for kernels 2.2.16 and above.
-                                 2.2.X kernels only
-
-                               o Secured the driver UDP debugging calls
-                                       - All illegal netowrk debugging calls are reported to
-                                         the log.
-                                       - Defined a set of allowed commands, all other denied.
-                                       
-                               o Cpipemon
-                                       - Added set FT1 commands to the cpipemon. Thus CSU/DSU
-                                         configuraiton can be performed using cpipemon.
-                                         All systems that cannot run cfgft1 GUI utility should
-                                         use cpipemon to configure the on board CSU/DSU.
-
-
-                               o Keyboard Led Monitor/Debugger
-                                       - A new utilty /usr/sbin/wpkbdmon uses keyboard leds
-                                         to convey operatinal statistic information of the 
-                                         Sangoma WANPIPE cards.
-                                       NUM_LOCK    = Line State  (On=connected,    Off=disconnected)
-                                       CAPS_LOCK   = Tx data     (On=transmitting, Off=no tx data)
-                                       SCROLL_LOCK = Rx data     (On=receiving,    Off=no rx data
-                                       
-                               o Hardware probe on module load and dynamic device allocation
-                                       - During WANPIPE module load, all Sangoma cards are probed
-                                         and found information is printed in the /var/log/messages.
-                                       - If no cards are found, the module load fails.
-                                       - Appropriate number of devices are dynamically loaded 
-                                         based on the number of Sangoma cards found.
-
-                                         Note: The kernel configuraiton option 
-                                               CONFIG_WANPIPE_CARDS has been taken out.
-                                       
-                               o Fixed the Frame Relay and Chdlc network interfaces so they are
-                                 compatible with libpcap libraries.  Meaning, tcpdump, snort,
-                                 ethereal, and all other packet sniffers and debuggers work on
-                                 all WANPIPE netowrk interfaces.
-                                       - Set the network interface encoding type to ARPHRD_PPP.
-                                         This tell the sniffers that data obtained from the
-                                         network interface is in pure IP format.
-                                 Fix for 2.2.X kernels only.
-                               
-                               o True interface encoding option for Frame Relay and CHDLC
-                                       - The above fix sets the network interface encoding
-                                         type to ARPHRD_PPP, however some customers use
-                                         the encoding interface type to determine the
-                                         protocol running.  Therefore, the TURE ENCODING
-                                         option will set the interface type back to the
-                                         original value.  
-
-                                         NOTE: If this option is used with Frame Relay and CHDLC
-                                               libpcap library support will be broken.  
-                                               i.e. tcpdump will not work.
-                                       Fix for 2.2.x Kernels only.
-                                               
-                               o Ethernet Bridgind over Frame Relay
-                                       - The Frame Relay bridging has been developed by 
-                                         Kristian Hoffmann and Mark Wells.  
-                                       - The Linux kernel bridge is used to send ethernet 
-                                         data over the frame relay links.
-                                       For 2.2.X Kernels only.
-
-                               o Added extensive 2.0.X support. Most new features of
-                                 2.1.5 for protocols Frame Relay, PPP and CHDLC are
-                                 supported under 2.0.X kernels. 
-
-beta1-2.2.0    Dec 30 2000
-                               o Updated drivers for 2.4.X kernels.
-                               o Updated drivers for SMP support.
-                               o X25API is now able to share PCI interrupts.
-                               o Took out a general polling routine that was used
-                                 only by X25API. 
-                               o Added appropriate locks to the dynamic reconfiguration
-                                 code.
-                               o Fixed a bug in the keyboard debug monitor.
-
-beta2-2.2.0    Jan 8 2001
-                               o Patches for 2.4.0 kernel
-                               o Patches for 2.2.18 kernel
-                               o Minor updates to PPP and CHLDC drivers.
-                                 Note: No functinal difference. 
-
-beta3-2.2.9    Jan 10 2001
-                               o I missed the 2.2.18 kernel patches in beta2-2.2.0
-                                 release.  They are included in this release.
-
-Stable Release
-2.2.0          Feb 01 2001
-                               o Bug fix in wancfg GUI configurator.
-                                       The edit function didn't work properly.
-
-
-bata1-2.2.1    Feb 09 2001
-                       o WANPIPE TTY Driver emulation. 
-                         Two modes of operation Sync and Async.
-                               Sync: Using the PPPD daemon, kernel SyncPPP layer
-                                     and the Wanpipe sync TTY driver: a PPP protocol 
-                                     connection can be established via Sangoma adapter, over
-                                     a T1 leased line.
-                       
-                                     The 2.4.0 kernel PPP layer supports MULTILINK
-                                     protocol, that can be used to bundle any number of Sangoma
-                                     adapters (T1 lines) into one, under a single IP address.
-                                     Thus, efficiently obtaining multiple T1 throughput. 
-
-                                     NOTE: The remote side must also implement MULTILINK PPP
-                                           protocol.
-
-                               Async:Using the PPPD daemon, kernel AsyncPPP layer
-                                     and the WANPIPE async TTY driver: a PPP protocol
-                                     connection can be established via Sangoma adapter and
-                                     a modem, over a telephone line.
-
-                                     Thus, the WANPIPE async TTY driver simulates a serial
-                                     TTY driver that would normally be used to interface the 
-                                     MODEM to the linux kernel.
-                               
-                       o WANPIPE PPP Backup Utility
-                               This utility will monitor the state of the PPP T1 line.
-                               In case of failure, a dial up connection will be established
-                               via pppd daemon, ether via a serial tty driver (serial port), 
-                               or a WANPIPE async TTY driver (in case serial port is unavailable).
-                               
-                               Furthermore, while in dial up mode, the primary PPP T1 link
-                               will be monitored for signs of life.  
-
-                               If the PPP T1 link comes back to life, the dial up connection
-                               will be shutdown and T1 line re-established.
-                       
-
-                       o New Setup installation script.
-                               Option to UPGRADE device drivers if the kernel source has
-                               already been patched with WANPIPE.
-
-                               Option to COMPILE WANPIPE modules against the currently 
-                               running kernel, thus no need for manual kernel and module
-                               re-compilatin.
-                       
-                       o Updates and Bug Fixes to wancfg utility.
-
-bata2-2.2.1    Feb 20 2001
-
-                       o Bug fixes to the CHDLC device drivers.
-                               The driver had compilation problems under kernels
-                               2.2.14 or lower.
-
-                       o Bug fixes to the Setup installation script.
-                               The device drivers compilation options didn't work
-                               properly.
-
-                       o Update to the wpbackupd daemon.  
-                               Optimized the cross-over times, between the primary
-                               link and the backup dialup.
-
-beta3-2.2.1    Mar 02 2001
-                       o Patches for 2.4.2 kernel.
-
-                       o Bug fixes to util/ make files.
-                       o Bug fixes to the Setup installation script.
-
-                       o Took out the backupd support and made it into
-                         as separate package.
-                         
-beta4-2.2.1     Mar 12 2001
-
-               o Fix to the Frame Relay Device driver.
-                       IPSAC sends a packet of zero length
-                       header to the frame relay driver.  The
-                       driver tries to push its own 2 byte header
-                       into the packet, which causes the driver to
-                       crash.
-
-               o Fix the WANPIPE re-configuration code.
-                       Bug was found by trying to run  the cfgft1 while the
-                       interface was already running.  
-
-               o Updates to cfgft1.
-                       Writes a wanpipe#.cfgft1 configuration file
-                       once the CSU/DSU is configured. This file can
-                       holds the current CSU/DSU configuration.
-
-
-
->>>>>> END OF README <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
-
-
index 60b548105edf7052501fa43ab299dbbc44208fd8..fb57784986b1fcdee6b76048fb9c9703939bc849 100644 (file)
@@ -12,8 +12,7 @@ refrigerator. Code to do this looks like this:
        do {
                hub_events();
                wait_event_interruptible(khubd_wait, !list_empty(&hub_event_list));
-               if (current->flags & PF_FREEZE)
-                       refrigerator(PF_FREEZE);
+               try_to_freeze();
        } while (!signal_pending(current));
 
 from drivers/usb/core/hub.c::hub_thread()
index 35b1a7dae34253751ade84ca7f0eda948fac11dd..6fc9d511fc39ef01af4b88492b4b2edea5ffb623 100644 (file)
@@ -291,6 +291,44 @@ a request to enable wake events from D3, two calls should be made to
 pci_enable_wake (one for both D3hot and D3cold).
 
 
+A reference implementation
+-------------------------
+.suspend()
+{
+       /* driver specific operations */
+
+       /* Disable IRQ */
+       free_irq();
+       /* If using MSI */
+       pci_disable_msi();
+
+       pci_save_state();
+       pci_enable_wake();
+       /* Disable IO/bus master/irq router */
+       pci_disable_device();
+       pci_set_power_state(pci_choose_state());
+}
+
+.resume()
+{
+       pci_set_power_state(PCI_D0);
+       pci_restore_state();
+       /* device's irq possibly is changed, driver should take care */
+       pci_enable_device();
+       pci_set_master();
+
+       /* if using MSI, device's vector possibly is changed */
+       pci_enable_msi();
+
+       request_irq();
+       /* driver specific operations; */
+}
+
+This is a typical implementation. Drivers can slightly change the order
+of the operations in the implementation, ignore some operations or add
+more deriver specific operations in it, but drivers should do something like
+this on the whole.
+
 5. Resources
 ~~~~~~~~~~~~
 
index c7c3459fde4343fa3823db8ce21acb8830638df7..7a6b7896645942d69815ee3b37594618367a9069 100644 (file)
@@ -164,11 +164,11 @@ place where the thread is safe to be frozen (no kernel semaphores
 should be held at that point and it must be safe to sleep there), and
 add:
 
-            if (current->flags & PF_FREEZE)
-                    refrigerator(PF_FREEZE);
+       try_to_freeze();
 
 If the thread is needed for writing the image to storage, you should
-instead set the PF_NOFREEZE process flag when creating the thread.
+instead set the PF_NOFREEZE process flag when creating the thread (and
+be very carefull).
 
 
 Q: What is the difference between between "platform", "shutdown" and
@@ -233,3 +233,81 @@ A: Try running
 cat `cat /proc/[0-9]*/maps | grep / | sed 's:.* /:/:' | sort -u` > /dev/null
 
 after resume. swapoff -a; swapon -a may also be usefull.
+
+Q: What happens to devices during swsusp? They seem to be resumed
+during system suspend?
+
+A: That's correct. We need to resume them if we want to write image to
+disk. Whole sequence goes like
+
+      Suspend part
+      ~~~~~~~~~~~~
+      running system, user asks for suspend-to-disk
+
+      user processes are stopped
+
+      suspend(PMSG_FREEZE): devices are frozen so that they don't interfere
+                     with state snapshot
+
+      state snapshot: copy of whole used memory is taken with interrupts disabled
+
+      resume(): devices are woken up so that we can write image to swap
+
+      write image to swap
+
+      suspend(PMSG_SUSPEND): suspend devices so that we can power off
+
+      turn the power off
+
+      Resume part
+      ~~~~~~~~~~~
+      (is actually pretty similar)
+
+      running system, user asks for suspend-to-disk
+
+      user processes are stopped (in common case there are none, but with resume-from-initrd, noone knows)
+
+      read image from disk
+
+      suspend(PMSG_FREEZE): devices are frozen so that they don't interfere
+                     with image restoration
+
+      image restoration: rewrite memory with image
+
+      resume(): devices are woken up so that system can continue
+
+      thaw all user processes
+
+Q: What is this 'Encrypt suspend image' for?
+
+A: First of all: it is not a replacement for dm-crypt encrypted swap.
+It cannot protect your computer while it is suspended. Instead it does
+protect from leaking sensitive data after resume from suspend.
+
+Think of the following: you suspend while an application is running
+that keeps sensitive data in memory. The application itself prevents
+the data from being swapped out. Suspend, however, must write these
+data to swap to be able to resume later on. Without suspend encryption
+your sensitive data are then stored in plaintext on disk.  This means
+that after resume your sensitive data are accessible to all
+applications having direct access to the swap device which was used
+for suspend. If you don't need swap after resume these data can remain
+on disk virtually forever. Thus it can happen that your system gets
+broken in weeks later and sensitive data which you thought were
+encrypted and protected are retrieved and stolen from the swap device.
+To prevent this situation you should use 'Encrypt suspend image'.
+
+During suspend a temporary key is created and this key is used to
+encrypt the data written to disk. When, during resume, the data was
+read back into memory the temporary key is destroyed which simply
+means that all data written to disk during suspend are then
+inaccessible so they can't be stolen later on.  The only thing that
+you must then take care of is that you call 'mkswap' for the swap
+partition used for suspend as early as possible during regular
+boot. This asserts that any temporary key from an oopsed suspend or
+from a failed or aborted resume is erased from the swap device.
+
+As a rule of thumb use encrypted swap to protect your data while your
+system is shut down or suspended. Additionally use the encrypted
+suspend image to prevent sensitive data from being stolen after
+resume.
index 68734355d7cffccdac1071e733c419fef525f9b4..881a37e3eeb0a8cd36194453c3c728c9e3720fc1 100644 (file)
@@ -83,8 +83,10 @@ Compaq Armada E500 - P3-700     none (1) (S1 also works OK)
 Compaq Evo N620c               vga=normal, s3_bios (2)
 Dell 600m, ATI R250 Lf         none (1), but needs xorg-x11-6.8.1.902-1
 Dell D600, ATI RV250            vga=normal and X, or try vbestate (6)
+Dell D610                      vga=normal and X (possibly vbestate (6) too, but not tested)
 Dell Inspiron 4000             ??? (*)
 Dell Inspiron 500m             ??? (*)
+Dell Inspiron 510m             ???
 Dell Inspiron 600m             ??? (*)
 Dell Inspiron 8200             ??? (*)
 Dell Inspiron 8500             ??? (*)
@@ -123,6 +125,7 @@ Toshiba Satellite 4030CDT   s3_mode (3)
 Toshiba Satellite 4080XCDT      s3_mode (3)
 Toshiba Satellite 4090XCDT      ??? (*)
 Toshiba Satellite P10-554       s3_bios,s3_mode (4)(****)
+Toshiba M30                     (2) xor X with nvidia driver using internal AGP
 Uniwill 244IIO                 ??? (*)
 
 
index 8e33d7c82c49c05e53c7a45e29fd8de5af9e9bdf..b2f9b1598ac21c5df72b5327226db1891713cf24 100644 (file)
@@ -1,13 +1,16 @@
-This driver implement the ACPI Extensions For Display Adapters
-for integrated graphics devices on motherboard, as specified in
-ACPI 2.0 Specification, Appendix B, allowing to perform some basic
-control like defining the video POST device, retrieving EDID information
-or to setup a video output, etc.  Note that this is an ref. implementation only.
-It may or may not work for your integrated video device.
+ACPI video extensions
+~~~~~~~~~~~~~~~~~~~~~
+
+This driver implement the ACPI Extensions For Display Adapters for
+integrated graphics devices on motherboard, as specified in ACPI 2.0
+Specification, Appendix B, allowing to perform some basic control like
+defining the video POST device, retrieving EDID information or to
+setup a video output, etc.  Note that this is an ref. implementation
+only.  It may or may not work for your integrated video device.
 
 Interfaces exposed to userland through /proc/acpi/video:
 
-VGA/info : display the supported video bus device capability like ,Video ROM, CRT/LCD/TV.
+VGA/info : display the supported video bus device capability like Video ROM, CRT/LCD/TV.
 VGA/ROM :  Used to get a copy of the display devices' ROM data (up to 4k).
 VGA/POST_info : Used to determine what options are implemented.
 VGA/POST : Used to get/set POST device.
@@ -15,7 +18,7 @@ VGA/DOS : Used to get/set ownership of output switching:
        Please refer ACPI spec B.4.1 _DOS
 VGA/CRT : CRT output
 VGA/LCD : LCD output
-VGA/TV : TV output 
+VGA/TVO : TV output
 VGA/*/brightness : Used to get/set brightness of output device
 
 Notify event through /proc/acpi/event:
index 2d1cd939b4df784d3644c6572d54693ff70b6b96..e24fdeada9705e3e9a14cc4195592e832d169c00 100644 (file)
@@ -12,8 +12,8 @@ where log records can be stored efficiently in memory, where each component
 One purpose of this is to inspect the debug logs after a production system crash
 in order to analyze the reason for the crash.
 If the system still runs but only a subcomponent which uses dbf failes,
-it is possible to look at the debug logs on a live system via the Linux proc
-filesystem.
+it is possible to look at the debug logs on a live system via the Linux
+debugfs filesystem.
 The debug feature may also very useful for kernel and driver development.
 
 Design:
@@ -52,16 +52,18 @@ Each debug entry contains the following data:
 - Flag, if entry is an exception or not
 
 The debug logs can be inspected in a live system through entries in
-the proc-filesystem. Under the path /proc/s390dbf there is 
+the debugfs-filesystem. Under the toplevel directory "s390dbf" there is
 a directory for each registered component, which is named like the
-corresponding component.
+corresponding component. The debugfs normally should be mounted to
+/sys/kernel/debug therefore the debug feature can be accessed unter
+/sys/kernel/debug/s390dbf.
 
 The content of the directories are files which represent different views
 to the debug log. Each component can decide which views should be
 used through registering them with the function debug_register_view().
 Predefined views for hex/ascii, sprintf and raw binary data are provided.
 It is also possible to define other views. The content of
-a view can be inspected simply by reading the corresponding proc file.
+a view can be inspected simply by reading the corresponding debugfs file.
 
 All debug logs have an an actual debug level (range from 0 to 6).
 The default level is 3. Event and Exception functions have a 'level'
@@ -69,14 +71,14 @@ parameter. Only debug entries with a level that is lower or equal
 than the actual level are written to the log. This means, when
 writing events, high priority log entries should have a low level
 value whereas low priority entries should have a high one.
-The actual debug level can be changed with the help of the proc-filesystem 
-through writing a number string "x" to the 'level' proc file which is
+The actual debug level can be changed with the help of the debugfs-filesystem
+through writing a number string "x" to the 'level' debugfs file which is
 provided for every debug log. Debugging can be switched off completely
-by using "-" on the 'level' proc file.
+by using "-" on the 'level' debugfs file.
 
 Example:
 
-> echo "-" > /proc/s390dbf/dasd/level
+> echo "-" > /sys/kernel/debug/s390dbf/dasd/level
 
 It is also possible to deactivate the debug feature globally for every
 debug log. You can change the behavior using  2 sysctl parameters in
@@ -99,11 +101,11 @@ Kernel Interfaces:
 ------------------
 
 ----------------------------------------------------------------------------
-debug_info_t *debug_register(char *name, int pages_index, int nr_areas,
+debug_info_t *debug_register(char *name, int pages, int nr_areas,
                              int buf_size);
 
-Parameter:    name:        Name of debug log (e.g. used for proc entry) 
-              pages_index: 2^pages_index pages will be allocated per area
+Parameter:    name:        Name of debug log (e.g. used for debugfs entry)
+              pages:       number of pages, which will be allocated per area
               nr_areas:    number of debug areas
               buf_size:    size of data area in each debug entry
 
@@ -134,7 +136,7 @@ Return Value:  none
 Description:   Sets new actual debug level if new_level is valid. 
 
 ---------------------------------------------------------------------------
-+void debug_stop_all(void);
+void debug_stop_all(void);
 
 Parameter:     none
 
@@ -270,7 +272,7 @@ Parameter:     id:    handle for debug log
 Return Value:  0  : ok 
                < 0: Error 
 
-Description:   registers new debug view and creates proc dir entry 
+Description:   registers new debug view and creates debugfs dir entry
 
 ---------------------------------------------------------------------------
 int debug_unregister_view (debug_info_t * id, struct debug_view *view); 
@@ -281,7 +283,7 @@ Parameter:     id:    handle for debug log
 Return Value:  0  : ok 
                < 0: Error 
 
-Description:   unregisters debug view and removes proc dir entry 
+Description:   unregisters debug view and removes debugfs dir entry
 
 
 
@@ -308,7 +310,7 @@ static int init(void)
 {
     /* register 4 debug areas with one page each and 4 byte data field */
 
-    debug_info = debug_register ("test", 0, 4, 4 );
+    debug_info = debug_register ("test", 1, 4, 4 );
     debug_register_view(debug_info,&debug_hex_ascii_view);
     debug_register_view(debug_info,&debug_raw_view);
 
@@ -343,7 +345,7 @@ static int init(void)
     /* register 4 debug areas with one page each and data field for */
     /* format string pointer + 2 varargs (= 3 * sizeof(long))       */
 
-    debug_info = debug_register ("test", 0, 4, sizeof(long) * 3);
+    debug_info = debug_register ("test", 1, 4, sizeof(long) * 3);
     debug_register_view(debug_info,&debug_sprintf_view);
 
     debug_sprintf_event(debug_info, 2 , "first event in %s:%i\n",__FILE__,__LINE__);
@@ -362,16 +364,16 @@ module_exit(cleanup);
 
 
 
-ProcFS Interface
+Debugfs Interface
 ----------------
 Views to the debug logs can be investigated through reading the corresponding 
-proc-files:
+debugfs-files:
 
 Example:
 
-> ls /proc/s390dbf/dasd
-flush  hex_ascii  level      raw 
-> cat /proc/s390dbf/dasd/hex_ascii | sort +1
+> ls /sys/kernel/debug/s390dbf/dasd
+flush  hex_ascii  level pages raw
+> cat /sys/kernel/debug/s390dbf/dasd/hex_ascii | sort +1
 00 00974733272:680099 2 - 02 0006ad7e  07 ea 4a 90 | ....
 00 00974733272:682210 2 - 02 0006ade6  46 52 45 45 | FREE
 00 00974733272:682213 2 - 02 0006adf6  07 ea 4a 90 | ....
@@ -391,25 +393,36 @@ Changing the debug level
 Example:
 
 
-> cat /proc/s390dbf/dasd/level
+> cat /sys/kernel/debug/s390dbf/dasd/level
 3
-> echo "5" > /proc/s390dbf/dasd/level
-> cat /proc/s390dbf/dasd/level
+> echo "5" > /sys/kernel/debug/s390dbf/dasd/level
+> cat /sys/kernel/debug/s390dbf/dasd/level
 5
 
 Flushing debug areas
 --------------------
 Debug areas can be flushed with piping the number of the desired
-area (0...n) to the proc file "flush". When using "-" all debug areas
+area (0...n) to the debugfs file "flush". When using "-" all debug areas
 are flushed.
 
 Examples:
 
 1. Flush debug area 0:
-> echo "0" > /proc/s390dbf/dasd/flush  
+> echo "0" > /sys/kernel/debug/s390dbf/dasd/flush
 
 2. Flush all debug areas:
-> echo "-" > /proc/s390dbf/dasd/flush
+> echo "-" > /sys/kernel/debug/s390dbf/dasd/flush
+
+Changing the size of debug areas
+------------------------------------
+It is possible the change the size of debug areas through piping
+the number of pages to the debugfs file "pages". The resize request will
+also flush the debug areas.
+
+Example:
+
+Define 4 pages for the debug areas of debug feature "dasd":
+> echo "4" > /sys/kernel/debug/s390dbf/dasd/pages
 
 Stooping the debug feature
 --------------------------
@@ -491,7 +504,7 @@ Defining views
 --------------
 
 Views are specified with the 'debug_view' structure. There are defined
-callback functions which are used for reading and writing the proc files:
+callback functions which are used for reading and writing the debugfs files:
 
 struct debug_view {
         char name[DEBUG_MAX_PROCF_LEN];  
@@ -525,7 +538,7 @@ typedef int (debug_input_proc_t) (debug_info_t* id,
 The "private_data" member can be used as pointer to view specific data.
 It is not used by the debug feature itself.
 
-The output when reading a debug-proc file is structured like this:
+The output when reading a debugfs file is structured like this:
 
 "prolog_proc output"
 
@@ -534,13 +547,13 @@ The output when reading a debug-proc file is structured like this:
 "header_proc output 3"  "format_proc output 3"
 ...
 
-When a view is read from the proc fs, the Debug Feature calls the 
+When a view is read from the debugfs, the Debug Feature calls the
 'prolog_proc' once for writing the prolog.
 Then 'header_proc' and 'format_proc' are called for each 
 existing debug entry.
 
 The input_proc can be used to implement functionality when it is written to 
-the view (e.g. like with 'echo "0" > /proc/s390dbf/dasd/level).
+the view (e.g. like with 'echo "0" > /sys/kernel/debug/s390dbf/dasd/level).
 
 For header_proc there can be used the default function
 debug_dflt_header_fn() which is defined in in debug.h.
@@ -602,7 +615,7 @@ debug_info = debug_register ("test", 0, 4, 4 ));
 debug_register_view(debug_info, &debug_test_view);
 for(i = 0; i < 10; i ++) debug_int_event(debug_info, 1, i);
 
-> cat /proc/s390dbf/test/myview
+> cat /sys/kernel/debug/s390dbf/test/myview
 00 00964419734:611402 1 - 00 88042ca   This error...........
 00 00964419734:611405 1 - 00 88042ca   That error...........
 00 00964419734:611408 1 - 00 88042ca   Problem..............
index f98c2e31c143e6a114f61feaef725f4422e3b028..136d817c01babb51fc8e80ba5917544a7204c5ab 100644 (file)
@@ -72,6 +72,8 @@ On all -  write a character to /proc/sysrq-trigger.  eg:
 'b'     - Will immediately reboot the system without syncing or unmounting
           your disks.
 
+'c'    - Will perform a kexec reboot in order to take a crashdump.
+
 'o'     - Will shut your system off (if configured and supported).
 
 's'     - Will attempt to sync all mounted filesystems.
@@ -122,6 +124,9 @@ useful when you want to exit a program that will not let you switch consoles.
 re'B'oot is good when you're unable to shut down. But you should also 'S'ync
 and 'U'mount first.
 
+'C'rashdump can be used to manually trigger a crashdump when the system is hung.
+The kernel needs to have been built with CONFIG_KEXEC enabled.
+
 'S'ync is great when your system is locked up, it allows you to sync your
 disks and will certainly lessen the chance of data loss and fscking. Note
 that the sync hasn't taken place until you see the "OK" and "Done" appear
index a07eeb4113702bfe0338d96d5d74da3fb93fe6ea..a0b0d595d17c8998be66cb6a56329671c601ff10 100644 (file)
@@ -576,10 +576,9 @@ S: Supported
 
 COMPUTONE INTELLIPORT MULTIPORT CARD
 P:     Michael H. Warfield
-M:     Michael H. Warfield <mhw@wittsend.com>
+M:     mhw@wittsend.com
 W:     http://www.wittsend.com/computone.html
-L:     linux-computone@lazuli.wittsend.com
-S:     Orphaned
+S:     Maintained
 
 COSA/SRP SYNC SERIAL DRIVER
 P:     Jan "Yenya" Kasprzak
@@ -1330,6 +1329,16 @@ M:       rml@novell.com
 L:     linux-kernel@vger.kernel.org
 S:     Maintained
 
+KEXEC
+P:     Eric Biederman
+P:     Randy Dunlap
+M:     ebiederm@xmission.com
+M:     rddunlap@osdl.org
+W:     http://www.xmission.com/~ebiederm/files/kexec/
+L:     linux-kernel@vger.kernel.org
+L:     fastboot@osdl.org
+S:     Maintained
+
 LANMEDIA WAN CARD DRIVER
 P:     Andrew Stanley-Jones
 M:     asj@lanmedia.com
@@ -2115,9 +2124,7 @@ S:        Maintained
 SOFTWARE SUSPEND:
 P:     Pavel Machek
 M:     pavel@suse.cz
-M:     pavel@ucw.cz
-L:     http://lister.fornax.hu/mailman/listinfo/swsusp
-W:     http://swsusp.sf.net/
+L:     linux-pm@osdl.org
 S:     Maintained
 
 SONIC NETWORK DRIVER
@@ -2594,7 +2601,7 @@ M:        davidm@snapgear.com
 P:     D. Jeff Dionne (created first uClinux port)
 M:     jeff@uclinux.org
 W:     http://www.uclinux.org/
-L:     uclinux-dev@uclinux.org
+L:     uclinux-dev@uclinux.org  (subscribers-only)
 S:     Maintained
 
 UCLINUX FOR NEC V850
index fad349724e993f6a297ca019aab9b4d0a2455d35..1fdace757e157fdf98177264e529df8113526214 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -281,7 +281,7 @@ export quiet Q KBUILD_VERBOSE
 # See documentation in Documentation/kbuild/makefiles.txt
 
 # cc-option
-# Usage: cflags-y += $(call gcc-option, -march=winchip-c6, -march=i586)
+# Usage: cflags-y += $(call cc-option, -march=winchip-c6, -march=i586)
 
 cc-option = $(shell if $(CC) $(CFLAGS) $(1) -S -o /dev/null -xc /dev/null \
              > /dev/null 2>&1; then echo "$(1)"; else echo "$(2)"; fi ;)
index 07ba77c19f6c9172771c91f697ad0d2217439fdc..c8d94dcd8ef7daed544f14d5ac2db98c0236c952 100644 (file)
@@ -157,7 +157,7 @@ config ARCH_RPC
 config ARCH_SA1100
        bool "SA1100-based"
        select ISA
-       select DISCONTIGMEM
+       select ARCH_DISCONTIGMEM_ENABLE
 
 config ARCH_S3C2410
        bool "Samsung S3C2410"
@@ -346,6 +346,21 @@ config PREEMPT
          Say Y here if you are building a kernel for a desktop, embedded
          or real-time system.  Say N if you are unsure.
 
+config NO_IDLE_HZ
+       bool "Dynamic tick timer"
+       help
+         Select this option if you want to disable continuous timer ticks
+         and have them programmed to occur as required. This option saves
+         power as the system can remain in idle state for longer.
+
+         By default dynamic tick is disabled during the boot, and can be
+         manually enabled with:
+
+           echo 1 > /sys/devices/system/timer/timer0/dyn_tick
+
+         Alternatively, if you want dynamic tick automatically enabled
+         during boot, pass "dyntick=enable" via the kernel command string.
+
 config ARCH_DISCONTIGMEM_ENABLE
        bool
        default (ARCH_LH7A40X && !LH7A40X_CONTIGMEM)
index 06fae4b62774659a1b6389db4a1a5d56f5a088c2..b8c51ee7f1bb05e530bdb252e5db4b55c8bfe405 100644 (file)
@@ -1,14 +1,13 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.12-rc1-bk2
-# Sun Mar 27 22:08:24 2005
+# Linux kernel version: 2.6.12-git6
+# Sat Jun 25 00:57:29 2005
 #
 CONFIG_ARM=y
 CONFIG_MMU=y
 CONFIG_UID16=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_GENERIC_IOMAP=y
 
 #
 # Code maturity level options
@@ -16,6 +15,7 @@ CONFIG_GENERIC_IOMAP=y
 CONFIG_EXPERIMENTAL=y
 CONFIG_CLEAN_COMPILE=y
 CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
 
 #
 # General setup
@@ -35,6 +35,8 @@ CONFIG_EMBEDDED=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_ALL is not set
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
@@ -82,6 +84,7 @@ CONFIG_ARCH_IXP2000=y
 # CONFIG_ARCH_VERSATILE is not set
 # CONFIG_ARCH_IMX is not set
 # CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_AAEC2000 is not set
 CONFIG_ARCH_SUPPORTS_BIG_ENDIAN=y
 
 #
@@ -96,6 +99,7 @@ CONFIG_ARCH_ENP2611=y
 # CONFIG_ARCH_IXDP2800 is not set
 # CONFIG_ARCH_IXDP2401 is not set
 # CONFIG_ARCH_IXDP2801 is not set
+# CONFIG_IXP2000_SUPPORT_BROKEN_PCI_IO is not set
 
 #
 # Processor Type
@@ -106,7 +110,6 @@ CONFIG_CPU_32v5=y
 CONFIG_CPU_ABRT_EV5T=y
 CONFIG_CPU_CACHE_VIVT=y
 CONFIG_CPU_TLB_V4WBI=y
-CONFIG_CPU_MINICACHE=y
 
 #
 # Processor Features
@@ -118,9 +121,11 @@ CONFIG_XSCALE_PMU=y
 #
 # Bus support
 #
+CONFIG_ISA_DMA_API=y
 CONFIG_PCI=y
 CONFIG_PCI_LEGACY_PROC=y
 CONFIG_PCI_NAMES=y
+# CONFIG_PCI_DEBUG is not set
 
 #
 # PCCARD (PCMCIA/CardBus) support
@@ -130,7 +135,15 @@ CONFIG_PCI_NAMES=y
 #
 # Kernel Features
 #
+# CONFIG_SMP is not set
 # CONFIG_PREEMPT is not set
+# CONFIG_ARCH_DISCONTIGMEM_ENABLE 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_ALIGNMENT_TRAP=y
 
 #
@@ -269,7 +282,6 @@ CONFIG_MTD_IXP2000=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
@@ -308,6 +320,7 @@ CONFIG_IOSCHED_CFQ=y
 #
 # Fusion MPT device support
 #
+# CONFIG_FUSION is not set
 
 #
 # IEEE 1394 (FireWire) support
@@ -329,10 +342,11 @@ CONFIG_NET=y
 #
 CONFIG_PACKET=y
 CONFIG_PACKET_MMAP=y
-# CONFIG_NETLINK_DEV is not set
 CONFIG_UNIX=y
 # CONFIG_NET_KEY is not set
 CONFIG_INET=y
+CONFIG_IP_FIB_HASH=y
+# CONFIG_IP_FIB_TRIE is not set
 # CONFIG_IP_MULTICAST is not set
 # CONFIG_IP_ADVANCED_ROUTER is not set
 CONFIG_IP_PNP=y
@@ -349,6 +363,17 @@ CONFIG_SYN_COOKIES=y
 # CONFIG_INET_TUNNEL is not set
 # CONFIG_IP_TCPDIAG is not set
 # CONFIG_IP_TCPDIAG_IPV6 is not set
+
+#
+# TCP congestion control
+#
+CONFIG_TCP_CONG_BIC=y
+CONFIG_TCP_CONG_WESTWOOD=m
+CONFIG_TCP_CONG_HTCP=m
+# CONFIG_TCP_CONG_HSTCP is not set
+# CONFIG_TCP_CONG_HYBLA is not set
+# CONFIG_TCP_CONG_VEGAS is not set
+# CONFIG_TCP_CONG_SCALABLE is not set
 # CONFIG_IPV6 is not set
 # CONFIG_NETFILTER is not set
 
@@ -404,6 +429,7 @@ CONFIG_MII=y
 # CONFIG_SUNGEM is not set
 # CONFIG_NET_VENDOR_3COM is not set
 # CONFIG_SMC91X is not set
+# CONFIG_DM9000 is not set
 
 #
 # Tulip family network device support
@@ -440,9 +466,11 @@ CONFIG_EEPRO100=y
 # 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
 
 #
 # Ethernet (10000 Mbit)
@@ -464,6 +492,7 @@ CONFIG_EEPRO100=y
 # Wan interfaces
 #
 CONFIG_WAN=y
+# CONFIG_DSCC4 is not set
 # CONFIG_LANMEDIA is not set
 # CONFIG_SYNCLINK_SYNCPPP is not set
 CONFIG_HDLC=y
@@ -526,7 +555,6 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
 #
 # CONFIG_SERIO is not set
 # CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
 
 #
 # Character devices
@@ -547,6 +575,7 @@ CONFIG_SERIAL_8250_NR_UARTS=2
 #
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_JSM is not set
 CONFIG_UNIX98_PTYS=y
 CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
@@ -613,17 +642,18 @@ CONFIG_I2C_ALGOBIT=y
 # CONFIG_I2C_AMD8111 is not set
 # CONFIG_I2C_I801 is not set
 # CONFIG_I2C_I810 is not set
+# CONFIG_I2C_PIIX4 is not set
 # CONFIG_I2C_ISA is not set
 # CONFIG_I2C_IXP2000 is not set
 # CONFIG_I2C_NFORCE2 is not set
 # CONFIG_I2C_PARPORT_LIGHT is not set
-# CONFIG_I2C_PIIX4 is not set
 # CONFIG_I2C_PROSAVAGE is not set
 # CONFIG_I2C_SAVAGE4 is not set
 # CONFIG_SCx200_ACB is not set
 # 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
@@ -637,7 +667,9 @@ CONFIG_I2C_SENSOR=y
 # CONFIG_SENSORS_ADM1025 is not set
 # CONFIG_SENSORS_ADM1026 is not set
 # CONFIG_SENSORS_ADM1031 is not set
+# CONFIG_SENSORS_ADM9240 is not set
 # CONFIG_SENSORS_ASB100 is not set
+# CONFIG_SENSORS_ATXP1 is not set
 # CONFIG_SENSORS_DS1621 is not set
 # CONFIG_SENSORS_FSCHER is not set
 # CONFIG_SENSORS_FSCPOS is not set
@@ -653,6 +685,7 @@ CONFIG_I2C_SENSOR=y
 # CONFIG_SENSORS_LM85 is not set
 # CONFIG_SENSORS_LM87 is not set
 # CONFIG_SENSORS_LM90 is not set
+# CONFIG_SENSORS_LM92 is not set
 # CONFIG_SENSORS_MAX1619 is not set
 # CONFIG_SENSORS_PC87360 is not set
 # CONFIG_SENSORS_SMSC47B397 is not set
@@ -662,14 +695,19 @@ CONFIG_I2C_SENSOR=y
 # CONFIG_SENSORS_W83781D is not set
 # CONFIG_SENSORS_W83L785TS is not set
 # CONFIG_SENSORS_W83627HF is not set
+# CONFIG_SENSORS_W83627EHF is not set
 
 #
 # Other I2C Chip support
 #
+# CONFIG_SENSORS_DS1337 is not set
+# CONFIG_SENSORS_DS1374 is not set
 CONFIG_SENSORS_EEPROM=y
 # 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_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
@@ -723,6 +761,7 @@ CONFIG_EXT2_FS=y
 CONFIG_EXT2_FS_XATTR=y
 CONFIG_EXT2_FS_POSIX_ACL=y
 # 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=y
@@ -763,7 +802,6 @@ CONFIG_DNOTIFY=y
 #
 CONFIG_PROC_FS=y
 CONFIG_SYSFS=y
-# CONFIG_DEVFS_FS is not set
 # CONFIG_DEVPTS_FS_XATTR is not set
 CONFIG_TMPFS=y
 # CONFIG_TMPFS_XATTR is not set
@@ -801,12 +839,14 @@ CONFIG_JFFS2_RTIME=y
 #
 CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
 # CONFIG_NFS_V4 is not set
 # CONFIG_NFS_DIRECTIO is not set
 # CONFIG_NFSD is not set
 CONFIG_ROOT_NFS=y
 CONFIG_LOCKD=y
 CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
@@ -891,3 +931,4 @@ CONFIG_CRC32=y
 # CONFIG_LIBCRC32C is not set
 CONFIG_ZLIB_INFLATE=y
 CONFIG_ZLIB_DEFLATE=y
+# CONFIG_TEXTSEARCH is not set
index 810a450a55d22a4c1dbcc139688f937aafab9db8..3cfbe2ec29ca6baeba87a066e486da5b259bb7dc 100644 (file)
@@ -1,14 +1,13 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.12-rc1-bk2
-# Sun Mar 27 21:13:38 2005
+# Linux kernel version: 2.6.12-git6
+# Sat Jun 25 00:58:38 2005
 #
 CONFIG_ARM=y
 CONFIG_MMU=y
 CONFIG_UID16=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_GENERIC_IOMAP=y
 
 #
 # Code maturity level options
@@ -16,6 +15,7 @@ CONFIG_GENERIC_IOMAP=y
 CONFIG_EXPERIMENTAL=y
 CONFIG_CLEAN_COMPILE=y
 CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
 
 #
 # General setup
@@ -35,6 +35,8 @@ CONFIG_EMBEDDED=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_ALL is not set
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
@@ -82,6 +84,7 @@ CONFIG_ARCH_IXP2000=y
 # CONFIG_ARCH_VERSATILE is not set
 # CONFIG_ARCH_IMX is not set
 # CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_AAEC2000 is not set
 CONFIG_ARCH_SUPPORTS_BIG_ENDIAN=y
 
 #
@@ -97,6 +100,7 @@ CONFIG_ARCH_IXDP2400=y
 CONFIG_ARCH_IXDP2X00=y
 # CONFIG_ARCH_IXDP2401 is not set
 # CONFIG_ARCH_IXDP2801 is not set
+# CONFIG_IXP2000_SUPPORT_BROKEN_PCI_IO is not set
 
 #
 # Processor Type
@@ -107,7 +111,6 @@ CONFIG_CPU_32v5=y
 CONFIG_CPU_ABRT_EV5T=y
 CONFIG_CPU_CACHE_VIVT=y
 CONFIG_CPU_TLB_V4WBI=y
-CONFIG_CPU_MINICACHE=y
 
 #
 # Processor Features
@@ -119,9 +122,11 @@ CONFIG_XSCALE_PMU=y
 #
 # Bus support
 #
+CONFIG_ISA_DMA_API=y
 CONFIG_PCI=y
 CONFIG_PCI_LEGACY_PROC=y
 CONFIG_PCI_NAMES=y
+# CONFIG_PCI_DEBUG is not set
 
 #
 # PCCARD (PCMCIA/CardBus) support
@@ -131,7 +136,15 @@ CONFIG_PCI_NAMES=y
 #
 # Kernel Features
 #
+# CONFIG_SMP is not set
 # CONFIG_PREEMPT is not set
+# CONFIG_ARCH_DISCONTIGMEM_ENABLE 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_ALIGNMENT_TRAP=y
 
 #
@@ -270,7 +283,6 @@ CONFIG_MTD_IXP2000=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
@@ -309,6 +321,7 @@ CONFIG_IOSCHED_CFQ=y
 #
 # Fusion MPT device support
 #
+# CONFIG_FUSION is not set
 
 #
 # IEEE 1394 (FireWire) support
@@ -330,10 +343,11 @@ CONFIG_NET=y
 #
 CONFIG_PACKET=y
 CONFIG_PACKET_MMAP=y
-# CONFIG_NETLINK_DEV is not set
 CONFIG_UNIX=y
 # CONFIG_NET_KEY is not set
 CONFIG_INET=y
+CONFIG_IP_FIB_HASH=y
+# CONFIG_IP_FIB_TRIE is not set
 # CONFIG_IP_MULTICAST is not set
 # CONFIG_IP_ADVANCED_ROUTER is not set
 CONFIG_IP_PNP=y
@@ -350,6 +364,17 @@ CONFIG_SYN_COOKIES=y
 # CONFIG_INET_TUNNEL is not set
 # CONFIG_IP_TCPDIAG is not set
 # CONFIG_IP_TCPDIAG_IPV6 is not set
+
+#
+# TCP congestion control
+#
+CONFIG_TCP_CONG_BIC=y
+CONFIG_TCP_CONG_WESTWOOD=m
+CONFIG_TCP_CONG_HTCP=m
+# CONFIG_TCP_CONG_HSTCP is not set
+# CONFIG_TCP_CONG_HYBLA is not set
+# CONFIG_TCP_CONG_VEGAS is not set
+# CONFIG_TCP_CONG_SCALABLE is not set
 # CONFIG_IPV6 is not set
 # CONFIG_NETFILTER is not set
 
@@ -405,6 +430,7 @@ CONFIG_MII=y
 # CONFIG_SUNGEM is not set
 # CONFIG_NET_VENDOR_3COM is not set
 # CONFIG_SMC91X is not set
+# CONFIG_DM9000 is not set
 
 #
 # Tulip family network device support
@@ -441,9 +467,11 @@ CONFIG_EEPRO100=y
 # 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
 
 #
 # Ethernet (10000 Mbit)
@@ -465,6 +493,7 @@ CONFIG_EEPRO100=y
 # Wan interfaces
 #
 CONFIG_WAN=y
+# CONFIG_DSCC4 is not set
 # CONFIG_LANMEDIA is not set
 # CONFIG_SYNCLINK_SYNCPPP is not set
 CONFIG_HDLC=y
@@ -527,7 +556,6 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
 #
 # CONFIG_SERIO is not set
 # CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
 
 #
 # Character devices
@@ -548,6 +576,7 @@ CONFIG_SERIAL_8250_NR_UARTS=2
 #
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_JSM is not set
 CONFIG_UNIX98_PTYS=y
 CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
@@ -614,17 +643,18 @@ CONFIG_I2C_ALGOBIT=y
 # CONFIG_I2C_AMD8111 is not set
 # CONFIG_I2C_I801 is not set
 # CONFIG_I2C_I810 is not set
+# CONFIG_I2C_PIIX4 is not set
 # CONFIG_I2C_ISA is not set
 # CONFIG_I2C_IXP2000 is not set
 # CONFIG_I2C_NFORCE2 is not set
 # CONFIG_I2C_PARPORT_LIGHT is not set
-# CONFIG_I2C_PIIX4 is not set
 # CONFIG_I2C_PROSAVAGE is not set
 # CONFIG_I2C_SAVAGE4 is not set
 # CONFIG_SCx200_ACB is not set
 # 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
@@ -638,7 +668,9 @@ CONFIG_I2C_SENSOR=y
 # CONFIG_SENSORS_ADM1025 is not set
 # CONFIG_SENSORS_ADM1026 is not set
 # CONFIG_SENSORS_ADM1031 is not set
+# CONFIG_SENSORS_ADM9240 is not set
 # CONFIG_SENSORS_ASB100 is not set
+# CONFIG_SENSORS_ATXP1 is not set
 # CONFIG_SENSORS_DS1621 is not set
 # CONFIG_SENSORS_FSCHER is not set
 # CONFIG_SENSORS_FSCPOS is not set
@@ -654,6 +686,7 @@ CONFIG_I2C_SENSOR=y
 # CONFIG_SENSORS_LM85 is not set
 # CONFIG_SENSORS_LM87 is not set
 # CONFIG_SENSORS_LM90 is not set
+# CONFIG_SENSORS_LM92 is not set
 # CONFIG_SENSORS_MAX1619 is not set
 # CONFIG_SENSORS_PC87360 is not set
 # CONFIG_SENSORS_SMSC47B397 is not set
@@ -663,14 +696,19 @@ CONFIG_I2C_SENSOR=y
 # CONFIG_SENSORS_W83781D is not set
 # CONFIG_SENSORS_W83L785TS is not set
 # CONFIG_SENSORS_W83627HF is not set
+# CONFIG_SENSORS_W83627EHF is not set
 
 #
 # Other I2C Chip support
 #
+# CONFIG_SENSORS_DS1337 is not set
+# CONFIG_SENSORS_DS1374 is not set
 CONFIG_SENSORS_EEPROM=y
 # 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_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
@@ -724,6 +762,7 @@ CONFIG_EXT2_FS=y
 CONFIG_EXT2_FS_XATTR=y
 CONFIG_EXT2_FS_POSIX_ACL=y
 # 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=y
@@ -764,7 +803,6 @@ CONFIG_DNOTIFY=y
 #
 CONFIG_PROC_FS=y
 CONFIG_SYSFS=y
-# CONFIG_DEVFS_FS is not set
 # CONFIG_DEVPTS_FS_XATTR is not set
 CONFIG_TMPFS=y
 # CONFIG_TMPFS_XATTR is not set
@@ -802,12 +840,14 @@ CONFIG_JFFS2_RTIME=y
 #
 CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
 # CONFIG_NFS_V4 is not set
 # CONFIG_NFS_DIRECTIO is not set
 # CONFIG_NFSD is not set
 CONFIG_ROOT_NFS=y
 CONFIG_LOCKD=y
 CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
@@ -892,3 +932,4 @@ CONFIG_CRC32=y
 # CONFIG_LIBCRC32C is not set
 CONFIG_ZLIB_INFLATE=y
 CONFIG_ZLIB_DEFLATE=y
+# CONFIG_TEXTSEARCH is not set
index 72e1b940e975b858769ac25ce0556dee0b0d0c62..5c87e8e6969b1cb828158c853344d844a0071da7 100644 (file)
@@ -1,14 +1,13 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.12-rc1-bk2
-# Sun Mar 27 21:53:55 2005
+# Linux kernel version: 2.6.12-git6
+# Sat Jun 25 00:59:35 2005
 #
 CONFIG_ARM=y
 CONFIG_MMU=y
 CONFIG_UID16=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_GENERIC_IOMAP=y
 
 #
 # Code maturity level options
@@ -16,6 +15,7 @@ CONFIG_GENERIC_IOMAP=y
 CONFIG_EXPERIMENTAL=y
 CONFIG_CLEAN_COMPILE=y
 CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
 
 #
 # General setup
@@ -35,6 +35,8 @@ CONFIG_EMBEDDED=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_ALL is not set
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
@@ -82,6 +84,7 @@ CONFIG_ARCH_IXP2000=y
 # CONFIG_ARCH_VERSATILE is not set
 # CONFIG_ARCH_IMX is not set
 # CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_AAEC2000 is not set
 CONFIG_ARCH_SUPPORTS_BIG_ENDIAN=y
 
 #
@@ -97,6 +100,7 @@ CONFIG_ARCH_SUPPORTS_BIG_ENDIAN=y
 CONFIG_ARCH_IXDP2401=y
 # CONFIG_ARCH_IXDP2801 is not set
 CONFIG_ARCH_IXDP2X01=y
+# CONFIG_IXP2000_SUPPORT_BROKEN_PCI_IO is not set
 
 #
 # Processor Type
@@ -107,7 +111,6 @@ CONFIG_CPU_32v5=y
 CONFIG_CPU_ABRT_EV5T=y
 CONFIG_CPU_CACHE_VIVT=y
 CONFIG_CPU_TLB_V4WBI=y
-CONFIG_CPU_MINICACHE=y
 
 #
 # Processor Features
@@ -119,9 +122,11 @@ CONFIG_XSCALE_PMU=y
 #
 # Bus support
 #
+CONFIG_ISA_DMA_API=y
 CONFIG_PCI=y
 CONFIG_PCI_LEGACY_PROC=y
 CONFIG_PCI_NAMES=y
+# CONFIG_PCI_DEBUG is not set
 
 #
 # PCCARD (PCMCIA/CardBus) support
@@ -131,7 +136,15 @@ CONFIG_PCI_NAMES=y
 #
 # Kernel Features
 #
+# CONFIG_SMP is not set
 # CONFIG_PREEMPT is not set
+# CONFIG_ARCH_DISCONTIGMEM_ENABLE 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_ALIGNMENT_TRAP=y
 
 #
@@ -270,7 +283,6 @@ CONFIG_MTD_IXP2000=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
@@ -309,6 +321,7 @@ CONFIG_IOSCHED_CFQ=y
 #
 # Fusion MPT device support
 #
+# CONFIG_FUSION is not set
 
 #
 # IEEE 1394 (FireWire) support
@@ -330,10 +343,11 @@ CONFIG_NET=y
 #
 CONFIG_PACKET=y
 CONFIG_PACKET_MMAP=y
-# CONFIG_NETLINK_DEV is not set
 CONFIG_UNIX=y
 # CONFIG_NET_KEY is not set
 CONFIG_INET=y
+CONFIG_IP_FIB_HASH=y
+# CONFIG_IP_FIB_TRIE is not set
 # CONFIG_IP_MULTICAST is not set
 # CONFIG_IP_ADVANCED_ROUTER is not set
 CONFIG_IP_PNP=y
@@ -350,6 +364,17 @@ CONFIG_SYN_COOKIES=y
 # CONFIG_INET_TUNNEL is not set
 CONFIG_IP_TCPDIAG=y
 # CONFIG_IP_TCPDIAG_IPV6 is not set
+
+#
+# TCP congestion control
+#
+CONFIG_TCP_CONG_BIC=y
+CONFIG_TCP_CONG_WESTWOOD=m
+CONFIG_TCP_CONG_HTCP=m
+# CONFIG_TCP_CONG_HSTCP is not set
+# CONFIG_TCP_CONG_HYBLA is not set
+# CONFIG_TCP_CONG_VEGAS is not set
+# CONFIG_TCP_CONG_SCALABLE is not set
 # CONFIG_IPV6 is not set
 # CONFIG_NETFILTER is not set
 
@@ -405,6 +430,7 @@ CONFIG_MII=y
 # CONFIG_SUNGEM is not set
 # CONFIG_NET_VENDOR_3COM is not set
 # CONFIG_SMC91X is not set
+# CONFIG_DM9000 is not set
 
 #
 # Tulip family network device support
@@ -442,9 +468,11 @@ CONFIG_EEPRO100=y
 # 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
 
 #
 # Ethernet (10000 Mbit)
@@ -466,6 +494,7 @@ CONFIG_EEPRO100=y
 # Wan interfaces
 #
 CONFIG_WAN=y
+# CONFIG_DSCC4 is not set
 # CONFIG_LANMEDIA is not set
 # CONFIG_SYNCLINK_SYNCPPP is not set
 CONFIG_HDLC=y
@@ -528,7 +557,6 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
 #
 # CONFIG_SERIO is not set
 # CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
 
 #
 # Character devices
@@ -549,6 +577,7 @@ CONFIG_SERIAL_8250_NR_UARTS=2
 #
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_JSM is not set
 CONFIG_UNIX98_PTYS=y
 CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
@@ -615,17 +644,18 @@ CONFIG_I2C_ALGOBIT=y
 # CONFIG_I2C_AMD8111 is not set
 # CONFIG_I2C_I801 is not set
 # CONFIG_I2C_I810 is not set
+# CONFIG_I2C_PIIX4 is not set
 # CONFIG_I2C_ISA is not set
 # CONFIG_I2C_IXP2000 is not set
 # CONFIG_I2C_NFORCE2 is not set
 # CONFIG_I2C_PARPORT_LIGHT is not set
-# CONFIG_I2C_PIIX4 is not set
 # CONFIG_I2C_PROSAVAGE is not set
 # CONFIG_I2C_SAVAGE4 is not set
 # CONFIG_SCx200_ACB is not set
 # 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
@@ -639,7 +669,9 @@ CONFIG_I2C_SENSOR=y
 # CONFIG_SENSORS_ADM1025 is not set
 # CONFIG_SENSORS_ADM1026 is not set
 # CONFIG_SENSORS_ADM1031 is not set
+# CONFIG_SENSORS_ADM9240 is not set
 # CONFIG_SENSORS_ASB100 is not set
+# CONFIG_SENSORS_ATXP1 is not set
 # CONFIG_SENSORS_DS1621 is not set
 # CONFIG_SENSORS_FSCHER is not set
 # CONFIG_SENSORS_FSCPOS is not set
@@ -655,6 +687,7 @@ CONFIG_I2C_SENSOR=y
 # CONFIG_SENSORS_LM85 is not set
 # CONFIG_SENSORS_LM87 is not set
 # CONFIG_SENSORS_LM90 is not set
+# CONFIG_SENSORS_LM92 is not set
 # CONFIG_SENSORS_MAX1619 is not set
 # CONFIG_SENSORS_PC87360 is not set
 # CONFIG_SENSORS_SMSC47B397 is not set
@@ -664,14 +697,19 @@ CONFIG_I2C_SENSOR=y
 # CONFIG_SENSORS_W83781D is not set
 # CONFIG_SENSORS_W83L785TS is not set
 # CONFIG_SENSORS_W83627HF is not set
+# CONFIG_SENSORS_W83627EHF is not set
 
 #
 # Other I2C Chip support
 #
+# CONFIG_SENSORS_DS1337 is not set
+# CONFIG_SENSORS_DS1374 is not set
 CONFIG_SENSORS_EEPROM=y
 # 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_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
@@ -725,6 +763,7 @@ CONFIG_EXT2_FS=y
 CONFIG_EXT2_FS_XATTR=y
 CONFIG_EXT2_FS_POSIX_ACL=y
 # 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=y
@@ -765,7 +804,6 @@ CONFIG_DNOTIFY=y
 #
 CONFIG_PROC_FS=y
 CONFIG_SYSFS=y
-# CONFIG_DEVFS_FS is not set
 # CONFIG_DEVPTS_FS_XATTR is not set
 CONFIG_TMPFS=y
 # CONFIG_TMPFS_XATTR is not set
@@ -803,12 +841,14 @@ CONFIG_JFFS2_RTIME=y
 #
 CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
 # CONFIG_NFS_V4 is not set
 # CONFIG_NFS_DIRECTIO is not set
 # CONFIG_NFSD is not set
 CONFIG_ROOT_NFS=y
 CONFIG_LOCKD=y
 CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
@@ -893,3 +933,4 @@ CONFIG_CRC32=y
 # CONFIG_LIBCRC32C is not set
 CONFIG_ZLIB_INFLATE=y
 CONFIG_ZLIB_DEFLATE=y
+# CONFIG_TEXTSEARCH is not set
index 1592e45f027839e7967ef26c17e79bdc44bd1f64..3cb561a551cb598c5fe13033b7d8dffd4c2f886e 100644 (file)
@@ -1,14 +1,13 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.12-rc1-bk2
-# Sun Mar 27 22:15:23 2005
+# Linux kernel version: 2.6.12-git6
+# Sat Jun 25 01:00:27 2005
 #
 CONFIG_ARM=y
 CONFIG_MMU=y
 CONFIG_UID16=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_GENERIC_IOMAP=y
 
 #
 # Code maturity level options
@@ -16,6 +15,7 @@ CONFIG_GENERIC_IOMAP=y
 CONFIG_EXPERIMENTAL=y
 CONFIG_CLEAN_COMPILE=y
 CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
 
 #
 # General setup
@@ -35,6 +35,8 @@ CONFIG_EMBEDDED=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_ALL is not set
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
@@ -82,6 +84,7 @@ CONFIG_ARCH_IXP2000=y
 # CONFIG_ARCH_VERSATILE is not set
 # CONFIG_ARCH_IMX is not set
 # CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_AAEC2000 is not set
 CONFIG_ARCH_SUPPORTS_BIG_ENDIAN=y
 
 #
@@ -97,6 +100,7 @@ CONFIG_ARCH_IXDP2800=y
 CONFIG_ARCH_IXDP2X00=y
 # CONFIG_ARCH_IXDP2401 is not set
 # CONFIG_ARCH_IXDP2801 is not set
+# CONFIG_IXP2000_SUPPORT_BROKEN_PCI_IO is not set
 
 #
 # Processor Type
@@ -107,7 +111,6 @@ CONFIG_CPU_32v5=y
 CONFIG_CPU_ABRT_EV5T=y
 CONFIG_CPU_CACHE_VIVT=y
 CONFIG_CPU_TLB_V4WBI=y
-CONFIG_CPU_MINICACHE=y
 
 #
 # Processor Features
@@ -119,9 +122,11 @@ CONFIG_XSCALE_PMU=y
 #
 # Bus support
 #
+CONFIG_ISA_DMA_API=y
 CONFIG_PCI=y
 CONFIG_PCI_LEGACY_PROC=y
 CONFIG_PCI_NAMES=y
+# CONFIG_PCI_DEBUG is not set
 
 #
 # PCCARD (PCMCIA/CardBus) support
@@ -131,7 +136,15 @@ CONFIG_PCI_NAMES=y
 #
 # Kernel Features
 #
+# CONFIG_SMP is not set
 # CONFIG_PREEMPT is not set
+# CONFIG_ARCH_DISCONTIGMEM_ENABLE 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_ALIGNMENT_TRAP=y
 
 #
@@ -270,7 +283,6 @@ CONFIG_MTD_IXP2000=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
@@ -309,6 +321,7 @@ CONFIG_IOSCHED_CFQ=y
 #
 # Fusion MPT device support
 #
+# CONFIG_FUSION is not set
 
 #
 # IEEE 1394 (FireWire) support
@@ -330,10 +343,11 @@ CONFIG_NET=y
 #
 CONFIG_PACKET=y
 CONFIG_PACKET_MMAP=y
-# CONFIG_NETLINK_DEV is not set
 CONFIG_UNIX=y
 # CONFIG_NET_KEY is not set
 CONFIG_INET=y
+CONFIG_IP_FIB_HASH=y
+# CONFIG_IP_FIB_TRIE is not set
 # CONFIG_IP_MULTICAST is not set
 # CONFIG_IP_ADVANCED_ROUTER is not set
 CONFIG_IP_PNP=y
@@ -350,6 +364,17 @@ CONFIG_SYN_COOKIES=y
 # CONFIG_INET_TUNNEL is not set
 # CONFIG_IP_TCPDIAG is not set
 # CONFIG_IP_TCPDIAG_IPV6 is not set
+
+#
+# TCP congestion control
+#
+CONFIG_TCP_CONG_BIC=y
+CONFIG_TCP_CONG_WESTWOOD=m
+CONFIG_TCP_CONG_HTCP=m
+# CONFIG_TCP_CONG_HSTCP is not set
+# CONFIG_TCP_CONG_HYBLA is not set
+# CONFIG_TCP_CONG_VEGAS is not set
+# CONFIG_TCP_CONG_SCALABLE is not set
 # CONFIG_IPV6 is not set
 # CONFIG_NETFILTER is not set
 
@@ -405,6 +430,7 @@ CONFIG_MII=y
 # CONFIG_SUNGEM is not set
 # CONFIG_NET_VENDOR_3COM is not set
 # CONFIG_SMC91X is not set
+# CONFIG_DM9000 is not set
 
 #
 # Tulip family network device support
@@ -441,9 +467,11 @@ CONFIG_EEPRO100=y
 # 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
 
 #
 # Ethernet (10000 Mbit)
@@ -465,6 +493,7 @@ CONFIG_EEPRO100=y
 # Wan interfaces
 #
 CONFIG_WAN=y
+# CONFIG_DSCC4 is not set
 # CONFIG_LANMEDIA is not set
 # CONFIG_SYNCLINK_SYNCPPP is not set
 CONFIG_HDLC=y
@@ -527,7 +556,6 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
 #
 # CONFIG_SERIO is not set
 # CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
 
 #
 # Character devices
@@ -548,6 +576,7 @@ CONFIG_SERIAL_8250_NR_UARTS=2
 #
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_JSM is not set
 CONFIG_UNIX98_PTYS=y
 CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
@@ -614,17 +643,18 @@ CONFIG_I2C_ALGOBIT=y
 # CONFIG_I2C_AMD8111 is not set
 # CONFIG_I2C_I801 is not set
 # CONFIG_I2C_I810 is not set
+# CONFIG_I2C_PIIX4 is not set
 # CONFIG_I2C_ISA is not set
 # CONFIG_I2C_IXP2000 is not set
 # CONFIG_I2C_NFORCE2 is not set
 # CONFIG_I2C_PARPORT_LIGHT is not set
-# CONFIG_I2C_PIIX4 is not set
 # CONFIG_I2C_PROSAVAGE is not set
 # CONFIG_I2C_SAVAGE4 is not set
 # CONFIG_SCx200_ACB is not set
 # 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
@@ -638,7 +668,9 @@ CONFIG_I2C_SENSOR=y
 # CONFIG_SENSORS_ADM1025 is not set
 # CONFIG_SENSORS_ADM1026 is not set
 # CONFIG_SENSORS_ADM1031 is not set
+# CONFIG_SENSORS_ADM9240 is not set
 # CONFIG_SENSORS_ASB100 is not set
+# CONFIG_SENSORS_ATXP1 is not set
 # CONFIG_SENSORS_DS1621 is not set
 # CONFIG_SENSORS_FSCHER is not set
 # CONFIG_SENSORS_FSCPOS is not set
@@ -654,6 +686,7 @@ CONFIG_I2C_SENSOR=y
 # CONFIG_SENSORS_LM85 is not set
 # CONFIG_SENSORS_LM87 is not set
 # CONFIG_SENSORS_LM90 is not set
+# CONFIG_SENSORS_LM92 is not set
 # CONFIG_SENSORS_MAX1619 is not set
 # CONFIG_SENSORS_PC87360 is not set
 # CONFIG_SENSORS_SMSC47B397 is not set
@@ -663,14 +696,19 @@ CONFIG_I2C_SENSOR=y
 # CONFIG_SENSORS_W83781D is not set
 # CONFIG_SENSORS_W83L785TS is not set
 # CONFIG_SENSORS_W83627HF is not set
+# CONFIG_SENSORS_W83627EHF is not set
 
 #
 # Other I2C Chip support
 #
+# CONFIG_SENSORS_DS1337 is not set
+# CONFIG_SENSORS_DS1374 is not set
 CONFIG_SENSORS_EEPROM=y
 # 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_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
@@ -724,6 +762,7 @@ CONFIG_EXT2_FS=y
 CONFIG_EXT2_FS_XATTR=y
 CONFIG_EXT2_FS_POSIX_ACL=y
 # 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=y
@@ -764,7 +803,6 @@ CONFIG_DNOTIFY=y
 #
 CONFIG_PROC_FS=y
 CONFIG_SYSFS=y
-# CONFIG_DEVFS_FS is not set
 # CONFIG_DEVPTS_FS_XATTR is not set
 CONFIG_TMPFS=y
 # CONFIG_TMPFS_XATTR is not set
@@ -802,12 +840,14 @@ CONFIG_JFFS2_RTIME=y
 #
 CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
 # CONFIG_NFS_V4 is not set
 # CONFIG_NFS_DIRECTIO is not set
 # CONFIG_NFSD is not set
 CONFIG_ROOT_NFS=y
 CONFIG_LOCKD=y
 CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
@@ -892,3 +932,4 @@ CONFIG_CRC32=y
 # CONFIG_LIBCRC32C is not set
 CONFIG_ZLIB_INFLATE=y
 CONFIG_ZLIB_DEFLATE=y
+# CONFIG_TEXTSEARCH is not set
index f1afe3d09ec66c5797ed553f1de4d1c1138396ed..b1e162f29cb9490b64b59c0cd04d6973369e9c52 100644 (file)
@@ -1,14 +1,13 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.12-rc1-bk2
-# Sun Mar 27 22:39:19 2005
+# Linux kernel version: 2.6.12-git6
+# Sat Jun 25 01:01:18 2005
 #
 CONFIG_ARM=y
 CONFIG_MMU=y
 CONFIG_UID16=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_GENERIC_IOMAP=y
 
 #
 # Code maturity level options
@@ -16,6 +15,7 @@ CONFIG_GENERIC_IOMAP=y
 CONFIG_EXPERIMENTAL=y
 CONFIG_CLEAN_COMPILE=y
 CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
 
 #
 # General setup
@@ -35,6 +35,8 @@ CONFIG_EMBEDDED=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_ALL is not set
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
@@ -82,6 +84,7 @@ CONFIG_ARCH_IXP2000=y
 # CONFIG_ARCH_VERSATILE is not set
 # CONFIG_ARCH_IMX is not set
 # CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_AAEC2000 is not set
 CONFIG_ARCH_SUPPORTS_BIG_ENDIAN=y
 
 #
@@ -97,6 +100,7 @@ CONFIG_ARCH_SUPPORTS_BIG_ENDIAN=y
 # CONFIG_ARCH_IXDP2401 is not set
 CONFIG_ARCH_IXDP2801=y
 CONFIG_ARCH_IXDP2X01=y
+# CONFIG_IXP2000_SUPPORT_BROKEN_PCI_IO is not set
 
 #
 # Processor Type
@@ -107,7 +111,6 @@ CONFIG_CPU_32v5=y
 CONFIG_CPU_ABRT_EV5T=y
 CONFIG_CPU_CACHE_VIVT=y
 CONFIG_CPU_TLB_V4WBI=y
-CONFIG_CPU_MINICACHE=y
 
 #
 # Processor Features
@@ -119,9 +122,11 @@ CONFIG_XSCALE_PMU=y
 #
 # Bus support
 #
+CONFIG_ISA_DMA_API=y
 CONFIG_PCI=y
 CONFIG_PCI_LEGACY_PROC=y
 CONFIG_PCI_NAMES=y
+# CONFIG_PCI_DEBUG is not set
 
 #
 # PCCARD (PCMCIA/CardBus) support
@@ -131,7 +136,15 @@ CONFIG_PCI_NAMES=y
 #
 # Kernel Features
 #
+# CONFIG_SMP is not set
 # CONFIG_PREEMPT is not set
+# CONFIG_ARCH_DISCONTIGMEM_ENABLE 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_ALIGNMENT_TRAP=y
 
 #
@@ -270,7 +283,6 @@ CONFIG_MTD_IXP2000=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
@@ -309,6 +321,7 @@ CONFIG_IOSCHED_CFQ=y
 #
 # Fusion MPT device support
 #
+# CONFIG_FUSION is not set
 
 #
 # IEEE 1394 (FireWire) support
@@ -330,10 +343,11 @@ CONFIG_NET=y
 #
 CONFIG_PACKET=y
 CONFIG_PACKET_MMAP=y
-# CONFIG_NETLINK_DEV is not set
 CONFIG_UNIX=y
 # CONFIG_NET_KEY is not set
 CONFIG_INET=y
+CONFIG_IP_FIB_HASH=y
+# CONFIG_IP_FIB_TRIE is not set
 # CONFIG_IP_MULTICAST is not set
 # CONFIG_IP_ADVANCED_ROUTER is not set
 CONFIG_IP_PNP=y
@@ -350,6 +364,17 @@ CONFIG_SYN_COOKIES=y
 # CONFIG_INET_TUNNEL is not set
 # CONFIG_IP_TCPDIAG is not set
 # CONFIG_IP_TCPDIAG_IPV6 is not set
+
+#
+# TCP congestion control
+#
+CONFIG_TCP_CONG_BIC=y
+CONFIG_TCP_CONG_WESTWOOD=m
+CONFIG_TCP_CONG_HTCP=m
+# CONFIG_TCP_CONG_HSTCP is not set
+# CONFIG_TCP_CONG_HYBLA is not set
+# CONFIG_TCP_CONG_VEGAS is not set
+# CONFIG_TCP_CONG_SCALABLE is not set
 # CONFIG_IPV6 is not set
 # CONFIG_NETFILTER is not set
 
@@ -405,6 +430,7 @@ CONFIG_MII=y
 # CONFIG_SUNGEM is not set
 # CONFIG_NET_VENDOR_3COM is not set
 # CONFIG_SMC91X is not set
+# CONFIG_DM9000 is not set
 
 #
 # Tulip family network device support
@@ -442,9 +468,11 @@ CONFIG_EEPRO100=y
 # 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
 
 #
 # Ethernet (10000 Mbit)
@@ -466,6 +494,7 @@ CONFIG_EEPRO100=y
 # Wan interfaces
 #
 CONFIG_WAN=y
+# CONFIG_DSCC4 is not set
 # CONFIG_LANMEDIA is not set
 # CONFIG_SYNCLINK_SYNCPPP is not set
 CONFIG_HDLC=y
@@ -528,7 +557,6 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
 #
 # CONFIG_SERIO is not set
 # CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
 
 #
 # Character devices
@@ -549,6 +577,7 @@ CONFIG_SERIAL_8250_NR_UARTS=2
 #
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_JSM is not set
 CONFIG_UNIX98_PTYS=y
 CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
@@ -615,17 +644,18 @@ CONFIG_I2C_ALGOBIT=y
 # CONFIG_I2C_AMD8111 is not set
 # CONFIG_I2C_I801 is not set
 # CONFIG_I2C_I810 is not set
+# CONFIG_I2C_PIIX4 is not set
 # CONFIG_I2C_ISA is not set
 # CONFIG_I2C_IXP2000 is not set
 # CONFIG_I2C_NFORCE2 is not set
 # CONFIG_I2C_PARPORT_LIGHT is not set
-# CONFIG_I2C_PIIX4 is not set
 # CONFIG_I2C_PROSAVAGE is not set
 # CONFIG_I2C_SAVAGE4 is not set
 # CONFIG_SCx200_ACB is not set
 # 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
@@ -639,7 +669,9 @@ CONFIG_I2C_SENSOR=y
 # CONFIG_SENSORS_ADM1025 is not set
 # CONFIG_SENSORS_ADM1026 is not set
 # CONFIG_SENSORS_ADM1031 is not set
+# CONFIG_SENSORS_ADM9240 is not set
 # CONFIG_SENSORS_ASB100 is not set
+# CONFIG_SENSORS_ATXP1 is not set
 # CONFIG_SENSORS_DS1621 is not set
 # CONFIG_SENSORS_FSCHER is not set
 # CONFIG_SENSORS_FSCPOS is not set
@@ -655,6 +687,7 @@ CONFIG_I2C_SENSOR=y
 # CONFIG_SENSORS_LM85 is not set
 # CONFIG_SENSORS_LM87 is not set
 # CONFIG_SENSORS_LM90 is not set
+# CONFIG_SENSORS_LM92 is not set
 # CONFIG_SENSORS_MAX1619 is not set
 # CONFIG_SENSORS_PC87360 is not set
 # CONFIG_SENSORS_SMSC47B397 is not set
@@ -664,14 +697,19 @@ CONFIG_I2C_SENSOR=y
 # CONFIG_SENSORS_W83781D is not set
 # CONFIG_SENSORS_W83L785TS is not set
 # CONFIG_SENSORS_W83627HF is not set
+# CONFIG_SENSORS_W83627EHF is not set
 
 #
 # Other I2C Chip support
 #
+# CONFIG_SENSORS_DS1337 is not set
+# CONFIG_SENSORS_DS1374 is not set
 CONFIG_SENSORS_EEPROM=y
 # 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_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
@@ -725,6 +763,7 @@ CONFIG_EXT2_FS=y
 CONFIG_EXT2_FS_XATTR=y
 CONFIG_EXT2_FS_POSIX_ACL=y
 # 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=y
@@ -765,7 +804,6 @@ CONFIG_DNOTIFY=y
 #
 CONFIG_PROC_FS=y
 CONFIG_SYSFS=y
-# CONFIG_DEVFS_FS is not set
 # CONFIG_DEVPTS_FS_XATTR is not set
 CONFIG_TMPFS=y
 # CONFIG_TMPFS_XATTR is not set
@@ -803,12 +841,14 @@ CONFIG_JFFS2_RTIME=y
 #
 CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
 # CONFIG_NFS_V4 is not set
 # CONFIG_NFS_DIRECTIO is not set
 # CONFIG_NFSD is not set
 CONFIG_ROOT_NFS=y
 CONFIG_LOCKD=y
 CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
@@ -893,3 +933,4 @@ CONFIG_CRC32=y
 # CONFIG_LIBCRC32C is not set
 CONFIG_ZLIB_INFLATE=y
 CONFIG_ZLIB_DEFLATE=y
+# CONFIG_TEXTSEARCH is not set
index ff187f4308f01ec786056f07b82299d8adf90cb2..395137a8fad276ce20cb250d58920f7c12fac501 100644 (file)
@@ -4,6 +4,10 @@
  *  Copyright (C) 1992 Linus Torvalds
  *  Modifications for ARM processor Copyright (C) 1995-2000 Russell King.
  *
+ *  Support for Dynamic Tick Timer Copyright (C) 2004-2005 Nokia Corporation.
+ *  Dynamic Tick Timer written by Tony Lindgren <tony@atomide.com> and
+ *  Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com>.
+ *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
@@ -37,6 +41,7 @@
 #include <asm/irq.h>
 #include <asm/system.h>
 #include <asm/mach/irq.h>
+#include <asm/mach/time.h>
 
 /*
  * Maximum IRQ count.  Currently, this is arbitary.  However, it should
@@ -329,6 +334,15 @@ __do_irq(unsigned int irq, struct irqaction *action, struct pt_regs *regs)
 
        spin_unlock(&irq_controller_lock);
 
+#ifdef CONFIG_NO_IDLE_HZ
+       if (!(action->flags & SA_TIMER) && system_timer->dyn_tick != NULL) {
+               write_seqlock(&xtime_lock);
+               if (system_timer->dyn_tick->state & DYN_TICK_ENABLED)
+                       system_timer->dyn_tick->handler(irq, 0, regs);
+               write_sequnlock(&xtime_lock);
+       }
+#endif
+
        if (!(action->flags & SA_INTERRUPT))
                local_irq_enable();
 
index 07ddeed61766559c1a6d12b1fb70f92608f31c8c..5e435e42dacdef45d87173527d60759aa7af083f 100644 (file)
@@ -697,7 +697,7 @@ static int do_signal(sigset_t *oldset, struct pt_regs *regs, int syscall)
        if (!user_mode(regs))
                return 0;
 
-       if (try_to_freeze(0))
+       if (try_to_freeze())
                goto no_signal;
 
        if (current->ptrace & PT_SINGLESTEP)
index c232f24f4a60042806958f8e74e685af473e3196..06054c9ba07435ac33b4962caa0c8fd5378269b3 100644 (file)
@@ -381,6 +381,95 @@ static struct sysdev_class timer_sysclass = {
        .resume         = timer_resume,
 };
 
+#ifdef CONFIG_NO_IDLE_HZ
+static int timer_dyn_tick_enable(void)
+{
+       struct dyn_tick_timer *dyn_tick = system_timer->dyn_tick;
+       unsigned long flags;
+       int ret = -ENODEV;
+
+       if (dyn_tick) {
+               write_seqlock_irqsave(&xtime_lock, flags);
+               ret = 0;
+               if (!(dyn_tick->state & DYN_TICK_ENABLED)) {
+                       ret = dyn_tick->enable();
+
+                       if (ret == 0)
+                               dyn_tick->state |= DYN_TICK_ENABLED;
+               }
+               write_sequnlock_irqrestore(&xtime_lock, flags);
+       }
+
+       return ret;
+}
+
+static int timer_dyn_tick_disable(void)
+{
+       struct dyn_tick_timer *dyn_tick = system_timer->dyn_tick;
+       unsigned long flags;
+       int ret = -ENODEV;
+
+       if (dyn_tick) {
+               write_seqlock_irqsave(&xtime_lock, flags);
+               ret = 0;
+               if (dyn_tick->state & DYN_TICK_ENABLED) {
+                       ret = dyn_tick->disable();
+
+                       if (ret == 0)
+                               dyn_tick->state &= ~DYN_TICK_ENABLED;
+               }
+               write_sequnlock_irqrestore(&xtime_lock, flags);
+       }
+
+       return ret;
+}
+
+void timer_dyn_reprogram(void)
+{
+       struct dyn_tick_timer *dyn_tick = system_timer->dyn_tick;
+       unsigned long flags;
+
+       write_seqlock_irqsave(&xtime_lock, flags);
+       if (dyn_tick->state & DYN_TICK_ENABLED)
+               dyn_tick->reprogram(next_timer_interrupt() - jiffies);
+       write_sequnlock_irqrestore(&xtime_lock, flags);
+}
+
+static ssize_t timer_show_dyn_tick(struct sys_device *dev, char *buf)
+{
+       return sprintf(buf, "%i\n",
+                      (system_timer->dyn_tick->state & DYN_TICK_ENABLED) >> 1);
+}
+
+static ssize_t timer_set_dyn_tick(struct sys_device *dev, const char *buf,
+                                 size_t count)
+{
+       unsigned int enable = simple_strtoul(buf, NULL, 2);
+
+       if (enable)
+               timer_dyn_tick_enable();
+       else
+               timer_dyn_tick_disable();
+
+       return count;
+}
+static SYSDEV_ATTR(dyn_tick, 0644, timer_show_dyn_tick, timer_set_dyn_tick);
+
+/*
+ * dyntick=enable|disable
+ */
+static char dyntick_str[4] __initdata = "";
+
+static int __init dyntick_setup(char *str)
+{
+       if (str)
+               strlcpy(dyntick_str, str, sizeof(dyntick_str));
+       return 1;
+}
+
+__setup("dyntick=", dyntick_setup);
+#endif
+
 static int __init timer_init_sysfs(void)
 {
        int ret = sysdev_class_register(&timer_sysclass);
@@ -388,6 +477,20 @@ static int __init timer_init_sysfs(void)
                system_timer->dev.cls = &timer_sysclass;
                ret = sysdev_register(&system_timer->dev);
        }
+
+#ifdef CONFIG_NO_IDLE_HZ
+       if (ret == 0 && system_timer->dyn_tick) {
+               ret = sysdev_create_file(&system_timer->dev, &attr_dyn_tick);
+
+               /*
+                * Turn on dynamic tick after calibrate delay
+                * for correct bogomips
+                */
+               if (ret == 0 && dyntick_str[0] == 'e')
+                       ret = timer_dyn_tick_enable();
+       }
+#endif
+
        return ret;
 }
 
index 45c930ccd064802ec3195e342ed57476db6ca43d..0793dcf54f2e51dd30be757962db1483824a1d9d 100644 (file)
@@ -28,7 +28,7 @@ config ARCH_CLEP7312
 config ARCH_EDB7211
        bool "EDB7211"
        select ISA
-       select DISCONTIGMEM
+       select ARCH_DISCONTIGMEM_ENABLE
        help
          Say Y here if you intend to run this kernel on a Cirrus Logic EDB-7211
          evaluation board.
index 9361e05f6fa39e5519608c6e13fd806bbffd250c..ecb58d83478e32e511a77937328cfd79ef5f290a 100644 (file)
@@ -54,6 +54,14 @@ config ARCH_IXDP2X01
        depends on ARCH_IXDP2401 || ARCH_IXDP2801
        default y       
 
+config IXP2000_SUPPORT_BROKEN_PCI_IO
+       bool "Support broken PCI I/O on older IXP2000s"
+       default y
+       help
+         Say 'N' here if you only intend to run your kernel on an
+         IXP2000 B0 or later model and do not need the PCI I/O
+         byteswap workaround.  Say 'Y' otherwise.
+
 endmenu
 
 endif
index 04b38bcf9aace6deb405720e2d554594242ffc49..f3a291b6a9fb7b72d7eeece51e4739cabef45794 100644 (file)
@@ -197,8 +197,23 @@ static struct platform_device enp2611_flash = {
        .resource       = &enp2611_flash_resource,
 };
 
+static struct ixp2000_i2c_pins enp2611_i2c_gpio_pins = {
+       .sda_pin        = ENP2611_GPIO_SDA,
+       .scl_pin        = ENP2611_GPIO_SCL,
+};
+
+static struct platform_device enp2611_i2c_controller = {
+       .name           = "IXP2000-I2C",
+       .id             = 0,
+       .dev            = {
+               .platform_data = &enp2611_i2c_gpio_pins
+       },
+       .num_resources  = 0
+};
+
 static struct platform_device *enp2611_devices[] __initdata = {
-       &enp2611_flash
+       &enp2611_flash,
+       &enp2611_i2c_controller
 };
 
 static void __init enp2611_init_machine(void)
index 21c41fe15b99cacd2493ba5d2d22f472944eb1c0..5e4380747b53d1bb2b105b35ec71f890ba4440c1 100644 (file)
@@ -42,6 +42,9 @@
 #include <asm/mach/flash.h>
 #include <asm/mach/arch.h>
 
+#include <asm/arch/gpio.h>
+
+
 /*************************************************************************
  * IXDP2x00 IRQ Initialization
  *************************************************************************/
index 5ff2f2718c58c0762cfca0f3173cc74f80f09794..0788fb2b5c10e6ae6e2023649930205cc3afb016 100644 (file)
@@ -198,6 +198,19 @@ clear_master_aborts(void)
 void __init
 ixp2000_pci_preinit(void)
 {
+#ifndef CONFIG_IXP2000_SUPPORT_BROKEN_PCI_IO
+       /*
+        * Configure the PCI unit to properly byteswap I/O transactions,
+        * and verify that it worked.
+        */
+       ixp2000_reg_write(IXP2000_PCI_CONTROL,
+                         (*IXP2000_PCI_CONTROL | PCI_CONTROL_IEE));
+
+       if ((*IXP2000_PCI_CONTROL & PCI_CONTROL_IEE) == 0)
+               panic("IXP2000: PCI I/O is broken on this ixp model, and "
+                       "the needed workaround has not been configured in");
+#endif
+
        hook_fault_code(16+6, ixp2000_pci_abort_handler, SIGBUS,
                                "PCI config cycle to non-existent device");
 }
index ef6865f0b9792a1ac199127f73aba068d426b410..767ebb55bd83d7e763b38d719aee47728f037052 100644 (file)
@@ -790,12 +790,10 @@ void __init setup_arch(char **cmdline_p)
 #ifndef CONFIG_GDBSTUB_UART0
        __reg(UART0_BASE + UART_IER * 8) = 0;
        early_serial_setup(&__frv_uart0);
-//     register_serial(&__frv_uart0);
 #endif
 #ifndef CONFIG_GDBSTUB_UART1
        __reg(UART1_BASE + UART_IER * 8) = 0;
        early_serial_setup(&__frv_uart1);
-//     register_serial(&__frv_uart1);
 #endif
 
 #if defined(CONFIG_CHR_DEV_FLASH) || defined(CONFIG_BLK_DEV_FLASH)
index d8d8f3d4304d9c11387b09d892c032049e7f9f4f..36a2dffc8ebd953618a70a4f365b23ce3349ea3f 100644 (file)
@@ -536,10 +536,8 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset)
        if (!user_mode(regs))
                return 1;
 
-       if (current->flags & PF_FREEZE) {
-               refrigerator(0);
+       if (try_to_freeze())
                goto no_signal;
-       }
 
        if (!oldset)
                oldset = &current->blocked;
index a4799d633ef40e74a820bfef240a3e97be65c177..5aab87eae1f941f8373d8ea1db5882ced9b447d0 100644 (file)
@@ -517,10 +517,8 @@ asmlinkage int do_signal(struct pt_regs *regs, sigset_t *oldset)
        if ((regs->ccr & 0x10))
                return 1;
 
-       if (current->flags & PF_FREEZE) {
-               refrigerator(0);
+       if (try_to_freeze())
                goto no_signal;
-       }
 
        current->thread.esp0 = (unsigned long) regs;
 
index d4ae5f9ceae6bb0a9375c53259d77fdaa70e16a4..6c02336fe2e4489b89a74632404cf8f5aec07b71 100644 (file)
@@ -510,28 +510,7 @@ config SCHED_SMT
          cost of slightly increased overhead in some places. If unsure say
          N here.
 
-config PREEMPT
-       bool "Preemptible Kernel"
-       help
-         This option reduces the latency of the kernel when reacting to
-         real-time or interactive events by allowing a low priority process to
-         be preempted even if it is in kernel mode executing a system call.
-         This allows applications to run more reliably even when the system is
-         under load.
-
-         Say Y here if you are building a kernel for a desktop, embedded
-         or real-time system.  Say N if you are unsure.
-
-config PREEMPT_BKL
-       bool "Preempt The Big Kernel Lock"
-       depends on PREEMPT
-       default y
-       help
-         This option reduces the latency of the kernel by making the
-         big kernel lock preemptible.
-
-         Say Y here if you are building a kernel for a desktop system.
-         Say N if you are unsure.
+source "kernel/Kconfig.preempt"
 
 config X86_UP_APIC
        bool "Local APIC support on uniprocessors"
@@ -963,6 +942,41 @@ config SECCOMP
 
 source kernel/Kconfig.hz
 
+config PHYSICAL_START
+       hex "Physical address where the kernel is loaded" if EMBEDDED
+       default "0x100000"
+       help
+         This gives the physical address where the kernel is loaded.
+         Primarily used in the case of kexec on panic where the
+         fail safe kernel needs to run at a different address than
+         the panic-ed kernel.
+
+         Don't change this unless you know what you are doing.
+
+config KEXEC
+       bool "kexec system call (EXPERIMENTAL)"
+       depends on EXPERIMENTAL
+       help
+         kexec is a system call that implements the ability to shutdown your
+         current kernel, and to start another kernel.  It is like a reboot
+         but it is indepedent of the system firmware.   And like a reboot
+         you can start any kernel with it, not just Linux.
+
+         The name comes from the similiarity to the exec system call.
+
+         It is an ongoing process to be certain the hardware in a machine
+         is properly shutdown, so do not be surprised if this code does not
+         initially work for you.  It may help to enable device hotplugging
+         support.  As of this writing the exact hardware interface is
+         strongly in flux, so no good recommendation can be made.
+
+config CRASH_DUMP
+       bool "kernel crash dumps (EXPERIMENTAL)"
+       depends on EMBEDDED
+       depends on EXPERIMENTAL
+       depends on HIGHMEM
+       help
+         Generate crash dump after being started by kexec.
 endmenu
 
 
@@ -1250,6 +1264,15 @@ config SCx200
          This support is also available as a module.  If compiled as a
          module, it will be called scx200.
 
+config HOTPLUG_CPU
+       bool "Support for hot-pluggable CPUs (EXPERIMENTAL)"
+       depends on SMP && HOTPLUG && EXPERIMENTAL
+       ---help---
+         Say Y here to experiment with turning CPUs off and on.  CPUs
+         can be controlled through /sys/devices/system/cpu.
+
+         Say N.
+
 source "drivers/pcmcia/Kconfig"
 
 source "drivers/pci/hotplug/Kconfig"
index 43cd6220ee4905c2375cfb1cece6767c0d8fa28f..1e71382d413a99b40f3a1e759ee0254acff94539 100644 (file)
@@ -25,8 +25,8 @@ SVGA_MODE := -DSVGA_MODE=NORMAL_VGA
 
 #RAMDISK := -DRAMDISK=512
 
-targets                := vmlinux.bin bootsect bootsect.o setup setup.o \
-                  zImage bzImage
+targets                := vmlinux.bin bootsect bootsect.o \
+                  setup setup.o zImage bzImage
 subdir-        := compressed
 
 hostprogs-y    := tools/build
index c5e80b69e7d41d8ae580ae734553d2b9584b9760..b5893e4ecd376b54a3044c09e035ff82bf5e923c 100644 (file)
@@ -25,6 +25,7 @@
 
 #include <linux/linkage.h>
 #include <asm/segment.h>
+#include <asm/page.h>
 
        .globl startup_32
        
@@ -74,7 +75,7 @@ startup_32:
        popl %esi       # discard address
        popl %esi       # real mode pointer
        xorl %ebx,%ebx
-       ljmp $(__BOOT_CS), $0x100000
+       ljmp $(__BOOT_CS), $__PHYSICAL_START
 
 /*
  * We come here, if we were loaded high.
@@ -99,7 +100,7 @@ startup_32:
        popl %ecx       # lcount
        popl %edx       # high_buffer_start
        popl %eax       # hcount
-       movl $0x100000,%edi
+       movl $__PHYSICAL_START,%edi
        cli             # make sure we don't get interrupted
        ljmp $(__BOOT_CS), $0x1000 # and jump to the move routine
 
@@ -124,5 +125,5 @@ move_routine_start:
        movsl
        movl %ebx,%esi  # Restore setup pointer
        xorl %ebx,%ebx
-       ljmp $(__BOOT_CS), $0x100000
+       ljmp $(__BOOT_CS), $__PHYSICAL_START
 move_routine_end:
index cedc55cc47de0756df6e77afc0e94fedba2439f5..82a807f9f5e64d8e9230705941e55186d5537ab7 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/vmalloc.h>
 #include <linux/tty.h>
 #include <asm/io.h>
+#include <asm/page.h>
 
 /*
  * gzip declarations
@@ -308,7 +309,7 @@ static void setup_normal_output_buffer(void)
 #else
        if ((RM_ALT_MEM_K > RM_EXT_MEM_K ? RM_ALT_MEM_K : RM_EXT_MEM_K) < 1024) error("Less than 2MB of memory");
 #endif
-       output_data = (char *)0x100000; /* Points to 1M */
+       output_data = (char *)__PHYSICAL_START; /* Normally Points to 1M */
        free_mem_end_ptr = (long)real_mode;
 }
 
@@ -333,8 +334,8 @@ static void setup_output_buffer_if_we_run_high(struct moveparams *mv)
        low_buffer_size = low_buffer_end - LOW_BUFFER_START;
        high_loaded = 1;
        free_mem_end_ptr = (long)high_buffer_start;
-       if ( (0x100000 + low_buffer_size) > ((ulg)high_buffer_start)) {
-               high_buffer_start = (uch *)(0x100000 + low_buffer_size);
+       if ( (__PHYSICAL_START + low_buffer_size) > ((ulg)high_buffer_start)) {
+               high_buffer_start = (uch *)(__PHYSICAL_START + low_buffer_size);
                mv->hcount = 0; /* say: we need not to move high_buffer */
        }
        else mv->hcount = -1;
@@ -353,7 +354,6 @@ static void close_output_buffer_if_we_run_high(struct moveparams *mv)
        }
 }
 
-
 asmlinkage int decompress_kernel(struct moveparams *mv, void *rmode)
 {
        real_mode = rmode;
index 027d6b354ffbee7a1e5cde1a0d43f471cf5b2d64..d8d69f2b911d62c909b651de0d9e61a7c7b3b461 100644 (file)
@@ -6,7 +6,7 @@
  *   projects 1572D, 1484D, 1386D, 1226DT
  * disk signature read by Matt Domsch <Matt_Domsch@dell.com>
  *     and Andrew Wilks <Andrew_Wilks@dell.com> September 2003, June 2004
- * legacy CHS retreival by Patrick J. LoPresti <patl@users.sourceforge.net>
+ * legacy CHS retrieval by Patrick J. LoPresti <patl@users.sourceforge.net>
  *      March 2004
  * Command line option parsing, Matt Domsch, November 2004
  */
index caa1fde6904edc89eccdf49e693d8576aa9feecc..8cb420f40c58f106972d5ec830e8cd382378470c 100644 (file)
@@ -33,7 +33,7 @@
  * Transcribed from Intel (as86) -> AT&T (gas) by Chris Noe, May 1999.
  * <stiker@northlink.com>
  *
- * Fix to work around buggy BIOSes which dont use carry bit correctly
+ * Fix to work around buggy BIOSes which don't use carry bit correctly
  * and/or report extended memory in CX/DX for e801h memory size detection 
  * call.  As a result the kernel got wrong figures.  The int15/e801h docs
  * from Ralf Brown interrupt list seem to indicate AX/BX should be used
@@ -357,7 +357,7 @@ bail820:
 
 meme801:
        stc                                     # fix to work around buggy
-       xorw    %cx,%cx                         # BIOSes which dont clear/set
+       xorw    %cx,%cx                         # BIOSes which don't clear/set
        xorw    %dx,%dx                         # carry on pass/error of
                                                # e801h memory size call
                                                # or merely pass cx,dx though
@@ -847,7 +847,7 @@ flush_instr:
 #
 #      but we yet haven't reloaded the CS register, so the default size 
 #      of the target offset still is 16 bit.
-#       However, using an operand prefix (0x66), the CPU will properly
+#      However, using an operand prefix (0x66), the CPU will properly
 #      take our 48 bit far pointer. (INTeL 80386 Programmer's Reference
 #      Manual, Mixing 16-bit and 32-bit code, page 16-6)
 
index 26509b826aeda0468ca6bc26897e13c650952a7b..4a17956512e1a279d1ea28f4209748df509b151a 100644 (file)
@@ -1,6 +1,4 @@
 /*
- *  $Id: build.c,v 1.5 1997/05/19 12:29:58 mj Exp $
- *
  *  Copyright (C) 1991, 1992  Linus Torvalds
  *  Copyright (C) 1997 Martin Mares
  */
@@ -8,7 +6,8 @@
 /*
  * This file builds a disk-image from three different files:
  *
- * - bootsect: exactly 512 bytes of 8086 machine code, loads the rest
+ * - bootsect: compatibility mbr which prints an error message if
+ *             someone tries to boot the kernel directly.
  * - setup: 8086 machine code, sets up system parm
  * - system: 80386 code for actual system
  *
index 1019430fc1f11015128f2f22fdf44f7d24330ab3..88ee85c3b43be94868e0229286a6db51cc9229cf 100644 (file)
@@ -59,7 +59,7 @@ struct aes_ctx {
 };
 
 #define WPOLY 0x011b
-#define u32_in(x) le32_to_cpu(*(const u32 *)(x))
+#define u32_in(x) le32_to_cpup((const __le32 *)(x))
 #define bytes2word(b0, b1, b2, b3)  \
        (((u32)(b3) << 24) | ((u32)(b2) << 16) | ((u32)(b1) << 8) | (b0))
 
index 28e620383799a1a05ecf82fb11bd9bf275ff19f6..ca07b95c06b82e6eeffd79fd3649b4c3ca22b8b5 100644 (file)
@@ -126,7 +126,6 @@ CONFIG_HAVE_DEC_LOCK=y
 #
 CONFIG_PM=y
 CONFIG_SOFTWARE_SUSPEND=y
-# CONFIG_PM_DISK is not set
 
 #
 # ACPI (Advanced Configuration and Power Interface) Support
index 51ecd512603da25153cbf194dcda57d724a8edd8..4cc83b322b362dc85739cc42e8df6b955bc7da7e 100644 (file)
@@ -24,6 +24,7 @@ obj-$(CONFIG_X86_MPPARSE)     += mpparse.o
 obj-$(CONFIG_X86_LOCAL_APIC)   += apic.o nmi.o
 obj-$(CONFIG_X86_IO_APIC)      += io_apic.o
 obj-$(CONFIG_X86_REBOOTFIXUPS) += reboot_fixups.o
+obj-$(CONFIG_KEXEC)            += machine_kexec.o relocate_kernel.o crash.o
 obj-$(CONFIG_X86_NUMAQ)                += numaq.o
 obj-$(CONFIG_X86_SUMMIT_NUMA)  += summit.o
 obj-$(CONFIG_KPROBES)          += kprobes.o
index 848bb97af7ca316755f6e47e612ecc75717fb197..9f63ae0f404b2586f4c24182b408b9fc1f944dba 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/efi.h>
 #include <linux/irq.h>
 #include <linux/module.h>
+#include <linux/dmi.h>
 
 #include <asm/pgtable.h>
 #include <asm/io_apic.h>
@@ -815,6 +816,219 @@ acpi_process_madt(void)
        return;
 }
 
+extern int acpi_force;
+
+#ifdef __i386__
+
+#ifdef CONFIG_ACPI_PCI
+static int __init disable_acpi_irq(struct dmi_system_id *d)
+{
+       if (!acpi_force) {
+               printk(KERN_NOTICE "%s detected: force use of acpi=noirq\n",
+                      d->ident);
+               acpi_noirq_set();
+       }
+       return 0;
+}
+
+static int __init disable_acpi_pci(struct dmi_system_id *d)
+{
+       if (!acpi_force) {
+               printk(KERN_NOTICE "%s detected: force use of pci=noacpi\n",
+                      d->ident);
+               acpi_disable_pci();
+       }
+       return 0;
+}
+#endif
+
+static int __init dmi_disable_acpi(struct dmi_system_id *d)
+{
+       if (!acpi_force) {
+               printk(KERN_NOTICE "%s detected: acpi off\n",d->ident);
+               disable_acpi();
+       } else {
+               printk(KERN_NOTICE
+                      "Warning: DMI blacklist says broken, but acpi forced\n");
+       }
+       return 0;
+}
+
+/*
+ * Limit ACPI to CPU enumeration for HT
+ */
+static int __init force_acpi_ht(struct dmi_system_id *d)
+{
+       if (!acpi_force) {
+               printk(KERN_NOTICE "%s detected: force use of acpi=ht\n", d->ident);
+               disable_acpi();
+               acpi_ht = 1;
+       } else {
+               printk(KERN_NOTICE
+                      "Warning: acpi=force overrules DMI blacklist: acpi=ht\n");
+       }
+       return 0;
+}
+
+/*
+ * If your system is blacklisted here, but you find that acpi=force
+ * works for you, please contact acpi-devel@sourceforge.net
+ */
+static struct dmi_system_id __initdata acpi_dmi_table[] = {
+       /*
+        * Boxes that need ACPI disabled
+        */
+       {
+               .callback = dmi_disable_acpi,
+               .ident = "IBM Thinkpad",
+               .matches = {
+                       DMI_MATCH(DMI_BOARD_VENDOR, "IBM"),
+                       DMI_MATCH(DMI_BOARD_NAME, "2629H1G"),
+               },
+       },
+
+       /*
+        * Boxes that need acpi=ht
+        */
+       {
+               .callback = force_acpi_ht,
+               .ident = "FSC Primergy T850",
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "PRIMERGY T850"),
+               },
+       },
+       {
+               .callback = force_acpi_ht,
+               .ident = "DELL GX240",
+               .matches = {
+                       DMI_MATCH(DMI_BOARD_VENDOR, "Dell Computer Corporation"),
+                       DMI_MATCH(DMI_BOARD_NAME, "OptiPlex GX240"),
+               },
+       },
+       {
+               .callback = force_acpi_ht,
+               .ident = "HP VISUALIZE NT Workstation",
+               .matches = {
+                       DMI_MATCH(DMI_BOARD_VENDOR, "Hewlett-Packard"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "HP VISUALIZE NT Workstation"),
+               },
+       },
+       {
+               .callback = force_acpi_ht,
+               .ident = "Compaq Workstation W8000",
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Compaq"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "Workstation W8000"),
+               },
+       },
+       {
+               .callback = force_acpi_ht,
+               .ident = "ASUS P4B266",
+               .matches = {
+                       DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
+                       DMI_MATCH(DMI_BOARD_NAME, "P4B266"),
+               },
+       },
+       {
+               .callback = force_acpi_ht,
+               .ident = "ASUS P2B-DS",
+               .matches = {
+                       DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
+                       DMI_MATCH(DMI_BOARD_NAME, "P2B-DS"),
+               },
+       },
+       {
+               .callback = force_acpi_ht,
+               .ident = "ASUS CUR-DLS",
+               .matches = {
+                       DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
+                       DMI_MATCH(DMI_BOARD_NAME, "CUR-DLS"),
+               },
+       },
+       {
+               .callback = force_acpi_ht,
+               .ident = "ABIT i440BX-W83977",
+               .matches = {
+                       DMI_MATCH(DMI_BOARD_VENDOR, "ABIT <http://www.abit.com>"),
+                       DMI_MATCH(DMI_BOARD_NAME, "i440BX-W83977 (BP6)"),
+               },
+       },
+       {
+               .callback = force_acpi_ht,
+               .ident = "IBM Bladecenter",
+               .matches = {
+                       DMI_MATCH(DMI_BOARD_VENDOR, "IBM"),
+                       DMI_MATCH(DMI_BOARD_NAME, "IBM eServer BladeCenter HS20"),
+               },
+       },
+       {
+               .callback = force_acpi_ht,
+               .ident = "IBM eServer xSeries 360",
+               .matches = {
+                       DMI_MATCH(DMI_BOARD_VENDOR, "IBM"),
+                       DMI_MATCH(DMI_BOARD_NAME, "eServer xSeries 360"),
+               },
+       },
+       {
+               .callback = force_acpi_ht,
+               .ident = "IBM eserver xSeries 330",
+               .matches = {
+                       DMI_MATCH(DMI_BOARD_VENDOR, "IBM"),
+                       DMI_MATCH(DMI_BOARD_NAME, "eserver xSeries 330"),
+               },
+       },
+       {
+               .callback = force_acpi_ht,
+               .ident = "IBM eserver xSeries 440",
+               .matches = {
+                       DMI_MATCH(DMI_BOARD_VENDOR, "IBM"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "eserver xSeries 440"),
+               },
+       },
+
+#ifdef CONFIG_ACPI_PCI
+       /*
+        * Boxes that need ACPI PCI IRQ routing disabled
+        */
+       {
+               .callback = disable_acpi_irq,
+               .ident = "ASUS A7V",
+               .matches = {
+                       DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC"),
+                       DMI_MATCH(DMI_BOARD_NAME, "<A7V>"),
+                       /* newer BIOS, Revision 1011, does work */
+                       DMI_MATCH(DMI_BIOS_VERSION, "ASUS A7V ACPI BIOS Revision 1007"),
+               },
+       },
+
+       /*
+        * Boxes that need ACPI PCI IRQ routing and PCI scan disabled
+        */
+       {       /* _BBN 0 bug */
+               .callback = disable_acpi_pci,
+               .ident = "ASUS PR-DLS",
+               .matches = {
+                       DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
+                       DMI_MATCH(DMI_BOARD_NAME, "PR-DLS"),
+                       DMI_MATCH(DMI_BIOS_VERSION, "ASUS PR-DLS ACPI BIOS Revision 1010"),
+                       DMI_MATCH(DMI_BIOS_DATE, "03/21/2003")
+               },
+       },
+       {
+               .callback = disable_acpi_pci,
+               .ident = "Acer TravelMate 36x Laptop",
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 360"),
+               },
+       },
+#endif
+       { }
+};
+
+#endif /* __i386__ */
+
 /*
  * acpi_boot_table_init() and acpi_boot_init()
  *  called from setup_arch(), always.
@@ -843,6 +1057,10 @@ acpi_boot_table_init(void)
 {
        int error;
 
+#ifdef __i386__
+       dmi_check_system(acpi_dmi_table);
+#endif
+
        /*
         * If acpi_disabled, bail out
         * One exception: acpi=ht continues far enough to enumerate LAPICs
@@ -870,8 +1088,6 @@ acpi_boot_table_init(void)
         */
        error = acpi_blacklisted();
        if (error) {
-               extern int acpi_force;
-
                if (acpi_force) {
                        printk(KERN_WARNING PREFIX "acpi=force override\n");
                } else {
index 28bb0514bb6e1ce0a038b5945f3f0f9673a4a038..c1af93032ff32bc02df16891819159e473efb78e 100644 (file)
@@ -7,6 +7,7 @@
 
 #include <linux/acpi.h>
 #include <linux/bootmem.h>
+#include <linux/dmi.h>
 #include <asm/smp.h>
 #include <asm/tlbflush.h>
 
@@ -91,3 +92,29 @@ static int __init acpi_sleep_setup(char *str)
 
 
 __setup("acpi_sleep=", acpi_sleep_setup);
+
+
+static __init int reset_videomode_after_s3(struct dmi_system_id *d)
+{
+       acpi_video_flags |= 2;
+       return 0;
+}
+
+static __initdata struct dmi_system_id acpisleep_dmi_table[] = {
+       {       /* Reset video mode after returning from ACPI S3 sleep */
+               .callback = reset_videomode_after_s3,
+               .ident = "Toshiba Satellite 4030cdt",
+               .matches = {
+                       DMI_MATCH(DMI_PRODUCT_NAME, "S4030CDT/4.3"),
+               },
+       },
+       { }
+};
+
+static int __init acpisleep_dmi_init(void)
+{
+       dmi_check_system(acpisleep_dmi_table);
+       return 0;
+}
+
+core_initcall(acpisleep_dmi_init);
index 8d993fa71754a50a800ea5fd05749017be643a96..93df90bbb87e00e4f438d10d449f91b8faa4b801 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/mc146818rtc.h>
 #include <linux/kernel_stat.h>
 #include <linux/sysdev.h>
+#include <linux/cpu.h>
 
 #include <asm/atomic.h>
 #include <asm/smp.h>
 
 #include "io_ports.h"
 
+/*
+ * Knob to control our willingness to enable the local APIC.
+ */
+int enable_local_apic __initdata = 0; /* -1=force-disable, +1=force-enable */
+
 /*
  * Debug level
  */
@@ -205,7 +211,7 @@ void __init connect_bsp_APIC(void)
        enable_apic_mode();
 }
 
-void disconnect_bsp_APIC(void)
+void disconnect_bsp_APIC(int virt_wire_setup)
 {
        if (pic_mode) {
                /*
@@ -219,6 +225,42 @@ void disconnect_bsp_APIC(void)
                outb(0x70, 0x22);
                outb(0x00, 0x23);
        }
+       else {
+               /* Go back to Virtual Wire compatibility mode */
+               unsigned long value;
+
+               /* For the spurious interrupt use vector F, and enable it */
+               value = apic_read(APIC_SPIV);
+               value &= ~APIC_VECTOR_MASK;
+               value |= APIC_SPIV_APIC_ENABLED;
+               value |= 0xf;
+               apic_write_around(APIC_SPIV, value);
+
+               if (!virt_wire_setup) {
+                       /* For LVT0 make it edge triggered, active high, external and enabled */
+                       value = apic_read(APIC_LVT0);
+                       value &= ~(APIC_MODE_MASK | APIC_SEND_PENDING |
+                               APIC_INPUT_POLARITY | APIC_LVT_REMOTE_IRR |
+                               APIC_LVT_LEVEL_TRIGGER | APIC_LVT_MASKED );
+                       value |= APIC_LVT_REMOTE_IRR | APIC_SEND_PENDING;
+                       value = SET_APIC_DELIVERY_MODE(value, APIC_MODE_EXTINT);
+                       apic_write_around(APIC_LVT0, value);
+               }
+               else {
+                       /* Disable LVT0 */
+                       apic_write_around(APIC_LVT0, APIC_LVT_MASKED);
+               }
+
+               /* For LVT1 make it edge triggered, active high, nmi and enabled */
+               value = apic_read(APIC_LVT1);
+               value &= ~(
+                       APIC_MODE_MASK | APIC_SEND_PENDING |
+                       APIC_INPUT_POLARITY | APIC_LVT_REMOTE_IRR |
+                       APIC_LVT_LEVEL_TRIGGER | APIC_LVT_MASKED);
+               value |= APIC_LVT_REMOTE_IRR | APIC_SEND_PENDING;
+               value = SET_APIC_DELIVERY_MODE(value, APIC_MODE_NMI);
+               apic_write_around(APIC_LVT1, value);
+       }
 }
 
 void disable_local_APIC(void)
@@ -363,7 +405,7 @@ void __init init_bsp_APIC(void)
        apic_write_around(APIC_LVT1, value);
 }
 
-void __init setup_local_APIC (void)
+void __devinit setup_local_APIC(void)
 {
        unsigned long oldvalue, value, ver, maxlvt;
 
@@ -634,7 +676,7 @@ static struct sys_device device_lapic = {
        .cls    = &lapic_sysclass,
 };
 
-static void __init apic_pm_activate(void)
+static void __devinit apic_pm_activate(void)
 {
        apic_pm_state.active = 1;
 }
@@ -665,26 +707,6 @@ static void apic_pm_activate(void) { }
  * Original code written by Keir Fraser.
  */
 
-/*
- * Knob to control our willingness to enable the local APIC.
- */
-int enable_local_apic __initdata = 0; /* -1=force-disable, +1=force-enable */
-
-static int __init lapic_disable(char *str)
-{
-       enable_local_apic = -1;
-       clear_bit(X86_FEATURE_APIC, boot_cpu_data.x86_capability);
-       return 0;
-}
-__setup("nolapic", lapic_disable);
-
-static int __init lapic_enable(char *str)
-{
-       enable_local_apic = 1;
-       return 0;
-}
-__setup("lapic", lapic_enable);
-
 static int __init apic_set_verbosity(char *str)
 {
        if (strcmp("debug", str) == 0)
@@ -855,7 +877,7 @@ fake_ioapic_page:
  * but we do not accept timer interrupts yet. We only allow the BP
  * to calibrate.
  */
-static unsigned int __init get_8254_timer_count(void)
+static unsigned int __devinit get_8254_timer_count(void)
 {
        extern spinlock_t i8253_lock;
        unsigned long flags;
@@ -874,7 +896,7 @@ static unsigned int __init get_8254_timer_count(void)
 }
 
 /* next tick in 8254 can be caught by catching timer wraparound */
-static void __init wait_8254_wraparound(void)
+static void __devinit wait_8254_wraparound(void)
 {
        unsigned int curr_count, prev_count;
 
@@ -894,7 +916,7 @@ static void __init wait_8254_wraparound(void)
  * Default initialization for 8254 timers. If we use other timers like HPET,
  * we override this later
  */
-void (*wait_timer_tick)(void) __initdata = wait_8254_wraparound;
+void (*wait_timer_tick)(void) __devinitdata = wait_8254_wraparound;
 
 /*
  * This function sets up the local APIC timer, with a timeout of
@@ -930,7 +952,7 @@ static void __setup_APIC_LVTT(unsigned int clocks)
        apic_write_around(APIC_TMICT, clocks/APIC_DIVISOR);
 }
 
-static void __init setup_APIC_timer(unsigned int clocks)
+static void __devinit setup_APIC_timer(unsigned int clocks)
 {
        unsigned long flags;
 
@@ -1043,12 +1065,12 @@ void __init setup_boot_APIC_clock(void)
        local_irq_enable();
 }
 
-void __init setup_secondary_APIC_clock(void)
+void __devinit setup_secondary_APIC_clock(void)
 {
        setup_APIC_timer(calibration_result);
 }
 
-void __init disable_APIC_timer(void)
+void __devinit disable_APIC_timer(void)
 {
        if (using_apic_timer) {
                unsigned long v;
index 0ff65abcd56c3c1139b4849a80228f555785c655..d48ce929096316bb433956ab4a278a159b12ff59 100644 (file)
@@ -346,10 +346,10 @@ extern int (*console_blank_hook)(int);
 struct apm_user {
        int             magic;
        struct apm_user *       next;
-       int             suser: 1;
-       int             writer: 1;
-       int             reader: 1;
-       int             suspend_wait: 1;
+       unsigned int    suser: 1;
+       unsigned int    writer: 1;
+       unsigned int    reader: 1;
+       unsigned int    suspend_wait: 1;
        int             suspend_result;
        int             suspends_pending;
        int             standbys_pending;
index b9954248d0aaf13f8861a87c7b55e1ab9314e8a6..2203a9d2021251a59776109064d10d558b898574 100644 (file)
@@ -24,9 +24,9 @@ EXPORT_PER_CPU_SYMBOL(cpu_gdt_table);
 DEFINE_PER_CPU(unsigned char, cpu_16bit_stack[CPU_16BIT_STACK_SIZE]);
 EXPORT_PER_CPU_SYMBOL(cpu_16bit_stack);
 
-static int cachesize_override __initdata = -1;
-static int disable_x86_fxsr __initdata = 0;
-static int disable_x86_serial_nr __initdata = 1;
+static int cachesize_override __devinitdata = -1;
+static int disable_x86_fxsr __devinitdata = 0;
+static int disable_x86_serial_nr __devinitdata = 1;
 
 struct cpu_dev * cpu_devs[X86_VENDOR_NUM] = {};
 
@@ -59,7 +59,7 @@ static int __init cachesize_setup(char *str)
 }
 __setup("cachesize=", cachesize_setup);
 
-int __init get_model_name(struct cpuinfo_x86 *c)
+int __devinit get_model_name(struct cpuinfo_x86 *c)
 {
        unsigned int *v;
        char *p, *q;
@@ -89,7 +89,7 @@ int __init get_model_name(struct cpuinfo_x86 *c)
 }
 
 
-void __init display_cacheinfo(struct cpuinfo_x86 *c)
+void __devinit display_cacheinfo(struct cpuinfo_x86 *c)
 {
        unsigned int n, dummy, ecx, edx, l2size;
 
@@ -130,7 +130,7 @@ void __init display_cacheinfo(struct cpuinfo_x86 *c)
 /* in particular, if CPUID levels 0x80000002..4 are supported, this isn't used */
 
 /* Look up CPU names by table lookup. */
-static char __init *table_lookup_model(struct cpuinfo_x86 *c)
+static char __devinit *table_lookup_model(struct cpuinfo_x86 *c)
 {
        struct cpu_model_info *info;
 
@@ -151,7 +151,7 @@ static char __init *table_lookup_model(struct cpuinfo_x86 *c)
 }
 
 
-void __init get_cpu_vendor(struct cpuinfo_x86 *c, int early)
+void __devinit get_cpu_vendor(struct cpuinfo_x86 *c, int early)
 {
        char *v = c->x86_vendor_id;
        int i;
@@ -202,7 +202,7 @@ static inline int flag_is_changeable_p(u32 flag)
 
 
 /* Probe for the CPUID instruction */
-static int __init have_cpuid_p(void)
+static int __devinit have_cpuid_p(void)
 {
        return flag_is_changeable_p(X86_EFLAGS_ID);
 }
@@ -249,7 +249,7 @@ static void __init early_cpu_detect(void)
 #endif
 }
 
-void __init generic_identify(struct cpuinfo_x86 * c)
+void __devinit generic_identify(struct cpuinfo_x86 * c)
 {
        u32 tfms, xlvl;
        int junk;
@@ -296,7 +296,7 @@ void __init generic_identify(struct cpuinfo_x86 * c)
        }
 }
 
-static void __init squash_the_stupid_serial_number(struct cpuinfo_x86 *c)
+static void __devinit squash_the_stupid_serial_number(struct cpuinfo_x86 *c)
 {
        if (cpu_has(c, X86_FEATURE_PN) && disable_x86_serial_nr ) {
                /* Disable processor serial number */
@@ -324,7 +324,7 @@ __setup("serialnumber", x86_serial_nr_setup);
 /*
  * This does the hard work of actually picking apart the CPU stuff...
  */
-void __init identify_cpu(struct cpuinfo_x86 *c)
+void __devinit identify_cpu(struct cpuinfo_x86 *c)
 {
        int i;
 
@@ -432,10 +432,13 @@ void __init identify_cpu(struct cpuinfo_x86 *c)
 #ifdef CONFIG_X86_MCE
        mcheck_init(c);
 #endif
+       if (c == &boot_cpu_data)
+               sysenter_setup();
+       enable_sep_cpu();
 }
 
 #ifdef CONFIG_X86_HT
-void __init detect_ht(struct cpuinfo_x86 *c)
+void __devinit detect_ht(struct cpuinfo_x86 *c)
 {
        u32     eax, ebx, ecx, edx;
        int     index_msb, tmp;
@@ -490,7 +493,7 @@ void __init detect_ht(struct cpuinfo_x86 *c)
 }
 #endif
 
-void __init print_cpu_info(struct cpuinfo_x86 *c)
+void __devinit print_cpu_info(struct cpuinfo_x86 *c)
 {
        char *vendor = NULL;
 
@@ -513,7 +516,7 @@ void __init print_cpu_info(struct cpuinfo_x86 *c)
                printk("\n");
 }
 
-cpumask_t cpu_initialized __initdata = CPU_MASK_NONE;
+cpumask_t cpu_initialized __devinitdata = CPU_MASK_NONE;
 
 /* This is hacky. :)
  * We're emulating future behavior.
@@ -560,7 +563,7 @@ void __init early_cpu_init(void)
  * and IDT. We reload them nevertheless, this function acts as a
  * 'CPU state barrier', nothing should get across.
  */
-void __init cpu_init (void)
+void __devinit cpu_init(void)
 {
        int cpu = smp_processor_id();
        struct tss_struct * t = &per_cpu(init_tss, cpu);
@@ -648,3 +651,15 @@ void __init cpu_init (void)
        clear_used_math();
        mxcsr_feature_mask_init();
 }
+
+#ifdef CONFIG_HOTPLUG_CPU
+void __devinit cpu_uninit(void)
+{
+       int cpu = raw_smp_processor_id();
+       cpu_clear(cpu, cpu_initialized);
+
+       /* lazy TLB state */
+       per_cpu(cpu_tlbstate, cpu).state = 0;
+       per_cpu(cpu_tlbstate, cpu).active_mm = &init_mm;
+}
+#endif
index 5c530064eb74bf963a8f43ea4265b96d6042ac65..73a5dc5b26b8403493d099b6b22073561855fa58 100644 (file)
@@ -648,9 +648,7 @@ static int powernow_cpu_exit (struct cpufreq_policy *policy) {
        }
 #endif
 
-       if (powernow_table)
-               kfree(powernow_table);
-
+       kfree(powernow_table);
        return 0;
 }
 
index 121aa2176e694a34f1fd06f23e1d903230b2207a..96a75d0458350c67a4dc1f57d4414a5ffe227790 100644 (file)
@@ -28,7 +28,7 @@ extern int trap_init_f00f_bug(void);
 struct movsl_mask movsl_mask;
 #endif
 
-void __init early_intel_workaround(struct cpuinfo_x86 *c)
+void __devinit early_intel_workaround(struct cpuinfo_x86 *c)
 {
        if (c->x86_vendor != X86_VENDOR_INTEL)
                return;
@@ -43,7 +43,7 @@ void __init early_intel_workaround(struct cpuinfo_x86 *c)
  *     This is called before we do cpu ident work
  */
  
-int __init ppro_with_ram_bug(void)
+int __devinit ppro_with_ram_bug(void)
 {
        /* Uses data from early_cpu_detect now */
        if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL &&
@@ -61,7 +61,7 @@ int __init ppro_with_ram_bug(void)
  * P4 Xeon errata 037 workaround.
  * Hardware prefetcher may cause stale data to be loaded into the cache.
  */
-static void __init Intel_errata_workarounds(struct cpuinfo_x86 *c)
+static void __devinit Intel_errata_workarounds(struct cpuinfo_x86 *c)
 {
        unsigned long lo, hi;
 
@@ -80,7 +80,7 @@ static void __init Intel_errata_workarounds(struct cpuinfo_x86 *c)
 /*
  * find out the number of processor cores on the die
  */
-static int __init num_cpu_cores(struct cpuinfo_x86 *c)
+static int __devinit num_cpu_cores(struct cpuinfo_x86 *c)
 {
        unsigned int eax;
 
@@ -98,7 +98,7 @@ static int __init num_cpu_cores(struct cpuinfo_x86 *c)
                return 1;
 }
 
-static void __init init_intel(struct cpuinfo_x86 *c)
+static void __devinit init_intel(struct cpuinfo_x86 *c)
 {
        unsigned int l2 = 0;
        char *p = NULL;
@@ -204,7 +204,7 @@ static unsigned int intel_size_cache(struct cpuinfo_x86 * c, unsigned int size)
        return size;
 }
 
-static struct cpu_dev intel_cpu_dev __initdata = {
+static struct cpu_dev intel_cpu_dev __devinitdata = {
        .c_vendor       = "Intel",
        .c_ident        = { "GenuineIntel" },
        .c_models = {
index a710dc4eb20e33354cc446f6a74549f0e6a6e895..1d768b263269b0d8b728e57f9675ea1950efb8c6 100644 (file)
@@ -28,7 +28,7 @@ struct _cache_table
 };
 
 /* all the cache descriptor types we care about (no TLB or trace cache entries) */
-static struct _cache_table cache_table[] __initdata =
+static struct _cache_table cache_table[] __devinitdata =
 {
        { 0x06, LVL_1_INST, 8 },        /* 4-way set assoc, 32 byte line size */
        { 0x08, LVL_1_INST, 16 },       /* 4-way set assoc, 32 byte line size */
@@ -160,7 +160,7 @@ static int __init find_num_cache_leaves(void)
        return retval;
 }
 
-unsigned int __init init_intel_cacheinfo(struct cpuinfo_x86 *c)
+unsigned int __devinit init_intel_cacheinfo(struct cpuinfo_x86 *c)
 {
        unsigned int trace = 0, l1i = 0, l1d = 0, l2 = 0, l3 = 0; /* Cache sizes */
        unsigned int new_l1d = 0, new_l1i = 0; /* Cache sizes from cpuid(4) */
index 8df52e86c4d2918bc3b109ff9e4dbf34df6276ef..c4abe76573978fff801b487ebee33f050fd1cb79 100644 (file)
@@ -69,7 +69,7 @@ static fastcall void k7_machine_check(struct pt_regs * regs, long error_code)
 
 
 /* AMD K7 machine check is Intel like */
-void __init amd_mcheck_init(struct cpuinfo_x86 *c)
+void __devinit amd_mcheck_init(struct cpuinfo_x86 *c)
 {
        u32 l, h;
        int i;
index bf6d1aefafc0275f195d980aed1dd659d0cd09dc..2cf25d2ba0f11ee1b4120841e30f5cd9cabe5b98 100644 (file)
@@ -16,7 +16,7 @@
 
 #include "mce.h"
 
-int mce_disabled __initdata = 0;
+int mce_disabled __devinitdata = 0;
 int nr_mce_banks;
 
 EXPORT_SYMBOL_GPL(nr_mce_banks);       /* non-fatal.o */
@@ -31,7 +31,7 @@ static fastcall void unexpected_machine_check(struct pt_regs * regs, long error_
 void fastcall (*machine_check_vector)(struct pt_regs *, long error_code) = unexpected_machine_check;
 
 /* This has to be run for each processor */
-void __init mcheck_init(struct cpuinfo_x86 *c)
+void __devinit mcheck_init(struct cpuinfo_x86 *c)
 {
        if (mce_disabled==1)
                return;
index 8b16ceb929b400ea55ce042ad8154a63617d4976..0abccb6fdf9e1344dff1d79c409bcc97e1e9abf1 100644 (file)
@@ -78,7 +78,7 @@ fastcall void smp_thermal_interrupt(struct pt_regs *regs)
 }
 
 /* P4/Xeon Thermal regulation detect and init */
-static void __init intel_init_thermal(struct cpuinfo_x86 *c)
+static void __devinit intel_init_thermal(struct cpuinfo_x86 *c)
 {
        u32 l, h;
        unsigned int cpu = smp_processor_id();
@@ -232,7 +232,7 @@ static fastcall void intel_machine_check(struct pt_regs * regs, long error_code)
 }
 
 
-void __init intel_p4_mcheck_init(struct cpuinfo_x86 *c)
+void __devinit intel_p4_mcheck_init(struct cpuinfo_x86 *c)
 {
        u32 l, h;
        int i;
index c45a1b485c80df6f4b2855807026b2709918dea9..ec0614cd29250a6d15050781eabec475d439bdef 100644 (file)
@@ -29,7 +29,7 @@ static fastcall void pentium_machine_check(struct pt_regs * regs, long error_cod
 }
 
 /* Set up machine check reporting for processors with Intel style MCE */
-void __init intel_p5_mcheck_init(struct cpuinfo_x86 *c)
+void __devinit intel_p5_mcheck_init(struct cpuinfo_x86 *c)
 {
        u32 l, h;
        
index 46640f8c249415ddf045359c5e989d384b645c40..f01b73f947e1e010f5c3887ffeabb5aee91c5ea4 100644 (file)
@@ -80,7 +80,7 @@ static fastcall void intel_machine_check(struct pt_regs * regs, long error_code)
 }
 
 /* Set up machine check reporting for processors with Intel style MCE */
-void __init intel_p6_mcheck_init(struct cpuinfo_x86 *c)
+void __devinit intel_p6_mcheck_init(struct cpuinfo_x86 *c)
 {
        u32 l, h;
        int i;
index 753fa7acb9840bf3fd4e82933a5374dd3b90ce21..7bae68fa168fcbbe8325362730dfbf82ca9744ed 100644 (file)
@@ -23,7 +23,7 @@ static fastcall void winchip_machine_check(struct pt_regs * regs, long error_cod
 }
 
 /* Set up machine check reporting on the Winchip C6 series */
-void __init winchip_mcheck_init(struct cpuinfo_x86 *c)
+void __devinit winchip_mcheck_init(struct cpuinfo_x86 *c)
 {
        u32 lo, hi;
        machine_check_vector = winchip_machine_check;
index f468a979e9aab7296d120716c89c60016a3d395e..64d91f73a0a46210db764b885de72fe5d65378c9 100644 (file)
@@ -70,8 +70,7 @@ void __init get_mtrr_state(void)
 /*  Free resources associated with a struct mtrr_state  */
 void __init finalize_mtrr_state(void)
 {
-       if (mtrr_state.var_ranges)
-               kfree(mtrr_state.var_ranges);
+       kfree(mtrr_state.var_ranges);
        mtrr_state.var_ranges = NULL;
 }
 
diff --git a/arch/i386/kernel/crash.c b/arch/i386/kernel/crash.c
new file mode 100644 (file)
index 0000000..e5fab12
--- /dev/null
@@ -0,0 +1,223 @@
+/*
+ * Architecture specific (i386) functions for kexec based crash dumps.
+ *
+ * Created by: Hariprasad Nellitheertha (hari@in.ibm.com)
+ *
+ * Copyright (C) IBM Corporation, 2004. All rights reserved.
+ *
+ */
+
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/smp.h>
+#include <linux/irq.h>
+#include <linux/reboot.h>
+#include <linux/kexec.h>
+#include <linux/irq.h>
+#include <linux/delay.h>
+#include <linux/elf.h>
+#include <linux/elfcore.h>
+
+#include <asm/processor.h>
+#include <asm/hardirq.h>
+#include <asm/nmi.h>
+#include <asm/hw_irq.h>
+#include <asm/apic.h>
+#include <mach_ipi.h>
+
+
+note_buf_t crash_notes[NR_CPUS];
+/* This keeps a track of which one is crashing cpu. */
+static int crashing_cpu;
+
+static u32 *append_elf_note(u32 *buf, char *name, unsigned type, void *data,
+                                                              size_t data_len)
+{
+       struct elf_note note;
+
+       note.n_namesz = strlen(name) + 1;
+       note.n_descsz = data_len;
+       note.n_type   = type;
+       memcpy(buf, &note, sizeof(note));
+       buf += (sizeof(note) +3)/4;
+       memcpy(buf, name, note.n_namesz);
+       buf += (note.n_namesz + 3)/4;
+       memcpy(buf, data, note.n_descsz);
+       buf += (note.n_descsz + 3)/4;
+
+       return buf;
+}
+
+static void final_note(u32 *buf)
+{
+       struct elf_note note;
+
+       note.n_namesz = 0;
+       note.n_descsz = 0;
+       note.n_type   = 0;
+       memcpy(buf, &note, sizeof(note));
+}
+
+static void crash_save_this_cpu(struct pt_regs *regs, int cpu)
+{
+       struct elf_prstatus prstatus;
+       u32 *buf;
+
+       if ((cpu < 0) || (cpu >= NR_CPUS))
+               return;
+
+       /* Using ELF notes here is opportunistic.
+        * I need a well defined structure format
+        * for the data I pass, and I need tags
+        * on the data to indicate what information I have
+        * squirrelled away.  ELF notes happen to provide
+        * all of that that no need to invent something new.
+        */
+       buf = &crash_notes[cpu][0];
+       memset(&prstatus, 0, sizeof(prstatus));
+       prstatus.pr_pid = current->pid;
+       elf_core_copy_regs(&prstatus.pr_reg, regs);
+       buf = append_elf_note(buf, "CORE", NT_PRSTATUS, &prstatus,
+                               sizeof(prstatus));
+       final_note(buf);
+}
+
+static void crash_get_current_regs(struct pt_regs *regs)
+{
+       __asm__ __volatile__("movl %%ebx,%0" : "=m"(regs->ebx));
+       __asm__ __volatile__("movl %%ecx,%0" : "=m"(regs->ecx));
+       __asm__ __volatile__("movl %%edx,%0" : "=m"(regs->edx));
+       __asm__ __volatile__("movl %%esi,%0" : "=m"(regs->esi));
+       __asm__ __volatile__("movl %%edi,%0" : "=m"(regs->edi));
+       __asm__ __volatile__("movl %%ebp,%0" : "=m"(regs->ebp));
+       __asm__ __volatile__("movl %%eax,%0" : "=m"(regs->eax));
+       __asm__ __volatile__("movl %%esp,%0" : "=m"(regs->esp));
+       __asm__ __volatile__("movw %%ss, %%ax;" :"=a"(regs->xss));
+       __asm__ __volatile__("movw %%cs, %%ax;" :"=a"(regs->xcs));
+       __asm__ __volatile__("movw %%ds, %%ax;" :"=a"(regs->xds));
+       __asm__ __volatile__("movw %%es, %%ax;" :"=a"(regs->xes));
+       __asm__ __volatile__("pushfl; popl %0" :"=m"(regs->eflags));
+
+       regs->eip = (unsigned long)current_text_addr();
+}
+
+/* CPU does not save ss and esp on stack if execution is already
+ * running in kernel mode at the time of NMI occurrence. This code
+ * fixes it.
+ */
+static void crash_setup_regs(struct pt_regs *newregs, struct pt_regs *oldregs)
+{
+       memcpy(newregs, oldregs, sizeof(*newregs));
+       newregs->esp = (unsigned long)&(oldregs->esp);
+       __asm__ __volatile__("xorl %eax, %eax;");
+       __asm__ __volatile__ ("movw %%ss, %%ax;" :"=a"(newregs->xss));
+}
+
+/* We may have saved_regs from where the error came from
+ * or it is NULL if via a direct panic().
+ */
+static void crash_save_self(struct pt_regs *saved_regs)
+{
+       struct pt_regs regs;
+       int cpu;
+
+       cpu = smp_processor_id();
+       if (saved_regs)
+               crash_setup_regs(&regs, saved_regs);
+       else
+               crash_get_current_regs(&regs);
+       crash_save_this_cpu(&regs, cpu);
+}
+
+#ifdef CONFIG_SMP
+static atomic_t waiting_for_crash_ipi;
+
+static int crash_nmi_callback(struct pt_regs *regs, int cpu)
+{
+       struct pt_regs fixed_regs;
+
+       /* Don't do anything if this handler is invoked on crashing cpu.
+        * Otherwise, system will completely hang. Crashing cpu can get
+        * an NMI if system was initially booted with nmi_watchdog parameter.
+        */
+       if (cpu == crashing_cpu)
+               return 1;
+       local_irq_disable();
+
+       if (!user_mode(regs)) {
+               crash_setup_regs(&fixed_regs, regs);
+               regs = &fixed_regs;
+       }
+       crash_save_this_cpu(regs, cpu);
+       disable_local_APIC();
+       atomic_dec(&waiting_for_crash_ipi);
+       /* Assume hlt works */
+       __asm__("hlt");
+       for(;;);
+
+       return 1;
+}
+
+/*
+ * By using the NMI code instead of a vector we just sneak thru the
+ * word generator coming out with just what we want.  AND it does
+ * not matter if clustered_apic_mode is set or not.
+ */
+static void smp_send_nmi_allbutself(void)
+{
+       send_IPI_allbutself(APIC_DM_NMI);
+}
+
+static void nmi_shootdown_cpus(void)
+{
+       unsigned long msecs;
+
+       atomic_set(&waiting_for_crash_ipi, num_online_cpus() - 1);
+       /* Would it be better to replace the trap vector here? */
+       set_nmi_callback(crash_nmi_callback);
+       /* Ensure the new callback function is set before sending
+        * out the NMI
+        */
+       wmb();
+
+       smp_send_nmi_allbutself();
+
+       msecs = 1000; /* Wait at most a second for the other cpus to stop */
+       while ((atomic_read(&waiting_for_crash_ipi) > 0) && msecs) {
+               mdelay(1);
+               msecs--;
+       }
+
+       /* Leave the nmi callback set */
+       disable_local_APIC();
+}
+#else
+static void nmi_shootdown_cpus(void)
+{
+       /* There are no cpus to shootdown */
+}
+#endif
+
+void machine_crash_shutdown(struct pt_regs *regs)
+{
+       /* This function is only called after the system
+        * has paniced or is otherwise in a critical state.
+        * The minimum amount of code to allow a kexec'd kernel
+        * to run successfully needs to happen here.
+        *
+        * In practice this means shooting down the other cpus in
+        * an SMP system.
+        */
+       /* The kernel is broken so disable interrupts */
+       local_irq_disable();
+
+       /* Make a note of crashing cpu. Will be used in NMI callback.*/
+       crashing_cpu = smp_processor_id();
+       nmi_shootdown_cpus();
+       lapic_shutdown();
+#if defined(CONFIG_X86_IO_APIC)
+       disable_IO_APIC();
+#endif
+       crash_save_self(regs);
+}
index 6ed7e28f306cf2321d72b636f3327051fd0eb754..a3cdf894302b0d5fe48ecfcd1581be41d99c8932 100644 (file)
@@ -1,22 +1,15 @@
 #include <linux/types.h>
-#include <linux/kernel.h>
 #include <linux/string.h>
 #include <linux/init.h>
 #include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/acpi.h>
-#include <asm/io.h>
-#include <linux/pm.h>
-#include <asm/system.h>
 #include <linux/dmi.h>
 #include <linux/bootmem.h>
 
 
-struct dmi_header
-{
-       u8      type;
-       u8      length;
-       u16     handle;
+struct dmi_header {
+       u8 type;
+       u8 length;
+       u16 handle;
 };
 
 #undef DMI_DEBUG
@@ -29,15 +22,13 @@ struct dmi_header
 
 static char * __init dmi_string(struct dmi_header *dm, u8 s)
 {
-       u8 *bp=(u8 *)dm;
-       bp+=dm->length;
-       if(!s)
+       u8 *bp = ((u8 *) dm) + dm->length;
+
+       if (!s)
                return "";
        s--;
-       while(s>0 && *bp)
-       {
-               bp+=strlen(bp);
-               bp++;
+       while (s > 0 && *bp) {
+               bp += strlen(bp) + 1;
                s--;
        }
        return bp;
@@ -47,16 +38,14 @@ static char * __init dmi_string(struct dmi_header *dm, u8 s)
  *     We have to be cautious here. We have seen BIOSes with DMI pointers
  *     pointing to completely the wrong place for example
  */
-static int __init dmi_table(u32 base, int len, int num, void (*decode)(struct dmi_header *))
+static int __init dmi_table(u32 base, int len, int num,
+                           void (*decode)(struct dmi_header *))
 {
-       u8 *buf;
-       struct dmi_header *dm;
-       u8 *data;
-       int i=0;
+       u8 *buf, *data;
+       int i = 0;
                
        buf = bt_ioremap(base, len);
-       if(buf==NULL)
+       if (buf == NULL)
                return -1;
 
        data = buf;
@@ -65,36 +54,34 @@ static int __init dmi_table(u32 base, int len, int num, void (*decode)(struct dm
         *      Stop when we see all the items the table claimed to have
         *      OR we run off the end of the table (also happens)
         */
-       while(i<num && data-buf+sizeof(struct dmi_header)<=len)
-       {
-               dm=(struct dmi_header *)data;
+       while ((i < num) && (data - buf + sizeof(struct dmi_header)) <= len) {
+               struct dmi_header *dm = (struct dmi_header *)data;
                /*
                 *  We want to know the total length (formated area and strings)
                 *  before decoding to make sure we won't run off the table in
                 *  dmi_decode or dmi_string
                 */
-               data+=dm->length;
-               while(data-buf<len-1 && (data[0] || data[1]))
+               data += dm->length;
+               while ((data - buf < len - 1) && (data[0] || data[1]))
                        data++;
-               if(data-buf<len-1)
+               if (data - buf < len - 1)
                        decode(dm);
-               data+=2;
+               data += 2;
                i++;
        }
        bt_iounmap(buf, len);
        return 0;
 }
 
-
-inline static int __init dmi_checksum(u8 *buf)
+static int __init dmi_checksum(u8 *buf)
 {
-       u8 sum=0;
+       u8 sum = 0;
        int a;
        
-       for(a=0; a<15; a++)
-               sum+=buf[a];
-       return (sum==0);
+       for (a = 0; a < 15; a++)
+               sum += buf[a];
+
+       return sum == 0;
 }
 
 static int __init dmi_iterate(void (*decode)(struct dmi_header *))
@@ -110,28 +97,30 @@ static int __init dmi_iterate(void (*decode)(struct dmi_header *))
        p = ioremap(0xF0000, 0x10000);
        if (p == NULL)
                return -1;
+
        for (q = p; q < p + 0x10000; q += 16) {
                memcpy_fromio(buf, q, 15);
-               if(memcmp(buf, "_DMI_", 5)==0 && dmi_checksum(buf))
-               {
-                       u16 num=buf[13]<<8|buf[12];
-                       u16 len=buf[7]<<8|buf[6];
-                       u32 base=buf[11]<<24|buf[10]<<16|buf[9]<<8|buf[8];
+               if ((memcmp(buf, "_DMI_", 5) == 0) && dmi_checksum(buf)) {
+                       u16 num = (buf[13] << 8) | buf[12];
+                       u16 len = (buf[7] << 8) | buf[6];
+                       u32 base = (buf[11] << 24) | (buf[10] << 16) |
+                                  (buf[9] << 8) | buf[8];
 
                        /*
                         * DMI version 0.0 means that the real version is taken from
                         * the SMBIOS version, which we don't know at this point.
                         */
-                       if(buf[14]!=0)
+                       if (buf[14] != 0)
                                printk(KERN_INFO "DMI %d.%d present.\n",
-                                       buf[14]>>4, buf[14]&0x0F);
+                                       buf[14] >> 4, buf[14] & 0xF);
                        else
                                printk(KERN_INFO "DMI present.\n");
+
                        dmi_printk((KERN_INFO "%d structures occupying %d bytes.\n",
                                num, len));
-                       dmi_printk((KERN_INFO "DMI table at 0x%08X.\n",
-                               base));
-                       if(dmi_table(base,len, num, decode)==0)
+                       dmi_printk((KERN_INFO "DMI table at 0x%08X.\n", base));
+
+                       if (dmi_table(base,len, num, decode) == 0)
                                return 0;
                }
        }
@@ -143,298 +132,65 @@ static char *dmi_ident[DMI_STRING_MAX];
 /*
  *     Save a DMI string
  */
 static void __init dmi_save_ident(struct dmi_header *dm, int slot, int string)
 {
        char *d = (char*)dm;
        char *p = dmi_string(dm, d[string]);
-       if(p==NULL || *p == 0)
+
+       if (p == NULL || *p == 0)
                return;
        if (dmi_ident[slot])
                return;
-       dmi_ident[slot] = alloc_bootmem(strlen(p)+1);
+
+       dmi_ident[slot] = alloc_bootmem(strlen(p) + 1);
        if(dmi_ident[slot])
                strcpy(dmi_ident[slot], p);
        else
                printk(KERN_ERR "dmi_save_ident: out of memory.\n");
 }
 
-/*
- * Ugly compatibility crap.
- */
-#define dmi_blacklist  dmi_system_id
-#define NO_MATCH       { DMI_NONE, NULL}
-#define MATCH          DMI_MATCH
-
-/*
- * Toshiba keyboard likes to repeat keys when they are not repeated.
- */
-
-static __init int broken_toshiba_keyboard(struct dmi_blacklist *d)
-{
-       printk(KERN_WARNING "Toshiba with broken keyboard detected. If your keyboard sometimes generates 3 keypresses instead of one, see http://davyd.ucc.asn.au/projects/toshiba/README\n");
-       return 0;
-}
-
-
-#ifdef CONFIG_ACPI_SLEEP
-static __init int reset_videomode_after_s3(struct dmi_blacklist *d)
-{
-       /* See acpi_wakeup.S */
-       extern long acpi_video_flags;
-       acpi_video_flags |= 2;
-       return 0;
-}
-#endif
-
-
-#ifdef CONFIG_ACPI_BOOT
-extern int acpi_force;
-
-static __init __attribute__((unused)) int dmi_disable_acpi(struct dmi_blacklist *d) 
-{ 
-       if (!acpi_force) { 
-               printk(KERN_NOTICE "%s detected: acpi off\n",d->ident); 
-               disable_acpi();
-       } else { 
-               printk(KERN_NOTICE 
-                      "Warning: DMI blacklist says broken, but acpi forced\n"); 
-       }
-       return 0;
-} 
-
-/*
- * Limit ACPI to CPU enumeration for HT
- */
-static __init __attribute__((unused)) int force_acpi_ht(struct dmi_blacklist *d) 
-{ 
-       if (!acpi_force) { 
-               printk(KERN_NOTICE "%s detected: force use of acpi=ht\n", d->ident); 
-               disable_acpi();
-               acpi_ht = 1; 
-       } else { 
-               printk(KERN_NOTICE 
-                      "Warning: acpi=force overrules DMI blacklist: acpi=ht\n"); 
-       }
-       return 0;
-} 
-#endif
-
-#ifdef CONFIG_ACPI_PCI
-static __init int disable_acpi_irq(struct dmi_blacklist *d) 
-{
-       if (!acpi_force) {
-               printk(KERN_NOTICE "%s detected: force use of acpi=noirq\n",
-                      d->ident);       
-               acpi_noirq_set();
-       }
-       return 0;
-}
-static __init int disable_acpi_pci(struct dmi_blacklist *d) 
-{
-       if (!acpi_force) {
-               printk(KERN_NOTICE "%s detected: force use of pci=noacpi\n",
-                      d->ident);       
-               acpi_disable_pci();
-       }
-       return 0;
-}  
-#endif
-
-/*
- *     Process the DMI blacklists
- */
-
-/*
- *     This will be expanded over time to force things like the APM 
- *     interrupt mask settings according to the laptop
- */
-static __initdata struct dmi_blacklist dmi_blacklist[]={
-
-       { broken_toshiba_keyboard, "Toshiba Satellite 4030cdt", { /* Keyboard generates spurious repeats */
-                       MATCH(DMI_PRODUCT_NAME, "S4030CDT/4.3"),
-                       NO_MATCH, NO_MATCH, NO_MATCH
-                       } },
-#ifdef CONFIG_ACPI_SLEEP
-       { reset_videomode_after_s3, "Toshiba Satellite 4030cdt", { /* Reset video mode after returning from ACPI S3 sleep */
-                       MATCH(DMI_PRODUCT_NAME, "S4030CDT/4.3"),
-                       NO_MATCH, NO_MATCH, NO_MATCH
-                       } },
-#endif
-
-#ifdef CONFIG_ACPI_BOOT
-       /*
-        * If your system is blacklisted here, but you find that acpi=force
-        * works for you, please contact acpi-devel@sourceforge.net
-        */
-
-       /*
-        *      Boxes that need ACPI disabled
-        */
-
-       { dmi_disable_acpi, "IBM Thinkpad", {
-                       MATCH(DMI_BOARD_VENDOR, "IBM"),
-                       MATCH(DMI_BOARD_NAME, "2629H1G"),
-                       NO_MATCH, NO_MATCH }},
-
-       /*
-        *      Boxes that need acpi=ht 
-        */
-
-       { force_acpi_ht, "FSC Primergy T850", {
-                       MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
-                       MATCH(DMI_PRODUCT_NAME, "PRIMERGY T850"),
-                       NO_MATCH, NO_MATCH }},
-
-       { force_acpi_ht, "DELL GX240", {
-                       MATCH(DMI_BOARD_VENDOR, "Dell Computer Corporation"),
-                       MATCH(DMI_BOARD_NAME, "OptiPlex GX240"),
-                       NO_MATCH, NO_MATCH }},
-
-       { force_acpi_ht, "HP VISUALIZE NT Workstation", {
-                       MATCH(DMI_BOARD_VENDOR, "Hewlett-Packard"),
-                       MATCH(DMI_PRODUCT_NAME, "HP VISUALIZE NT Workstation"),
-                       NO_MATCH, NO_MATCH }},
-
-       { force_acpi_ht, "Compaq Workstation W8000", {
-                       MATCH(DMI_SYS_VENDOR, "Compaq"),
-                       MATCH(DMI_PRODUCT_NAME, "Workstation W8000"),
-                       NO_MATCH, NO_MATCH }},
-
-       { force_acpi_ht, "ASUS P4B266", {
-                       MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
-                       MATCH(DMI_BOARD_NAME, "P4B266"),
-                       NO_MATCH, NO_MATCH }},
-
-       { force_acpi_ht, "ASUS P2B-DS", {
-                       MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
-                       MATCH(DMI_BOARD_NAME, "P2B-DS"),
-                       NO_MATCH, NO_MATCH }},
-
-       { force_acpi_ht, "ASUS CUR-DLS", {
-                       MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
-                       MATCH(DMI_BOARD_NAME, "CUR-DLS"),
-                       NO_MATCH, NO_MATCH }},
-
-       { force_acpi_ht, "ABIT i440BX-W83977", {
-                       MATCH(DMI_BOARD_VENDOR, "ABIT <http://www.abit.com>"),
-                       MATCH(DMI_BOARD_NAME, "i440BX-W83977 (BP6)"),
-                       NO_MATCH, NO_MATCH }},
-
-       { force_acpi_ht, "IBM Bladecenter", {
-                       MATCH(DMI_BOARD_VENDOR, "IBM"),
-                       MATCH(DMI_BOARD_NAME, "IBM eServer BladeCenter HS20"),
-                       NO_MATCH, NO_MATCH }},
-
-       { force_acpi_ht, "IBM eServer xSeries 360", {
-                       MATCH(DMI_BOARD_VENDOR, "IBM"),
-                       MATCH(DMI_BOARD_NAME, "eServer xSeries 360"),
-                       NO_MATCH, NO_MATCH }},
-
-       { force_acpi_ht, "IBM eserver xSeries 330", {
-                       MATCH(DMI_BOARD_VENDOR, "IBM"),
-                       MATCH(DMI_BOARD_NAME, "eserver xSeries 330"),
-                       NO_MATCH, NO_MATCH }},
-
-       { force_acpi_ht, "IBM eserver xSeries 440", {
-                       MATCH(DMI_BOARD_VENDOR, "IBM"),
-                       MATCH(DMI_PRODUCT_NAME, "eserver xSeries 440"),
-                       NO_MATCH, NO_MATCH }},
-
-#endif // CONFIG_ACPI_BOOT
-
-#ifdef CONFIG_ACPI_PCI
-       /*
-        *      Boxes that need ACPI PCI IRQ routing disabled
-        */
-
-       { disable_acpi_irq, "ASUS A7V", {
-                       MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC"),
-                       MATCH(DMI_BOARD_NAME, "<A7V>"),
-                       /* newer BIOS, Revision 1011, does work */
-                       MATCH(DMI_BIOS_VERSION, "ASUS A7V ACPI BIOS Revision 1007"),
-                       NO_MATCH }},
-
-       /*
-        *      Boxes that need ACPI PCI IRQ routing and PCI scan disabled
-        */
-       { disable_acpi_pci, "ASUS PR-DLS", {    /* _BBN 0 bug */
-                       MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
-                       MATCH(DMI_BOARD_NAME, "PR-DLS"),
-                       MATCH(DMI_BIOS_VERSION, "ASUS PR-DLS ACPI BIOS Revision 1010"),
-                       MATCH(DMI_BIOS_DATE, "03/21/2003") }},
-
-       { disable_acpi_pci, "Acer TravelMate 36x Laptop", {
-                       MATCH(DMI_SYS_VENDOR, "Acer"),
-                       MATCH(DMI_PRODUCT_NAME, "TravelMate 360"),
-                       NO_MATCH, NO_MATCH
-                       } },
-
-#endif
-
-       { NULL, }
-};
-
 /*
  *     Process a DMI table entry. Right now all we care about are the BIOS
  *     and machine entries. For 2.5 we should pull the smbus controller info
  *     out of here.
  */
-
 static void __init dmi_decode(struct dmi_header *dm)
 {
-#ifdef DMI_DEBUG
-       u8 *data = (u8 *)dm;
-#endif
+       u8 *data __attribute__((__unused__)) = (u8 *)dm;
        
-       switch(dm->type)
-       {
-               case  0:
-                       dmi_printk(("BIOS Vendor: %s\n",
-                               dmi_string(dm, data[4])));
-                       dmi_save_ident(dm, DMI_BIOS_VENDOR, 4);
-                       dmi_printk(("BIOS Version: %s\n", 
-                               dmi_string(dm, data[5])));
-                       dmi_save_ident(dm, DMI_BIOS_VERSION, 5);
-                       dmi_printk(("BIOS Release: %s\n",
-                               dmi_string(dm, data[8])));
-                       dmi_save_ident(dm, DMI_BIOS_DATE, 8);
-                       break;
-               case 1:
-                       dmi_printk(("System Vendor: %s\n",
-                               dmi_string(dm, data[4])));
-                       dmi_save_ident(dm, DMI_SYS_VENDOR, 4);
-                       dmi_printk(("Product Name: %s\n",
-                               dmi_string(dm, data[5])));
-                       dmi_save_ident(dm, DMI_PRODUCT_NAME, 5);
-                       dmi_printk(("Version: %s\n",
-                               dmi_string(dm, data[6])));
-                       dmi_save_ident(dm, DMI_PRODUCT_VERSION, 6);
-                       dmi_printk(("Serial Number: %s\n",
-                               dmi_string(dm, data[7])));
-                       break;
-               case 2:
-                       dmi_printk(("Board Vendor: %s\n",
-                               dmi_string(dm, data[4])));
-                       dmi_save_ident(dm, DMI_BOARD_VENDOR, 4);
-                       dmi_printk(("Board Name: %s\n",
-                               dmi_string(dm, data[5])));
-                       dmi_save_ident(dm, DMI_BOARD_NAME, 5);
-                       dmi_printk(("Board Version: %s\n",
-                               dmi_string(dm, data[6])));
-                       dmi_save_ident(dm, DMI_BOARD_VERSION, 6);
-                       break;
+       switch(dm->type) {
+       case  0:
+               dmi_printk(("BIOS Vendor: %s\n", dmi_string(dm, data[4])));
+               dmi_save_ident(dm, DMI_BIOS_VENDOR, 4);
+               dmi_printk(("BIOS Version: %s\n", dmi_string(dm, data[5])));
+               dmi_save_ident(dm, DMI_BIOS_VERSION, 5);
+               dmi_printk(("BIOS Release: %s\n", dmi_string(dm, data[8])));
+               dmi_save_ident(dm, DMI_BIOS_DATE, 8);
+               break;
+       case 1:
+               dmi_printk(("System Vendor: %s\n", dmi_string(dm, data[4])));
+               dmi_save_ident(dm, DMI_SYS_VENDOR, 4);
+               dmi_printk(("Product Name: %s\n", dmi_string(dm, data[5])));
+               dmi_save_ident(dm, DMI_PRODUCT_NAME, 5);
+               dmi_printk(("Version: %s\n", dmi_string(dm, data[6])));
+               dmi_save_ident(dm, DMI_PRODUCT_VERSION, 6);
+               dmi_printk(("Serial Number: %s\n", dmi_string(dm, data[7])));
+               dmi_save_ident(dm, DMI_PRODUCT_SERIAL, 7);
+               break;
+       case 2:
+               dmi_printk(("Board Vendor: %s\n", dmi_string(dm, data[4])));
+               dmi_save_ident(dm, DMI_BOARD_VENDOR, 4);
+               dmi_printk(("Board Name: %s\n", dmi_string(dm, data[5])));
+               dmi_save_ident(dm, DMI_BOARD_NAME, 5);
+               dmi_printk(("Board Version: %s\n", dmi_string(dm, data[6])));
+               dmi_save_ident(dm, DMI_BOARD_VERSION, 6);
+               break;
        }
 }
 
 void __init dmi_scan_machine(void)
 {
-       int err = dmi_iterate(dmi_decode);
-       if(err == 0)
-               dmi_check_system(dmi_blacklist);
-       else
+       if (dmi_iterate(dmi_decode))
                printk(KERN_INFO "DMI not present.\n");
 }
 
@@ -470,7 +226,6 @@ fail:               d++;
 
        return count;
 }
-
 EXPORT_SYMBOL(dmi_check_system);
 
 /**
@@ -480,8 +235,8 @@ EXPORT_SYMBOL(dmi_check_system);
  *     Returns one DMI data value, can be used to perform
  *     complex DMI data checks.
  */
-char * dmi_get_system_info(int field)
+char *dmi_get_system_info(int field)
 {
        return dmi_ident[field];
 }
-
+EXPORT_SYMBOL(dmi_get_system_info);
index f732f427b418a02672409e8168f7701f032873bc..385883ea8c199d1008d0db050e1c71ec32ce64ec 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/ioport.h>
 #include <linux/module.h>
 #include <linux/efi.h>
+#include <linux/kexec.h>
 
 #include <asm/setup.h>
 #include <asm/io.h>
@@ -598,6 +599,9 @@ efi_initialize_iomem_resources(struct resource *code_resource,
                if (md->type == EFI_CONVENTIONAL_MEMORY) {
                        request_resource(res, code_resource);
                        request_resource(res, data_resource);
+#ifdef CONFIG_KEXEC
+                       request_resource(res, &crashk_res);
+#endif
                }
        }
 }
index e966fc8c44c49711f0fecbbc03cc183656aa6b40..4477bb107098c2863ee85a0ef8a27374147ca494 100644 (file)
@@ -299,7 +299,6 @@ is386:      movl $2,%ecx            # set MP
        movl %eax,%cr0
 
        call check_x87
-       incb ready
        lgdt cpu_gdt_descr
        lidt idt_descr
        ljmp $(__KERNEL_CS),$1f
@@ -316,8 +315,9 @@ is386:      movl $2,%ecx            # set MP
        lldt %ax
        cld                     # gcc2 wants the direction flag cleared at all times
 #ifdef CONFIG_SMP
-       movb ready, %cl 
-       cmpb $1,%cl
+       movb ready, %cl
+       movb $1, ready
+       cmpb $0,%cl
        je 1f                   # the first CPU calls start_kernel
                                # all other CPUs call initialize_secondary
        call initialize_secondary
index 2c4813b47e57a5603e7bec605129b8890d68c3de..178f4e9bac9d14c84a5046b6c967982000120f73 100644 (file)
@@ -268,10 +268,22 @@ static int i8259A_suspend(struct sys_device *dev, pm_message_t state)
        return 0;
 }
 
+static int i8259A_shutdown(struct sys_device *dev)
+{
+       /* Put the i8259A into a quiescent state that
+        * the kernel initialization code can get it
+        * out of.
+        */
+       outb(0xff, 0x21);       /* mask all of 8259A-1 */
+       outb(0xff, 0xA1);       /* mask all of 8259A-1 */
+       return 0;
+}
+
 static struct sysdev_class i8259_sysdev_class = {
        set_kset_name("i8259"),
        .suspend = i8259A_suspend,
        .resume = i8259A_resume,
+       .shutdown = i8259A_shutdown,
 };
 
 static struct sys_device device_i8259A = {
index 08540bc4ba3e19494a51f7424dddc3753726f9e9..35eb8e29c485a05c6d5c6a17e8712f5ded763711 100644 (file)
@@ -573,12 +573,14 @@ static int balanced_irq(void *unused)
        for ( ; ; ) {
                set_current_state(TASK_INTERRUPTIBLE);
                time_remaining = schedule_timeout(time_remaining);
-               try_to_freeze(PF_FREEZE);
+               try_to_freeze();
                if (time_after(jiffies,
                                prev_balance_time+balanced_irq_interval)) {
+                       preempt_disable();
                        do_irq_balance();
                        prev_balance_time = jiffies;
                        time_remaining = balanced_irq_interval;
+                       preempt_enable();
                }
        }
        return 0;
@@ -630,10 +632,8 @@ static int __init balanced_irq_init(void)
                printk(KERN_ERR "balanced_irq_init: failed to spawn balanced_irq");
 failed:
        for (i = 0; i < NR_CPUS; i++) {
-               if(irq_cpu_data[i].irq_delta)
-                       kfree(irq_cpu_data[i].irq_delta);
-               if(irq_cpu_data[i].last_irq)
-                       kfree(irq_cpu_data[i].last_irq);
+               kfree(irq_cpu_data[i].irq_delta);
+               kfree(irq_cpu_data[i].last_irq);
        }
        return 0;
 }
@@ -1634,12 +1634,43 @@ static void __init enable_IO_APIC(void)
  */
 void disable_IO_APIC(void)
 {
+       int pin;
        /*
         * Clear the IO-APIC before rebooting:
         */
        clear_IO_APIC();
 
-       disconnect_bsp_APIC();
+       /*
+        * If the i82559 is routed through an IOAPIC
+        * Put that IOAPIC in virtual wire mode
+        * so legacy interrups can be delivered.
+        */
+       pin = find_isa_irq_pin(0, mp_ExtINT);
+       if (pin != -1) {
+               struct IO_APIC_route_entry entry;
+               unsigned long flags;
+
+               memset(&entry, 0, sizeof(entry));
+               entry.mask            = 0; /* Enabled */
+               entry.trigger         = 0; /* Edge */
+               entry.irr             = 0;
+               entry.polarity        = 0; /* High */
+               entry.delivery_status = 0;
+               entry.dest_mode       = 0; /* Physical */
+               entry.delivery_mode   = 7; /* ExtInt */
+               entry.vector          = 0;
+               entry.dest.physical.physical_dest = 0;
+
+
+               /*
+                * Add it to the IO-APIC irq-routing table:
+                */
+               spin_lock_irqsave(&ioapic_lock, flags);
+               io_apic_write(0, 0x11+2*pin, *(((int *)&entry)+1));
+               io_apic_write(0, 0x10+2*pin, *(((int *)&entry)+0));
+               spin_unlock_irqrestore(&ioapic_lock, flags);
+       }
+       disconnect_bsp_APIC(pin != -1);
 }
 
 /*
index 73945a3c53c4c5559e2a1935f69cda24d20e6b18..ce66dcc26d9072cf14bea63c83ae1db8ddde1934 100644 (file)
@@ -15,6 +15,9 @@
 #include <linux/seq_file.h>
 #include <linux/interrupt.h>
 #include <linux/kernel_stat.h>
+#include <linux/notifier.h>
+#include <linux/cpu.h>
+#include <linux/delay.h>
 
 DEFINE_PER_CPU(irq_cpustat_t, irq_stat) ____cacheline_maxaligned_in_smp;
 EXPORT_PER_CPU_SYMBOL(irq_stat);
@@ -153,6 +156,11 @@ void irq_ctx_init(int cpu)
                cpu,hardirq_ctx[cpu],softirq_ctx[cpu]);
 }
 
+void irq_ctx_exit(int cpu)
+{
+       hardirq_ctx[cpu] = NULL;
+}
+
 extern asmlinkage void __do_softirq(void);
 
 asmlinkage void do_softirq(void)
@@ -210,9 +218,8 @@ int show_interrupts(struct seq_file *p, void *v)
 
        if (i == 0) {
                seq_printf(p, "           ");
-               for (j=0; j<NR_CPUS; j++)
-                       if (cpu_online(j))
-                               seq_printf(p, "CPU%d       ",j);
+               for_each_cpu(j)
+                       seq_printf(p, "CPU%d       ",j);
                seq_putc(p, '\n');
        }
 
@@ -225,9 +232,8 @@ int show_interrupts(struct seq_file *p, void *v)
 #ifndef CONFIG_SMP
                seq_printf(p, "%10u ", kstat_irqs(i));
 #else
-               for (j = 0; j < NR_CPUS; j++)
-                       if (cpu_online(j))
-                               seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]);
+               for_each_cpu(j)
+                       seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]);
 #endif
                seq_printf(p, " %14s", irq_desc[i].handler->typename);
                seq_printf(p, "  %s", action->name);
@@ -240,16 +246,14 @@ skip:
                spin_unlock_irqrestore(&irq_desc[i].lock, flags);
        } else if (i == NR_IRQS) {
                seq_printf(p, "NMI: ");
-               for (j = 0; j < NR_CPUS; j++)
-                       if (cpu_online(j))
-                               seq_printf(p, "%10u ", nmi_count(j));
+               for_each_cpu(j)
+                       seq_printf(p, "%10u ", nmi_count(j));
                seq_putc(p, '\n');
 #ifdef CONFIG_X86_LOCAL_APIC
                seq_printf(p, "LOC: ");
-               for (j = 0; j < NR_CPUS; j++)
-                       if (cpu_online(j))
-                               seq_printf(p, "%10u ",
-                                       per_cpu(irq_stat,j).apic_timer_irqs);
+               for_each_cpu(j)
+                       seq_printf(p, "%10u ",
+                               per_cpu(irq_stat,j).apic_timer_irqs);
                seq_putc(p, '\n');
 #endif
                seq_printf(p, "ERR: %10u\n", atomic_read(&irq_err_count));
@@ -259,3 +263,45 @@ skip:
        }
        return 0;
 }
+
+#ifdef CONFIG_HOTPLUG_CPU
+#include <mach_apic.h>
+
+void fixup_irqs(cpumask_t map)
+{
+       unsigned int irq;
+       static int warned;
+
+       for (irq = 0; irq < NR_IRQS; irq++) {
+               cpumask_t mask;
+               if (irq == 2)
+                       continue;
+
+               cpus_and(mask, irq_affinity[irq], map);
+               if (any_online_cpu(mask) == NR_CPUS) {
+                       printk("Breaking affinity for irq %i\n", irq);
+                       mask = map;
+               }
+               if (irq_desc[irq].handler->set_affinity)
+                       irq_desc[irq].handler->set_affinity(irq, mask);
+               else if (irq_desc[irq].action && !(warned++))
+                       printk("Cannot set affinity for irq %i\n", irq);
+       }
+
+#if 0
+       barrier();
+       /* Ingo Molnar says: "after the IO-APIC masks have been redirected
+          [note the nop - the interrupt-enable boundary on x86 is two
+          instructions from sti] - to flush out pending hardirqs and
+          IPIs. After this point nothing is supposed to reach this CPU." */
+       __asm__ __volatile__("sti; nop; cli");
+       barrier();
+#else
+       /* That doesn't seem sufficient.  Give it 1ms. */
+       local_irq_enable();
+       mdelay(1);
+       local_irq_disable();
+#endif
+}
+#endif
+
diff --git a/arch/i386/kernel/machine_kexec.c b/arch/i386/kernel/machine_kexec.c
new file mode 100644 (file)
index 0000000..52ed18d
--- /dev/null
@@ -0,0 +1,226 @@
+/*
+ * machine_kexec.c - handle transition of Linux booting another kernel
+ * Copyright (C) 2002-2005 Eric Biederman  <ebiederm@xmission.com>
+ *
+ * This source code is licensed under the GNU General Public License,
+ * Version 2.  See the file COPYING for more details.
+ */
+
+#include <linux/mm.h>
+#include <linux/kexec.h>
+#include <linux/delay.h>
+#include <asm/pgtable.h>
+#include <asm/pgalloc.h>
+#include <asm/tlbflush.h>
+#include <asm/mmu_context.h>
+#include <asm/io.h>
+#include <asm/apic.h>
+#include <asm/cpufeature.h>
+
+static inline unsigned long read_cr3(void)
+{
+       unsigned long cr3;
+       asm volatile("movl %%cr3,%0": "=r"(cr3));
+       return cr3;
+}
+
+#define PAGE_ALIGNED __attribute__ ((__aligned__(PAGE_SIZE)))
+
+#define L0_ATTR (_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED | _PAGE_DIRTY)
+#define L1_ATTR (_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED | _PAGE_DIRTY)
+#define L2_ATTR (_PAGE_PRESENT)
+
+#define LEVEL0_SIZE (1UL << 12UL)
+
+#ifndef CONFIG_X86_PAE
+#define LEVEL1_SIZE (1UL << 22UL)
+static u32 pgtable_level1[1024] PAGE_ALIGNED;
+
+static void identity_map_page(unsigned long address)
+{
+       unsigned long level1_index, level2_index;
+       u32 *pgtable_level2;
+
+       /* Find the current page table */
+       pgtable_level2 = __va(read_cr3());
+
+       /* Find the indexes of the physical address to identity map */
+       level1_index = (address % LEVEL1_SIZE)/LEVEL0_SIZE;
+       level2_index = address / LEVEL1_SIZE;
+
+       /* Identity map the page table entry */
+       pgtable_level1[level1_index] = address | L0_ATTR;
+       pgtable_level2[level2_index] = __pa(pgtable_level1) | L1_ATTR;
+
+       /* Flush the tlb so the new mapping takes effect.
+        * Global tlb entries are not flushed but that is not an issue.
+        */
+       load_cr3(pgtable_level2);
+}
+
+#else
+#define LEVEL1_SIZE (1UL << 21UL)
+#define LEVEL2_SIZE (1UL << 30UL)
+static u64 pgtable_level1[512] PAGE_ALIGNED;
+static u64 pgtable_level2[512] PAGE_ALIGNED;
+
+static void identity_map_page(unsigned long address)
+{
+       unsigned long level1_index, level2_index, level3_index;
+       u64 *pgtable_level3;
+
+       /* Find the current page table */
+       pgtable_level3 = __va(read_cr3());
+
+       /* Find the indexes of the physical address to identity map */
+       level1_index = (address % LEVEL1_SIZE)/LEVEL0_SIZE;
+       level2_index = (address % LEVEL2_SIZE)/LEVEL1_SIZE;
+       level3_index = address / LEVEL2_SIZE;
+
+       /* Identity map the page table entry */
+       pgtable_level1[level1_index] = address | L0_ATTR;
+       pgtable_level2[level2_index] = __pa(pgtable_level1) | L1_ATTR;
+       set_64bit(&pgtable_level3[level3_index],
+                                              __pa(pgtable_level2) | L2_ATTR);
+
+       /* Flush the tlb so the new mapping takes effect.
+        * Global tlb entries are not flushed but that is not an issue.
+        */
+       load_cr3(pgtable_level3);
+}
+#endif
+
+
+static void set_idt(void *newidt, __u16 limit)
+{
+       unsigned char curidt[6];
+
+       /* ia32 supports unaliged loads & stores */
+       (*(__u16 *)(curidt)) = limit;
+       (*(__u32 *)(curidt +2)) = (unsigned long)(newidt);
+
+       __asm__ __volatile__ (
+               "lidt %0\n"
+               : "=m" (curidt)
+               );
+};
+
+
+static void set_gdt(void *newgdt, __u16 limit)
+{
+       unsigned char curgdt[6];
+
+       /* ia32 supports unaligned loads & stores */
+       (*(__u16 *)(curgdt)) = limit;
+       (*(__u32 *)(curgdt +2)) = (unsigned long)(newgdt);
+
+       __asm__ __volatile__ (
+               "lgdt %0\n"
+               : "=m" (curgdt)
+               );
+};
+
+static void load_segments(void)
+{
+#define __STR(X) #X
+#define STR(X) __STR(X)
+
+       __asm__ __volatile__ (
+               "\tljmp $"STR(__KERNEL_CS)",$1f\n"
+               "\t1:\n"
+               "\tmovl $"STR(__KERNEL_DS)",%eax\n"
+               "\tmovl %eax,%ds\n"
+               "\tmovl %eax,%es\n"
+               "\tmovl %eax,%fs\n"
+               "\tmovl %eax,%gs\n"
+               "\tmovl %eax,%ss\n"
+               );
+#undef STR
+#undef __STR
+}
+
+typedef asmlinkage NORET_TYPE void (*relocate_new_kernel_t)(
+                                       unsigned long indirection_page,
+                                       unsigned long reboot_code_buffer,
+                                       unsigned long start_address,
+                                       unsigned int has_pae) ATTRIB_NORET;
+
+const extern unsigned char relocate_new_kernel[];
+extern void relocate_new_kernel_end(void);
+const extern unsigned int relocate_new_kernel_size;
+
+/*
+ * A architecture hook called to validate the
+ * proposed image and prepare the control pages
+ * as needed.  The pages for KEXEC_CONTROL_CODE_SIZE
+ * have been allocated, but the segments have yet
+ * been copied into the kernel.
+ *
+ * Do what every setup is needed on image and the
+ * reboot code buffer to allow us to avoid allocations
+ * later.
+ *
+ * Currently nothing.
+ */
+int machine_kexec_prepare(struct kimage *image)
+{
+       return 0;
+}
+
+/*
+ * Undo anything leftover by machine_kexec_prepare
+ * when an image is freed.
+ */
+void machine_kexec_cleanup(struct kimage *image)
+{
+}
+
+/*
+ * Do not allocate memory (or fail in any way) in machine_kexec().
+ * We are past the point of no return, committed to rebooting now.
+ */
+NORET_TYPE void machine_kexec(struct kimage *image)
+{
+       unsigned long page_list;
+       unsigned long reboot_code_buffer;
+
+       relocate_new_kernel_t rnk;
+
+       /* Interrupts aren't acceptable while we reboot */
+       local_irq_disable();
+
+       /* Compute some offsets */
+       reboot_code_buffer = page_to_pfn(image->control_code_page)
+                                                               << PAGE_SHIFT;
+       page_list = image->head;
+
+       /* Set up an identity mapping for the reboot_code_buffer */
+       identity_map_page(reboot_code_buffer);
+
+       /* copy it out */
+       memcpy((void *)reboot_code_buffer, relocate_new_kernel,
+                                               relocate_new_kernel_size);
+
+       /* The segment registers are funny things, they are
+        * automatically loaded from a table, in memory wherever you
+        * set them to a specific selector, but this table is never
+        * accessed again you set the segment to a different selector.
+        *
+        * The more common model is are caches where the behide
+        * the scenes work is done, but is also dropped at arbitrary
+        * times.
+        *
+        * I take advantage of this here by force loading the
+        * segments, before I zap the gdt with an invalid value.
+        */
+       load_segments();
+       /* The gdt & idt are now invalid.
+        * If you want to load them you must set up your own idt & gdt.
+        */
+       set_gdt(phys_to_virt(0),0);
+       set_idt(phys_to_virt(0),0);
+
+       /* now call it */
+       rnk = (relocate_new_kernel_t) reboot_code_buffer;
+       (*rnk)(page_list, reboot_code_buffer, image->start, cpu_has_pae);
+}
index 383a11600d2c35d4e940d5a3e8bb647accb45f6a..af917f609c7de00b3b959c28439aa48ebce09488 100644 (file)
@@ -67,7 +67,6 @@ unsigned long mp_lapic_addr;
 
 /* Processor that is doing the boot up */
 unsigned int boot_cpu_physical_apicid = -1U;
-unsigned int boot_cpu_logical_apicid = -1U;
 /* Internal processor count */
 static unsigned int __initdata num_processors;
 
@@ -180,7 +179,6 @@ static void __init MP_processor_info (struct mpc_config_processor *m)
        if (m->mpc_cpuflag & CPU_BOOTPROCESSOR) {
                Dprintk("    Bootup CPU\n");
                boot_cpu_physical_apicid = m->mpc_apicid;
-               boot_cpu_logical_apicid = apicid;
        }
 
        if (num_processors >= NR_CPUS) {
index aea2ce1145df7327161acdf42230c1559fa27323..5f8cfa6b794085b9fb224e229398369bc0f4c64a 100644 (file)
@@ -13,6 +13,7 @@
 
 #include <stdarg.h>
 
+#include <linux/cpu.h>
 #include <linux/errno.h>
 #include <linux/sched.h>
 #include <linux/fs.h>
@@ -55,6 +56,9 @@
 #include <linux/irq.h>
 #include <linux/err.h>
 
+#include <asm/tlbflush.h>
+#include <asm/cpu.h>
+
 asmlinkage void ret_from_fork(void) __asm__("ret_from_fork");
 
 static int hlt_counter;
@@ -143,14 +147,42 @@ static void poll_idle (void)
        }
 }
 
+#ifdef CONFIG_HOTPLUG_CPU
+#include <asm/nmi.h>
+/* We don't actually take CPU down, just spin without interrupts. */
+static inline void play_dead(void)
+{
+       /* This must be done before dead CPU ack */
+       cpu_exit_clear();
+       wbinvd();
+       mb();
+       /* Ack it */
+       __get_cpu_var(cpu_state) = CPU_DEAD;
+
+       /*
+        * With physical CPU hotplug, we should halt the cpu
+        */
+       local_irq_disable();
+       while (1)
+               __asm__ __volatile__("hlt":::"memory");
+}
+#else
+static inline void play_dead(void)
+{
+       BUG();
+}
+#endif /* CONFIG_HOTPLUG_CPU */
+
 /*
  * The idle thread. There's no useful work to be
  * done, so just try to conserve power and have a
  * low exit latency (ie sit in a loop waiting for
  * somebody to say that they'd like to reschedule)
  */
-void cpu_idle (void)
+void cpu_idle(void)
 {
+       int cpu = raw_smp_processor_id();
+
        /* endless idle loop with no priority at all */
        while (1) {
                while (!need_resched()) {
@@ -165,6 +197,9 @@ void cpu_idle (void)
                        if (!idle)
                                idle = default_idle;
 
+                       if (cpu_is_offline(cpu))
+                               play_dead();
+
                        __get_cpu_var(irq_stat).idle_timestamp = jiffies;
                        idle();
                }
@@ -223,7 +258,7 @@ static void mwait_idle(void)
        }
 }
 
-void __init select_idle_routine(const struct cpuinfo_x86 *c)
+void __devinit select_idle_routine(const struct cpuinfo_x86 *c)
 {
        if (cpu_has(c, X86_FEATURE_MWAIT)) {
                printk("monitor/mwait feature present.\n");
index db912209a8d312d5ebec4b6c155399b764d3cf82..b3e584849961e79872a92b6518ab15c47071e797 100644 (file)
@@ -26,7 +26,6 @@ static int reboot_mode;
 static int reboot_thru_bios;
 
 #ifdef CONFIG_SMP
-int reboot_smp = 0;
 static int reboot_cpu = -1;
 /* shamelessly grabbed from lib/vsprintf.c for readability */
 #define is_digit(c)    ((c) >= '0' && (c) <= '9')
@@ -49,7 +48,6 @@ static int __init reboot_setup(char *str)
                        break;
 #ifdef CONFIG_SMP
                case 's': /* "smp" reboot by executing reset on BSP or other CPU*/
-                       reboot_smp = 1;
                        if (is_digit(*(str+1))) {
                                reboot_cpu = (int) (*(str+1) - '0');
                                if (is_digit(*(str+2))) 
@@ -88,33 +86,9 @@ static int __init set_bios_reboot(struct dmi_system_id *d)
        return 0;
 }
 
-/*
- * Some machines require the "reboot=s"  commandline option, this quirk makes that automatic.
- */
-static int __init set_smp_reboot(struct dmi_system_id *d)
-{
-#ifdef CONFIG_SMP
-       if (!reboot_smp) {
-               reboot_smp = 1;
-               printk(KERN_INFO "%s series board detected. Selecting SMP-method for reboots.\n", d->ident);
-       }
-#endif
-       return 0;
-}
-
-/*
- * Some machines require the "reboot=b,s"  commandline option, this quirk makes that automatic.
- */
-static int __init set_smp_bios_reboot(struct dmi_system_id *d)
-{
-       set_smp_reboot(d);
-       set_bios_reboot(d);
-       return 0;
-}
-
 static struct dmi_system_id __initdata reboot_dmi_table[] = {
        {       /* Handle problems with rebooting on Dell 1300's */
-               .callback = set_smp_bios_reboot,
+               .callback = set_bios_reboot,
                .ident = "Dell PowerEdge 1300",
                .matches = {
                        DMI_MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"),
@@ -301,41 +275,32 @@ void machine_real_restart(unsigned char *code, int length)
 EXPORT_SYMBOL(machine_real_restart);
 #endif
 
-void machine_restart(char * __unused)
+void machine_shutdown(void)
 {
 #ifdef CONFIG_SMP
-       int cpuid;
-       
-       cpuid = GET_APIC_ID(apic_read(APIC_ID));
-
-       if (reboot_smp) {
-
-               /* check to see if reboot_cpu is valid 
-                  if its not, default to the BSP */
-               if ((reboot_cpu == -1) ||  
-                     (reboot_cpu > (NR_CPUS -1))  || 
-                     !physid_isset(cpuid, phys_cpu_present_map))
-                       reboot_cpu = boot_cpu_physical_apicid;
-
-               reboot_smp = 0;  /* use this as a flag to only go through this once*/
-               /* re-run this function on the other CPUs
-                  it will fall though this section since we have 
-                  cleared reboot_smp, and do the reboot if it is the
-                  correct CPU, otherwise it halts. */
-               if (reboot_cpu != cpuid)
-                       smp_call_function((void *)machine_restart , NULL, 1, 0);
+       int reboot_cpu_id;
+
+       /* The boot cpu is always logical cpu 0 */
+       reboot_cpu_id = 0;
+
+       /* See if there has been given a command line override */
+       if ((reboot_cpu_id != -1) && (reboot_cpu < NR_CPUS) &&
+               cpu_isset(reboot_cpu, cpu_online_map)) {
+               reboot_cpu_id = reboot_cpu;
        }
 
-       /* if reboot_cpu is still -1, then we want a tradional reboot, 
-          and if we are not running on the reboot_cpu,, halt */
-       if ((reboot_cpu != -1) && (cpuid != reboot_cpu)) {
-               for (;;)
-               __asm__ __volatile__ ("hlt");
+       /* Make certain the cpu I'm rebooting on is online */
+       if (!cpu_isset(reboot_cpu_id, cpu_online_map)) {
+               reboot_cpu_id = smp_processor_id();
        }
-       /*
-        * Stop all CPUs and turn off local APICs and the IO-APIC, so
-        * other OSs see a clean IRQ state.
+
+       /* Make certain I only run on the appropriate processor */
+       set_cpus_allowed(current, cpumask_of_cpu(reboot_cpu_id));
+
+       /* O.K. Now that I'm on the appropriate processor, stop
+        * all of the others, and disable their local APICs.
         */
+
        smp_send_stop();
 #endif /* CONFIG_SMP */
 
@@ -344,6 +309,11 @@ void machine_restart(char * __unused)
 #ifdef CONFIG_X86_IO_APIC
        disable_IO_APIC();
 #endif
+}
+
+void machine_restart(char * __unused)
+{
+       machine_shutdown();
 
        if (!reboot_thru_bios) {
                if (efi_enabled) {
diff --git a/arch/i386/kernel/relocate_kernel.S b/arch/i386/kernel/relocate_kernel.S
new file mode 100644 (file)
index 0000000..d312616
--- /dev/null
@@ -0,0 +1,120 @@
+/*
+ * relocate_kernel.S - put the kernel image in place to boot
+ * Copyright (C) 2002-2004 Eric Biederman  <ebiederm@xmission.com>
+ *
+ * This source code is licensed under the GNU General Public License,
+ * Version 2.  See the file COPYING for more details.
+ */
+
+#include <linux/linkage.h>
+
+       /*
+        * Must be relocatable PIC code callable as a C function, that once
+        * it starts can not use the previous processes stack.
+        */
+       .globl relocate_new_kernel
+relocate_new_kernel:
+       /* read the arguments and say goodbye to the stack */
+       movl  4(%esp), %ebx /* page_list */
+       movl  8(%esp), %ebp /* reboot_code_buffer */
+       movl  12(%esp), %edx /* start address */
+       movl  16(%esp), %ecx /* cpu_has_pae */
+
+       /* zero out flags, and disable interrupts */
+       pushl $0
+       popfl
+
+       /* set a new stack at the bottom of our page... */
+       lea   4096(%ebp), %esp
+
+       /* store the parameters back on the stack */
+       pushl   %edx /* store the start address */
+
+       /* Set cr0 to a known state:
+        * 31 0 == Paging disabled
+        * 18 0 == Alignment check disabled
+        * 16 0 == Write protect disabled
+        * 3  0 == No task switch
+        * 2  0 == Don't do FP software emulation.
+        * 0  1 == Proctected mode enabled
+        */
+       movl    %cr0, %eax
+       andl    $~((1<<31)|(1<<18)|(1<<16)|(1<<3)|(1<<2)), %eax
+       orl     $(1<<0), %eax
+       movl    %eax, %cr0
+
+       /* clear cr4 if applicable */
+       testl   %ecx, %ecx
+       jz      1f
+       /* Set cr4 to a known state:
+        * Setting everything to zero seems safe.
+        */
+       movl    %cr4, %eax
+       andl    $0, %eax
+       movl    %eax, %cr4
+
+       jmp 1f
+1:
+
+       /* Flush the TLB (needed?) */
+       xorl    %eax, %eax
+       movl    %eax, %cr3
+
+       /* Do the copies */
+       movl    %ebx, %ecx
+       jmp     1f
+
+0:     /* top, read another word from the indirection page */
+       movl    (%ebx), %ecx
+       addl    $4, %ebx
+1:
+       testl   $0x1,   %ecx  /* is it a destination page */
+       jz      2f
+       movl    %ecx,   %edi
+       andl    $0xfffff000, %edi
+       jmp     0b
+2:
+       testl   $0x2,   %ecx  /* is it an indirection page */
+       jz      2f
+       movl    %ecx,   %ebx
+       andl    $0xfffff000, %ebx
+       jmp     0b
+2:
+       testl   $0x4,   %ecx /* is it the done indicator */
+       jz      2f
+       jmp     3f
+2:
+       testl   $0x8,   %ecx /* is it the source indicator */
+       jz      0b           /* Ignore it otherwise */
+       movl    %ecx,   %esi /* For every source page do a copy */
+       andl    $0xfffff000, %esi
+
+       movl    $1024, %ecx
+       rep ; movsl
+       jmp     0b
+
+3:
+
+       /* To be certain of avoiding problems with self-modifying code
+        * I need to execute a serializing instruction here.
+        * So I flush the TLB, it's handy, and not processor dependent.
+        */
+       xorl    %eax, %eax
+       movl    %eax, %cr3
+
+       /* set all of the registers to known values */
+       /* leave %esp alone */
+
+       xorl    %eax, %eax
+       xorl    %ebx, %ebx
+       xorl    %ecx, %ecx
+       xorl    %edx, %edx
+       xorl    %esi, %esi
+       xorl    %edi, %edi
+       xorl    %ebp, %ebp
+       ret
+relocate_new_kernel_end:
+
+       .globl relocate_new_kernel_size
+relocate_new_kernel_size:
+       .long relocate_new_kernel_end - relocate_new_kernel
index 30406fd0b64c56e1f3586f398e3f18183604c5bf..7306353c520ec6dc4c74a6cac328f8b5ba446d64 100644 (file)
 #include <linux/init.h>
 #include <linux/edd.h>
 #include <linux/nodemask.h>
+#include <linux/kexec.h>
+#include <linux/crash_dump.h>
+
 #include <video/edid.h>
+
+#include <asm/apic.h>
 #include <asm/e820.h>
 #include <asm/mpspec.h>
 #include <asm/setup.h>
 #include "setup_arch_pre.h"
 #include <bios_ebda.h>
 
+/* Forward Declaration. */
+void __init find_max_pfn(void);
+
 /* This value is set up by the early boot code to point to the value
    immediately after the boot time page tables.  It contains a *physical*
    address, and must not be in the .bss segment! */
 unsigned long init_pg_tables_end __initdata = ~0UL;
 
-int disable_pse __initdata = 0;
+int disable_pse __devinitdata = 0;
 
 /*
  * Machine setup..
@@ -732,6 +740,15 @@ static void __init parse_cmdline_early (char ** cmdline_p)
                        if (to != command_line)
                                to--;
                        if (!memcmp(from+7, "exactmap", 8)) {
+#ifdef CONFIG_CRASH_DUMP
+                               /* If we are doing a crash dump, we
+                                * still need to know the real mem
+                                * size before original memory map is
+                                * reset.
+                                */
+                               find_max_pfn();
+                               saved_max_pfn = max_pfn;
+#endif
                                from += 8+7;
                                e820.nr_map = 0;
                                userdef = 1;
@@ -835,6 +852,44 @@ static void __init parse_cmdline_early (char ** cmdline_p)
 #endif /* CONFIG_X86_LOCAL_APIC */
 #endif /* CONFIG_ACPI_BOOT */
 
+#ifdef CONFIG_X86_LOCAL_APIC
+               /* enable local APIC */
+               else if (!memcmp(from, "lapic", 5))
+                       lapic_enable();
+
+               /* disable local APIC */
+               else if (!memcmp(from, "nolapic", 6))
+                       lapic_disable();
+#endif /* CONFIG_X86_LOCAL_APIC */
+
+#ifdef CONFIG_KEXEC
+               /* crashkernel=size@addr specifies the location to reserve for
+                * a crash kernel.  By reserving this memory we guarantee
+                * that linux never set's it up as a DMA target.
+                * Useful for holding code to do something appropriate
+                * after a kernel panic.
+                */
+               else if (!memcmp(from, "crashkernel=", 12)) {
+                       unsigned long size, base;
+                       size = memparse(from+12, &from);
+                       if (*from == '@') {
+                               base = memparse(from+1, &from);
+                               /* FIXME: Do I want a sanity check
+                                * to validate the memory range?
+                                */
+                               crashk_res.start = base;
+                               crashk_res.end   = base + size - 1;
+                       }
+               }
+#endif
+#ifdef CONFIG_CRASH_DUMP
+               /* elfcorehdr= specifies the location of elf core header
+                * stored by the crashed kernel.
+                */
+               else if (!memcmp(from, "elfcorehdr=", 11))
+                       elfcorehdr_addr = memparse(from+11, &from);
+#endif
+
                /*
                 * highmem=size forces highmem to be exactly 'size' bytes.
                 * This works even on boxes that have no highmem otherwise.
@@ -1113,8 +1168,8 @@ void __init setup_bootmem_allocator(void)
         * the (very unlikely) case of us accidentally initializing the
         * bootmem allocator with an invalid RAM area.
         */
-       reserve_bootmem(HIGH_MEMORY, (PFN_PHYS(min_low_pfn) +
-                        bootmap_size + PAGE_SIZE-1) - (HIGH_MEMORY));
+       reserve_bootmem(__PHYSICAL_START, (PFN_PHYS(min_low_pfn) +
+                        bootmap_size + PAGE_SIZE-1) - (__PHYSICAL_START));
 
        /*
         * reserve physical page 0 - it's a special BIOS page on many boxes,
@@ -1170,6 +1225,11 @@ void __init setup_bootmem_allocator(void)
                }
        }
 #endif
+#ifdef CONFIG_KEXEC
+       if (crashk_res.start != crashk_res.end)
+               reserve_bootmem(crashk_res.start,
+                       crashk_res.end - crashk_res.start + 1);
+#endif
 }
 
 /*
@@ -1223,6 +1283,9 @@ legacy_init_iomem_resources(struct resource *code_resource, struct resource *dat
                         */
                        request_resource(res, code_resource);
                        request_resource(res, data_resource);
+#ifdef CONFIG_KEXEC
+                       request_resource(res, &crashk_res);
+#endif
                }
        }
 }
index b9b8f4e20fad6e79fbc5acef91115415cd3aaace..89ef7adc63a4be19611f57b580fddf46259dbd73 100644 (file)
@@ -608,10 +608,8 @@ int fastcall do_signal(struct pt_regs *regs, sigset_t *oldset)
        if (!user_mode(regs))
                return 1;
 
-       if (current->flags & PF_FREEZE) {
-               refrigerator(0);
+       if (try_to_freeze())
                goto no_signal;
-       }
 
        if (!oldset)
                oldset = &current->blocked;
index 68be7d0c7238c1feaf4eff4856fac04f111ae0dd..cec4bde67161254106267d6c6e4715aaeea93a3a 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/mc146818rtc.h>
 #include <linux/cache.h>
 #include <linux/interrupt.h>
+#include <linux/cpu.h>
 #include <linux/module.h>
 
 #include <asm/mtrr.h>
@@ -164,7 +165,7 @@ void send_IPI_mask_bitmask(cpumask_t cpumask, int vector)
        unsigned long flags;
 
        local_irq_save(flags);
-               
+       WARN_ON(mask & ~cpus_addr(cpu_online_map)[0]);
        /*
         * Wait for idle.
         */
@@ -346,21 +347,21 @@ out:
 static void flush_tlb_others(cpumask_t cpumask, struct mm_struct *mm,
                                                unsigned long va)
 {
-       cpumask_t tmp;
        /*
         * A couple of (to be removed) sanity checks:
         *
-        * - we do not send IPIs to not-yet booted CPUs.
         * - current CPU must not be in mask
         * - mask must exist :)
         */
        BUG_ON(cpus_empty(cpumask));
-
-       cpus_and(tmp, cpumask, cpu_online_map);
-       BUG_ON(!cpus_equal(cpumask, tmp));
        BUG_ON(cpu_isset(smp_processor_id(), cpumask));
        BUG_ON(!mm);
 
+       /* If a CPU which we ran on has gone down, OK. */
+       cpus_and(cpumask, cpumask, cpu_online_map);
+       if (cpus_empty(cpumask))
+               return;
+
        /*
         * i'm not happy about this global shared spinlock in the
         * MM hot path, but we'll see how contended it is.
@@ -476,6 +477,7 @@ void flush_tlb_all(void)
  */
 void smp_send_reschedule(int cpu)
 {
+       WARN_ON(cpu_is_offline(cpu));
        send_IPI_mask(cpumask_of_cpu(cpu), RESCHEDULE_VECTOR);
 }
 
@@ -493,6 +495,16 @@ struct call_data_struct {
        int wait;
 };
 
+void lock_ipi_call_lock(void)
+{
+       spin_lock_irq(&call_lock);
+}
+
+void unlock_ipi_call_lock(void)
+{
+       spin_unlock_irq(&call_lock);
+}
+
 static struct call_data_struct * call_data;
 
 /*
@@ -516,10 +528,15 @@ int smp_call_function (void (*func) (void *info), void *info, int nonatomic,
  */
 {
        struct call_data_struct data;
-       int cpus = num_online_cpus()-1;
+       int cpus;
 
-       if (!cpus)
+       /* Holding any lock stops cpus from going down. */
+       spin_lock(&call_lock);
+       cpus = num_online_cpus() - 1;
+       if (!cpus) {
+               spin_unlock(&call_lock);
                return 0;
+       }
 
        /* Can deadlock when called with interrupts disabled */
        WARN_ON(irqs_disabled());
@@ -531,7 +548,6 @@ int smp_call_function (void (*func) (void *info), void *info, int nonatomic,
        if (wait)
                atomic_set(&data.finished, 0);
 
-       spin_lock(&call_lock);
        call_data = &data;
        mb();
        
index c20d96d5c15c738709cc4667233a0e0945b093a0..d66bf489a2e90782044a09e2562fb84d06d893a0 100644 (file)
@@ -44,6 +44,9 @@
 #include <linux/smp_lock.h>
 #include <linux/irq.h>
 #include <linux/bootmem.h>
+#include <linux/notifier.h>
+#include <linux/cpu.h>
+#include <linux/percpu.h>
 
 #include <linux/delay.h>
 #include <linux/mc146818rtc.h>
 #include <smpboot_hooks.h>
 
 /* Set if we find a B stepping CPU */
-static int __initdata smp_b_stepping;
+static int __devinitdata smp_b_stepping;
 
 /* Number of siblings per CPU package */
 int smp_num_siblings = 1;
 #ifdef CONFIG_X86_HT
 EXPORT_SYMBOL(smp_num_siblings);
 #endif
-int phys_proc_id[NR_CPUS]; /* Package ID of each logical CPU */
+
+/* Package ID of each logical CPU */
+int phys_proc_id[NR_CPUS] = {[0 ... NR_CPUS-1] = BAD_APICID};
 EXPORT_SYMBOL(phys_proc_id);
-int cpu_core_id[NR_CPUS]; /* Core ID of each logical CPU */
+
+/* Core ID of each logical CPU */
+int cpu_core_id[NR_CPUS] = {[0 ... NR_CPUS-1] = BAD_APICID};
 EXPORT_SYMBOL(cpu_core_id);
 
+cpumask_t cpu_sibling_map[NR_CPUS];
+EXPORT_SYMBOL(cpu_sibling_map);
+
+cpumask_t cpu_core_map[NR_CPUS];
+EXPORT_SYMBOL(cpu_core_map);
+
 /* bitmap of online cpus */
 cpumask_t cpu_online_map;
 EXPORT_SYMBOL(cpu_online_map);
@@ -77,6 +90,12 @@ cpumask_t cpu_callout_map;
 EXPORT_SYMBOL(cpu_callout_map);
 static cpumask_t smp_commenced_mask;
 
+/* TSC's upper 32 bits can't be written in eariler CPU (before prescott), there
+ * is no way to resync one AP against BP. TBD: for prescott and above, we
+ * should use IA64's algorithm
+ */
+static int __devinitdata tsc_sync_disabled;
+
 /* Per CPU bogomips and other parameters */
 struct cpuinfo_x86 cpu_data[NR_CPUS] __cacheline_aligned;
 EXPORT_SYMBOL(cpu_data);
@@ -96,13 +115,16 @@ static int trampoline_exec;
 
 static void map_cpu_to_logical_apicid(void);
 
+/* State of each CPU. */
+DEFINE_PER_CPU(int, cpu_state) = { 0 };
+
 /*
  * Currently trivial. Write the real->protected mode
  * bootstrap into the page concerned. The caller
  * has made sure it's suitably aligned.
  */
 
-static unsigned long __init setup_trampoline(void)
+static unsigned long __devinit setup_trampoline(void)
 {
        memcpy(trampoline_base, trampoline_data, trampoline_end - trampoline_data);
        return virt_to_phys(trampoline_base);
@@ -132,7 +154,7 @@ void __init smp_alloc_memory(void)
  * a given CPU
  */
 
-static void __init smp_store_cpu_info(int id)
+static void __devinit smp_store_cpu_info(int id)
 {
        struct cpuinfo_x86 *c = cpu_data + id;
 
@@ -326,7 +348,7 @@ extern void calibrate_delay(void);
 
 static atomic_t init_deasserted;
 
-static void __init smp_callin(void)
+static void __devinit smp_callin(void)
 {
        int cpuid, phys_id;
        unsigned long timeout;
@@ -411,16 +433,48 @@ static void __init smp_callin(void)
        /*
         *      Synchronize the TSC with the BP
         */
-       if (cpu_has_tsc && cpu_khz)
+       if (cpu_has_tsc && cpu_khz && !tsc_sync_disabled)
                synchronize_tsc_ap();
 }
 
 static int cpucount;
 
+static inline void
+set_cpu_sibling_map(int cpu)
+{
+       int i;
+
+       if (smp_num_siblings > 1) {
+               for (i = 0; i < NR_CPUS; i++) {
+                       if (!cpu_isset(i, cpu_callout_map))
+                               continue;
+                       if (cpu_core_id[cpu] == cpu_core_id[i]) {
+                               cpu_set(i, cpu_sibling_map[cpu]);
+                               cpu_set(cpu, cpu_sibling_map[i]);
+                       }
+               }
+       } else {
+               cpu_set(cpu, cpu_sibling_map[cpu]);
+       }
+
+       if (current_cpu_data.x86_num_cores > 1) {
+               for (i = 0; i < NR_CPUS; i++) {
+                       if (!cpu_isset(i, cpu_callout_map))
+                               continue;
+                       if (phys_proc_id[cpu] == phys_proc_id[i]) {
+                               cpu_set(i, cpu_core_map[cpu]);
+                               cpu_set(cpu, cpu_core_map[i]);
+                       }
+               }
+       } else {
+               cpu_core_map[cpu] = cpu_sibling_map[cpu];
+       }
+}
+
 /*
  * Activate a secondary processor.
  */
-static void __init start_secondary(void *unused)
+static void __devinit start_secondary(void *unused)
 {
        /*
         * Dont put anything before smp_callin(), SMP
@@ -443,7 +497,23 @@ static void __init start_secondary(void *unused)
         * the local TLBs too.
         */
        local_flush_tlb();
+
+       /* This must be done before setting cpu_online_map */
+       set_cpu_sibling_map(raw_smp_processor_id());
+       wmb();
+
+       /*
+        * We need to hold call_lock, so there is no inconsistency
+        * between the time smp_call_function() determines number of
+        * IPI receipients, and the time when the determination is made
+        * for which cpus receive the IPI. Holding this
+        * lock helps us to not include this cpu in a currently in progress
+        * smp_call_function().
+        */
+       lock_ipi_call_lock();
        cpu_set(smp_processor_id(), cpu_online_map);
+       unlock_ipi_call_lock();
+       per_cpu(cpu_state, smp_processor_id()) = CPU_ONLINE;
 
        /* We can take interrupts now: we're officially "up". */
        local_irq_enable();
@@ -458,7 +528,7 @@ static void __init start_secondary(void *unused)
  * from the task structure
  * This function must not return.
  */
-void __init initialize_secondary(void)
+void __devinit initialize_secondary(void)
 {
        /*
         * We don't actually need to load the full TSS,
@@ -572,7 +642,7 @@ static inline void __inquire_remote_apic(int apicid)
  * INIT, INIT, STARTUP sequence will reset the chip hard for us, and this
  * won't ... remember to clear down the APIC, etc later.
  */
-static int __init
+static int __devinit
 wakeup_secondary_cpu(int logical_apicid, unsigned long start_eip)
 {
        unsigned long send_status = 0, accept_status = 0;
@@ -618,7 +688,7 @@ wakeup_secondary_cpu(int logical_apicid, unsigned long start_eip)
 #endif /* WAKE_SECONDARY_VIA_NMI */
 
 #ifdef WAKE_SECONDARY_VIA_INIT
-static int __init
+static int __devinit
 wakeup_secondary_cpu(int phys_apicid, unsigned long start_eip)
 {
        unsigned long send_status = 0, accept_status = 0;
@@ -753,8 +823,43 @@ wakeup_secondary_cpu(int phys_apicid, unsigned long start_eip)
 #endif /* WAKE_SECONDARY_VIA_INIT */
 
 extern cpumask_t cpu_initialized;
+static inline int alloc_cpu_id(void)
+{
+       cpumask_t       tmp_map;
+       int cpu;
+       cpus_complement(tmp_map, cpu_present_map);
+       cpu = first_cpu(tmp_map);
+       if (cpu >= NR_CPUS)
+               return -ENODEV;
+       return cpu;
+}
+
+#ifdef CONFIG_HOTPLUG_CPU
+static struct task_struct * __devinitdata cpu_idle_tasks[NR_CPUS];
+static inline struct task_struct * alloc_idle_task(int cpu)
+{
+       struct task_struct *idle;
+
+       if ((idle = cpu_idle_tasks[cpu]) != NULL) {
+               /* initialize thread_struct.  we really want to avoid destroy
+                * idle tread
+                */
+               idle->thread.esp = (unsigned long)(((struct pt_regs *)
+                       (THREAD_SIZE + (unsigned long) idle->thread_info)) - 1);
+               init_idle(idle, cpu);
+               return idle;
+       }
+       idle = fork_idle(cpu);
+
+       if (!IS_ERR(idle))
+               cpu_idle_tasks[cpu] = idle;
+       return idle;
+}
+#else
+#define alloc_idle_task(cpu) fork_idle(cpu)
+#endif
 
-static int __init do_boot_cpu(int apicid)
+static int __devinit do_boot_cpu(int apicid, int cpu)
 /*
  * NOTE - on most systems this is a PHYSICAL apic ID, but on multiquad
  * (ie clustered apic addressing mode), this is a LOGICAL apic ID.
@@ -763,16 +868,17 @@ static int __init do_boot_cpu(int apicid)
 {
        struct task_struct *idle;
        unsigned long boot_error;
-       int timeout, cpu;
+       int timeout;
        unsigned long start_eip;
        unsigned short nmi_high = 0, nmi_low = 0;
 
-       cpu = ++cpucount;
+       ++cpucount;
+
        /*
         * We can't use kernel_thread since we must avoid to
         * reschedule the child.
         */
-       idle = fork_idle(cpu);
+       idle = alloc_idle_task(cpu);
        if (IS_ERR(idle))
                panic("failed fork for CPU %d", cpu);
        idle->thread.eip = (unsigned long) start_secondary;
@@ -839,13 +945,16 @@ static int __init do_boot_cpu(int apicid)
                        inquire_remote_apic(apicid);
                }
        }
-       x86_cpu_to_apicid[cpu] = apicid;
+
        if (boot_error) {
                /* Try to put things back the way they were before ... */
                unmap_cpu_to_logical_apicid(cpu);
                cpu_clear(cpu, cpu_callout_map); /* was set here (do_boot_cpu()) */
                cpu_clear(cpu, cpu_initialized); /* was set by cpu_init() */
                cpucount--;
+       } else {
+               x86_cpu_to_apicid[cpu] = apicid;
+               cpu_set(cpu, cpu_present_map);
        }
 
        /* mark "stuck" area as not stuck */
@@ -854,6 +963,75 @@ static int __init do_boot_cpu(int apicid)
        return boot_error;
 }
 
+#ifdef CONFIG_HOTPLUG_CPU
+void cpu_exit_clear(void)
+{
+       int cpu = raw_smp_processor_id();
+
+       idle_task_exit();
+
+       cpucount --;
+       cpu_uninit();
+       irq_ctx_exit(cpu);
+
+       cpu_clear(cpu, cpu_callout_map);
+       cpu_clear(cpu, cpu_callin_map);
+       cpu_clear(cpu, cpu_present_map);
+
+       cpu_clear(cpu, smp_commenced_mask);
+       unmap_cpu_to_logical_apicid(cpu);
+}
+
+struct warm_boot_cpu_info {
+       struct completion *complete;
+       int apicid;
+       int cpu;
+};
+
+static void __devinit do_warm_boot_cpu(void *p)
+{
+       struct warm_boot_cpu_info *info = p;
+       do_boot_cpu(info->apicid, info->cpu);
+       complete(info->complete);
+}
+
+int __devinit smp_prepare_cpu(int cpu)
+{
+       DECLARE_COMPLETION(done);
+       struct warm_boot_cpu_info info;
+       struct work_struct task;
+       int     apicid, ret;
+
+       lock_cpu_hotplug();
+       apicid = x86_cpu_to_apicid[cpu];
+       if (apicid == BAD_APICID) {
+               ret = -ENODEV;
+               goto exit;
+       }
+
+       info.complete = &done;
+       info.apicid = apicid;
+       info.cpu = cpu;
+       INIT_WORK(&task, do_warm_boot_cpu, &info);
+
+       tsc_sync_disabled = 1;
+
+       /* init low mem mapping */
+       memcpy(swapper_pg_dir, swapper_pg_dir + USER_PGD_PTRS,
+                       sizeof(swapper_pg_dir[0]) * KERNEL_PGD_PTRS);
+       flush_tlb_all();
+       schedule_work(&task);
+       wait_for_completion(&done);
+
+       tsc_sync_disabled = 0;
+       zap_low_mappings();
+       ret = 0;
+exit:
+       unlock_cpu_hotplug();
+       return ret;
+}
+#endif
+
 static void smp_tune_scheduling (void)
 {
        unsigned long cachesize;       /* kB   */
@@ -895,13 +1073,6 @@ void *xquad_portio;
 EXPORT_SYMBOL(xquad_portio);
 #endif
 
-cpumask_t cpu_sibling_map[NR_CPUS] __cacheline_aligned;
-#ifdef CONFIG_X86_HT
-EXPORT_SYMBOL(cpu_sibling_map);
-#endif
-cpumask_t cpu_core_map[NR_CPUS] __cacheline_aligned;
-EXPORT_SYMBOL(cpu_core_map);
-
 static void __init smp_boot_cpus(unsigned int max_cpus)
 {
        int apicid, cpu, bit, kicked;
@@ -1013,7 +1184,7 @@ static void __init smp_boot_cpus(unsigned int max_cpus)
                if (max_cpus <= cpucount+1)
                        continue;
 
-               if (do_boot_cpu(apicid))
+               if (((cpu = alloc_cpu_id()) <= 0) || do_boot_cpu(apicid, cpu))
                        printk("CPU #%d not responding - cannot use it.\n",
                                                                apicid);
                else
@@ -1065,44 +1236,8 @@ static void __init smp_boot_cpus(unsigned int max_cpus)
                cpus_clear(cpu_core_map[cpu]);
        }
 
-       for (cpu = 0; cpu < NR_CPUS; cpu++) {
-               struct cpuinfo_x86 *c = cpu_data + cpu;
-               int siblings = 0;
-               int i;
-               if (!cpu_isset(cpu, cpu_callout_map))
-                       continue;
-
-               if (smp_num_siblings > 1) {
-                       for (i = 0; i < NR_CPUS; i++) {
-                               if (!cpu_isset(i, cpu_callout_map))
-                                       continue;
-                               if (cpu_core_id[cpu] == cpu_core_id[i]) {
-                                       siblings++;
-                                       cpu_set(i, cpu_sibling_map[cpu]);
-                               }
-                       }
-               } else {
-                       siblings++;
-                       cpu_set(cpu, cpu_sibling_map[cpu]);
-               }
-
-               if (siblings != smp_num_siblings) {
-                       printk(KERN_WARNING "WARNING: %d siblings found for CPU%d, should be %d\n", siblings, cpu, smp_num_siblings);
-                       smp_num_siblings = siblings;
-               }
-
-               if (c->x86_num_cores > 1) {
-                       for (i = 0; i < NR_CPUS; i++) {
-                               if (!cpu_isset(i, cpu_callout_map))
-                                       continue;
-                               if (phys_proc_id[cpu] == phys_proc_id[i]) {
-                                       cpu_set(i, cpu_core_map[cpu]);
-                               }
-                       }
-               } else {
-                       cpu_core_map[cpu] = cpu_sibling_map[cpu];
-               }
-       }
+       cpu_set(0, cpu_sibling_map[0]);
+       cpu_set(0, cpu_core_map[0]);
 
        smpboot_setup_io_apic();
 
@@ -1119,6 +1254,9 @@ static void __init smp_boot_cpus(unsigned int max_cpus)
    who understands all this stuff should rewrite it properly. --RR 15/Jul/02 */
 void __init smp_prepare_cpus(unsigned int max_cpus)
 {
+       smp_commenced_mask = cpumask_of_cpu(0);
+       cpu_callin_map = cpumask_of_cpu(0);
+       mb();
        smp_boot_cpus(max_cpus);
 }
 
@@ -1126,23 +1264,98 @@ void __devinit smp_prepare_boot_cpu(void)
 {
        cpu_set(smp_processor_id(), cpu_online_map);
        cpu_set(smp_processor_id(), cpu_callout_map);
+       cpu_set(smp_processor_id(), cpu_present_map);
+       per_cpu(cpu_state, smp_processor_id()) = CPU_ONLINE;
 }
 
-int __devinit __cpu_up(unsigned int cpu)
+#ifdef CONFIG_HOTPLUG_CPU
+static void
+remove_siblinginfo(int cpu)
 {
-       /* This only works at boot for x86.  See "rewrite" above. */
-       if (cpu_isset(cpu, smp_commenced_mask)) {
-               local_irq_enable();
-               return -ENOSYS;
+       int sibling;
+
+       for_each_cpu_mask(sibling, cpu_sibling_map[cpu])
+               cpu_clear(cpu, cpu_sibling_map[sibling]);
+       for_each_cpu_mask(sibling, cpu_core_map[cpu])
+               cpu_clear(cpu, cpu_core_map[sibling]);
+       cpus_clear(cpu_sibling_map[cpu]);
+       cpus_clear(cpu_core_map[cpu]);
+       phys_proc_id[cpu] = BAD_APICID;
+       cpu_core_id[cpu] = BAD_APICID;
+}
+
+int __cpu_disable(void)
+{
+       cpumask_t map = cpu_online_map;
+       int cpu = smp_processor_id();
+
+       /*
+        * Perhaps use cpufreq to drop frequency, but that could go
+        * into generic code.
+        *
+        * We won't take down the boot processor on i386 due to some
+        * interrupts only being able to be serviced by the BSP.
+        * Especially so if we're not using an IOAPIC   -zwane
+        */
+       if (cpu == 0)
+               return -EBUSY;
+
+       /* We enable the timer again on the exit path of the death loop */
+       disable_APIC_timer();
+       /* Allow any queued timer interrupts to get serviced */
+       local_irq_enable();
+       mdelay(1);
+       local_irq_disable();
+
+       remove_siblinginfo(cpu);
+
+       cpu_clear(cpu, map);
+       fixup_irqs(map);
+       /* It's now safe to remove this processor from the online map */
+       cpu_clear(cpu, cpu_online_map);
+       return 0;
+}
+
+void __cpu_die(unsigned int cpu)
+{
+       /* We don't do anything here: idle task is faking death itself. */
+       unsigned int i;
+
+       for (i = 0; i < 10; i++) {
+               /* They ack this in play_dead by setting CPU_DEAD */
+               if (per_cpu(cpu_state, cpu) == CPU_DEAD) {
+                       printk ("CPU %d is now offline\n", cpu);
+                       return;
+               }
+               current->state = TASK_UNINTERRUPTIBLE;
+               schedule_timeout(HZ/10);
        }
+       printk(KERN_ERR "CPU %u didn't die...\n", cpu);
+}
+#else /* ... !CONFIG_HOTPLUG_CPU */
+int __cpu_disable(void)
+{
+       return -ENOSYS;
+}
+
+void __cpu_die(unsigned int cpu)
+{
+       /* We said "no" in __cpu_disable */
+       BUG();
+}
+#endif /* CONFIG_HOTPLUG_CPU */
 
+int __devinit __cpu_up(unsigned int cpu)
+{
        /* In case one didn't come up */
        if (!cpu_isset(cpu, cpu_callin_map)) {
+               printk(KERN_DEBUG "skipping cpu%d, didn't come online\n", cpu);
                local_irq_enable();
                return -EIO;
        }
 
        local_irq_enable();
+       per_cpu(cpu_state, cpu) = CPU_UP_PREPARE;
        /* Unleash the CPU! */
        cpu_set(cpu, smp_commenced_mask);
        while (!cpu_isset(cpu, cpu_online_map))
@@ -1156,10 +1369,12 @@ void __init smp_cpus_done(unsigned int max_cpus)
        setup_ioapic_dest();
 #endif
        zap_low_mappings();
+#ifndef CONFIG_HOTPLUG_CPU
        /*
         * Disable executability of the SMP trampoline:
         */
        set_kernel_exec((unsigned long)trampoline_base, trampoline_exec);
+#endif
 }
 
 void __init smp_intr_init(void)
index d408afaf6495918b3591bbcda5dbcd5a95a34a36..442a6e937b191612c6e6eab0090079ebb1137f8b 100644 (file)
@@ -283,7 +283,7 @@ ENTRY(sys_call_table)
        .long sys_mq_timedreceive       /* 280 */
        .long sys_mq_notify
        .long sys_mq_getsetattr
-       .long sys_ni_syscall            /* reserved for kexec */
+       .long sys_kexec_load
        .long sys_waitid
        .long sys_ni_syscall            /* 285 */ /* available */
        .long sys_add_key
index 960d8bd137d0ce86b6b76ac22c3930bb2833711d..0bada1870bdf5691631e10558bf43cbb350691a1 100644 (file)
 
 extern asmlinkage void sysenter_entry(void);
 
-void enable_sep_cpu(void *info)
+void enable_sep_cpu(void)
 {
        int cpu = get_cpu();
        struct tss_struct *tss = &per_cpu(init_tss, cpu);
 
+       if (!boot_cpu_has(X86_FEATURE_SEP)) {
+               put_cpu();
+               return;
+       }
+
        tss->ss1 = __KERNEL_CS;
        tss->esp1 = sizeof(struct tss_struct) + (unsigned long) tss;
        wrmsr(MSR_IA32_SYSENTER_CS, __KERNEL_CS, 0);
@@ -41,7 +46,7 @@ void enable_sep_cpu(void *info)
 extern const char vsyscall_int80_start, vsyscall_int80_end;
 extern const char vsyscall_sysenter_start, vsyscall_sysenter_end;
 
-static int __init sysenter_setup(void)
+int __init sysenter_setup(void)
 {
        void *page = (void *)get_zeroed_page(GFP_ATOMIC);
 
@@ -58,8 +63,5 @@ static int __init sysenter_setup(void)
               &vsyscall_sysenter_start,
               &vsyscall_sysenter_end - &vsyscall_sysenter_start);
 
-       on_each_cpu(enable_sep_cpu, NULL, 1, 1);
        return 0;
 }
-
-__initcall(sysenter_setup);
index 10a0cbb88e754e81cb01604bca90e989c5b9d50c..658c0629ba6aa9e9d2062cd9111ba14a3b888e0c 100644 (file)
@@ -50,7 +50,7 @@ static void hpet_writel(unsigned long d, unsigned long a)
  * comparator value and continue. Next tick can be caught by checking
  * for a change in the comparator value. Used in apic.c.
  */
-static void __init wait_hpet_tick(void)
+static void __devinit wait_hpet_tick(void)
 {
        unsigned int start_cmp_val, end_cmp_val;
 
index 37353bd318036f4f6d0dc4d00c5f1a7ea9c973e1..8163fe0cf1f0333dc59935ec5e4032aa8bab7a7a 100644 (file)
@@ -86,7 +86,7 @@ bad_ctc:
 #define CALIBRATE_CNT_HPET     (5 * hpet_tick)
 #define CALIBRATE_TIME_HPET    (5 * KERNEL_TICK_USEC)
 
-unsigned long __init calibrate_tsc_hpet(unsigned long *tsc_hpet_quotient_ptr)
+unsigned long __devinit calibrate_tsc_hpet(unsigned long *tsc_hpet_quotient_ptr)
 {
        unsigned long tsc_startlow, tsc_starthigh;
        unsigned long tsc_endlow, tsc_endhigh;
index 54c36b182021a3cbc0b9359b95581f499c522353..f46e625bab67f117a9ed046f1662515b434d389f 100644 (file)
@@ -33,7 +33,7 @@ static struct timer_opts timer_tsc;
 
 static inline void cpufreq_delayed_get(void);
 
-int tsc_disable __initdata = 0;
+int tsc_disable __devinitdata = 0;
 
 extern spinlock_t i8253_lock;
 
index e4d4e2162c7a3873d36f5d0e64c451c96852889b..a61f33d06ea34313b9a36a271d9fd69f2b2034db 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/ptrace.h>
 #include <linux/utsname.h>
 #include <linux/kprobes.h>
+#include <linux/kexec.h>
 
 #ifdef CONFIG_EISA
 #include <linux/ioport.h>
@@ -234,22 +235,22 @@ void show_registers(struct pt_regs *regs)
         * time of the fault..
         */
        if (in_kernel) {
-               u8 *eip;
+               u8 __user *eip;
 
                printk("\nStack: ");
                show_stack(NULL, (unsigned long*)esp);
 
                printk("Code: ");
 
-               eip = (u8 *)regs->eip - 43;
+               eip = (u8 __user *)regs->eip - 43;
                for (i = 0; i < 64; i++, eip++) {
                        unsigned char c;
 
-                       if (eip < (u8 *)PAGE_OFFSET || __get_user(c, eip)) {
+                       if (eip < (u8 __user *)PAGE_OFFSET || __get_user(c, eip)) {
                                printk(" Bad EIP value.");
                                break;
                        }
-                       if (eip == (u8 *)regs->eip)
+                       if (eip == (u8 __user *)regs->eip)
                                printk("<%02x> ", c);
                        else
                                printk("%02x ", c);
@@ -273,13 +274,13 @@ static void handle_BUG(struct pt_regs *regs)
 
        if (eip < PAGE_OFFSET)
                goto no_bug;
-       if (__get_user(ud2, (unsigned short *)eip))
+       if (__get_user(ud2, (unsigned short __user *)eip))
                goto no_bug;
        if (ud2 != 0x0b0f)
                goto no_bug;
-       if (__get_user(line, (unsigned short *)(eip + 2)))
+       if (__get_user(line, (unsigned short __user *)(eip + 2)))
                goto bug;
-       if (__get_user(file, (char **)(eip + 4)) ||
+       if (__get_user(file, (char * __user *)(eip + 4)) ||
                (unsigned long)file < PAGE_OFFSET || __get_user(c, file))
                file = "<bad filename>";
 
@@ -294,6 +295,9 @@ bug:
        printk("Kernel BUG\n");
 }
 
+/* This is gone through when something in the kernel
+ * has done something bad and is about to be terminated.
+*/
 void die(const char * str, struct pt_regs * regs, long err)
 {
        static struct {
@@ -341,6 +345,10 @@ void die(const char * str, struct pt_regs * regs, long err)
        bust_spinlocks(0);
        die.lock_owner = -1;
        spin_unlock_irq(&die.lock);
+
+       if (kexec_should_crash(current))
+               crash_kexec(regs);
+
        if (in_interrupt())
                panic("Fatal exception in interrupt");
 
@@ -361,6 +369,10 @@ static inline void die_if_kernel(const char * str, struct pt_regs * regs, long e
 static void do_trap(int trapnr, int signr, char *str, int vm86,
                           struct pt_regs * regs, long error_code, siginfo_t *info)
 {
+       struct task_struct *tsk = current;
+       tsk->thread.error_code = error_code;
+       tsk->thread.trap_no = trapnr;
+
        if (regs->eflags & VM_MASK) {
                if (vm86)
                        goto vm86_trap;
@@ -371,9 +383,6 @@ static void do_trap(int trapnr, int signr, char *str, int vm86,
                goto kernel_trap;
 
        trap_signal: {
-               struct task_struct *tsk = current;
-               tsk->thread.error_code = error_code;
-               tsk->thread.trap_no = trapnr;
                if (info)
                        force_sig_info(signr, info, tsk);
                else
@@ -486,6 +495,9 @@ fastcall void do_general_protection(struct pt_regs * regs, long error_code)
        }
        put_cpu();
 
+       current->thread.error_code = error_code;
+       current->thread.trap_no = 13;
+
        if (regs->eflags & VM_MASK)
                goto gp_in_vm86;
 
@@ -570,6 +582,15 @@ void die_nmi (struct pt_regs *regs, const char *msg)
        console_silent();
        spin_unlock(&nmi_print_lock);
        bust_spinlocks(0);
+
+       /* If we are in kernel we are probably nested up pretty bad
+        * and might aswell get out now while we still can.
+       */
+       if (!user_mode(regs)) {
+               current->thread.trap_no = 2;
+               crash_kexec(regs);
+       }
+
        do_exit(SIGSEGV);
 }
 
@@ -625,6 +646,14 @@ fastcall void do_nmi(struct pt_regs * regs, long error_code)
        nmi_enter();
 
        cpu = smp_processor_id();
+
+#ifdef CONFIG_HOTPLUG_CPU
+       if (!cpu_online(cpu)) {
+               nmi_exit();
+               return;
+       }
+#endif
+
        ++nmi_count(cpu);
 
        if (!nmi_callback(regs, cpu))
@@ -872,9 +901,9 @@ fastcall void do_simd_coprocessor_error(struct pt_regs * regs,
                                          error_code);
                        return;
                }
-               die_if_kernel("cache flush denied", regs, error_code);
                current->thread.trap_no = 19;
                current->thread.error_code = error_code;
+               die_if_kernel("cache flush denied", regs, error_code);
                force_sig(SIGSEGV, current);
        }
 }
index e0512cc8bea76b9b73c75177426209b0b6306095..7e01a528a83a168f86214907103d7bbe1f2e964d 100644 (file)
@@ -2,20 +2,23 @@
  * Written by Martin Mares <mj@atrey.karlin.mff.cuni.cz>;
  */
 
+#define LOAD_OFFSET __PAGE_OFFSET
+
 #include <asm-generic/vmlinux.lds.h>
 #include <asm/thread_info.h>
 #include <asm/page.h>
 
 OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
 OUTPUT_ARCH(i386)
-ENTRY(startup_32)
+ENTRY(phys_startup_32)
 jiffies = jiffies_64;
 SECTIONS
 {
-  . = __PAGE_OFFSET + 0x100000;
+  . = __KERNEL_START;
+  phys_startup_32 = startup_32 - LOAD_OFFSET;
   /* read-only */
   _text = .;                   /* Text and read-only data */
-  .text : {
+  .text : AT(ADDR(.text) - LOAD_OFFSET) {
        *(.text)
        SCHED_TEXT
        LOCK_TEXT
@@ -27,49 +30,55 @@ SECTIONS
 
   . = ALIGN(16);               /* Exception table */
   __start___ex_table = .;
-  __ex_table : { *(__ex_table) }
+  __ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) { *(__ex_table) }
   __stop___ex_table = .;
 
   RODATA
 
   /* writeable */
-  .data : {                    /* Data */
+  .data : AT(ADDR(.data) - LOAD_OFFSET) {      /* Data */
        *(.data)
        CONSTRUCTORS
        }
 
   . = ALIGN(4096);
   __nosave_begin = .;
-  .data_nosave : { *(.data.nosave) }
+  .data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) { *(.data.nosave) }
   . = ALIGN(4096);
   __nosave_end = .;
 
   . = ALIGN(4096);
-  .data.page_aligned : { *(.data.idt) }
+  .data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET) {
+       *(.data.idt)
+  }
 
   . = ALIGN(32);
-  .data.cacheline_aligned : { *(.data.cacheline_aligned) }
+  .data.cacheline_aligned : AT(ADDR(.data.cacheline_aligned) - LOAD_OFFSET) {
+       *(.data.cacheline_aligned)
+  }
 
   _edata = .;                  /* End of data section */
 
   . = ALIGN(THREAD_SIZE);      /* init_task */
-  .data.init_task : { *(.data.init_task) }
+  .data.init_task : AT(ADDR(.data.init_task) - LOAD_OFFSET) {
+       *(.data.init_task)
+  }
 
   /* will be freed after init */
   . = ALIGN(4096);             /* Init code and data */
   __init_begin = .;
-  .init.text : 
+  .init.text : AT(ADDR(.init.text) - LOAD_OFFSET) {
        _sinittext = .;
        *(.init.text)
        _einittext = .;
   }
-  .init.data : { *(.init.data) }
+  .init.data : AT(ADDR(.init.data) - LOAD_OFFSET) { *(.init.data) }
   . = ALIGN(16);
   __setup_start = .;
-  .init.setup : { *(.init.setup) }
+  .init.setup : AT(ADDR(.init.setup) - LOAD_OFFSET) { *(.init.setup) }
   __setup_end = .;
   __initcall_start = .;
-  .initcall.init : {
+  .initcall.init : AT(ADDR(.initcall.init) - LOAD_OFFSET) {
        *(.initcall1.init) 
        *(.initcall2.init) 
        *(.initcall3.init) 
@@ -80,33 +89,41 @@ SECTIONS
   }
   __initcall_end = .;
   __con_initcall_start = .;
-  .con_initcall.init : { *(.con_initcall.init) }
+  .con_initcall.init : AT(ADDR(.con_initcall.init) - LOAD_OFFSET) {
+       *(.con_initcall.init)
+  }
   __con_initcall_end = .;
   SECURITY_INIT
   . = ALIGN(4);
   __alt_instructions = .;
-  .altinstructions : { *(.altinstructions) } 
+  .altinstructions : AT(ADDR(.altinstructions) - LOAD_OFFSET) {
+       *(.altinstructions)
+  }
   __alt_instructions_end = .; 
- .altinstr_replacement : { *(.altinstr_replacement) } 
+  .altinstr_replacement : AT(ADDR(.altinstr_replacement) - LOAD_OFFSET) {
+       *(.altinstr_replacement)
+  }
   /* .exit.text is discard at runtime, not link time, to deal with references
      from .altinstructions and .eh_frame */
-  .exit.text : { *(.exit.text) }
-  .exit.data : { *(.exit.data) }
+  .exit.text : AT(ADDR(.exit.text) - LOAD_OFFSET) { *(.exit.text) }
+  .exit.data : AT(ADDR(.exit.data) - LOAD_OFFSET) { *(.exit.data) }
   . = ALIGN(4096);
   __initramfs_start = .;
-  .init.ramfs : { *(.init.ramfs) }
+  .init.ramfs : AT(ADDR(.init.ramfs) - LOAD_OFFSET) { *(.init.ramfs) }
   __initramfs_end = .;
   . = ALIGN(32);
   __per_cpu_start = .;
-  .data.percpu  : { *(.data.percpu) }
+  .data.percpu  : AT(ADDR(.data.percpu) - LOAD_OFFSET) { *(.data.percpu) }
   __per_cpu_end = .;
   . = ALIGN(4096);
   __init_end = .;
   /* freed after init ends here */
        
   __bss_start = .;             /* BSS */
-  .bss : {
+  .bss.page_aligned : AT(ADDR(.bss.page_aligned) - LOAD_OFFSET) {
        *(.bss.page_aligned)
+  }
+  .bss : AT(ADDR(.bss) - LOAD_OFFSET) {
        *(.bss)
   }
   . = ALIGN(4);
index 0aa08eaa893281f6c74e49a0ac7f34f5203a481f..e5a1a83d09ef8d6c4efe1e74c7fa1d77c5f371dc 100644 (file)
 #include <asm/acpi.h>
 #include <asm/arch_hooks.h>
 
+#ifdef CONFIG_HOTPLUG_CPU
+#define DEFAULT_SEND_IPI       (1)
+#else
+#define DEFAULT_SEND_IPI       (0)
+#endif
+
+int no_broadcast=DEFAULT_SEND_IPI;
+
 /**
  * pre_intr_init_hook - initialisation prior to setting up interrupt vectors
  *
@@ -104,3 +112,22 @@ void __init mca_nmi_hook(void)
        printk("NMI generated from unknown source!\n");
 }
 #endif
+
+static __init int no_ipi_broadcast(char *str)
+{
+       get_option(&str, &no_broadcast);
+       printk ("Using %s mode\n", no_broadcast ? "No IPI Broadcast" :
+                                                                                       "IPI Broadcast");
+       return 1;
+}
+
+__setup("no_ipi_broadcast", no_ipi_broadcast);
+
+static int __init print_ipi_mode(void)
+{
+       printk ("Using IPI %s mode\n", no_broadcast ? "No-Shortcut" :
+                                                                                       "Shortcut");
+       return 0;
+}
+
+late_initcall(print_ipi_mode);
index 5b3e8817dae828054dd3ee8449f1fd9c6ae6265d..23395fff35d16e59dcade164354dc0045ee95d1f 100644 (file)
@@ -73,12 +73,11 @@ static int __init topology_init(void)
 {
        int i;
 
-       for (i = 0; i < MAX_NUMNODES; i++) {
-               if (node_online(i))
-                       arch_register_node(i);
-       }
-       for (i = 0; i < NR_CPUS; i++)
-               if (cpu_possible(i)) arch_register_cpu(i);
+       for_each_online_node(i)
+               arch_register_node(i);
+
+       for_each_cpu(i)
+               arch_register_cpu(i);
        return 0;
 }
 
@@ -88,8 +87,8 @@ static int __init topology_init(void)
 {
        int i;
 
-       for (i = 0; i < NR_CPUS; i++)
-               if (cpu_possible(i)) arch_register_cpu(i);
+       for_each_cpu(i)
+               arch_register_cpu(i);
        return 0;
 }
 
index 5a22082147f4efc5fc738d5d2402c76118c561ae..5f3d7e6de37b9cc4440cc9f7e7ba6a52271477cc 100644 (file)
@@ -23,7 +23,6 @@ unsigned long mp_lapic_addr;
 
 /* Processor that is doing the boot up */
 unsigned int boot_cpu_physical_apicid = -1U;
-unsigned int boot_cpu_logical_apicid = -1U;
 
 /* Bitmask of physically existing CPUs */
 physid_mask_t phys_cpu_present_map;
@@ -52,10 +51,8 @@ static void __init MP_processor_info (struct mpc_config_processor *m)
                (m->mpc_cpufeature & CPU_MODEL_MASK) >> 4,
                m->mpc_apicver);
 
-       if (m->mpc_cpuflag & CPU_BOOTPROCESSOR) {
+       if (m->mpc_cpuflag & CPU_BOOTPROCESSOR)
                boot_cpu_physical_apicid = m->mpc_apicid;
-               boot_cpu_logical_apicid = logical_apicid;
-       }
 
        ver = m->mpc_apicver;
        if ((ver >= 0x14 && m->mpc_apicid >= 0xff) || m->mpc_apicid >= 0xf) {
index f429c871e8450b5e344cf60aca1fc6cd97b01733..b358f0702a44fab313811594390f91fbd91aa7dc 100644 (file)
@@ -30,6 +30,8 @@
 #include <linux/initrd.h>
 #include <linux/nodemask.h>
 #include <linux/module.h>
+#include <linux/kexec.h>
+
 #include <asm/e820.h>
 #include <asm/setup.h>
 #include <asm/mmzone.h>
index a509237c4815ed6f8443e85b973dda2a0f2c0688..8e90339d6eaaa18c96a5292c53f6590235804764 100644 (file)
@@ -146,7 +146,7 @@ static int __is_prefetch(struct pt_regs *regs, unsigned long addr)
 
                if (instr > limit)
                        break;
-               if (__get_user(opcode, (unsigned char *) instr))
+               if (__get_user(opcode, (unsigned char __user *) instr))
                        break; 
 
                instr_hi = opcode & 0xf0; 
@@ -173,7 +173,7 @@ static int __is_prefetch(struct pt_regs *regs, unsigned long addr)
                        scan_more = 0;
                        if (instr > limit)
                                break;
-                       if (__get_user(opcode, (unsigned char *) instr)) 
+                       if (__get_user(opcode, (unsigned char __user *) instr))
                                break;
                        prefetch = (instr_lo == 0xF) &&
                                (opcode == 0x0D || opcode == 0x18);
@@ -463,6 +463,9 @@ no_context:
                printk(KERN_ALERT "*pte = %08lx\n", page);
        }
 #endif
+       tsk->thread.cr2 = address;
+       tsk->thread.trap_no = 14;
+       tsk->thread.error_code = error_code;
        die("Oops", regs, error_code);
        bust_spinlocks(0);
        do_exit(SIGKILL);
index 4b7aaf99d7ea7a1d9a19d2f821070fd4d1a85c4f..b6eb4dcb8777e60e173985b2ae67d3be5bc3a058 100644 (file)
@@ -75,6 +75,24 @@ void kunmap_atomic(void *kvaddr, enum km_type type)
        preempt_check_resched();
 }
 
+/* This is the same as kmap_atomic() but can map memory that doesn't
+ * have a struct page associated with it.
+ */
+void *kmap_atomic_pfn(unsigned long pfn, enum km_type type)
+{
+       enum fixed_addresses idx;
+       unsigned long vaddr;
+
+       inc_preempt_count();
+
+       idx = type + KM_TYPE_NR*smp_processor_id();
+       vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
+       set_pte(kmap_pte-idx, pfn_pte(pfn, kmap_prot));
+       __flush_tlb_one(vaddr);
+
+       return (void*) vaddr;
+}
+
 struct page *kmap_atomic_to_page(void *ptr)
 {
        unsigned long idx, vaddr = (unsigned long)ptr;
index 3672e2ef51ae528dcf9fabb0f1552babc4faecc1..12216b52e28bf9b50060c509060fea3057fb298e 100644 (file)
@@ -352,7 +352,7 @@ static void __init pagetable_init (void)
 #endif
 }
 
-#if defined(CONFIG_PM_DISK) || defined(CONFIG_SOFTWARE_SUSPEND)
+#ifdef CONFIG_SOFTWARE_SUSPEND
 /*
  * Swap suspend & friends need this for resume because things like the intel-agp
  * driver might have split up a kernel 4MB mapping.
index d393eefc70524e8464a93845c99ddeac03ef1b0b..6b25afc933b605b0f515372d900cdc272ffc2e71 100644 (file)
@@ -243,7 +243,7 @@ void iounmap(volatile void __iomem *addr)
        write_lock(&vmlist_lock);
        p = __remove_vm_area((void *) (PAGE_MASK & (unsigned long __force) addr));
        if (!p) { 
-               printk("iounmap: bad address %p\n", addr);
+               printk(KERN_WARNING "iounmap: bad address %p\n", addr);
                goto out_unlock;
        }
 
index 270c59f099a445f667dab7c0d403b14ed21d1939..bd2f7afc7a2a5d6726b14a35bdf48492bf4730a1 100644 (file)
@@ -32,9 +32,9 @@ void show_mem(void)
        unsigned long i;
        struct page_state ps;
 
-       printk("Mem-info:\n");
+       printk(KERN_INFO "Mem-info:\n");
        show_free_areas();
-       printk("Free swap:       %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10));
+       printk(KERN_INFO "Free swap:       %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10));
        for_each_pgdat(pgdat) {
                for (i = 0; i < pgdat->node_spanned_pages; ++i) {
                        page = pgdat_page_nr(pgdat, i);
@@ -49,18 +49,18 @@ void show_mem(void)
                                shared += page_count(page) - 1;
                }
        }
-       printk("%d pages of RAM\n", total);
-       printk("%d pages of HIGHMEM\n",highmem);
-       printk("%d reserved pages\n",reserved);
-       printk("%d pages shared\n",shared);
-       printk("%d pages swap cached\n",cached);
+       printk(KERN_INFO "%d pages of RAM\n", total);
+       printk(KERN_INFO "%d pages of HIGHMEM\n", highmem);
+       printk(KERN_INFO "%d reserved pages\n", reserved);
+       printk(KERN_INFO "%d pages shared\n", shared);
+       printk(KERN_INFO "%d pages swap cached\n", cached);
 
        get_page_state(&ps);
-       printk("%lu pages dirty\n", ps.nr_dirty);
-       printk("%lu pages writeback\n", ps.nr_writeback);
-       printk("%lu pages mapped\n", ps.nr_mapped);
-       printk("%lu pages slab\n", ps.nr_slab);
-       printk("%lu pages pagetables\n", ps.nr_page_table_pages);
+       printk(KERN_INFO "%lu pages dirty\n", ps.nr_dirty);
+       printk(KERN_INFO "%lu pages writeback\n", ps.nr_writeback);
+       printk(KERN_INFO "%lu pages mapped\n", ps.nr_mapped);
+       printk(KERN_INFO "%lu pages slab\n", ps.nr_slab);
+       printk(KERN_INFO "%lu pages pagetables\n", ps.nr_page_table_pages);
 }
 
 /*
@@ -113,16 +113,16 @@ void set_pmd_pfn(unsigned long vaddr, unsigned long pfn, pgprot_t flags)
        pmd_t *pmd;
 
        if (vaddr & (PMD_SIZE-1)) {             /* vaddr is misaligned */
-               printk ("set_pmd_pfn: vaddr misaligned\n");
+               printk(KERN_WARNING "set_pmd_pfn: vaddr misaligned\n");
                return; /* BUG(); */
        }
        if (pfn & (PTRS_PER_PTE-1)) {           /* pfn is misaligned */
-               printk ("set_pmd_pfn: pfn misaligned\n");
+               printk(KERN_WARNING "set_pmd_pfn: pfn misaligned\n");
                return; /* BUG(); */
        }
        pgd = swapper_pg_dir + pgd_index(vaddr);
        if (pgd_none(*pgd)) {
-               printk ("set_pmd_pfn: pgd_none\n");
+               printk(KERN_WARNING "set_pmd_pfn: pgd_none\n");
                return; /* BUG(); */
        }
        pud = pud_offset(pgd, vaddr);
index 6f521cf19a133924b026b13bb3695218fd2a2e6b..0e6b45b612514669d9dbaf8df092b56a4b0d6fb9 100644 (file)
 #include <linux/device.h>
 #include <linux/suspend.h>
 #include <linux/acpi.h>
+
 #include <asm/uaccess.h>
 #include <asm/acpi.h>
 #include <asm/tlbflush.h>
+#include <asm/processor.h>
 
 static struct saved_context saved_context;
 
@@ -33,8 +35,6 @@ unsigned long saved_context_esp, saved_context_ebp;
 unsigned long saved_context_esi, saved_context_edi;
 unsigned long saved_context_eflags;
 
-extern void enable_sep_cpu(void *);
-
 void __save_processor_state(struct saved_context *ctxt)
 {
        kernel_fpu_begin();
@@ -44,7 +44,6 @@ void __save_processor_state(struct saved_context *ctxt)
         */
        asm volatile ("sgdt %0" : "=m" (ctxt->gdt_limit));
        asm volatile ("sidt %0" : "=m" (ctxt->idt_limit));
-       asm volatile ("sldt %0" : "=m" (ctxt->ldt));
        asm volatile ("str %0"  : "=m" (ctxt->tr));
 
        /*
@@ -107,7 +106,6 @@ static void fix_processor_context(void)
 
 void __restore_processor_state(struct saved_context *ctxt)
 {
-
        /*
         * control registers
         */
@@ -116,6 +114,13 @@ void __restore_processor_state(struct saved_context *ctxt)
        asm volatile ("movl %0, %%cr2" :: "r" (ctxt->cr2));
        asm volatile ("movl %0, %%cr0" :: "r" (ctxt->cr0));
 
+       /*
+        * now restore the descriptor tables to their proper values
+        * ltr is done i fix_processor_context().
+        */
+       asm volatile ("lgdt %0" :: "m" (ctxt->gdt_limit));
+       asm volatile ("lidt %0" :: "m" (ctxt->idt_limit));
+
        /*
         * segment registers
         */
@@ -124,19 +129,11 @@ void __restore_processor_state(struct saved_context *ctxt)
        asm volatile ("movw %0, %%gs" :: "r" (ctxt->gs));
        asm volatile ("movw %0, %%ss" :: "r" (ctxt->ss));
 
-       /*
-        * now restore the descriptor tables to their proper values
-        * ltr is done i fix_processor_context().
-        */
-       asm volatile ("lgdt %0" :: "m" (ctxt->gdt_limit));
-       asm volatile ("lidt %0" :: "m" (ctxt->idt_limit));
-       asm volatile ("lldt %0" :: "m" (ctxt->ldt));
-
        /*
         * sysenter MSRs
         */
        if (boot_cpu_has(X86_FEATURE_SEP))
-               enable_sep_cpu(NULL);
+               enable_sep_cpu();
 
        fix_processor_context();
        do_fpu_end();
index fe532c970438973393cb4e1dc40f502e15aef858..d65e87b6394fa2c636f9593718f6e84f29c9804c 100644 (file)
@@ -14,7 +14,7 @@
 #include <linux/topology.h>
 #include <linux/nodemask.h>
 
-#define SD_NODES_PER_DOMAIN 6
+#define SD_NODES_PER_DOMAIN 16
 
 #ifdef CONFIG_NUMA
 /**
@@ -27,7 +27,7 @@
  *
  * Should use nodemask_t.
  */
-static int __devinit find_next_best_node(int node, unsigned long *used_nodes)
+static int find_next_best_node(int node, unsigned long *used_nodes)
 {
        int i, n, val, min_val, best_node = 0;
 
@@ -66,7 +66,7 @@ static int __devinit find_next_best_node(int node, unsigned long *used_nodes)
  * should be one that prevents unnecessary balancing, but also spreads tasks
  * out optimally.
  */
-static cpumask_t __devinit sched_domain_node_span(int node)
+static cpumask_t sched_domain_node_span(int node)
 {
        int i;
        cpumask_t span, nodemask;
@@ -96,7 +96,7 @@ static cpumask_t __devinit sched_domain_node_span(int node)
 #ifdef CONFIG_SCHED_SMT
 static DEFINE_PER_CPU(struct sched_domain, cpu_domains);
 static struct sched_group sched_group_cpus[NR_CPUS];
-static int __devinit cpu_to_cpu_group(int cpu)
+static int cpu_to_cpu_group(int cpu)
 {
        return cpu;
 }
@@ -104,7 +104,7 @@ static int __devinit cpu_to_cpu_group(int cpu)
 
 static DEFINE_PER_CPU(struct sched_domain, phys_domains);
 static struct sched_group sched_group_phys[NR_CPUS];
-static int __devinit cpu_to_phys_group(int cpu)
+static int cpu_to_phys_group(int cpu)
 {
 #ifdef CONFIG_SCHED_SMT
        return first_cpu(cpu_sibling_map[cpu]);
@@ -125,44 +125,36 @@ static struct sched_group *sched_group_nodes[MAX_NUMNODES];
 static DEFINE_PER_CPU(struct sched_domain, allnodes_domains);
 static struct sched_group sched_group_allnodes[MAX_NUMNODES];
 
-static int __devinit cpu_to_allnodes_group(int cpu)
+static int cpu_to_allnodes_group(int cpu)
 {
        return cpu_to_node(cpu);
 }
 #endif
 
 /*
- * Set up scheduler domains and groups.  Callers must hold the hotplug lock.
+ * Build sched domains for a given set of cpus and attach the sched domains
+ * to the individual cpus
  */
-void __devinit arch_init_sched_domains(void)
+void build_sched_domains(const cpumask_t *cpu_map)
 {
        int i;
-       cpumask_t cpu_default_map;
 
        /*
-        * Setup mask for cpus without special case scheduling requirements.
-        * For now this just excludes isolated cpus, but could be used to
-        * exclude other special cases in the future.
+        * Set up domains for cpus specified by the cpu_map.
         */
-       cpus_complement(cpu_default_map, cpu_isolated_map);
-       cpus_and(cpu_default_map, cpu_default_map, cpu_online_map);
-
-       /*
-        * Set up domains. Isolated domains just stay on the dummy domain.
-        */
-       for_each_cpu_mask(i, cpu_default_map) {
+       for_each_cpu_mask(i, *cpu_map) {
                int group;
                struct sched_domain *sd = NULL, *p;
                cpumask_t nodemask = node_to_cpumask(cpu_to_node(i));
 
-               cpus_and(nodemask, nodemask, cpu_default_map);
+               cpus_and(nodemask, nodemask, *cpu_map);
 
 #ifdef CONFIG_NUMA
                if (num_online_cpus()
                                > SD_NODES_PER_DOMAIN*cpus_weight(nodemask)) {
                        sd = &per_cpu(allnodes_domains, i);
                        *sd = SD_ALLNODES_INIT;
-                       sd->span = cpu_default_map;
+                       sd->span = *cpu_map;
                        group = cpu_to_allnodes_group(i);
                        sd->groups = &sched_group_allnodes[group];
                        p = sd;
@@ -173,7 +165,7 @@ void __devinit arch_init_sched_domains(void)
                *sd = SD_NODE_INIT;
                sd->span = sched_domain_node_span(cpu_to_node(i));
                sd->parent = p;
-               cpus_and(sd->span, sd->span, cpu_default_map);
+               cpus_and(sd->span, sd->span, *cpu_map);
 #endif
 
                p = sd;
@@ -190,7 +182,7 @@ void __devinit arch_init_sched_domains(void)
                group = cpu_to_cpu_group(i);
                *sd = SD_SIBLING_INIT;
                sd->span = cpu_sibling_map[i];
-               cpus_and(sd->span, sd->span, cpu_default_map);
+               cpus_and(sd->span, sd->span, *cpu_map);
                sd->parent = p;
                sd->groups = &sched_group_cpus[group];
 #endif
@@ -198,9 +190,9 @@ void __devinit arch_init_sched_domains(void)
 
 #ifdef CONFIG_SCHED_SMT
        /* Set up CPU (sibling) groups */
-       for_each_cpu_mask(i, cpu_default_map) {
+       for_each_cpu_mask(i, *cpu_map) {
                cpumask_t this_sibling_map = cpu_sibling_map[i];
-               cpus_and(this_sibling_map, this_sibling_map, cpu_default_map);
+               cpus_and(this_sibling_map, this_sibling_map, *cpu_map);
                if (i != first_cpu(this_sibling_map))
                        continue;
 
@@ -213,7 +205,7 @@ void __devinit arch_init_sched_domains(void)
        for (i = 0; i < MAX_NUMNODES; i++) {
                cpumask_t nodemask = node_to_cpumask(i);
 
-               cpus_and(nodemask, nodemask, cpu_default_map);
+               cpus_and(nodemask, nodemask, *cpu_map);
                if (cpus_empty(nodemask))
                        continue;
 
@@ -222,7 +214,7 @@ void __devinit arch_init_sched_domains(void)
        }
 
 #ifdef CONFIG_NUMA
-       init_sched_build_groups(sched_group_allnodes, cpu_default_map,
+       init_sched_build_groups(sched_group_allnodes, *cpu_map,
                                &cpu_to_allnodes_group);
 
        for (i = 0; i < MAX_NUMNODES; i++) {
@@ -233,12 +225,12 @@ void __devinit arch_init_sched_domains(void)
                cpumask_t covered = CPU_MASK_NONE;
                int j;
 
-               cpus_and(nodemask, nodemask, cpu_default_map);
+               cpus_and(nodemask, nodemask, *cpu_map);
                if (cpus_empty(nodemask))
                        continue;
 
                domainspan = sched_domain_node_span(i);
-               cpus_and(domainspan, domainspan, cpu_default_map);
+               cpus_and(domainspan, domainspan, *cpu_map);
 
                sg = kmalloc(sizeof(struct sched_group), GFP_KERNEL);
                sched_group_nodes[i] = sg;
@@ -266,7 +258,7 @@ void __devinit arch_init_sched_domains(void)
                        int n = (i + j) % MAX_NUMNODES;
 
                        cpus_complement(notcovered, covered);
-                       cpus_and(tmp, notcovered, cpu_default_map);
+                       cpus_and(tmp, notcovered, *cpu_map);
                        cpus_and(tmp, tmp, domainspan);
                        if (cpus_empty(tmp))
                                break;
@@ -293,7 +285,7 @@ void __devinit arch_init_sched_domains(void)
 #endif
 
        /* Calculate CPU power for physical packages and nodes */
-       for_each_cpu_mask(i, cpu_default_map) {
+       for_each_cpu_mask(i, *cpu_map) {
                int power;
                struct sched_domain *sd;
 #ifdef CONFIG_SCHED_SMT
@@ -359,13 +351,35 @@ next_sg:
                cpu_attach_domain(sd, i);
        }
 }
+/*
+ * Set up scheduler domains and groups.  Callers must hold the hotplug lock.
+ */
+void arch_init_sched_domains(const cpumask_t *cpu_map)
+{
+       cpumask_t cpu_default_map;
+
+       /*
+        * Setup mask for cpus without special case scheduling requirements.
+        * For now this just excludes isolated cpus, but could be used to
+        * exclude other special cases in the future.
+        */
+       cpus_andnot(cpu_default_map, *cpu_map, cpu_isolated_map);
+
+       build_sched_domains(&cpu_default_map);
+}
 
-void __devinit arch_destroy_sched_domains(void)
+void arch_destroy_sched_domains(const cpumask_t *cpu_map)
 {
 #ifdef CONFIG_NUMA
        int i;
        for (i = 0; i < MAX_NUMNODES; i++) {
+               cpumask_t nodemask = node_to_cpumask(i);
                struct sched_group *oldsg, *sg = sched_group_nodes[i];
+
+               cpus_and(nodemask, nodemask, *cpu_map);
+               if (cpus_empty(nodemask))
+                       continue;
+
                if (sg == NULL)
                        continue;
                sg = sg->next;
index 3865f088ffa26d9c7db30c932098a09db0762ba0..623b0a54670973039d65b5c4ad38b7488d2314d4 100644 (file)
@@ -346,6 +346,7 @@ smp_callin (void)
        lock_ipi_calllock();
        cpu_set(cpuid, cpu_online_map);
        unlock_ipi_calllock();
+       per_cpu(cpu_state, cpuid) = CPU_ONLINE;
 
        smp_setup_percpu_timer();
 
@@ -611,6 +612,7 @@ void __devinit smp_prepare_boot_cpu(void)
 {
        cpu_set(smp_processor_id(), cpu_online_map);
        cpu_set(smp_processor_id(), cpu_callin_map);
+       per_cpu(cpu_state, smp_processor_id()) = CPU_ONLINE;
 }
 
 /*
@@ -688,6 +690,7 @@ int __cpu_disable(void)
                return -EBUSY;
 
        remove_siblinginfo(cpu);
+       cpu_clear(cpu, cpu_online_map);
        fixup_irqs();
        local_flush_tlb_all();
        cpu_clear(cpu, cpu_callin_map);
@@ -774,6 +777,7 @@ __cpu_up (unsigned int cpu)
        if (cpu_isset(cpu, cpu_callin_map))
                return -EINVAL;
 
+       per_cpu(cpu_state, cpu) = CPU_UP_PREPARE;
        /* Processor goes to start_secondary(), sets online flag */
        ret = do_boot_cpu(sapicid, cpu);
        if (ret < 0)
index 1a0aed8490d177a7830dbe17f11b22e976fdc945..d0ee635daf2e7f4104c8b0dca480d9c4712d7dda 100644 (file)
@@ -87,7 +87,7 @@ struct xpc_rsvd_page {
        u8 partid;              /* partition ID from SAL */
        u8 version;
        u8 pad[6];              /* pad to u64 align */
-       u64 vars_pa;
+       volatile u64 vars_pa;
        u64 part_nasids[XP_NASID_MASK_WORDS] ____cacheline_aligned;
        u64 mach_nasids[XP_NASID_MASK_WORDS] ____cacheline_aligned;
 };
@@ -138,7 +138,7 @@ struct xpc_vars {
  * occupies half a cacheline.
  */
 struct xpc_vars_part {
-       u64 magic;
+       volatile u64 magic;
 
        u64 openclose_args_pa;  /* physical address of open and close args */
        u64 GPs_pa;             /* physical address of Get/Put values */
@@ -185,8 +185,8 @@ struct xpc_vars_part {
  * Define a Get/Put value pair (pointers) used with a message queue.
  */
 struct xpc_gp {
-       s64 get;        /* Get value */
-       s64 put;        /* Put value */
+       volatile s64 get;       /* Get value */
+       volatile s64 put;       /* Put value */
 };
 
 #define XPC_GP_SIZE \
@@ -231,7 +231,7 @@ struct xpc_openclose_args {
  */
 struct xpc_notify {
        struct semaphore sema;          /* notify semaphore */
-       u8 type;                        /* type of notification */
+       volatile u8 type;                       /* type of notification */
 
        /* the following two fields are only used if type == XPC_N_CALL */
        xpc_notify_func func;           /* user's notify function */
@@ -439,7 +439,7 @@ struct xpc_partition {
 
        /* XPC infrastructure referencing and teardown control */
 
-       u8 setup_state;                 /* infrastructure setup state */
+       volatile u8 setup_state;                        /* infrastructure setup state */
        wait_queue_head_t teardown_wq;  /* kthread waiting to teardown infra */
        atomic_t references;            /* #of references to infrastructure */
 
index 0bf6fbcc46d206bd2eb46d71066a5c44fc91ae99..6d02dac8056f99bc72d08553be8d2e28a4128211 100644 (file)
@@ -209,7 +209,7 @@ xpc_setup_infrastructure(struct xpc_partition *part)
         * With the setting of the partition setup_state to XPC_P_SETUP, we're
         * declaring that this partition is ready to go.
         */
-       (volatile u8) part->setup_state = XPC_P_SETUP;
+       part->setup_state = XPC_P_SETUP;
 
 
        /*
@@ -227,7 +227,7 @@ xpc_setup_infrastructure(struct xpc_partition *part)
        xpc_vars_part[partid].IPI_phys_cpuid =
                                        cpu_physical_id(smp_processor_id());
        xpc_vars_part[partid].nchannels = part->nchannels;
-       (volatile u64) xpc_vars_part[partid].magic = XPC_VP_MAGIC1;
+       xpc_vars_part[partid].magic = XPC_VP_MAGIC1;
 
        return xpcSuccess;
 }
@@ -355,7 +355,7 @@ xpc_pull_remote_vars_part(struct xpc_partition *part)
 
                /* let the other side know that we've pulled their variables */
 
-               (volatile u64) xpc_vars_part[partid].magic = XPC_VP_MAGIC2;
+               xpc_vars_part[partid].magic = XPC_VP_MAGIC2;
        }
 
        if (pulled_entry->magic == XPC_VP_MAGIC1) {
@@ -1183,7 +1183,7 @@ xpc_process_msg_IPI(struct xpc_partition *part, int ch_number)
                 */
                xpc_clear_local_msgqueue_flags(ch);
 
-               (volatile s64) ch->w_remote_GP.get = ch->remote_GP.get;
+               ch->w_remote_GP.get = ch->remote_GP.get;
 
                dev_dbg(xpc_chan, "w_remote_GP.get changed to %ld, partid=%d, "
                        "channel=%d\n", ch->w_remote_GP.get, ch->partid,
@@ -1211,7 +1211,7 @@ xpc_process_msg_IPI(struct xpc_partition *part, int ch_number)
                 */
                xpc_clear_remote_msgqueue_flags(ch);
 
-               (volatile s64) ch->w_remote_GP.put = ch->remote_GP.put;
+               ch->w_remote_GP.put = ch->remote_GP.put;
 
                dev_dbg(xpc_chan, "w_remote_GP.put changed to %ld, partid=%d, "
                        "channel=%d\n", ch->w_remote_GP.put, ch->partid,
@@ -1875,7 +1875,7 @@ xpc_send_msg(struct xpc_channel *ch, struct xpc_msg *msg, u8 notify_type,
                notify = &ch->notify_queue[msg_number % ch->local_nentries];
                notify->func = func;
                notify->key = key;
-               (volatile u8) notify->type = notify_type;
+               notify->type = notify_type;
 
                // >>> is a mb() needed here?
 
index cd7ed73f0e7ab73a87b37ea4d567810b511ecee9..578265ea9e678bdaeca66c70b149ba5fa66104e0 100644 (file)
@@ -253,7 +253,7 @@ xpc_rsvd_page_init(void)
         * This signifies to the remote partition that our reserved
         * page is initialized.
         */
-       (volatile u64) rp->vars_pa = __pa(xpc_vars);
+       rp->vars_pa = __pa(xpc_vars);
 
        return rp;
 }
index 50311eb07a2485f940288ff25127b36062d5d572..5aef7e406ef5f2a0a74e90a334ee4a5ad2817ffd 100644 (file)
@@ -371,10 +371,8 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset)
        if (!user_mode(regs))
                return 1;
 
-       if (current->flags & PF_FREEZE) {
-               refrigerator(0);
+       if (try_to_freeze()) 
                goto no_signal;
-       }
 
        if (!oldset)
                oldset = &current->blocked;
index 94f5a8eb2c22ec59e9fe951172aeb92749f4b937..bd9de7b00c0aa26b996e11c5fd7fb577a63c2278 100644 (file)
@@ -1416,6 +1416,12 @@ config HIGHMEM
        bool "High Memory Support"
        depends on MIPS32 && (CPU_R3000 || CPU_SB1 || CPU_R7000 || CPU_RM9000 || CPU_R10000) && !(MACH_DECSTATION || MOMENCO_JAGUAR_ATX)
 
+config ARCH_FLATMEM_ENABLE
+       def_bool y
+       depends on !NUMA
+
+source "mm/Kconfig"
+
 config SMP
        bool "Multi-Processing support"
        depends on CPU_RM9000 || (SIBYTE_SB1250 && !SIBYTE_STANDALONE) || SGI_IP27
index 6018ca25acebaf038ccc20988624033966252957..3a240e3e004c368c10cc86df391ac2fc2ceefdbe 100644 (file)
@@ -33,6 +33,7 @@
 #include <linux/root_dev.h>
 #include <linux/highmem.h>
 #include <linux/console.h>
+#include <linux/mmzone.h>
 
 #include <asm/addrspace.h>
 #include <asm/bootinfo.h>
@@ -356,6 +357,8 @@ static inline void bootmem_init(void)
        }
 #endif
 
+       memory_present(0, first_usable_pfn, max_low_pfn);
+
        /* Initialize the boot-time allocator with low memory only.  */
        bootmap_size = init_bootmem(first_usable_pfn, max_low_pfn);
 
@@ -557,6 +560,7 @@ void __init setup_arch(char **cmdline_p)
 
        parse_cmdline_early();
        bootmem_init();
+       sparse_init();
        paging_init();
        resource_init();
 }
index 73843c5287782f3ef74a6adaec316445c8e20764..9c9a271c8a3ae440748d89a22c464ea46444c46c 100644 (file)
@@ -128,7 +128,7 @@ static void __init fixrange_init(unsigned long start, unsigned long end,
 #endif /* CONFIG_MIPS64 */
 #endif /* CONFIG_HIGHMEM */
 
-#ifndef CONFIG_DISCONTIGMEM
+#ifndef CONFIG_NEED_MULTIPLE_NODES
 extern void pagetable_init(void);
 
 void __init paging_init(void)
@@ -253,7 +253,7 @@ void __init mem_init(void)
               initsize >> 10,
               (unsigned long) (totalhigh_pages << (PAGE_SHIFT-10)));
 }
-#endif /* !CONFIG_DISCONTIGMEM */
+#endif /* !CONFIG_NEED_MULTIPLE_NODES */
 
 #ifdef CONFIG_BLK_DEV_INITRD
 void free_initrd_mem(unsigned long start, unsigned long end)
index 3b88fdeef3294ec51ab46854b130f10f1303ab78..3fe94202da8ca7c21f1d8d973537aeb18b663711 100644 (file)
@@ -5,7 +5,7 @@
 
 void show_mem(void)
 {
-#ifndef CONFIG_DISCONTIGMEM  /* XXX(hch): later.. */
+#ifndef CONFIG_NEED_MULTIPLE_NODES  /* XXX(hch): later.. */
        int pfn, total = 0, reserved = 0;
        int shared = 0, cached = 0;
        int highmem = 0;
index 848f43970a4b4cd7123e0fa188e34ddd18ce20c3..a7835cd3f51f32500b316d0cc1d4bed5aaefdaae 100644 (file)
@@ -88,6 +88,9 @@ config 8xx
        depends on BROKEN
        bool "8xx"
 
+config E200
+       bool "e200"
+
 config E500
        bool "e500"
 
@@ -98,12 +101,12 @@ config PPC_FPU
 
 config BOOKE
        bool
-       depends on E500
+       depends on E200 || E500
        default y
 
 config FSL_BOOKE
        bool
-       depends on E500
+       depends on E200 || E500
        default y
 
 config PTE_64BIT
@@ -141,16 +144,16 @@ config ALTIVEC
 
 config SPE
        bool "SPE Support"
-       depends on E500
+       depends on E200 || E500
        ---help---
          This option enables kernel support for the Signal Processing
          Extensions (SPE) to the PowerPC processor. The kernel currently
          supports saving and restoring SPE registers, and turning on the
          'spe enable' bit so user processes can execute SPE instructions.
 
-         This option is only usefully if you have a processor that supports
+         This option is only useful if you have a processor that supports
          SPE (e500, otherwise known as 85xx series), but does not have any
-         affect on a non-spe cpu (it does, however add code to the kernel).
+         effect on a non-spe cpu (it does, however add code to the kernel).
 
          If in doubt, say Y here.
 
@@ -200,7 +203,7 @@ config TAU_AVERAGE
 
 config MATH_EMULATION
        bool "Math emulation"
-       depends on 4xx || 8xx || E500
+       depends on 4xx || 8xx || E200 || E500
        ---help---
          Some PowerPC chips designed for embedded applications do not have
          a floating-point unit and therefore do not implement the
@@ -214,6 +217,26 @@ config MATH_EMULATION
          here.  Saying Y here will not hurt performance (on any machine) but
          will increase the size of the kernel.
 
+config KEXEC
+       bool "kexec system call (EXPERIMENTAL)"
+       depends on EXPERIMENTAL
+       help
+         kexec is a system call that implements the ability to shutdown your
+         current kernel, and to start another kernel.  It is like a reboot
+         but it is indepedent of the system firmware.   And like a reboot
+         you can start any kernel with it, not just Linux.
+
+         The name comes from the similiarity to the exec system call.
+
+         It is an ongoing process to be certain the hardware in a machine
+         is properly shutdown, so do not be surprised if this code does not
+         initially work for you.  It may help to enable device hotplugging
+         support.  As of this writing the exact hardware interface is
+         strongly in flux, so no good recommendation can be made.
+
+         In the GameCube implementation, kexec allows you to load and
+         run DOL files, including kernel and homebrew DOLs.
+
 source "drivers/cpufreq/Kconfig"
 
 config CPU_FREQ_PMAC
@@ -254,7 +277,7 @@ config PPC_STD_MMU
 
 config NOT_COHERENT_CACHE
        bool
-       depends on 4xx || 8xx
+       depends on 4xx || 8xx || E200
        default y
 
 endmenu
index d2e1eea8e8e4cc18ad4e2043b7e987d34c5d75f7..e16c7710d4bef3442160e3d1886b7ac2690ba786 100644 (file)
@@ -66,7 +66,7 @@ config SERIAL_TEXT_DEBUG
 
 config PPC_OCP
        bool
-       depends on IBM_OCP || FSL_OCP || XILINX_OCP
+       depends on IBM_OCP || XILINX_OCP
        default y
 
 endmenu
index 0432a25b47354e75d0a09e4b2817d1afe7849313..f9b0d778dd82ee1d0ec03b2273f46511a51cdf4c 100644 (file)
@@ -29,7 +29,7 @@ CPP           = $(CC) -E $(CFLAGS)
 
 CHECKFLAGS     += -D__powerpc__
 
-ifndef CONFIG_E500
+ifndef CONFIG_FSL_BOOKE
 CFLAGS         += -mstring
 endif
 
@@ -38,6 +38,7 @@ 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
 
 AFLAGS += $(cpu-as-y)
 CFLAGS += $(cpu-as-y)
index 6fb4f738728c8fd09e0c3b40327d5a728df0111b..effe4a0624b0840d524a9c69e0a619c38f4c8edf 100644 (file)
@@ -39,7 +39,7 @@ char *avail_high;
 
 #define SCRATCH_SIZE   (128 << 10)
 
-static char scratch[SCRATCH_SIZE];     /* 1MB of scratch space for gunzip */
+static char scratch[SCRATCH_SIZE];     /* 128k of scratch space for gunzip */
 
 typedef void (*kernel_start_t)(int, int, void *, unsigned int, unsigned int);
 
index b284451802c95b45f9f8a312096f556c8ab1ff3f..b1457a8a9c0f0eff8cf3cf130396076438d8d7e5 100644 (file)
@@ -26,7 +26,10 @@ obj-$(CONFIG_KGDB)           += ppc-stub.o
 obj-$(CONFIG_SMP)              += smp.o smp-tbsync.o
 obj-$(CONFIG_TAU)              += temp.o
 obj-$(CONFIG_ALTIVEC)          += vecemu.o vector.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
index 01c226008dbf2abb71ec55a6a41df0dc68c16d56..50936cda0af9a723977c7897c44c9aa080d90daa 100644 (file)
@@ -903,7 +903,30 @@ struct cpu_spec    cpu_specs[] = {
                .dcache_bsize           = 32,
        },
 #endif /* CONFIG_44x */
-#ifdef CONFIG_E500
+#ifdef CONFIG_FSL_BOOKE
+       {       /* e200z5 */
+               .pvr_mask               = 0xfff00000,
+               .pvr_value              = 0x81000000,
+               .cpu_name               = "e200z5",
+               /* xxx - galak: add CPU_FTR_MAYBE_CAN_DOZE */
+               .cpu_features           = CPU_FTR_USE_TB,
+               .cpu_user_features      = PPC_FEATURE_32 |
+                       PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_EFP_SINGLE |
+                       PPC_FEATURE_UNIFIED_CACHE,
+               .dcache_bsize           = 32,
+       },
+       {       /* e200z6 */
+               .pvr_mask               = 0xfff00000,
+               .pvr_value              = 0x81100000,
+               .cpu_name               = "e200z6",
+               /* xxx - galak: add CPU_FTR_MAYBE_CAN_DOZE */
+               .cpu_features           = CPU_FTR_USE_TB,
+               .cpu_user_features      = PPC_FEATURE_32 |
+                       PPC_FEATURE_HAS_MMU | PPC_FEATURE_SPE_COMP |
+                       PPC_FEATURE_HAS_EFP_SINGLE |
+                       PPC_FEATURE_UNIFIED_CACHE,
+               .dcache_bsize           = 32,
+       },
        {       /* e500 */
                .pvr_mask               = 0xffff0000,
                .pvr_value              = 0x80200000,
index 8377b6ca26da4039fabc0ba5dd46861edb4e9190..d4df68629cc6a750a22e1106018057b4fef9952c 100644 (file)
@@ -60,6 +60,11 @@ mcheck_transfer_to_handler:
        TRANSFER_TO_HANDLER_EXC_LEVEL(MCHECK)
        b       transfer_to_handler_full
 
+       .globl  debug_transfer_to_handler
+debug_transfer_to_handler:
+       TRANSFER_TO_HANDLER_EXC_LEVEL(DEBUG)
+       b       transfer_to_handler_full
+
        .globl  crit_transfer_to_handler
 crit_transfer_to_handler:
        TRANSFER_TO_HANDLER_EXC_LEVEL(CRIT)
@@ -835,6 +840,10 @@ ret_from_crit_exc:
        RET_FROM_EXC_LEVEL(SPRN_CSRR0, SPRN_CSRR1, RFCI)
 
 #ifdef CONFIG_BOOKE
+       .globl  ret_from_debug_exc
+ret_from_debug_exc:
+       RET_FROM_EXC_LEVEL(SPRN_DSRR0, SPRN_DSRR1, RFDI)
+
        .globl  ret_from_mcheck_exc
 ret_from_mcheck_exc:
        RET_FROM_EXC_LEVEL(SPRN_MCSRR0, SPRN_MCSRR1, RFMCI)
index 9c50f9d2657c10d1e0dea4199f3f33149c9cb33f..9342acf12e72d1c45bbec42ca09f6bdebf2cfe42 100644 (file)
@@ -49,6 +49,7 @@
  *
  * On 40x critical is the only additional level
  * On 44x/e500 we have critical and machine check
+ * On e200 we have critical and debug (machine check occurs via critical)
  *
  * Additionally we reserve a SPRG for each priority level so we can free up a
  * GPR to use as the base for indirect access to the exception stacks.  This
 
 /* CRIT_SPRG only used in critical exception handling */
 #define CRIT_SPRG      SPRN_SPRG2
-/* MCHECK_SPRG only used in critical exception handling */
+/* MCHECK_SPRG only used in machine check exception handling */
 #define MCHECK_SPRG    SPRN_SPRG6W
 
 #define MCHECK_STACK_TOP       (exception_stack_top - 4096)
 #define CRIT_STACK_TOP         (exception_stack_top)
 
+/* only on e200 for now */
+#define DEBUG_STACK_TOP                (exception_stack_top - 4096)
+#define DEBUG_SPRG             SPRN_SPRG6W
+
 #ifdef CONFIG_SMP
 #define BOOKE_LOAD_EXC_LEVEL_STACK(level)              \
        mfspr   r8,SPRN_PIR;                            \
 
 #define CRITICAL_EXCEPTION_PROLOG \
                EXC_LEVEL_EXCEPTION_PROLOG(CRIT, SPRN_CSRR0, SPRN_CSRR1)
+#define DEBUG_EXCEPTION_PROLOG \
+               EXC_LEVEL_EXCEPTION_PROLOG(DEBUG, SPRN_DSRR0, SPRN_DSRR1)
 #define MCHECK_EXCEPTION_PROLOG \
                EXC_LEVEL_EXCEPTION_PROLOG(MCHECK, SPRN_MCSRR0, SPRN_MCSRR1)
 
@@ -205,6 +212,60 @@ label:
  * save (and later restore) the MSR via SPRN_CSRR1, which will still have
  * the MSR_DE bit set.
  */
+#ifdef CONFIG_E200
+#define DEBUG_EXCEPTION                                                              \
+       START_EXCEPTION(Debug);                                               \
+       DEBUG_EXCEPTION_PROLOG;                                               \
+                                                                             \
+       /*                                                                    \
+        * If there is a single step or branch-taken exception in an          \
+        * exception entry sequence, it was probably meant to apply to        \
+        * the code where the exception occurred (since exception entry       \
+        * doesn't turn off DE automatically).  We simulate the effect        \
+        * of turning off DE on entry to an exception handler by turning      \
+        * off DE in the CSRR1 value and clearing the debug status.           \
+        */                                                                   \
+       mfspr   r10,SPRN_DBSR;          /* check single-step/branch taken */  \
+       andis.  r10,r10,DBSR_IC@h;                                            \
+       beq+    2f;                                                           \
+                                                                             \
+       lis     r10,KERNELBASE@h;       /* check if exception in vectors */   \
+       ori     r10,r10,KERNELBASE@l;                                         \
+       cmplw   r12,r10;                                                      \
+       blt+    2f;                     /* addr below exception vectors */    \
+                                                                             \
+       lis     r10,Debug@h;                                                  \
+       ori     r10,r10,Debug@l;                                              \
+       cmplw   r12,r10;                                                      \
+       bgt+    2f;                     /* addr above exception vectors */    \
+                                                                             \
+       /* here it looks like we got an inappropriate debug exception. */     \
+1:     rlwinm  r9,r9,0,~MSR_DE;        /* clear DE in the CDRR1 value */     \
+       lis     r10,DBSR_IC@h;          /* clear the IC event */              \
+       mtspr   SPRN_DBSR,r10;                                                \
+       /* restore state and get out */                                       \
+       lwz     r10,_CCR(r11);                                                \
+       lwz     r0,GPR0(r11);                                                 \
+       lwz     r1,GPR1(r11);                                                 \
+       mtcrf   0x80,r10;                                                     \
+       mtspr   SPRN_DSRR0,r12;                                               \
+       mtspr   SPRN_DSRR1,r9;                                                \
+       lwz     r9,GPR9(r11);                                                 \
+       lwz     r12,GPR12(r11);                                               \
+       mtspr   DEBUG_SPRG,r8;                                                \
+       BOOKE_LOAD_EXC_LEVEL_STACK(DEBUG); /* r8 points to the debug stack */ \
+       lwz     r10,GPR10-INT_FRAME_SIZE(r8);                                 \
+       lwz     r11,GPR11-INT_FRAME_SIZE(r8);                                 \
+       mfspr   r8,DEBUG_SPRG;                                                \
+                                                                             \
+       RFDI;                                                                 \
+       b       .;                                                            \
+                                                                             \
+       /* continue normal handling for a critical exception... */            \
+2:     mfspr   r4,SPRN_DBSR;                                                 \
+       addi    r3,r1,STACK_FRAME_OVERHEAD;                                   \
+       EXC_XFER_TEMPLATE(DebugException, 0x2002, (MSR_KERNEL & ~(MSR_ME|MSR_DE|MSR_CE)), NOCOPY, debug_transfer_to_handler, ret_from_debug_exc)
+#else
 #define DEBUG_EXCEPTION                                                              \
        START_EXCEPTION(Debug);                                               \
        CRITICAL_EXCEPTION_PROLOG;                                            \
@@ -257,6 +318,7 @@ label:
 2:     mfspr   r4,SPRN_DBSR;                                                 \
        addi    r3,r1,STACK_FRAME_OVERHEAD;                                   \
        EXC_XFER_TEMPLATE(DebugException, 0x2002, (MSR_KERNEL & ~(MSR_ME|MSR_DE|MSR_CE)), NOCOPY, crit_transfer_to_handler, ret_from_crit_exc)
+#endif
 
 #define INSTRUCTION_STORAGE_EXCEPTION                                        \
        START_EXCEPTION(InstructionStorage)                                   \
index ce36e88ba6277ea68631ddd0fc8fb13623e94fe6..eb804b7a3cb21117fbbcf45769aabb3788d0d37c 100644 (file)
@@ -102,6 +102,7 @@ invstr:     mflr    r6                              /* Make it accessible */
        or      r7,r7,r4
        mtspr   SPRN_MAS6,r7
        tlbsx   0,r6                            /* search MSR[IS], SPID=PID0 */
+#ifndef CONFIG_E200
        mfspr   r7,SPRN_MAS1
        andis.  r7,r7,MAS1_VALID@h
        bne     match_TLB
@@ -118,6 +119,7 @@ invstr:     mflr    r6                              /* Make it accessible */
        or      r7,r7,r4
        mtspr   SPRN_MAS6,r7
        tlbsx   0,r6                            /* Fall through, we had to match */
+#endif
 match_TLB:
        mfspr   r7,SPRN_MAS0
        rlwinm  r3,r7,16,20,31                  /* Extract MAS0(Entry) */
@@ -196,8 +198,10 @@ skpinv:    addi    r6,r6,1                         /* Increment */
 /* 4. Clear out PIDs & Search info */
        li      r6,0
        mtspr   SPRN_PID0,r6
+#ifndef CONFIG_E200
        mtspr   SPRN_PID1,r6
        mtspr   SPRN_PID2,r6
+#endif
        mtspr   SPRN_MAS6,r6
 
 /* 5. Invalidate mapping we started in */
@@ -277,7 +281,9 @@ skpinv:     addi    r6,r6,1                         /* Increment */
        SET_IVOR(32, SPEUnavailable);
        SET_IVOR(33, SPEFloatingPointData);
        SET_IVOR(34, SPEFloatingPointRound);
+#ifndef CONFIG_E200
        SET_IVOR(35, PerformanceMonitor);
+#endif
 
        /* Establish the interrupt vector base */
        lis     r4,interrupt_base@h     /* IVPR only uses the high 16-bits */
@@ -285,6 +291,9 @@ skpinv:     addi    r6,r6,1                         /* Increment */
 
        /* Setup the defaults for TLB entries */
        li      r2,(MAS4_TSIZED(BOOKE_PAGESZ_4K))@l
+#ifdef CONFIG_E200
+       oris    r2,r2,MAS4_TLBSELD(1)@h
+#endif
        mtspr   SPRN_MAS4, r2
 
 #if 0
@@ -293,6 +302,12 @@ skpinv:    addi    r6,r6,1                         /* Increment */
        oris    r2,r2,HID0_DOZE@h
        mtspr   SPRN_HID0, r2
 #endif
+#ifdef CONFIG_E200
+       /* enable dedicated debug exception handling resources (Debug APU) */
+       mfspr   r2,SPRN_HID0
+       ori     r2,r2,HID0_DAPUEN@l
+       mtspr   SPRN_HID0,r2
+#endif
 
 #if !defined(CONFIG_BDI_SWITCH)
        /*
@@ -414,7 +429,12 @@ interrupt_base:
        CRITICAL_EXCEPTION(0x0100, CriticalInput, UnknownException)
 
        /* Machine Check Interrupt */
+#ifdef CONFIG_E200
+       /* no RFMCI, MCSRRs on E200 */
+       CRITICAL_EXCEPTION(0x0200, MachineCheck, MachineCheckException)
+#else
        MCHECK_EXCEPTION(0x0200, MachineCheck, MachineCheckException)
+#endif
 
        /* Data Storage Interrupt */
        START_EXCEPTION(DataStorage)
@@ -519,8 +539,13 @@ interrupt_base:
        /* Floating Point Unavailable Interrupt */
 #ifdef CONFIG_PPC_FPU
        FP_UNAVAILABLE_EXCEPTION
+#else
+#ifdef CONFIG_E200
+       /* E200 treats 'normal' floating point instructions as FP Unavail exception */
+       EXCEPTION(0x0800, FloatingPointUnavailable, ProgramCheckException, EXC_XFER_EE)
 #else
        EXCEPTION(0x0800, FloatingPointUnavailable, UnknownException, EXC_XFER_EE)
+#endif
 #endif
 
        /* System Call Interrupt */
@@ -691,6 +716,7 @@ interrupt_base:
 /*
  * Local functions
  */
+
        /*
         * Data TLB exceptions will bail out to this point
         * if they can't resolve the lightweight TLB fault.
@@ -761,6 +787,31 @@ END_FTR_SECTION_IFSET(CPU_FTR_BIG_PHYS)
 2:     rlwimi  r11, r12, 0, 20, 31     /* Extract RPN from PTE and merge with perms */
        mtspr   SPRN_MAS3, r11
 #endif
+#ifdef CONFIG_E200
+       /* Round robin TLB1 entries assignment */
+       mfspr   r12, SPRN_MAS0
+
+       /* Extract TLB1CFG(NENTRY) */
+       mfspr   r11, SPRN_TLB1CFG
+       andi.   r11, r11, 0xfff
+
+       /* Extract MAS0(NV) */
+       andi.   r13, r12, 0xfff
+       addi    r13, r13, 1
+       cmpw    0, r13, r11
+       addi    r12, r12, 1
+
+       /* check if we need to wrap */
+       blt     7f
+
+       /* wrap back to first free tlbcam entry */
+       lis     r13, tlbcam_index@ha
+       lwz     r13, tlbcam_index@l(r13)
+       rlwimi  r12, r13, 0, 20, 31
+7:
+       mtspr   SPRN_MAS0,r12
+#endif /* CONFIG_E200 */
+
        tlbwe
 
        /* Done...restore registers and get out of here.  */
diff --git a/arch/ppc/kernel/machine_kexec.c b/arch/ppc/kernel/machine_kexec.c
new file mode 100644 (file)
index 0000000..84d65a8
--- /dev/null
@@ -0,0 +1,118 @@
+/*
+ * machine_kexec.c - handle transition of Linux booting another kernel
+ * Copyright (C) 2002-2003 Eric Biederman  <ebiederm@xmission.com>
+ *
+ * GameCube/ppc32 port Copyright (C) 2004 Albert Herranz
+ *
+ * This source code is licensed under the GNU General Public License,
+ * Version 2.  See the file COPYING for more details.
+ */
+
+#include <linux/mm.h>
+#include <linux/kexec.h>
+#include <linux/delay.h>
+#include <linux/reboot.h>
+#include <asm/pgtable.h>
+#include <asm/pgalloc.h>
+#include <asm/mmu_context.h>
+#include <asm/io.h>
+#include <asm/hw_irq.h>
+#include <asm/cacheflush.h>
+#include <asm/machdep.h>
+
+typedef NORET_TYPE void (*relocate_new_kernel_t)(
+                               unsigned long indirection_page,
+                               unsigned long reboot_code_buffer,
+                               unsigned long start_address) ATTRIB_NORET;
+
+const extern unsigned char relocate_new_kernel[];
+const extern unsigned int relocate_new_kernel_size;
+
+void machine_shutdown(void)
+{
+       if (ppc_md.machine_shutdown)
+               ppc_md.machine_shutdown();
+}
+
+void machine_crash_shutdown(struct pt_regs *regs)
+{
+       if (ppc_md.machine_crash_shutdown)
+               ppc_md.machine_crash_shutdown();
+}
+
+/*
+ * Do what every setup is needed on image and the
+ * reboot code buffer to allow us to avoid allocations
+ * later.
+ */
+int machine_kexec_prepare(struct kimage *image)
+{
+       if (ppc_md.machine_kexec_prepare)
+               return ppc_md.machine_kexec_prepare(image);
+       /*
+        * Fail if platform doesn't provide its own machine_kexec_prepare
+        * implementation.
+        */
+       return -ENOSYS;
+}
+
+void machine_kexec_cleanup(struct kimage *image)
+{
+       if (ppc_md.machine_kexec_cleanup)
+               ppc_md.machine_kexec_cleanup(image);
+}
+
+/*
+ * Do not allocate memory (or fail in any way) in machine_kexec().
+ * We are past the point of no return, committed to rebooting now.
+ */
+NORET_TYPE void machine_kexec(struct kimage *image)
+{
+       if (ppc_md.machine_kexec)
+               ppc_md.machine_kexec(image);
+       else {
+               /*
+                * Fall back to normal restart if platform doesn't provide
+                * its own kexec function, and user insist to kexec...
+                */
+               machine_restart(NULL);
+       }
+       for(;;);
+}
+
+/*
+ * This is a generic machine_kexec function suitable at least for
+ * non-OpenFirmware embedded platforms.
+ * It merely copies the image relocation code to the control page and
+ * jumps to it.
+ * A platform specific function may just call this one.
+ */
+void machine_kexec_simple(struct kimage *image)
+{
+       unsigned long page_list;
+       unsigned long reboot_code_buffer, reboot_code_buffer_phys;
+       relocate_new_kernel_t rnk;
+
+       /* Interrupts aren't acceptable while we reboot */
+       local_irq_disable();
+
+       page_list = image->head;
+
+       /* we need both effective and real address here */
+       reboot_code_buffer =
+                       (unsigned long)page_address(image->control_code_page);
+       reboot_code_buffer_phys = virt_to_phys((void *)reboot_code_buffer);
+
+       /* copy our kernel relocation code to the control code page */
+       memcpy((void *)reboot_code_buffer, relocate_new_kernel,
+                                               relocate_new_kernel_size);
+
+       flush_icache_range(reboot_code_buffer,
+                               reboot_code_buffer + KEXEC_CONTROL_CODE_SIZE);
+       printk(KERN_INFO "Bye!\n");
+
+       /* now call it */
+       rnk = (relocate_new_kernel_t) reboot_code_buffer;
+       (*rnk)(page_list, reboot_code_buffer_phys, image->start);
+}
+
index 7329ef177a18c36c4f068d2a09dad48d34fce92e..b6a63a49a23226312126c8809545ee7200599c19 100644 (file)
@@ -593,6 +593,14 @@ _GLOBAL(flush_instruction_cache)
        iccci   0,r3
 #endif
 #elif CONFIG_FSL_BOOKE
+BEGIN_FTR_SECTION
+       mfspr   r3,SPRN_L1CSR0
+       ori     r3,r3,L1CSR0_CFI|L1CSR0_CLFC
+       /* msync; isync recommended here */
+       mtspr   SPRN_L1CSR0,r3
+       isync
+       blr
+END_FTR_SECTION_IFCLR(CPU_FTR_SPLIT_ID_CACHE)
        mfspr   r3,SPRN_L1CSR1
        ori     r3,r3,L1CSR1_ICFI|L1CSR1_ICLFR
        mtspr   SPRN_L1CSR1,r3
@@ -1436,7 +1444,7 @@ _GLOBAL(sys_call_table)
        .long sys_mq_timedreceive       /* 265 */
        .long sys_mq_notify
        .long sys_mq_getsetattr
-       .long sys_ni_syscall            /* 268 reserved for sys_kexec_load */
+       .long sys_kexec_load
        .long sys_add_key
        .long sys_request_key           /* 270 */
        .long sys_keyctl
index 918f6b252e454cc9c8a3374abfe0bc6b57e60569..fa1dad96b8309f1b44a4a40aef2748a36b4cf3e0 100644 (file)
@@ -36,7 +36,7 @@
 /* A lock to regulate grabbing the interrupt */
 DEFINE_SPINLOCK(perfmon_lock);
 
-#ifdef CONFIG_FSL_BOOKE
+#if defined (CONFIG_FSL_BOOKE) && !defined (CONFIG_E200)
 static void dummy_perf(struct pt_regs *regs)
 {
        unsigned int pmgc0 = mfpmr(PMRN_PMGC0);
diff --git a/arch/ppc/kernel/relocate_kernel.S b/arch/ppc/kernel/relocate_kernel.S
new file mode 100644 (file)
index 0000000..7ff69c4
--- /dev/null
@@ -0,0 +1,123 @@
+/*
+ * relocate_kernel.S - put the kernel image in place to boot
+ * Copyright (C) 2002-2003 Eric Biederman  <ebiederm@xmission.com>
+ *
+ * GameCube/ppc32 port Copyright (C) 2004 Albert Herranz
+ *
+ * This source code is licensed under the GNU General Public License,
+ * Version 2.  See the file COPYING for more details.
+ */
+
+#include <asm/reg.h>
+#include <asm/ppc_asm.h>
+#include <asm/processor.h>
+
+#include <asm/kexec.h>
+
+#define PAGE_SIZE      4096 /* must be same value as in <asm/page.h> */
+
+       /*
+        * Must be relocatable PIC code callable as a C function.
+        */
+       .globl relocate_new_kernel
+relocate_new_kernel:
+       /* r3 = page_list   */
+       /* r4 = reboot_code_buffer */
+       /* r5 = start_address      */
+
+       li      r0, 0
+
+       /*
+        * Set Machine Status Register to a known status,
+        * switch the MMU off and jump to 1: in a single step.
+        */
+
+       mr      r8, r0
+       ori     r8, r8, MSR_RI|MSR_ME
+       mtspr   SRR1, r8
+       addi    r8, r4, 1f - relocate_new_kernel
+       mtspr   SRR0, r8
+       sync
+       rfi
+
+1:
+       /* from this point address translation is turned off */
+       /* and interrupts are disabled */
+
+       /* set a new stack at the bottom of our page... */
+       /* (not really needed now) */
+       addi    r1, r4, KEXEC_CONTROL_CODE_SIZE - 8 /* for LR Save+Back Chain */
+       stw     r0, 0(r1)
+
+       /* Do the copies */
+       li      r6, 0 /* checksum */
+       mr      r0, r3
+       b       1f
+
+0:     /* top, read another word for the indirection page */
+       lwzu    r0, 4(r3)
+
+1:
+       /* is it a destination page? (r8) */
+       rlwinm. r7, r0, 0, 31, 31 /* IND_DESTINATION (1<<0) */
+       beq     2f
+
+       rlwinm  r8, r0, 0, 0, 19 /* clear kexec flags, page align */
+       b       0b
+
+2:     /* is it an indirection page? (r3) */
+       rlwinm. r7, r0, 0, 30, 30 /* IND_INDIRECTION (1<<1) */
+       beq     2f
+
+       rlwinm  r3, r0, 0, 0, 19 /* clear kexec flags, page align */
+       subi    r3, r3, 4
+       b       0b
+
+2:     /* are we done? */
+       rlwinm. r7, r0, 0, 29, 29 /* IND_DONE (1<<2) */
+       beq     2f
+       b       3f
+
+2:     /* is it a source page? (r9) */
+       rlwinm. r7, r0, 0, 28, 28 /* IND_SOURCE (1<<3) */
+       beq     0b
+
+       rlwinm  r9, r0, 0, 0, 19 /* clear kexec flags, page align */
+
+       li      r7, PAGE_SIZE / 4
+       mtctr   r7
+       subi    r9, r9, 4
+       subi    r8, r8, 4
+9:
+       lwzu    r0, 4(r9)  /* do the copy */
+       xor     r6, r6, r0
+       stwu    r0, 4(r8)
+       dcbst   0, r8
+       sync
+       icbi    0, r8
+       bdnz    9b
+
+       addi    r9, r9, 4
+       addi    r8, r8, 4
+       b       0b
+
+3:
+
+       /* To be certain of avoiding problems with self-modifying code
+        * execute a serializing instruction here.
+        */
+       isync
+       sync
+
+       /* jump to the entry point, usually the setup routine */
+       mtlr    r5
+       blrl
+
+1:     b       1b
+
+relocate_new_kernel_end:
+
+       .globl relocate_new_kernel_size
+relocate_new_kernel_size:
+       .long relocate_new_kernel_end - relocate_new_kernel
+
index 7c8437da09d5d470407dee3eb07680e97404433a..8aaeb6f4e750249026e257b3e416604eb09c075f 100644 (file)
@@ -705,8 +705,7 @@ int do_signal(sigset_t *oldset, struct pt_regs *regs)
        unsigned long frame, newsp;
        int signr, ret;
 
-       if (current->flags & PF_FREEZE) {
-               refrigerator(PF_FREEZE);
+       if (try_to_freeze()) {
                signr = 0;
                if (!signal_pending(current))
                        goto no_signal;
index 2ca8ecfeefd978058bb65d6ca3d526d1e640a483..9e6ae5696650259da8212b076ca441f145fd5dbb 100644 (file)
@@ -173,13 +173,13 @@ static inline int check_io_access(struct pt_regs *regs)
 /* On 4xx, the reason for the machine check or program exception
    is in the ESR. */
 #define get_reason(regs)       ((regs)->dsisr)
-#ifndef CONFIG_E500
+#ifndef CONFIG_FSL_BOOKE
 #define get_mc_reason(regs)    ((regs)->dsisr)
 #else
 #define get_mc_reason(regs)    (mfspr(SPRN_MCSR))
 #endif
 #define REASON_FP              ESR_FP
-#define REASON_ILLEGAL         ESR_PIL
+#define REASON_ILLEGAL         (ESR_PIL | ESR_PUO)
 #define REASON_PRIVILEGED      ESR_PPR
 #define REASON_TRAP            ESR_PTR
 
@@ -302,7 +302,25 @@ void MachineCheckException(struct pt_regs *regs)
                printk("Bus - Instruction Parity Error\n");
        if (reason & MCSR_BUS_RPERR)
                printk("Bus - Read Parity Error\n");
-#else /* !CONFIG_4xx && !CONFIG_E500 */
+#elif defined (CONFIG_E200)
+       printk("Machine check in kernel mode.\n");
+       printk("Caused by (from MCSR=%lx): ", reason);
+
+       if (reason & MCSR_MCP)
+               printk("Machine Check Signal\n");
+       if (reason & MCSR_CP_PERR)
+               printk("Cache Push Parity Error\n");
+       if (reason & MCSR_CPERR)
+               printk("Cache Parity Error\n");
+       if (reason & MCSR_EXCP_ERR)
+               printk("ISI, ITLB, or Bus Error on first instruction fetch for an exception handler\n");
+       if (reason & MCSR_BUS_IRERR)
+               printk("Bus - Read Bus Error on instruction fetch\n");
+       if (reason & MCSR_BUS_DRERR)
+               printk("Bus - Read Bus Error on data load\n");
+       if (reason & MCSR_BUS_WRERR)
+               printk("Bus - Write Bus Error on buffered store or cache line push\n");
+#else /* !CONFIG_4xx && !CONFIG_E500 && !CONFIG_E200 */
        printk("Machine check in kernel mode.\n");
        printk("Caused by (from SRR1=%lx): ", reason);
        switch (reason & 0x601F0000) {
index 72f7c0d1c0ed90fccaa3fe2e56f02680ba3d44a1..3d79ce281b677f52eb359f6067e945706cf963c4 100644 (file)
@@ -39,7 +39,6 @@
 #include <linux/vmalloc.h>
 #include <linux/init.h>
 #include <linux/delay.h>
-#include <linux/bootmem.h>
 #include <linux/highmem.h>
 
 #include <asm/pgalloc.h>
index a7f61614038110436c534ba86929e4e467555db7..b7bcbc232f394cfc891c255716af34ff3657b8c8 100644 (file)
@@ -36,7 +36,6 @@
 #include <linux/vmalloc.h>
 #include <linux/init.h>
 #include <linux/delay.h>
-#include <linux/bootmem.h>
 #include <linux/highmem.h>
 
 #include <asm/pgalloc.h>
index e07990efa046e238b8dcc4deadff38bb80afcf3d..af9ca0eb6d55b6aba7fd0903371cbeef313c2199 100644 (file)
@@ -41,7 +41,6 @@
 #include <linux/vmalloc.h>
 #include <linux/init.h>
 #include <linux/delay.h>
-#include <linux/bootmem.h>
 #include <linux/highmem.h>
 
 #include <asm/pgalloc.h>
@@ -126,7 +125,7 @@ void settlbcam(int index, unsigned long virt, phys_addr_t phys,
                flags |= _PAGE_COHERENT;
 #endif
 
-       TLBCAM[index].MAS0 = MAS0_TLBSEL(1) | MAS0_ESEL(index);
+       TLBCAM[index].MAS0 = MAS0_TLBSEL(1) | MAS0_ESEL(index) | MAS0_NV(index+1);
        TLBCAM[index].MAS1 = MAS1_VALID | MAS1_IPROT | MAS1_TSIZE(tsize) | MAS1_TID(pid);
        TLBCAM[index].MAS2 = virt & PAGE_MASK;
 
index 37ece1542799cefdb069ff58e120fcfe5a89af86..ddd04d4c1ea9ecb0b95413d6e51fc01b0856fe38 100644 (file)
@@ -94,20 +94,24 @@ mpc834x_sys_setup_arch(void)
 
        /* setup the board related information for the enet controllers */
        pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC83xx_TSEC1);
-       pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR;
-       pdata->interruptPHY = MPC83xx_IRQ_EXT1;
-       pdata->phyid = 0;
-       /* fixup phy address */
-       pdata->phy_reg_addr += binfo->bi_immr_base;
-       memcpy(pdata->mac_addr, binfo->bi_enetaddr, 6);
+       if (pdata) {
+               pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR;
+               pdata->interruptPHY = MPC83xx_IRQ_EXT1;
+               pdata->phyid = 0;
+               /* fixup phy address */
+               pdata->phy_reg_addr += binfo->bi_immr_base;
+               memcpy(pdata->mac_addr, binfo->bi_enetaddr, 6);
+       }
 
        pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC83xx_TSEC2);
-       pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR;
-       pdata->interruptPHY = MPC83xx_IRQ_EXT2;
-       pdata->phyid = 1;
-       /* fixup phy address */
-       pdata->phy_reg_addr += binfo->bi_immr_base;
-       memcpy(pdata->mac_addr, binfo->bi_enet1addr, 6);
+       if (pdata) {
+               pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR;
+               pdata->interruptPHY = MPC83xx_IRQ_EXT2;
+               pdata->phyid = 1;
+               /* fixup phy address */
+               pdata->phy_reg_addr += binfo->bi_immr_base;
+               memcpy(pdata->mac_addr, binfo->bi_enet1addr, 6);
+       }
 
 #ifdef CONFIG_BLK_DEV_INITRD
        if (initrd_start)
index a2ed611cd936877f836e381b23c14cf0193969a2..ddd2e9a5bb121306863ce560ca48c967f562277a 100644 (file)
@@ -92,28 +92,34 @@ mpc8540ads_setup_arch(void)
 
        /* setup the board related information for the enet controllers */
        pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC1);
-       pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR;
-       pdata->interruptPHY = MPC85xx_IRQ_EXT5;
-       pdata->phyid = 0;
-       /* fixup phy address */
-       pdata->phy_reg_addr += binfo->bi_immr_base;
-       memcpy(pdata->mac_addr, binfo->bi_enetaddr, 6);
+       if (pdata) {
+               pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR;
+               pdata->interruptPHY = MPC85xx_IRQ_EXT5;
+               pdata->phyid = 0;
+               /* fixup phy address */
+               pdata->phy_reg_addr += binfo->bi_immr_base;
+               memcpy(pdata->mac_addr, binfo->bi_enetaddr, 6);
+       }
 
        pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC2);
-       pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR;
-       pdata->interruptPHY = MPC85xx_IRQ_EXT5;
-       pdata->phyid = 1;
-       /* fixup phy address */
-       pdata->phy_reg_addr += binfo->bi_immr_base;
-       memcpy(pdata->mac_addr, binfo->bi_enet1addr, 6);
-
-       pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_FEC);
-       pdata->board_flags = 0;
-       pdata->interruptPHY = MPC85xx_IRQ_EXT5;
-       pdata->phyid = 3;
-       /* fixup phy address */
-       pdata->phy_reg_addr += binfo->bi_immr_base;
-       memcpy(pdata->mac_addr, binfo->bi_enet2addr, 6);
+       if (pdata) {
+               pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR;
+               pdata->interruptPHY = MPC85xx_IRQ_EXT5;
+               pdata->phyid = 1;
+               /* fixup phy address */
+               pdata->phy_reg_addr += binfo->bi_immr_base;
+               memcpy(pdata->mac_addr, binfo->bi_enet1addr, 6);
+       }
+
+       if (pdata) {
+               pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_FEC);
+               pdata->board_flags = 0;
+               pdata->interruptPHY = MPC85xx_IRQ_EXT5;
+               pdata->phyid = 3;
+               /* fixup phy address */
+               pdata->phy_reg_addr += binfo->bi_immr_base;
+               memcpy(pdata->mac_addr, binfo->bi_enet2addr, 6);
+       }
 
 #ifdef CONFIG_BLK_DEV_INITRD
        if (initrd_start)
index d87dfd5ce0a23d62fed242154763b70e99e56f17..e18380258b6889b6e6bc77e875fc32299ebca10e 100644 (file)
@@ -90,20 +90,24 @@ mpc8560ads_setup_arch(void)
 
        /* setup the board related information for the enet controllers */
        pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC1);
-       pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR;
-       pdata->interruptPHY = MPC85xx_IRQ_EXT5;
-       pdata->phyid = 0;
-       /* fixup phy address */
-       pdata->phy_reg_addr += binfo->bi_immr_base;
-       memcpy(pdata->mac_addr, binfo->bi_enetaddr, 6);
+       if (pdata) {
+               pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR;
+               pdata->interruptPHY = MPC85xx_IRQ_EXT5;
+               pdata->phyid = 0;
+               /* fixup phy address */
+               pdata->phy_reg_addr += binfo->bi_immr_base;
+               memcpy(pdata->mac_addr, binfo->bi_enetaddr, 6);
+       }
 
        pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC2);
-       pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR;
-       pdata->interruptPHY = MPC85xx_IRQ_EXT5;
-       pdata->phyid = 1;
-       /* fixup phy address */
-       pdata->phy_reg_addr += binfo->bi_immr_base;
-       memcpy(pdata->mac_addr, binfo->bi_enet1addr, 6);
+       if (pdata) {
+               pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR;
+               pdata->interruptPHY = MPC85xx_IRQ_EXT5;
+               pdata->phyid = 1;
+               /* fixup phy address */
+               pdata->phy_reg_addr += binfo->bi_immr_base;
+               memcpy(pdata->mac_addr, binfo->bi_enet1addr, 6);
+       }
 
 #ifdef CONFIG_BLK_DEV_INITRD
        if (initrd_start)
index 3dbdd73618ebd9ce31d7377e60b9a2d57ffa3e33..165df94d4aa6d6d248479220e64b8005333aef1c 100644 (file)
@@ -129,20 +129,24 @@ sbc8560_setup_arch(void)
 
        /* setup the board related information for the enet controllers */
        pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC1);
-       pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR;
-       pdata->interruptPHY = MPC85xx_IRQ_EXT6;
-       pdata->phyid = 25;
-       /* fixup phy address */
-       pdata->phy_reg_addr += binfo->bi_immr_base;
-       memcpy(pdata->mac_addr, binfo->bi_enetaddr, 6);
+       if (pdata) {
+               pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR;
+               pdata->interruptPHY = MPC85xx_IRQ_EXT6;
+               pdata->phyid = 25;
+               /* fixup phy address */
+               pdata->phy_reg_addr += binfo->bi_immr_base;
+               memcpy(pdata->mac_addr, binfo->bi_enetaddr, 6);
+       }
 
        pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC2);
-       pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR;
-       pdata->interruptPHY = MPC85xx_IRQ_EXT7;
-       pdata->phyid = 26;
-       /* fixup phy address */
-       pdata->phy_reg_addr += binfo->bi_immr_base;
-       memcpy(pdata->mac_addr, binfo->bi_enet1addr, 6);
+       if (pdata) {
+               pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR;
+               pdata->interruptPHY = MPC85xx_IRQ_EXT7;
+               pdata->phyid = 26;
+               /* fixup phy address */
+               pdata->phy_reg_addr += binfo->bi_immr_base;
+               memcpy(pdata->mac_addr, binfo->bi_enet1addr, 6);
+       }
 
 #ifdef CONFIG_BLK_DEV_INITRD
        if (initrd_start)
index 9455bb6b45e933dfe220c62afe96a8bf4543b1ac..bb41265cfc85ca72675db8fd4ae7b46e9b8dfaad 100644 (file)
@@ -122,19 +122,23 @@ gp3_setup_arch(void)
 
        /* setup the board related information for the enet controllers */
        pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC1);
-/*     pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR; */
-       pdata->interruptPHY = MPC85xx_IRQ_EXT5;
-       pdata->phyid = 2;
-       pdata->phy_reg_addr += binfo->bi_immr_base;
-       memcpy(pdata->mac_addr, binfo->bi_enetaddr, 6);
+       if (pdata) {
+       /*      pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR; */
+               pdata->interruptPHY = MPC85xx_IRQ_EXT5;
+               pdata->phyid = 2;
+               pdata->phy_reg_addr += binfo->bi_immr_base;
+               memcpy(pdata->mac_addr, binfo->bi_enetaddr, 6);
+       }
 
        pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC2);
-/*     pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR; */
-       pdata->interruptPHY = MPC85xx_IRQ_EXT5;
-       pdata->phyid = 4;
-       /* fixup phy address */
-       pdata->phy_reg_addr += binfo->bi_immr_base;
-       memcpy(pdata->mac_addr, binfo->bi_enet1addr, 6);
+       if (pdata) {
+       /*      pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR; */
+               pdata->interruptPHY = MPC85xx_IRQ_EXT5;
+               pdata->phyid = 4;
+               /* fixup phy address */
+               pdata->phy_reg_addr += binfo->bi_immr_base;
+               memcpy(pdata->mac_addr, binfo->bi_enet1addr, 6);
+       }
 
 #ifdef CONFIG_BLK_DEV_INITRD
        if (initrd_start)
index 7d0ee308f662c7247c72f60484f58277a938b190..7d3fbb5c5db2955a1f5db8b1fc5cf13c2a2cd94e 100644 (file)
@@ -9,7 +9,6 @@
 #include <linux/string.h>
 #include <linux/init.h>
 #include <linux/ide.h>
-#include <linux/bootmem.h>
 
 #include <asm/io.h>
 #include <asm/pgtable.h>
index eda922ac31677db6bf12f18b0766a2beceaf8dcb..169dbf6534b9d0aec791a1c235d7a10635e4851b 100644 (file)
 #include <linux/root_dev.h>
 #include <linux/delay.h>
 #include <linux/seq_file.h>
-#include <linux/bootmem.h>
 #include <linux/mtd/physmap.h>
 #include <linux/mv643xx.h>
 #ifdef CONFIG_BOOTIMG
 #include <linux/bootimg.h>
 #endif
+#include <asm/io.h>
 #include <asm/page.h>
 #include <asm/time.h>
 #include <asm/smp.h>
index f6ff5192406115765036aaf0d386431acbb23073..719fb49fe2bcb22147988b7e96bdd0cd6c331579 100644 (file)
@@ -17,7 +17,6 @@
 #include <linux/delay.h>
 #include <linux/string.h>
 #include <linux/init.h>
-#include <linux/bootmem.h>
 
 #include <asm/sections.h>
 #include <asm/io.h>
index ea5e77080e8db58fbf2c970479f9881779d865d7..4c19a4ac7163134340b63077fb3df29b2312c6e0 100644 (file)
@@ -21,8 +21,8 @@
 #include <linux/string.h>
 #include <linux/mm.h>
 #include <linux/interrupt.h>
-#include <linux/bootmem.h>
 #include <linux/module.h>
+#include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/mpc8260.h>
 #include <asm/page.h>
index a5a752609e2c426c265a4c52fd274956a1f63d09..e71488469704bbea18077cbf903871b72d34afeb 100644 (file)
@@ -14,7 +14,6 @@
 #include <linux/delay.h>
 #include <linux/string.h>
 #include <linux/init.h>
-#include <linux/bootmem.h>
 
 #include <asm/io.h>
 #include <asm/prom.h>
index 580ed658e87253b51873b624ed5b8f0d228f1ba5..8f01e0f1d847404ceea8ce035f390c1fa2091f6c 100644 (file)
@@ -79,7 +79,7 @@ static struct ipic_info ipic_info[] = {
                .prio_mask = 7,
        },
        [17] = {
-               .pend   = IPIC_SIPNR_H,
+               .pend   = IPIC_SEPNR,
                .mask   = IPIC_SEMSR,
                .prio   = IPIC_SMPRR_A,
                .force  = IPIC_SEFCR,
@@ -87,7 +87,7 @@ static struct ipic_info ipic_info[] = {
                .prio_mask = 5,
        },
        [18] = {
-               .pend   = IPIC_SIPNR_H,
+               .pend   = IPIC_SEPNR,
                .mask   = IPIC_SEMSR,
                .prio   = IPIC_SMPRR_A,
                .force  = IPIC_SEFCR,
@@ -95,7 +95,7 @@ static struct ipic_info ipic_info[] = {
                .prio_mask = 6,
        },
        [19] = {
-               .pend   = IPIC_SIPNR_H,
+               .pend   = IPIC_SEPNR,
                .mask   = IPIC_SEMSR,
                .prio   = IPIC_SMPRR_A,
                .force  = IPIC_SEFCR,
@@ -103,7 +103,7 @@ static struct ipic_info ipic_info[] = {
                .prio_mask = 7,
        },
        [20] = {
-               .pend   = IPIC_SIPNR_H,
+               .pend   = IPIC_SEPNR,
                .mask   = IPIC_SEMSR,
                .prio   = IPIC_SMPRR_B,
                .force  = IPIC_SEFCR,
@@ -111,7 +111,7 @@ static struct ipic_info ipic_info[] = {
                .prio_mask = 4,
        },
        [21] = {
-               .pend   = IPIC_SIPNR_H,
+               .pend   = IPIC_SEPNR,
                .mask   = IPIC_SEMSR,
                .prio   = IPIC_SMPRR_B,
                .force  = IPIC_SEFCR,
@@ -119,7 +119,7 @@ static struct ipic_info ipic_info[] = {
                .prio_mask = 5,
        },
        [22] = {
-               .pend   = IPIC_SIPNR_H,
+               .pend   = IPIC_SEPNR,
                .mask   = IPIC_SEMSR,
                .prio   = IPIC_SMPRR_B,
                .force  = IPIC_SEFCR,
@@ -127,7 +127,7 @@ static struct ipic_info ipic_info[] = {
                .prio_mask = 6,
        },
        [23] = {
-               .pend   = IPIC_SIPNR_H,
+               .pend   = IPIC_SEPNR,
                .mask   = IPIC_SEMSR,
                .prio   = IPIC_SMPRR_B,
                .force  = IPIC_SEFCR,
index 7b241e7876bda9ca46ac5ffe7444bc5b90a7eb8b..cc77177fa1c620eb6aad9efb5f1776a8d0b816cb 100644 (file)
@@ -17,7 +17,6 @@
 #include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/string.h>
-#include <linux/bootmem.h>
 #include <linux/spinlock.h>
 #include <linux/mv643xx.h>
 
index b6f0f5dcf6eeaeb907ef39c460a513c0bd79eaf5..5b827e2bbe22f47a3d3b2e5ff44df82a4a65c384 100644 (file)
@@ -17,7 +17,6 @@
 #include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/string.h>
-#include <linux/bootmem.h>
 #include <linux/mv643xx.h>
 
 #include <asm/byteorder.h>
index cb27068bfcd49694123c1cf9cc27c692a80c2c9d..f804f25232ac5fc75168ad7c344ee88dc9dff6ee 100644 (file)
@@ -142,6 +142,23 @@ config PPC_SPLPAR
          processors, that is, which share physical processors between
          two or more partitions.
 
+config KEXEC
+       bool "kexec system call (EXPERIMENTAL)"
+       depends on PPC_MULTIPLATFORM && EXPERIMENTAL
+       help
+         kexec is a system call that implements the ability to shutdown your
+         current kernel, and to start another kernel.  It is like a reboot
+         but it is indepedent of the system firmware.  And like a reboot
+         you can start any kernel with it, not just Linux.
+
+         The name comes from the similiarity to the exec system call.
+
+         It is an ongoing process to be certain the hardware in a machine
+         is properly shutdown, so do not be surprised if this code does not
+         initially work for you.  It may help to enable device hotplugging
+         support.  As of this writing the exact hardware interface is
+         strongly in flux, so no good recommendation can be made.
+
 config IBMVIO
        depends on PPC_PSERIES || PPC_ISERIES
        bool
@@ -270,26 +287,7 @@ config SCHED_SMT
          when dealing with POWER5 cpus at a cost of slightly increased
          overhead in some places. If unsure say N here.
 
-config PREEMPT
-       bool "Preemptible Kernel"
-       help
-         This option reduces the latency of the kernel when reacting to
-         real-time or interactive events by allowing a low priority process to
-         be preempted even if it is in kernel mode executing a system call.
-
-         Say Y here if you are building a kernel for a desktop, embedded
-         or real-time system.  Say N if you are unsure.
-
-config PREEMPT_BKL
-       bool "Preempt The Big Kernel Lock"
-       depends on PREEMPT
-       default y
-       help
-         This option reduces the latency of the kernel by making the
-         big kernel lock preemptible.
-
-         Say Y here if you are building a kernel for a desktop system.
-         Say N if you are unsure.
+source "kernel/Kconfig.preempt"
 
 config EEH
        bool "PCI Extended Error Handling (EEH)" if EMBEDDED
index dffbfb7ac8d50590c9cabb2ee2eb58dd068785c0..d9b2660ef221f694e3b5a80c646b9fa508db0f41 100644 (file)
@@ -36,6 +36,7 @@ obj-$(CONFIG_PPC_PSERIES) += pSeries_pci.o pSeries_lpar.o pSeries_hvCall.o \
 obj-$(CONFIG_PPC_BPA) += bpa_setup.o bpa_iommu.o bpa_nvram.o \
                         bpa_iic.o spider-pic.o
 
+obj-$(CONFIG_KEXEC)            += machine_kexec.o
 obj-$(CONFIG_EEH)              += eeh.o
 obj-$(CONFIG_PROC_FS)          += proc_ppc64.o
 obj-$(CONFIG_RTAS_FLASH)       += rtas_flash.o
index 02c8f4e3e4bc644f66dbdde07b31544d9063266b..675c2708588f002758ff747490ec68817cb1d803 100644 (file)
@@ -1194,7 +1194,7 @@ _GLOBAL(pSeries_secondary_smp_init)
        bl      .__restore_cpu_setup
 
        /* Set up a paca value for this processor. Since we have the
-        * physical cpu id in r3, we need to search the pacas to find
+        * physical cpu id in r24, we need to search the pacas to find
         * which logical id maps to our physical one.
         */
        LOADADDR(r13, paca)             /* Get base vaddr of paca array  */
@@ -1207,8 +1207,8 @@ _GLOBAL(pSeries_secondary_smp_init)
        cmpwi   r5,NR_CPUS
        blt     1b
 
-99:    HMT_LOW                         /* Couldn't find our CPU id      */
-       b       99b
+       mr      r3,r24                  /* not found, copy phys to r3    */
+       b       .kexec_wait             /* next kernel might do better   */
 
 2:     mtspr   SPRG3,r13               /* Save vaddr of paca in SPRG3   */
        /* From now on, r24 is expected to be logica cpuid */
index 387923fcf9b06492a07b0b9e63c8748197de0e7b..02e96627fa6604999b3ac6aafd926fea185e2676 100644 (file)
@@ -34,6 +34,7 @@
 #include <asm/system.h>
 #include <asm/time.h>
 #include <asm/iSeries/ItExtVpdPanel.h>
+#include <asm/prom.h>
 
 #define MODULE_VERS "1.6"
 #define MODULE_NAME "lparcfg"
diff --git a/arch/ppc64/kernel/machine_kexec.c b/arch/ppc64/kernel/machine_kexec.c
new file mode 100644 (file)
index 0000000..fdb2fc6
--- /dev/null
@@ -0,0 +1,302 @@
+/*
+ * machine_kexec.c - handle transition of Linux booting another kernel
+ *
+ * Copyright (C) 2004-2005, IBM Corp.
+ *
+ * Created by: Milton D Miller II
+ *
+ * This source code is licensed under the GNU General Public License,
+ * Version 2.  See the file COPYING for more details.
+ */
+
+
+#include <linux/cpumask.h>
+#include <linux/kexec.h>
+#include <linux/smp.h>
+#include <linux/thread_info.h>
+#include <linux/errno.h>
+
+#include <asm/page.h>
+#include <asm/current.h>
+#include <asm/machdep.h>
+#include <asm/cacheflush.h>
+#include <asm/paca.h>
+#include <asm/mmu.h>
+#include <asm/sections.h>      /* _end */
+#include <asm/prom.h>
+
+#define HASH_GROUP_SIZE 0x80   /* size of each hash group, asm/mmu.h */
+
+/* Have this around till we move it into crash specific file */
+note_buf_t crash_notes[NR_CPUS];
+
+/* Dummy for now. Not sure if we need to have a crash shutdown in here
+ * and if what it will achieve. Letting it be now to compile the code
+ * in generic kexec environment
+ */
+void machine_crash_shutdown(struct pt_regs *regs)
+{
+       /* do nothing right now */
+       /* smp_relase_cpus() if we want smp on panic kernel */
+       /* cpu_irq_down to isolate us until we are ready */
+}
+
+int machine_kexec_prepare(struct kimage *image)
+{
+       int i;
+       unsigned long begin, end;       /* limits of segment */
+       unsigned long low, high;        /* limits of blocked memory range */
+       struct device_node *node;
+       unsigned long *basep;
+       unsigned int *sizep;
+
+       if (!ppc_md.hpte_clear_all)
+               return -ENOENT;
+
+       /*
+        * Since we use the kernel fault handlers and paging code to
+        * handle the virtual mode, we must make sure no destination
+        * overlaps kernel static data or bss.
+        */
+       for (i = 0; i < image->nr_segments; i++)
+               if (image->segment[i].mem < __pa(_end))
+                       return -ETXTBSY;
+
+       /*
+        * For non-LPAR, we absolutely can not overwrite the mmu hash
+        * table, since we are still using the bolted entries in it to
+        * do the copy.  Check that here.
+        *
+        * It is safe if the end is below the start of the blocked
+        * region (end <= low), or if the beginning is after the
+        * end of the blocked region (begin >= high).  Use the
+        * boolean identity !(a || b)  === (!a && !b).
+        */
+       if (htab_address) {
+               low = __pa(htab_address);
+               high = low + (htab_hash_mask + 1) * HASH_GROUP_SIZE;
+
+               for (i = 0; i < image->nr_segments; i++) {
+                       begin = image->segment[i].mem;
+                       end = begin + image->segment[i].memsz;
+
+                       if ((begin < high) && (end > low))
+                               return -ETXTBSY;
+               }
+       }
+
+       /* We also should not overwrite the tce tables */
+       for (node = of_find_node_by_type(NULL, "pci"); node != NULL;
+                       node = of_find_node_by_type(node, "pci")) {
+               basep = (unsigned long *)get_property(node, "linux,tce-base",
+                                                       NULL);
+               sizep = (unsigned int *)get_property(node, "linux,tce-size",
+                                                       NULL);
+               if (basep == NULL || sizep == NULL)
+                       continue;
+
+               low = *basep;
+               high = low + (*sizep);
+
+               for (i = 0; i < image->nr_segments; i++) {
+                       begin = image->segment[i].mem;
+                       end = begin + image->segment[i].memsz;
+
+                       if ((begin < high) && (end > low))
+                               return -ETXTBSY;
+               }
+       }
+
+       return 0;
+}
+
+void machine_kexec_cleanup(struct kimage *image)
+{
+       /* we do nothing in prepare that needs to be undone */
+}
+
+#define IND_FLAGS (IND_DESTINATION | IND_INDIRECTION | IND_DONE | IND_SOURCE)
+
+static void copy_segments(unsigned long ind)
+{
+       unsigned long entry;
+       unsigned long *ptr;
+       void *dest;
+       void *addr;
+
+       /*
+        * We rely on kexec_load to create a lists that properly
+        * initializes these pointers before they are used.
+        * We will still crash if the list is wrong, but at least
+        * the compiler will be quiet.
+        */
+       ptr = NULL;
+       dest = NULL;
+
+       for (entry = ind; !(entry & IND_DONE); entry = *ptr++) {
+               addr = __va(entry & PAGE_MASK);
+
+               switch (entry & IND_FLAGS) {
+               case IND_DESTINATION:
+                       dest = addr;
+                       break;
+               case IND_INDIRECTION:
+                       ptr = addr;
+                       break;
+               case IND_SOURCE:
+                       copy_page(dest, addr);
+                       dest += PAGE_SIZE;
+               }
+       }
+}
+
+void kexec_copy_flush(struct kimage *image)
+{
+       long i, nr_segments = image->nr_segments;
+       struct  kexec_segment ranges[KEXEC_SEGMENT_MAX];
+
+       /* save the ranges on the stack to efficiently flush the icache */
+       memcpy(ranges, image->segment, sizeof(ranges));
+
+       /*
+        * After this call we may not use anything allocated in dynamic
+        * memory, including *image.
+        *
+        * Only globals and the stack are allowed.
+        */
+       copy_segments(image->head);
+
+       /*
+        * we need to clear the icache for all dest pages sometime,
+        * including ones that were in place on the original copy
+        */
+       for (i = 0; i < nr_segments; i++)
+               flush_icache_range(ranges[i].mem + KERNELBASE,
+                               ranges[i].mem + KERNELBASE +
+                               ranges[i].memsz);
+}
+
+#ifdef CONFIG_SMP
+
+/* FIXME: we should schedule this function to be called on all cpus based
+ * on calling the interrupts, but we would like to call it off irq level
+ * so that the interrupt controller is clean.
+ */
+void kexec_smp_down(void *arg)
+{
+       if (ppc_md.cpu_irq_down)
+               ppc_md.cpu_irq_down();
+
+       local_irq_disable();
+       kexec_smp_wait();
+       /* NOTREACHED */
+}
+
+static void kexec_prepare_cpus(void)
+{
+       int my_cpu, i, notified=-1;
+
+       smp_call_function(kexec_smp_down, NULL, 0, /* wait */0);
+       my_cpu = get_cpu();
+
+       /* check the others cpus are now down (via paca hw cpu id == -1) */
+       for (i=0; i < NR_CPUS; i++) {
+               if (i == my_cpu)
+                       continue;
+
+               while (paca[i].hw_cpu_id != -1) {
+                       if (!cpu_possible(i)) {
+                               printk("kexec: cpu %d hw_cpu_id %d is not"
+                                               " possible, ignoring\n",
+                                               i, paca[i].hw_cpu_id);
+                               break;
+                       }
+                       if (!cpu_online(i)) {
+                               /* Fixme: this can be spinning in
+                                * pSeries_secondary_wait with a paca
+                                * waiting for it to go online.
+                                */
+                               printk("kexec: cpu %d hw_cpu_id %d is not"
+                                               " online, ignoring\n",
+                                               i, paca[i].hw_cpu_id);
+                               break;
+                       }
+                       if (i != notified) {
+                               printk( "kexec: waiting for cpu %d (physical"
+                                               " %d) to go down\n",
+                                               i, paca[i].hw_cpu_id);
+                               notified = i;
+                       }
+               }
+       }
+
+       /* after we tell the others to go down */
+       if (ppc_md.cpu_irq_down)
+               ppc_md.cpu_irq_down();
+
+       put_cpu();
+
+       local_irq_disable();
+}
+
+#else /* ! SMP */
+
+static void kexec_prepare_cpus(void)
+{
+       /*
+        * move the secondarys to us so that we can copy
+        * the new kernel 0-0x100 safely
+        *
+        * do this if kexec in setup.c ?
+        */
+       smp_relase_cpus();
+       if (ppc_md.cpu_irq_down)
+               ppc_md.cpu_irq_down();
+       local_irq_disable();
+}
+
+#endif /* SMP */
+
+/*
+ * kexec thread structure and stack.
+ *
+ * We need to make sure that this is 16384-byte aligned due to the
+ * way process stacks are handled.  It also must be statically allocated
+ * or allocated as part of the kimage, because everything else may be
+ * overwritten when we copy the kexec image.  We piggyback on the
+ * "init_task" linker section here to statically allocate a stack.
+ *
+ * We could use a smaller stack if we don't care about anything using
+ * current, but that audit has not been performed.
+ */
+union thread_union kexec_stack
+       __attribute__((__section__(".data.init_task"))) = { };
+
+/* Our assembly helper, in kexec_stub.S */
+extern NORET_TYPE void kexec_sequence(void *newstack, unsigned long start,
+                                       void *image, void *control,
+                                       void (*clear_all)(void)) ATTRIB_NORET;
+
+/* too late to fail here */
+void machine_kexec(struct kimage *image)
+{
+
+       /* prepare control code if any */
+
+       /* shutdown other cpus into our wait loop and quiesce interrupts */
+       kexec_prepare_cpus();
+
+       /* switch to a staticly allocated stack.  Based on irq stack code.
+        * XXX: the task struct will likely be invalid once we do the copy!
+        */
+       kexec_stack.thread_info.task = current_thread_info()->task;
+       kexec_stack.thread_info.flags = 0;
+
+       /* Some things are best done in assembly.  Finding globals with
+        * a toc is easier in C, so pass in what we can.
+        */
+       kexec_sequence(&kexec_stack, image->start, image,
+                       page_address(image->control_code_page),
+                       ppc_md.hpte_clear_all);
+       /* NOTREACHED */
+}
index e3c73b3425dc016447d7e417f536d7a66fde39c4..f3dea0c5a88c201caefe0bc35f429e7e020885f3 100644 (file)
@@ -680,6 +680,177 @@ _GLOBAL(kernel_thread)
        ld      r30,-16(r1)
        blr
 
+/* kexec_wait(phys_cpu)
+ *
+ * wait for the flag to change, indicating this kernel is going away but
+ * the slave code for the next one is at addresses 0 to 100.
+ *
+ * This is used by all slaves.
+ *
+ * Physical (hardware) cpu id should be in r3.
+ */
+_GLOBAL(kexec_wait)
+       bl      1f
+1:     mflr    r5
+       addi    r5,r5,kexec_flag-1b
+
+99:    HMT_LOW
+#ifdef CONFIG_KEXEC            /* use no memory without kexec */
+       lwz     r4,0(r5)
+       cmpwi   0,r4,0
+       bnea    0x60
+#endif
+       b       99b
+
+/* this can be in text because we won't change it until we are
+ * running in real anyways
+ */
+kexec_flag:
+       .long   0
+
+
+#ifdef CONFIG_KEXEC
+
+/* kexec_smp_wait(void)
+ *
+ * call with interrupts off
+ * note: this is a terminal routine, it does not save lr
+ *
+ * get phys id from paca
+ * set paca id to -1 to say we got here
+ * switch to real mode
+ * join other cpus in kexec_wait(phys_id)
+ */
+_GLOBAL(kexec_smp_wait)
+       lhz     r3,PACAHWCPUID(r13)
+       li      r4,-1
+       sth     r4,PACAHWCPUID(r13)     /* let others know we left */
+       bl      real_mode
+       b       .kexec_wait
+
+/*
+ * switch to real mode (turn mmu off)
+ * we use the early kernel trick that the hardware ignores bits
+ * 0 and 1 (big endian) of the effective address in real mode
+ *
+ * don't overwrite r3 here, it is live for kexec_wait above.
+ */
+real_mode:     /* assume normal blr return */
+1:     li      r9,MSR_RI
+       li      r10,MSR_DR|MSR_IR
+       mflr    r11             /* return address to SRR0 */
+       mfmsr   r12
+       andc    r9,r12,r9
+       andc    r10,r12,r10
+
+       mtmsrd  r9,1
+       mtspr   SPRN_SRR1,r10
+       mtspr   SPRN_SRR0,r11
+       rfid
+
+
+/*
+ * kexec_sequence(newstack, start, image, control, clear_all())
+ *
+ * does the grungy work with stack switching and real mode switches
+ * also does simple calls to other code
+ */
+
+_GLOBAL(kexec_sequence)
+       mflr    r0
+       std     r0,16(r1)
+
+       /* switch stacks to newstack -- &kexec_stack.stack */
+       stdu    r1,THREAD_SIZE-112(r3)
+       mr      r1,r3
+
+       li      r0,0
+       std     r0,16(r1)
+
+       /* save regs for local vars on new stack.
+        * yes, we won't go back, but ...
+        */
+       std     r31,-8(r1)
+       std     r30,-16(r1)
+       std     r29,-24(r1)
+       std     r28,-32(r1)
+       std     r27,-40(r1)
+       std     r26,-48(r1)
+       std     r25,-56(r1)
+
+       stdu    r1,-112-64(r1)
+
+       /* save args into preserved regs */
+       mr      r31,r3                  /* newstack (both) */
+       mr      r30,r4                  /* start (real) */
+       mr      r29,r5                  /* image (virt) */
+       mr      r28,r6                  /* control, unused */
+       mr      r27,r7                  /* clear_all() fn desc */
+       mr      r26,r8                  /* spare */
+       lhz     r25,PACAHWCPUID(r13)    /* get our phys cpu from paca */
+
+       /* disable interrupts, we are overwriting kernel data next */
+       mfmsr   r3
+       rlwinm  r3,r3,0,17,15
+       mtmsrd  r3,1
+
+       /* copy dest pages, flush whole dest image */
+       mr      r3,r29
+       bl      .kexec_copy_flush       /* (image) */
+
+       /* turn off mmu */
+       bl      real_mode
+
+       /* clear out hardware hash page table and tlb */
+       ld      r5,0(r27)               /* deref function descriptor */
+       mtctr   r5
+       bctrl                           /* ppc_md.hash_clear_all(void); */
+
+/*
+ *   kexec image calling is:
+ *      the first 0x100 bytes of the entry point are copied to 0
+ *
+ *      all slaves branch to slave = 0x60 (absolute)
+ *              slave(phys_cpu_id);
+ *
+ *      master goes to start = entry point
+ *              start(phys_cpu_id, start, 0);
+ *
+ *
+ *   a wrapper is needed to call existing kernels, here is an approximate
+ *   description of one method:
+ *
+ * v2: (2.6.10)
+ *   start will be near the boot_block (maybe 0x100 bytes before it?)
+ *   it will have a 0x60, which will b to boot_block, where it will wait
+ *   and 0 will store phys into struct boot-block and load r3 from there,
+ *   copy kernel 0-0x100 and tell slaves to back down to 0x60 again
+ *
+ * v1: (2.6.9)
+ *    boot block will have all cpus scanning device tree to see if they
+ *    are the boot cpu ?????
+ *    other device tree differences (prop sizes, va vs pa, etc)...
+ */
+
+       /* copy  0x100 bytes starting at start to 0 */
+       li      r3,0
+       mr      r4,r30
+       li      r5,0x100
+       li      r6,0
+       bl      .copy_and_flush /* (dest, src, copy limit, start offset) */
+1:     /* assume normal blr return */
+
+       /* release other cpus to the new kernel secondary start at 0x60 */
+       mflr    r5
+       li      r6,1
+       stw     r6,kexec_flag-1b(5)
+       mr      r3,r25  # my phys cpu
+       mr      r4,r30  # start, aka phys mem offset
+       mtlr    4
+       li      r5,0
+       blr     /* image->start(physid, image->start, 0); */
+#endif /* CONFIG_KEXEC */
+
 /* Why isn't this a) automatic, b) written in 'C'? */  
        .balign 8
 _GLOBAL(sys_call_table32)
@@ -951,7 +1122,7 @@ _GLOBAL(sys_call_table32)
        .llong .compat_sys_mq_timedreceive /* 265 */
        .llong .compat_sys_mq_notify
        .llong .compat_sys_mq_getsetattr
-       .llong .sys_ni_syscall          /* 268 reserved for sys_kexec_load */
+       .llong .compat_sys_kexec_load
        .llong .sys32_add_key
        .llong .sys32_request_key
        .llong .compat_sys_keyctl
@@ -1227,7 +1398,7 @@ _GLOBAL(sys_call_table)
        .llong .sys_mq_timedreceive     /* 265 */
        .llong .sys_mq_notify
        .llong .sys_mq_getsetattr
-       .llong .sys_ni_syscall          /* 268 reserved for sys_kexec_load */
+       .llong .sys_kexec_load
        .llong .sys_add_key
        .llong .sys_request_key         /* 270 */
        .llong .sys_keyctl
index 593ea5b82afa0502e33478896aa65abfbe46f25c..e8fbab1df37f842cda79e59f8eb077228b93c6d9 100644 (file)
@@ -792,6 +792,35 @@ void mpic_setup_this_cpu(void)
 #endif /* CONFIG_SMP */
 }
 
+/*
+ * XXX: someone who knows mpic should check this.
+ * do we need to eoi the ipi here (see xics comments)?
+ * or can we reset the mpic in the new kernel?
+ */
+void mpic_teardown_this_cpu(void)
+{
+       struct mpic *mpic = mpic_primary;
+       unsigned long flags;
+       u32 msk = 1 << hard_smp_processor_id();
+       unsigned int i;
+
+       BUG_ON(mpic == NULL);
+
+       DBG("%s: teardown_this_cpu(%d)\n", mpic->name, hard_smp_processor_id());
+       spin_lock_irqsave(&mpic_lock, flags);
+
+       /* let the mpic know we don't want intrs.  */
+       for (i = 0; i < mpic->num_sources ; i++)
+               mpic_irq_write(i, MPIC_IRQ_DESTINATION,
+                       mpic_irq_read(i, MPIC_IRQ_DESTINATION) & ~msk);
+
+       /* Set current processor priority to max */
+       mpic_cpu_write(MPIC_CPU_CURRENT_TASK_PRI, 0xf);
+
+       spin_unlock_irqrestore(&mpic_lock, flags);
+}
+
+
 void mpic_send_ipi(unsigned int ipi_no, unsigned int cpu_mask)
 {
        struct mpic *mpic = mpic_primary;
index 63e177143eac2f05a839e6d69e0e0f892fc093db..99fbbc9a084c46bec6e37789aca5987233177dd0 100644 (file)
@@ -255,6 +255,9 @@ extern unsigned int mpic_irq_get_priority(unsigned int irq);
 /* Setup a non-boot CPU */
 extern void mpic_setup_this_cpu(void);
 
+/* Clean up for kexec (or cpu offline or ...) */
+extern void mpic_teardown_this_cpu(void);
+
 /* Request IPIs on primary mpic */
 extern void mpic_request_ipis(void);
 
index f2b41243342c483a63088c5d5f8228744b09c2ef..44d9af72d225038da83e43d5f8dab15d4bb055eb 100644 (file)
@@ -187,14 +187,16 @@ static void __init pSeries_setup_arch(void)
 {
        /* Fixup ppc_md depending on the type of interrupt controller */
        if (ppc64_interrupt_controller == IC_OPEN_PIC) {
-               ppc_md.init_IRQ       = pSeries_init_mpic; 
+               ppc_md.init_IRQ       = pSeries_init_mpic;
                ppc_md.get_irq        = mpic_get_irq;
+               ppc_md.cpu_irq_down   = mpic_teardown_this_cpu;
                /* Allocate the mpic now, so that find_and_init_phbs() can
                 * fill the ISUs */
                pSeries_setup_mpic();
        } else {
                ppc_md.init_IRQ       = xics_init_IRQ;
                ppc_md.get_irq        = xics_get_irq;
+               ppc_md.cpu_irq_down   = xics_teardown_cpu;
        }
 
 #ifdef CONFIG_SMP
index 30154140f7e2403662935f1ee00c192f34ac3e6f..62c55a123560cf6850dc1c10c5a171c953a7290c 100644 (file)
@@ -93,10 +93,13 @@ static int query_cpu_stopped(unsigned int pcpu)
 
 int pSeries_cpu_disable(void)
 {
+       int cpu = smp_processor_id();
+
+       cpu_clear(cpu, cpu_online_map);
        systemcfg->processorCount--;
 
        /*fix boot_cpuid here*/
-       if (smp_processor_id() == boot_cpuid)
+       if (cpu == boot_cpuid)
                boot_cpuid = any_online_cpu(cpu_online_map);
 
        /* FIXME: abstract this to not be platform specific later on */
index 0a47a5ef428dfaae3d1aee77f520b7c3470abc39..d5e4866e9ac2e22599a5abf7979b99616071c65c 100644 (file)
@@ -677,11 +677,16 @@ void __init setup_system(void)
        DBG(" <- setup_system()\n");
 }
 
-
-void machine_restart(char *cmd)
+/* also used by kexec */
+void machine_shutdown(void)
 {
        if (ppc_md.nvram_sync)
                ppc_md.nvram_sync();
+}
+
+void machine_restart(char *cmd)
+{
+       machine_shutdown();
        ppc_md.restart(cmd);
 #ifdef CONFIG_SMP
        smp_send_stop();
@@ -690,13 +695,11 @@ void machine_restart(char *cmd)
        local_irq_disable();
        while (1) ;
 }
-
 EXPORT_SYMBOL(machine_restart);
-  
+
 void machine_power_off(void)
 {
-       if (ppc_md.nvram_sync)
-               ppc_md.nvram_sync();
+       machine_shutdown();
        ppc_md.power_off();
 #ifdef CONFIG_SMP
        smp_send_stop();
@@ -705,13 +708,11 @@ void machine_power_off(void)
        local_irq_disable();
        while (1) ;
 }
-
 EXPORT_SYMBOL(machine_power_off);
-  
+
 void machine_halt(void)
 {
-       if (ppc_md.nvram_sync)
-               ppc_md.nvram_sync();
+       machine_shutdown();
        ppc_md.halt();
 #ifdef CONFIG_SMP
        smp_send_stop();
@@ -720,7 +721,6 @@ void machine_halt(void)
        local_irq_disable();
        while (1) ;
 }
-
 EXPORT_SYMBOL(machine_halt);
 
 static int ppc64_panic_event(struct notifier_block *this,
index 879f39b90a337df2b63a88d5399fcf4971da36e7..677c4450984a85c3b53161f7409895309f907ce8 100644 (file)
@@ -647,6 +647,31 @@ static void xics_set_affinity(unsigned int virq, cpumask_t cpumask)
        }
 }
 
+void xics_teardown_cpu(void)
+{
+       int cpu = smp_processor_id();
+       int status;
+
+       ops->cppr_info(cpu, 0x00);
+       iosync();
+
+       /*
+        * we need to EOI the IPI if we got here from kexec down IPI
+        *
+        * xics doesn't care if we duplicate an EOI as long as we
+        * don't EOI and raise priority.
+        *
+        * probably need to check all the other interrupts too
+        * should we be flagging idle loop instead?
+        * or creating some task to be scheduled?
+        */
+       ops->xirr_info_set(cpu, XICS_IPI);
+
+       status = rtas_set_indicator(GLOBAL_INTERRUPT_QUEUE,
+               (1UL << interrupt_server_size) - 1 - default_distrib_server, 0);
+       WARN_ON(status != 0);
+}
+
 #ifdef CONFIG_HOTPLUG_CPU
 
 /* Interrupts are disabled. */
index 52b6b9305341e3774b94bba7bca216cbd6ce3bd0..4fec05817d660bcb95db16380745f4f209bfd62e 100644 (file)
@@ -304,6 +304,50 @@ static void native_hpte_invalidate(unsigned long slot, unsigned long va,
        local_irq_restore(flags);
 }
 
+/*
+ * clear all mappings on kexec.  All cpus are in real mode (or they will
+ * be when they isi), and we are the only one left.  We rely on our kernel
+ * mapping being 0xC0's and the hardware ignoring those two real bits.
+ *
+ * TODO: add batching support when enabled.  remember, no dynamic memory here,
+ * athough there is the control page available...
+ */
+static void native_hpte_clear(void)
+{
+       unsigned long slot, slots, flags;
+       HPTE *hptep = htab_address;
+       Hpte_dword0 dw0;
+       unsigned long pteg_count;
+
+       pteg_count = htab_hash_mask + 1;
+
+       local_irq_save(flags);
+
+       /* we take the tlbie lock and hold it.  Some hardware will
+        * deadlock if we try to tlbie from two processors at once.
+        */
+       spin_lock(&native_tlbie_lock);
+
+       slots = pteg_count * HPTES_PER_GROUP;
+
+       for (slot = 0; slot < slots; slot++, hptep++) {
+               /*
+                * we could lock the pte here, but we are the only cpu
+                * running,  right?  and for crash dump, we probably
+                * don't want to wait for a maybe bad cpu.
+                */
+               dw0 = hptep->dw0.dw0;
+
+               if (dw0.v) {
+                       hptep->dw0.dword0 = 0;
+                       tlbie(slot2va(dw0.avpn, dw0.l, dw0.h, slot), dw0.l);
+               }
+       }
+
+       spin_unlock(&native_tlbie_lock);
+       local_irq_restore(flags);
+}
+
 static void native_flush_hash_range(unsigned long context,
                                    unsigned long number, int local)
 {
@@ -415,7 +459,8 @@ void hpte_init_native(void)
        ppc_md.hpte_updatepp    = native_hpte_updatepp;
        ppc_md.hpte_updateboltedpp = native_hpte_updateboltedpp;
        ppc_md.hpte_insert      = native_hpte_insert;
-       ppc_md.hpte_remove      = native_hpte_remove;
+       ppc_md.hpte_remove      = native_hpte_remove;
+       ppc_md.hpte_clear_all   = native_hpte_clear;
        if (tlb_batching_enabled())
                ppc_md.flush_hash_range = native_flush_hash_range;
        htab_finish_init();
index 32696c1d92806c7cac9eebaa20220aacd6793993..6600ee87f896938bd7e71f30bc4e43c69e148c2a 100644 (file)
@@ -455,6 +455,14 @@ config NO_IDLE_HZ_INIT
          The HZ timer is switched off in idle by default. That means the
          HZ timer is already disabled at boot time.
 
+config KEXEC
+       bool "kexec system call (EXPERIMENTAL)"
+       depends on EXPERIMENTAL
+       help
+         kexec is a system call that implements the ability to shutdown your
+         current kernel, and to start another kernel.  It is like a reboot
+         but is independent of hardware/microcode support.
+
 endmenu
 
 config PCMCIA
index 07fd0414a4bf5eebf7e7d7259fbadd16a68ecfbb..89850b2c27ea0e94bd7a2daa25df18816ddc0587 100644 (file)
@@ -245,6 +245,7 @@ CONFIG_S390_TAPE_BLOCK=y
 #
 CONFIG_S390_TAPE_34XX=m
 # CONFIG_VMLOGRDR is not set
+# CONFIG_VMCP is not set
 # CONFIG_MONREADER is not set
 # CONFIG_DCSS_SHM is not set
 
index b41e0e199a7cf8aa9d5b8f221b72b4f58b27b4bc..ab1e49d2e5185dad2116aa8ff8afacf5e6f2cf2e 100644 (file)
@@ -25,6 +25,16 @@ obj-$(CONFIG_ARCH_S390X)     += entry64.o reipl64.o
 
 obj-$(CONFIG_VIRT_TIMER)       += vtime.o
 
+# Kexec part
+S390_KEXEC_OBJS := machine_kexec.o crash.o
+ifeq ($(CONFIG_ARCH_S390X),y)
+S390_KEXEC_OBJS += relocate_kernel64.o
+else
+S390_KEXEC_OBJS += relocate_kernel.o
+endif
+obj-$(CONFIG_KEXEC) += $(S390_KEXEC_OBJS)
+
+
 #
 # This is just to get the dependencies...
 #
index 7a607b1d03808f6abdb36e47de42d6c5ef91e2d8..bf529739c8ab6a53709b4bf5507ae7c4ca7410f0 100644 (file)
@@ -1441,3 +1441,11 @@ compat_sys_waitid_wrapper:
        lgfr    %r5,%r5                 # int
        llgtr   %r6,%r6                 # struct rusage_emu31 *
        jg      compat_sys_waitid
+
+       .globl  compat_sys_kexec_load_wrapper
+compat_sys_kexec_load_wrapper:
+       llgfr   %r2,%r2                 # unsigned long
+       llgfr   %r3,%r3                 # unsigned long
+       llgtr   %r4,%r4                 # struct kexec_segment *
+       llgfr   %r5,%r5                 # unsigned long
+       jg      compat_sys_kexec_load
index 44df8dc07c5923080626fe1b9603fe557d54fbc4..20062145e84e29bc1dcddcc258b7a29276991f84 100644 (file)
@@ -2,7 +2,7 @@
  *  arch/s390/kernel/cpcmd.c
  *
  *  S390 version
- *    Copyright (C) 1999,2000 IBM Deutschland Entwicklung GmbH, IBM Corporation
+ *    Copyright (C) 1999,2005 IBM Deutschland Entwicklung GmbH, IBM Corporation
  *    Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com),
  *               Christian Borntraeger (cborntra@de.ibm.com),
  */
 #include <asm/system.h>
 
 static DEFINE_SPINLOCK(cpcmd_lock);
-static char cpcmd_buf[240];
+static char cpcmd_buf[241];
 
 /*
  * the caller of __cpcmd has to ensure that the response buffer is below 2 GB
  */
-void __cpcmd(char *cmd, char *response, int rlen)
+int  __cpcmd(const char *cmd, char *response, int rlen, int *response_code)
 {
        const int mask = 0x40000000L;
        unsigned long flags;
+       int return_code;
+       int return_len;
        int cmdlen;
 
        spin_lock_irqsave(&cpcmd_lock, flags);
        cmdlen = strlen(cmd);
        BUG_ON(cmdlen > 240);
-       strcpy(cpcmd_buf, cmd);
+       memcpy(cpcmd_buf, cmd, cmdlen);
        ASCEBC(cpcmd_buf, cmdlen);
 
        if (response != NULL && rlen > 0) {
                memset(response, 0, rlen);
 #ifndef CONFIG_ARCH_S390X
-               asm volatile ("LRA   2,0(%0)\n\t"
-                              "LR    4,%1\n\t"
-                              "O     4,%4\n\t"
-                              "LRA   3,0(%2)\n\t"
-                              "LR    5,%3\n\t"
-                              ".long 0x83240008 # Diagnose X'08'\n\t"
-                              : /* no output */
-                              : "a" (cpcmd_buf), "d" (cmdlen),
-                                "a" (response), "d" (rlen), "m" (mask)
-                              : "cc", "2", "3", "4", "5" );
+               asm volatile (  "lra    2,0(%2)\n"
+                               "lr     4,%3\n"
+                               "o      4,%6\n"
+                               "lra    3,0(%4)\n"
+                               "lr     5,%5\n"
+                               "diag   2,4,0x8\n"
+                               "brc    8, .Litfits\n"
+                               "ar     5, %5\n"
+                               ".Litfits: \n"
+                               "lr     %0,4\n"
+                               "lr     %1,5\n"
+                               : "=d" (return_code), "=d" (return_len)
+                               : "a" (cpcmd_buf), "d" (cmdlen),
+                               "a" (response), "d" (rlen), "m" (mask)
+                               : "cc", "2", "3", "4", "5" );
 #else /* CONFIG_ARCH_S390X */
-                asm volatile ("   lrag  2,0(%0)\n"
-                              "   lgr   4,%1\n"
-                              "   o     4,%4\n"
-                              "   lrag  3,0(%2)\n"
-                              "   lgr   5,%3\n"
-                              "   sam31\n"
-                              "   .long 0x83240008 # Diagnose X'08'\n"
-                              "   sam64"
-                              : /* no output */
-                              : "a" (cpcmd_buf), "d" (cmdlen),
-                                "a" (response), "d" (rlen), "m" (mask)
-                              : "cc", "2", "3", "4", "5" );
+                asm volatile ( "lrag   2,0(%2)\n"
+                               "lgr    4,%3\n"
+                               "o      4,%6\n"
+                               "lrag   3,0(%4)\n"
+                               "lgr    5,%5\n"
+                               "sam31\n"
+                               "diag   2,4,0x8\n"
+                               "sam64\n"
+                               "brc    8, .Litfits\n"
+                               "agr    5, %5\n"
+                               ".Litfits: \n"
+                               "lgr    %0,4\n"
+                               "lgr    %1,5\n"
+                               : "=d" (return_code), "=d" (return_len)
+                               : "a" (cpcmd_buf), "d" (cmdlen),
+                               "a" (response), "d" (rlen), "m" (mask)
+                               : "cc", "2", "3", "4", "5" );
 #endif /* CONFIG_ARCH_S390X */
                 EBCASC(response, rlen);
         } else {
+               return_len = 0;
 #ifndef CONFIG_ARCH_S390X
-                asm volatile ("LRA   2,0(%0)\n\t"
-                              "LR    3,%1\n\t"
-                              ".long 0x83230008 # Diagnose X'08'\n\t"
-                              : /* no output */
-                              : "a" (cpcmd_buf), "d" (cmdlen)
-                              : "2", "3"  );
+                asm volatile ( "lra    2,0(%1)\n"
+                               "lr     3,%2\n"
+                               "diag   2,3,0x8\n"
+                               "lr     %0,3\n"
+                               : "=d" (return_code)
+                               : "a" (cpcmd_buf), "d" (cmdlen)
+                               : "2", "3"  );
 #else /* CONFIG_ARCH_S390X */
-                asm volatile ("   lrag  2,0(%0)\n"
-                              "   lgr   3,%1\n"
-                              "   sam31\n"
-                              "   .long 0x83230008 # Diagnose X'08'\n"
-                              "   sam64"
-                              : /* no output */
-                              : "a" (cpcmd_buf), "d" (cmdlen)
-                              : "2", "3"  );
+                asm volatile ( "lrag   2,0(%1)\n"
+                               "lgr    3,%2\n"
+                               "sam31\n"
+                               "diag   2,3,0x8\n"
+                               "sam64\n"
+                               "lgr    %0,3\n"
+                               : "=d" (return_code)
+                               : "a" (cpcmd_buf), "d" (cmdlen)
+                               : "2", "3" );
 #endif /* CONFIG_ARCH_S390X */
         }
        spin_unlock_irqrestore(&cpcmd_lock, flags);
+       if (response_code != NULL)
+               *response_code = return_code;
+       return return_len;
 }
 
 EXPORT_SYMBOL(__cpcmd);
 
 #ifdef CONFIG_ARCH_S390X
-void cpcmd(char *cmd, char *response, int rlen)
+int cpcmd(const char *cmd, char *response, int rlen, int *response_code)
 {
        char *lowbuf;
+       int len;
+
        if ((rlen == 0) || (response == NULL)
            || !((unsigned long)response >> 31))
-               __cpcmd(cmd, response, rlen);
+               len = __cpcmd(cmd, response, rlen, response_code);
        else {
                lowbuf = kmalloc(rlen, GFP_KERNEL | GFP_DMA);
                if (!lowbuf) {
                        printk(KERN_WARNING
                                "cpcmd: could not allocate response buffer\n");
-                       return;
+                       return -ENOMEM;
                }
-               __cpcmd(cmd, lowbuf, rlen);
+               len = __cpcmd(cmd, lowbuf, rlen, response_code);
                memcpy(response, lowbuf, rlen);
                kfree(lowbuf);
        }
+       return len;
 }
 
 EXPORT_SYMBOL(cpcmd);
diff --git a/arch/s390/kernel/crash.c b/arch/s390/kernel/crash.c
new file mode 100644 (file)
index 0000000..7bd169c
--- /dev/null
@@ -0,0 +1,17 @@
+/*
+ * arch/s390/kernel/crash.c
+ *
+ * (C) Copyright IBM Corp. 2005
+ *
+ * Author(s): Heiko Carstens <heiko.carstens@de.ibm.com>
+ *
+ */
+
+#include <linux/threads.h>
+#include <linux/kexec.h>
+
+note_buf_t crash_notes[NR_CPUS];
+
+void machine_crash_shutdown(struct pt_regs *regs)
+{
+}
index 91f8ce5543d3b405287056b562e4d754b987476e..960ba6029c3a00c0f77727519450b3591278a272 100644 (file)
 #include <linux/sysctl.h>
 #include <asm/uaccess.h>
 #include <asm/semaphore.h>
-
 #include <linux/module.h>
 #include <linux/init.h>
+#include <linux/fs.h>
+#include <linux/debugfs.h>
 
 #include <asm/debug.h>
 
 #define DEBUG_PROLOG_ENTRY -1
 
+#define ALL_AREAS 0 /* copy all debug areas */
+#define NO_AREAS  1 /* copy no debug areas */
+
 /* typedefs */
 
 typedef struct file_private_info {
        loff_t offset;                  /* offset of last read in file */
        int    act_area;                /* number of last formated area */
+       int    act_page;                /* act page in given area */
        int    act_entry;               /* last formated entry (offset */
                                         /* relative to beginning of last */
-                                        /* formated area) */ 
+                                        /* formated page) */
        size_t act_entry_offset;        /* up to this offset we copied */
                                        /* in last read the last formated */
                                        /* entry to userland */
@@ -51,8 +56,8 @@ typedef struct
         * This assumes that all args are converted into longs 
         * on L/390 this is the case for all types of parameter 
         * except of floats, and long long (32 bit) 
-         *
-         */
+        *
+        */
        long args[0];
 } debug_sprintf_entry_t;
 
@@ -63,32 +68,38 @@ extern void tod_to_timeval(uint64_t todval, struct timeval *xtime);
 
 static int debug_init(void);
 static ssize_t debug_output(struct file *file, char __user *user_buf,
-                           size_t user_len, loff_t * offset);
+                       size_t user_len, loff_t * offset);
 static ssize_t debug_input(struct file *file, const char __user *user_buf,
-                          size_t user_len, loff_t * offset);
+                       size_t user_len, loff_t * offset);
 static int debug_open(struct inode *inode, struct file *file);
 static int debug_close(struct inode *inode, struct file *file);
-static debug_info_t*  debug_info_create(char *name, int page_order, int nr_areas, int buf_size);
+static debug_info_t*  debug_info_create(char *name, int pages_per_area,
+                       int nr_areas, int buf_size);
 static void debug_info_get(debug_info_t *);
 static void debug_info_put(debug_info_t *);
 static int debug_prolog_level_fn(debug_info_t * id,
-                                struct debug_view *view, char *out_buf);
+                       struct debug_view *view, char *out_buf);
 static int debug_input_level_fn(debug_info_t * id, struct debug_view *view,
-                               struct file *file, const char __user *user_buf,
-                               size_t user_buf_size, loff_t * offset);
+                       struct file *file, const char __user *user_buf,
+                       size_t user_buf_size, loff_t * offset);
+static int debug_prolog_pages_fn(debug_info_t * id,
+                       struct debug_view *view, char *out_buf);
+static int debug_input_pages_fn(debug_info_t * id, struct debug_view *view,
+                       struct file *file, const char __user *user_buf,
+                       size_t user_buf_size, loff_t * offset);
 static int debug_input_flush_fn(debug_info_t * id, struct debug_view *view,
-                                struct file *file, const char __user *user_buf,
-                                size_t user_buf_size, loff_t * offset);
+                       struct file *file, const char __user *user_buf,
+                       size_t user_buf_size, loff_t * offset);
 static int debug_hex_ascii_format_fn(debug_info_t * id, struct debug_view *view,
-                                char *out_buf, const char *in_buf);
+                       char *out_buf, const char *in_buf);
 static int debug_raw_format_fn(debug_info_t * id,
-                                struct debug_view *view, char *out_buf,
-                                const char *in_buf);
+                       struct debug_view *view, char *out_buf,
+                       const char *in_buf);
 static int debug_raw_header_fn(debug_info_t * id, struct debug_view *view,
-                         int area, debug_entry_t * entry, char *out_buf);
+                       int area, debug_entry_t * entry, char *out_buf);
 
 static int debug_sprintf_format_fn(debug_info_t * id, struct debug_view *view,
-                                  char *out_buf, debug_sprintf_entry_t *curr_event);
+                       char *out_buf, debug_sprintf_entry_t *curr_event);
 
 /* globals */
 
@@ -119,6 +130,15 @@ struct debug_view debug_level_view = {
        NULL
 };
 
+struct debug_view debug_pages_view = {
+       "pages",
+       &debug_prolog_pages_fn,
+       NULL,
+       NULL,
+       &debug_input_pages_fn,
+       NULL
+};
+
 struct debug_view debug_flush_view = {
         "flush",
         NULL,
@@ -149,98 +169,161 @@ DECLARE_MUTEX(debug_lock);
 static int initialized;
 
 static struct file_operations debug_file_ops = {
-       .owner   = THIS_MODULE,
+       .owner   = THIS_MODULE,
        .read    = debug_output,
-       .write   = debug_input, 
+       .write   = debug_input,
        .open    = debug_open,
        .release = debug_close,
 };
 
-static struct proc_dir_entry *debug_proc_root_entry;
+static struct dentry *debug_debugfs_root_entry;
 
 /* functions */
 
+/*
+ * debug_areas_alloc
+ * - Debug areas are implemented as a threedimensonal array:
+ *   areas[areanumber][pagenumber][pageoffset]
+ */
+
+static debug_entry_t***
+debug_areas_alloc(int pages_per_area, int nr_areas)
+{
+       debug_entry_t*** areas;
+       int i,j;
+
+       areas = (debug_entry_t ***) kmalloc(nr_areas *
+                                       sizeof(debug_entry_t**),
+                                       GFP_KERNEL);
+       if (!areas)
+               goto fail_malloc_areas;
+       for (i = 0; i < nr_areas; i++) {
+               areas[i] = (debug_entry_t**) kmalloc(pages_per_area *
+                               sizeof(debug_entry_t*),GFP_KERNEL);
+               if (!areas[i]) {
+                       goto fail_malloc_areas2;
+               }
+               for(j = 0; j < pages_per_area; j++) {
+                       areas[i][j] = (debug_entry_t*)kmalloc(PAGE_SIZE,
+                                               GFP_KERNEL);
+                       if(!areas[i][j]) {
+                               for(j--; j >=0 ; j--) {
+                                       kfree(areas[i][j]);
+                               }
+                               kfree(areas[i]);
+                               goto fail_malloc_areas2;
+                       } else {
+                               memset(areas[i][j],0,PAGE_SIZE);
+                       }
+               }
+       }
+       return areas;
+
+fail_malloc_areas2:
+       for(i--; i >= 0; i--){
+               for(j=0; j < pages_per_area;j++){
+                       kfree(areas[i][j]);
+               }
+               kfree(areas[i]);
+       }
+       kfree(areas);
+fail_malloc_areas:
+       return NULL;
+
+}
+
+
 /*
  * debug_info_alloc
  * - alloc new debug-info
  */
 
-static debug_info_t*  debug_info_alloc(char *name, int page_order,
-                                        int nr_areas, int buf_size)
+static debug_info_t*
+debug_info_alloc(char *name, int pages_per_area, int nr_areas, int buf_size,
+               int level, int mode)
 {
        debug_info_t* rc;
-       int i;
 
        /* alloc everything */
 
-       rc = (debug_info_t*) kmalloc(sizeof(debug_info_t), GFP_ATOMIC);
+       rc = (debug_info_t*) kmalloc(sizeof(debug_info_t), GFP_KERNEL);
        if(!rc)
                goto fail_malloc_rc;
-       rc->active_entry = (int*)kmalloc(nr_areas * sizeof(int), GFP_ATOMIC);
-       if(!rc->active_entry)
-               goto fail_malloc_active_entry;
-       memset(rc->active_entry, 0, nr_areas * sizeof(int));
-       rc->areas = (debug_entry_t **) kmalloc(nr_areas *
-                                               sizeof(debug_entry_t *),
-                                               GFP_ATOMIC);
-       if (!rc->areas)
-               goto fail_malloc_areas;
-       for (i = 0; i < nr_areas; i++) {
-               rc->areas[i] = (debug_entry_t *) __get_free_pages(GFP_ATOMIC,
-                                                               page_order);
-               if (!rc->areas[i]) {
-                       for (i--; i >= 0; i--) {
-                               free_pages((unsigned long) rc->areas[i],
-                                               page_order);
-                       }
-                       goto fail_malloc_areas2;
-               } else {
-                       memset(rc->areas[i], 0, PAGE_SIZE << page_order);
-               }
+       rc->active_entries = (int*)kmalloc(nr_areas * sizeof(int), GFP_KERNEL);
+       if(!rc->active_entries)
+               goto fail_malloc_active_entries;
+       memset(rc->active_entries, 0, nr_areas * sizeof(int));
+       rc->active_pages = (int*)kmalloc(nr_areas * sizeof(int), GFP_KERNEL);
+       if(!rc->active_pages)
+               goto fail_malloc_active_pages;
+       memset(rc->active_pages, 0, nr_areas * sizeof(int));
+       if((mode == ALL_AREAS) && (pages_per_area != 0)){
+               rc->areas = debug_areas_alloc(pages_per_area, nr_areas);
+               if(!rc->areas)
+                       goto fail_malloc_areas;
+       } else {
+               rc->areas = NULL;
        }
 
        /* initialize members */
 
        spin_lock_init(&rc->lock);
-       rc->page_order  = page_order;
-       rc->nr_areas    = nr_areas;
-       rc->active_area = 0;
-       rc->level       = DEBUG_DEFAULT_LEVEL;
-       rc->buf_size    = buf_size;
-       rc->entry_size  = sizeof(debug_entry_t) + buf_size;
-       strlcpy(rc->name, name, sizeof(rc->name));
+       rc->pages_per_area = pages_per_area;
+       rc->nr_areas       = nr_areas;
+       rc->active_area    = 0;
+       rc->level          = level;
+       rc->buf_size       = buf_size;
+       rc->entry_size     = sizeof(debug_entry_t) + buf_size;
+       strlcpy(rc->name, name, sizeof(rc->name)-1);
        memset(rc->views, 0, DEBUG_MAX_VIEWS * sizeof(struct debug_view *));
-#ifdef CONFIG_PROC_FS
-       memset(rc->proc_entries, 0 ,DEBUG_MAX_VIEWS *
-               sizeof(struct proc_dir_entry*));
-#endif /* CONFIG_PROC_FS */
+       memset(rc->debugfs_entries, 0 ,DEBUG_MAX_VIEWS *
+               sizeof(struct dentry*));
        atomic_set(&(rc->ref_count), 0);
 
        return rc;
 
-fail_malloc_areas2:
-       kfree(rc->areas);
 fail_malloc_areas:
-       kfree(rc->active_entry);
-fail_malloc_active_entry:
+       kfree(rc->active_pages);
+fail_malloc_active_pages:
+       kfree(rc->active_entries);
+fail_malloc_active_entries:
        kfree(rc);
 fail_malloc_rc:
        return NULL;
 }
 
 /*
- * debug_info_free
- * - free memory debug-info
+ * debug_areas_free
+ * - free all debug areas
  */
 
-static void debug_info_free(debug_info_t* db_info){
-       int i;
+static void
+debug_areas_free(debug_info_t* db_info)
+{
+       int i,j;
+
+       if(!db_info->areas)
+               return;
        for (i = 0; i < db_info->nr_areas; i++) {
-               free_pages((unsigned long) db_info->areas[i],
-               db_info->page_order);
+               for(j = 0; j < db_info->pages_per_area; j++) {
+                       kfree(db_info->areas[i][j]);
+               }
+               kfree(db_info->areas[i]);
        }
        kfree(db_info->areas);
-       kfree(db_info->active_entry);
+       db_info->areas = NULL;
+}
+
+/*
+ * debug_info_free
+ * - free memory debug-info
+ */
+
+static void
+debug_info_free(debug_info_t* db_info){
+       debug_areas_free(db_info);
+       kfree(db_info->active_entries);
+       kfree(db_info->active_pages);
        kfree(db_info);
 }
 
@@ -249,21 +332,22 @@ static void debug_info_free(debug_info_t* db_info){
  * - create new debug-info
  */
 
-static debug_info_t*  debug_info_create(char *name, int page_order, 
-                                        int nr_areas, int buf_size)
+static debug_info_t*
+debug_info_create(char *name, int pages_per_area, int nr_areas, int buf_size)
 {
        debug_info_t* rc;
 
-        rc = debug_info_alloc(name, page_order, nr_areas, buf_size);
+        rc = debug_info_alloc(name, pages_per_area, nr_areas, buf_size,
+                               DEBUG_DEFAULT_LEVEL, ALL_AREAS);
         if(!rc) 
                goto out;
 
-
-       /* create proc rood directory */
-        rc->proc_root_entry = proc_mkdir(rc->name, debug_proc_root_entry);
+       /* create root directory */
+        rc->debugfs_root_entry = debugfs_create_dir(rc->name,
+                                       debug_debugfs_root_entry);
 
        /* append new element to linked list */
-        if (debug_area_first == NULL) {
+        if (!debug_area_first) {
                 /* first element in list */
                 debug_area_first = rc;
                 rc->prev = NULL;
@@ -285,17 +369,21 @@ out:
  * - copy debug-info
  */
 
-static debug_info_t* debug_info_copy(debug_info_t* in)
+static debug_info_t*
+debug_info_copy(debug_info_t* in, int mode)
 {
-        int i;
+        int i,j;
         debug_info_t* rc;
-        rc = debug_info_alloc(in->name, in->page_order, 
-                                in->nr_areas, in->buf_size);
-        if(!rc)
+
+        rc = debug_info_alloc(in->name, in->pages_per_area, in->nr_areas,
+                               in->buf_size, in->level, mode);
+        if(!rc || (mode == NO_AREAS))
                 goto out;
 
         for(i = 0; i < in->nr_areas; i++){
-                memcpy(rc->areas[i],in->areas[i], PAGE_SIZE << in->page_order);
+               for(j = 0; j < in->pages_per_area; j++) {
+                       memcpy(rc->areas[i][j], in->areas[i][j],PAGE_SIZE);
+               }
         }
 out:
         return rc;
@@ -306,7 +394,8 @@ out:
  * - increments reference count for debug-info
  */
 
-static void debug_info_get(debug_info_t * db_info)
+static void
+debug_info_get(debug_info_t * db_info)
 {
        if (db_info)
                atomic_inc(&db_info->ref_count);
@@ -317,29 +406,20 @@ static void debug_info_get(debug_info_t * db_info)
  * - decreases reference count for debug-info and frees it if necessary
  */
 
-static void debug_info_put(debug_info_t *db_info)
+static void
+debug_info_put(debug_info_t *db_info)
 {
        int i;
 
        if (!db_info)
                return;
        if (atomic_dec_and_test(&db_info->ref_count)) {
-#ifdef DEBUG
-               printk(KERN_INFO "debug: freeing debug area %p (%s)\n",
-                      db_info, db_info->name);
-#endif
                for (i = 0; i < DEBUG_MAX_VIEWS; i++) {
-                       if (db_info->views[i] == NULL)
+                       if (!db_info->views[i])
                                continue;
-#ifdef CONFIG_PROC_FS
-                       remove_proc_entry(db_info->proc_entries[i]->name,
-                                         db_info->proc_root_entry);
-#endif
+                       debugfs_remove(db_info->debugfs_entries[i]);
                }
-#ifdef CONFIG_PROC_FS
-               remove_proc_entry(db_info->proc_root_entry->name,
-                                 debug_proc_root_entry);
-#endif
+               debugfs_remove(db_info->debugfs_root_entry);
                if(db_info == debug_area_first)
                        debug_area_first = db_info->next;
                if(db_info == debug_area_last)
@@ -355,9 +435,9 @@ static void debug_info_put(debug_info_t *db_info)
  * - format one debug entry and return size of formated data
  */
 
-static int debug_format_entry(file_private_info_t *p_info)
+static int
+debug_format_entry(file_private_info_t *p_info)
 {
-       debug_info_t *id_org    = p_info->debug_info_org;
        debug_info_t *id_snap   = p_info->debug_info_snap;
        struct debug_view *view = p_info->view;
        debug_entry_t *act_entry;
@@ -365,22 +445,23 @@ static int debug_format_entry(file_private_info_t *p_info)
        if(p_info->act_entry == DEBUG_PROLOG_ENTRY){
                /* print prolog */
                if (view->prolog_proc)
-                       len += view->prolog_proc(id_org, view,p_info->temp_buf);
+                       len += view->prolog_proc(id_snap,view,p_info->temp_buf);
                goto out;
        }
-
-       act_entry = (debug_entry_t *) ((char*)id_snap->areas[p_info->act_area] +
-                                       p_info->act_entry);
+       if (!id_snap->areas) /* this is true, if we have a prolog only view */
+               goto out;    /* or if 'pages_per_area' is 0 */
+       act_entry = (debug_entry_t *) ((char*)id_snap->areas[p_info->act_area]
+                               [p_info->act_page] + p_info->act_entry);
                         
        if (act_entry->id.stck == 0LL)
                        goto out;  /* empty entry */
        if (view->header_proc)
-               len += view->header_proc(id_org, view, p_info->act_area, 
+               len += view->header_proc(id_snap, view, p_info->act_area,
                                        act_entry, p_info->temp_buf + len);
        if (view->format_proc)
-               len += view->format_proc(id_org, view, p_info->temp_buf + len,
+               len += view->format_proc(id_snap, view, p_info->temp_buf + len,
                                                DEBUG_DATA(act_entry));
-      out:
+out:
         return len;
 }
 
@@ -389,20 +470,30 @@ static int debug_format_entry(file_private_info_t *p_info)
  * - goto next entry in p_info
  */
 
-extern inline int debug_next_entry(file_private_info_t *p_info)
+extern inline int
+debug_next_entry(file_private_info_t *p_info)
 {
-       debug_info_t *id = p_info->debug_info_snap;
+       debug_info_t *id;
+
+       id = p_info->debug_info_snap;
        if(p_info->act_entry == DEBUG_PROLOG_ENTRY){
                p_info->act_entry = 0;
+               p_info->act_page  = 0;
                goto out;
        }
-       if ((p_info->act_entry += id->entry_size)
-               > ((PAGE_SIZE << (id->page_order)) 
-               - id->entry_size)){
-
-               /* next area */
+       if(!id->areas)
+               return 1;
+       p_info->act_entry += id->entry_size;
+       /* switch to next page, if we reached the end of the page  */
+       if (p_info->act_entry > (PAGE_SIZE - id->entry_size)){
+               /* next page */
                p_info->act_entry = 0;
-               p_info->act_area++;
+               p_info->act_page += 1;
+               if((p_info->act_page % id->pages_per_area) == 0) {
+                       /* next area */
+                       p_info->act_area++;
+                       p_info->act_page=0;
+               }
                if(p_info->act_area >= id->nr_areas)
                        return 1;
        }
@@ -416,13 +507,14 @@ out:
  * - copies formated debug entries to the user buffer
  */
 
-static ssize_t debug_output(struct file *file,         /* file descriptor */
-                           char __user *user_buf,      /* user buffer */
-                           size_t  len,                /* length of buffer */
-                           loff_t *offset)           /* offset in the file */
+static ssize_t
+debug_output(struct file *file,                /* file descriptor */
+           char __user *user_buf,      /* user buffer */
+           size_t  len,                /* length of buffer */
+           loff_t *offset)             /* offset in the file */
 {
        size_t count = 0;
-       size_t entry_offset, size = 0;
+       size_t entry_offset;
        file_private_info_t *p_info;
 
        p_info = ((file_private_info_t *) file->private_data);
@@ -430,27 +522,33 @@ static ssize_t debug_output(struct file *file,            /* file descriptor */
                return -EPIPE;
        if(p_info->act_area >= p_info->debug_info_snap->nr_areas)
                return 0;
-
        entry_offset = p_info->act_entry_offset;
-
        while(count < len){
-               size = debug_format_entry(p_info);
-               size = min((len - count), (size - entry_offset));
-
-               if(size){
-                       if (copy_to_user(user_buf + count, 
-                                       p_info->temp_buf + entry_offset, size))
-                       return -EFAULT;
+               int formatted_line_size;
+               int formatted_line_residue;
+               int user_buf_residue;
+               size_t copy_size;
+
+               formatted_line_size = debug_format_entry(p_info);
+               formatted_line_residue = formatted_line_size - entry_offset;
+               user_buf_residue = len-count;
+               copy_size = min(user_buf_residue, formatted_line_residue);
+               if(copy_size){
+                       if (copy_to_user(user_buf + count, p_info->temp_buf
+                                       + entry_offset, copy_size))
+                               return -EFAULT;
+                       count += copy_size;
+                       entry_offset += copy_size;
                }
-               count += size;
-               entry_offset = 0;
-               if(count != len)
-                       if(debug_next_entry(p_info)) 
+               if(copy_size == formatted_line_residue){
+                       entry_offset = 0;
+                       if(debug_next_entry(p_info))
                                goto out;
+               }
        }
 out:
        p_info->offset           = *offset + count;
-       p_info->act_entry_offset = size;        
+       p_info->act_entry_offset = entry_offset;
        *offset = p_info->offset;
        return count;
 }
@@ -461,9 +559,9 @@ out:
  * - calls input function of view
  */
 
-static ssize_t debug_input(struct file *file,
-                          const char __user *user_buf, size_t length,
-                          loff_t *offset)
+static ssize_t
+debug_input(struct file *file, const char __user *user_buf, size_t length,
+               loff_t *offset)
 {
        int rc = 0;
        file_private_info_t *p_info;
@@ -487,26 +585,23 @@ static ssize_t debug_input(struct file *file,
  *   handle
  */
 
-static int debug_open(struct inode *inode, struct file *file)
+static int
+debug_open(struct inode *inode, struct file *file)
 {
        int i = 0, rc = 0;
        file_private_info_t *p_info;
        debug_info_t *debug_info, *debug_info_snapshot;
 
-#ifdef DEBUG
-       printk("debug_open\n");
-#endif
        down(&debug_lock);
 
        /* find debug log and view */
-
        debug_info = debug_area_first;
        while(debug_info != NULL){
                for (i = 0; i < DEBUG_MAX_VIEWS; i++) {
-                       if (debug_info->views[i] == NULL)
+                       if (!debug_info->views[i])
                                continue;
-                       else if (debug_info->proc_entries[i] ==
-                                PDE(file->f_dentry->d_inode)) {
+                       else if (debug_info->debugfs_entries[i] ==
+                                file->f_dentry) {
                                goto found;     /* found view ! */
                        }
                }
@@ -516,41 +611,42 @@ static int debug_open(struct inode *inode, struct file *file)
        rc = -EINVAL;
        goto out;
 
-      found:
+found:
 
-       /* make snapshot of current debug areas to get it consistent */
+       /* Make snapshot of current debug areas to get it consistent.     */
+       /* To copy all the areas is only needed, if we have a view which  */
+       /* formats the debug areas. */
 
-       debug_info_snapshot = debug_info_copy(debug_info);
+       if(!debug_info->views[i]->format_proc &&
+               !debug_info->views[i]->header_proc){
+               debug_info_snapshot = debug_info_copy(debug_info, NO_AREAS);
+       } else {
+               debug_info_snapshot = debug_info_copy(debug_info, ALL_AREAS);
+       }
 
        if(!debug_info_snapshot){
-#ifdef DEBUG
-               printk(KERN_ERR "debug_open: debug_info_copy failed (out of mem)\n");
-#endif
                rc = -ENOMEM;
                goto out;
        }
-
-       if ((file->private_data =
-            kmalloc(sizeof(file_private_info_t), GFP_ATOMIC)) == 0) {
-#ifdef DEBUG
-               printk(KERN_ERR "debug_open: kmalloc failed\n");
-#endif
-               debug_info_free(debug_info_snapshot);   
+       p_info = (file_private_info_t *) kmalloc(sizeof(file_private_info_t),
+                                               GFP_KERNEL);
+       if(!p_info){
+               if(debug_info_snapshot)
+                       debug_info_free(debug_info_snapshot);
                rc = -ENOMEM;
                goto out;
        }
-       p_info = (file_private_info_t *) file->private_data;
        p_info->offset = 0;
        p_info->debug_info_snap = debug_info_snapshot;
        p_info->debug_info_org  = debug_info;
        p_info->view = debug_info->views[i];
        p_info->act_area = 0;
+       p_info->act_page = 0;
        p_info->act_entry = DEBUG_PROLOG_ENTRY;
        p_info->act_entry_offset = 0;
-
+       file->private_data = p_info;
        debug_info_get(debug_info);
-
-      out:
+out:
        up(&debug_lock);
        return rc;
 }
@@ -561,14 +657,13 @@ static int debug_open(struct inode *inode, struct file *file)
  * - deletes  private_data area of the file handle
  */
 
-static int debug_close(struct inode *inode, struct file *file)
+static int
+debug_close(struct inode *inode, struct file *file)
 {
        file_private_info_t *p_info;
-#ifdef DEBUG
-       printk("debug_close\n");
-#endif
        p_info = (file_private_info_t *) file->private_data;
-       debug_info_free(p_info->debug_info_snap);
+       if(p_info->debug_info_snap)
+               debug_info_free(p_info->debug_info_snap);
        debug_info_put(p_info->debug_info_org);
        kfree(file->private_data);
        return 0;               /* success */
@@ -580,8 +675,8 @@ static int debug_close(struct inode *inode, struct file *file)
  * - returns handle for debug area
  */
 
-debug_info_t *debug_register
-    (char *name, int page_order, int nr_areas, int buf_size) 
+debug_info_t*
+debug_register (char *name, int pages_per_area, int nr_areas, int buf_size)
 {
        debug_info_t *rc = NULL;
 
@@ -591,18 +686,14 @@ debug_info_t *debug_register
 
         /* create new debug_info */
 
-       rc = debug_info_create(name, page_order, nr_areas, buf_size);
+       rc = debug_info_create(name, pages_per_area, nr_areas, buf_size);
        if(!rc) 
                goto out;
        debug_register_view(rc, &debug_level_view);
         debug_register_view(rc, &debug_flush_view);
-#ifdef DEBUG
-       printk(KERN_INFO
-              "debug: reserved %d areas of %d pages for debugging %s\n",
-              nr_areas, 1 << page_order, rc->name);
-#endif
-      out:
-        if (rc == NULL){
+       debug_register_view(rc, &debug_pages_view);
+out:
+        if (!rc){
                printk(KERN_ERR "debug: debug_register failed for %s\n",name);
         }
        up(&debug_lock);
@@ -614,27 +705,65 @@ debug_info_t *debug_register
  * - give back debug area
  */
 
-void debug_unregister(debug_info_t * id)
+void
+debug_unregister(debug_info_t * id)
 {
        if (!id)
                goto out;
        down(&debug_lock);
-#ifdef DEBUG
-       printk(KERN_INFO "debug: unregistering %s\n", id->name);
-#endif
        debug_info_put(id);
        up(&debug_lock);
 
-      out:
+out:
        return;
 }
 
+/*
+ * debug_set_size:
+ * - set area size (number of pages) and number of areas
+ */
+static int
+debug_set_size(debug_info_t* id, int nr_areas, int pages_per_area)
+{
+       unsigned long flags;
+       debug_entry_t *** new_areas;
+       int rc=0;
+
+       if(!id || (nr_areas <= 0) || (pages_per_area < 0))
+               return -EINVAL;
+       if(pages_per_area > 0){
+               new_areas = debug_areas_alloc(pages_per_area, nr_areas);
+               if(!new_areas) {
+                       printk(KERN_WARNING "debug: could not allocate memory "\
+                                        "for pagenumber: %i\n",pages_per_area);
+                       rc = -ENOMEM;
+                       goto out;
+               }
+       } else {
+               new_areas = NULL;
+       }
+       spin_lock_irqsave(&id->lock,flags);
+       debug_areas_free(id);
+       id->areas = new_areas;
+       id->nr_areas = nr_areas;
+       id->pages_per_area = pages_per_area;
+       id->active_area = 0;
+       memset(id->active_entries,0,sizeof(int)*id->nr_areas);
+       memset(id->active_pages, 0, sizeof(int)*id->nr_areas);
+       spin_unlock_irqrestore(&id->lock,flags);
+       printk(KERN_INFO "debug: %s: set new size (%i pages)\n"\
+                        ,id->name, pages_per_area);
+out:
+       return rc;
+}
+
 /*
  * debug_set_level:
  * - set actual debug level
  */
 
-void debug_set_level(debug_info_t* id, int new_level)
+void
+debug_set_level(debug_info_t* id, int new_level)
 {
        unsigned long flags;
        if(!id)
@@ -649,10 +778,6 @@ void debug_set_level(debug_info_t* id, int new_level)
                         id->name, new_level, 0, DEBUG_MAX_LEVEL);
         } else {
                 id->level = new_level;
-#ifdef DEBUG
-                printk(KERN_INFO 
-                       "debug: %s: new level %i\n",id->name,id->level);
-#endif
         }
        spin_unlock_irqrestore(&id->lock,flags);
 }
@@ -663,11 +788,16 @@ void debug_set_level(debug_info_t* id, int new_level)
  * - set active entry to next in the ring buffer
  */
 
-extern inline void proceed_active_entry(debug_info_t * id)
+extern inline void
+proceed_active_entry(debug_info_t * id)
 {
-       if ((id->active_entry[id->active_area] += id->entry_size)
-           > ((PAGE_SIZE << (id->page_order)) - id->entry_size))
-               id->active_entry[id->active_area] = 0;
+       if ((id->active_entries[id->active_area] += id->entry_size)
+           > (PAGE_SIZE - id->entry_size)){
+               id->active_entries[id->active_area] = 0;
+               id->active_pages[id->active_area] =
+                       (id->active_pages[id->active_area] + 1) %
+                       id->pages_per_area;
+       }
 }
 
 /*
@@ -675,7 +805,8 @@ extern inline void proceed_active_entry(debug_info_t * id)
  * - set active area to next in the ring buffer
  */
 
-extern inline void proceed_active_area(debug_info_t * id)
+extern inline void
+proceed_active_area(debug_info_t * id)
 {
        id->active_area++;
        id->active_area = id->active_area % id->nr_areas;
@@ -685,10 +816,12 @@ extern inline void proceed_active_area(debug_info_t * id)
  * get_active_entry:
  */
 
-extern inline debug_entry_t *get_active_entry(debug_info_t * id)
+extern inline debug_entry_t*
+get_active_entry(debug_info_t * id)
 {
-       return (debug_entry_t *) ((char *) id->areas[id->active_area] +
-                                 id->active_entry[id->active_area]);
+       return (debug_entry_t *) (((char *) id->areas[id->active_area]
+                                       [id->active_pages[id->active_area]]) +
+                                       id->active_entries[id->active_area]);
 }
 
 /*
@@ -696,8 +829,9 @@ extern inline debug_entry_t *get_active_entry(debug_info_t * id)
  * - set timestamp, caller address, cpu number etc.
  */
 
-extern inline void debug_finish_entry(debug_info_t * id, debug_entry_t* active,
-               int level, int exception)
+extern inline void
+debug_finish_entry(debug_info_t * id, debug_entry_t* active, int level,
+                       int exception)
 {
        STCK(active->id.stck);
        active->id.fields.cpuid = smp_processor_id();
@@ -721,7 +855,8 @@ static int debug_active=1;
  * always allow read, allow write only if debug_stoppable is set or
  * if debug_active is already off
  */
-static int s390dbf_procactive(ctl_table *table, int write, struct file *filp,
+static int
+s390dbf_procactive(ctl_table *table, int write, struct file *filp,
                      void __user *buffer, size_t *lenp, loff_t *ppos)
 {
        if (!write || debug_stoppable || !debug_active)
@@ -766,7 +901,8 @@ static struct ctl_table s390dbf_dir_table[] = {
 
 struct ctl_table_header *s390dbf_sysctl_header;
 
-void debug_stop_all(void)
+void
+debug_stop_all(void)
 {
        if (debug_stoppable)
                debug_active = 0;
@@ -778,13 +914,13 @@ void debug_stop_all(void)
  * - write debug entry with given size
  */
 
-debug_entry_t *debug_event_common(debug_info_t * id, int level, const void *buf,
-                                 int len)
+debug_entry_t*
+debug_event_common(debug_info_t * id, int level, const void *buf, int len)
 {
        unsigned long flags;
        debug_entry_t *active;
 
-       if (!debug_active)
+       if (!debug_active || !id->areas)
                return NULL;
        spin_lock_irqsave(&id->lock, flags);
        active = get_active_entry(id);
@@ -801,13 +937,13 @@ debug_entry_t *debug_event_common(debug_info_t * id, int level, const void *buf,
  * - write debug entry with given size and switch to next debug area
  */
 
-debug_entry_t *debug_exception_common(debug_info_t * id, int level, 
-                                      const void *buf, int len)
+debug_entry_t
+*debug_exception_common(debug_info_t * id, int level, const void *buf, int len)
 {
        unsigned long flags;
        debug_entry_t *active;
 
-       if (!debug_active)
+       if (!debug_active || !id->areas)
                return NULL;
        spin_lock_irqsave(&id->lock, flags);
        active = get_active_entry(id);
@@ -823,7 +959,8 @@ debug_entry_t *debug_exception_common(debug_info_t * id, int level,
  * counts arguments in format string for sprintf view
  */
 
-extern inline int debug_count_numargs(char *string)
+extern inline int
+debug_count_numargs(char *string)
 {
        int numargs=0;
 
@@ -838,8 +975,8 @@ extern inline int debug_count_numargs(char *string)
  * debug_sprintf_event:
  */
 
-debug_entry_t *debug_sprintf_event(debug_info_t* id,
-                                   int level,char *string,...)
+debug_entry_t*
+debug_sprintf_event(debug_info_t* id, int level,char *string,...)
 {
        va_list   ap;
        int numargs,idx;
@@ -849,7 +986,7 @@ debug_entry_t *debug_sprintf_event(debug_info_t* id,
 
        if((!id) || (level > id->level))
                return NULL;
-       if (!debug_active)
+       if (!debug_active || !id->areas)
                return NULL;
        numargs=debug_count_numargs(string);
 
@@ -871,8 +1008,8 @@ debug_entry_t *debug_sprintf_event(debug_info_t* id,
  * debug_sprintf_exception:
  */
 
-debug_entry_t *debug_sprintf_exception(debug_info_t* id,
-                                       int level,char *string,...)
+debug_entry_t*
+debug_sprintf_exception(debug_info_t* id, int level,char *string,...)
 {
        va_list   ap;
        int numargs,idx;
@@ -882,7 +1019,7 @@ debug_entry_t *debug_sprintf_exception(debug_info_t* id,
 
        if((!id) || (level > id->level))
                return NULL;
-       if (!debug_active)
+       if (!debug_active || !id->areas)
                return NULL;
 
        numargs=debug_count_numargs(string);
@@ -906,15 +1043,14 @@ debug_entry_t *debug_sprintf_exception(debug_info_t* id,
  * - is called exactly once to initialize the debug feature
  */
 
-static int __init debug_init(void)
+static int
+__init debug_init(void)
 {
        int rc = 0;
 
        s390dbf_sysctl_header = register_sysctl_table(s390dbf_dir_table, 1);
        down(&debug_lock);
-#ifdef CONFIG_PROC_FS
-       debug_proc_root_entry = proc_mkdir(DEBUG_DIR_ROOT, NULL);
-#endif /* CONFIG_PROC_FS */
+       debug_debugfs_root_entry = debugfs_create_dir(DEBUG_DIR_ROOT,NULL);
        printk(KERN_INFO "debug: Initialization complete\n");
        initialized = 1;
        up(&debug_lock);
@@ -926,13 +1062,14 @@ static int __init debug_init(void)
  * debug_register_view:
  */
 
-int debug_register_view(debug_info_t * id, struct debug_view *view)
+int
+debug_register_view(debug_info_t * id, struct debug_view *view)
 {
        int rc = 0;
        int i;
        unsigned long flags;
        mode_t mode = S_IFREG;
-       struct proc_dir_entry *pde;
+       struct dentry *pde;
 
        if (!id)
                goto out;
@@ -940,16 +1077,17 @@ int debug_register_view(debug_info_t * id, struct debug_view *view)
                mode |= S_IRUSR;
        if (view->input_proc)
                mode |= S_IWUSR;
-       pde = create_proc_entry(view->name, mode, id->proc_root_entry);
+       pde = debugfs_create_file(view->name, mode, id->debugfs_root_entry,
+                               NULL, &debug_file_ops);
        if (!pde){
-               printk(KERN_WARNING "debug: create_proc_entry() failed! Cannot register view %s/%s\n", id->name,view->name);
+               printk(KERN_WARNING "debug: debugfs_create_file() failed!"\
+                       " Cannot register view %s/%s\n", id->name,view->name);
                rc = -1;
                goto out;
        }
-
        spin_lock_irqsave(&id->lock, flags);
        for (i = 0; i < DEBUG_MAX_VIEWS; i++) {
-               if (id->views[i] == NULL)
+               if (!id->views[i])
                        break;
        }
        if (i == DEBUG_MAX_VIEWS) {
@@ -957,16 +1095,14 @@ int debug_register_view(debug_info_t * id, struct debug_view *view)
                        id->name,view->name);
                printk(KERN_WARNING 
                        "debug: maximum number of views reached (%i)!\n", i);
-               remove_proc_entry(pde->name, id->proc_root_entry);
+               debugfs_remove(pde);
                rc = -1;
-       }
-       else {
+       } else {
                id->views[i] = view;
-               pde->proc_fops = &debug_file_ops;
-               id->proc_entries[i] = pde;
+               id->debugfs_entries[i] = pde;
        }
        spin_unlock_irqrestore(&id->lock, flags);
-      out:
+out:
        return rc;
 }
 
@@ -974,7 +1110,8 @@ int debug_register_view(debug_info_t * id, struct debug_view *view)
  * debug_unregister_view:
  */
 
-int debug_unregister_view(debug_info_t * id, struct debug_view *view)
+int
+debug_unregister_view(debug_info_t * id, struct debug_view *view)
 {
        int rc = 0;
        int i;
@@ -990,15 +1127,46 @@ int debug_unregister_view(debug_info_t * id, struct debug_view *view)
        if (i == DEBUG_MAX_VIEWS)
                rc = -1;
        else {
-#ifdef CONFIG_PROC_FS
-               remove_proc_entry(id->proc_entries[i]->name,
-                                 id->proc_root_entry);
-#endif
+               debugfs_remove(id->debugfs_entries[i]);
                id->views[i] = NULL;
                rc = 0;
        }
        spin_unlock_irqrestore(&id->lock, flags);
-      out:
+out:
+       return rc;
+}
+
+static inline char *
+debug_get_user_string(const char __user *user_buf, size_t user_len)
+{
+       char* buffer;
+
+       buffer = kmalloc(user_len + 1, GFP_KERNEL);
+       if (!buffer)
+               return ERR_PTR(-ENOMEM);
+       if (copy_from_user(buffer, user_buf, user_len) != 0) {
+               kfree(buffer);
+               return ERR_PTR(-EFAULT);
+       }
+       /* got the string, now strip linefeed. */
+       if (buffer[user_len - 1] == '\n')
+               buffer[user_len - 1] = 0;
+       else
+               buffer[user_len] = 0;
+        return buffer;
+}
+
+static inline int
+debug_get_uint(char *buf)
+{
+       int rc;
+
+       for(; isspace(*buf); buf++);
+       rc = simple_strtoul(buf, &buf, 10);
+       if(*buf){
+               printk("debug: no integer specified!\n");
+               rc = -EINVAL;
+       }
        return rc;
 }
 
@@ -1011,13 +1179,69 @@ int debug_unregister_view(debug_info_t * id, struct debug_view *view)
  * prints out actual debug level
  */
 
-static int debug_prolog_level_fn(debug_info_t * id,
+static int
+debug_prolog_pages_fn(debug_info_t * id,
                                 struct debug_view *view, char *out_buf)
+{
+       return sprintf(out_buf, "%i\n", id->pages_per_area);
+}
+
+/*
+ * reads new size (number of pages per debug area)
+ */
+
+static int
+debug_input_pages_fn(debug_info_t * id, struct debug_view *view,
+                       struct file *file, const char __user *user_buf,
+                       size_t user_len, loff_t * offset)
+{
+       char *str;
+       int rc,new_pages;
+
+       if (user_len > 0x10000)
+                user_len = 0x10000;
+       if (*offset != 0){
+               rc = -EPIPE;
+               goto out;
+       }
+       str = debug_get_user_string(user_buf,user_len);
+       if(IS_ERR(str)){
+               rc = PTR_ERR(str);
+               goto out;
+       }
+       new_pages = debug_get_uint(str);
+       if(new_pages < 0){
+               rc = -EINVAL;
+               goto free_str;
+       }
+       rc = debug_set_size(id,id->nr_areas, new_pages);
+       if(rc != 0){
+               rc = -EINVAL;
+               goto free_str;
+       }
+       rc = user_len;
+free_str:
+       kfree(str);
+out:
+       *offset += user_len;
+       return rc;              /* number of input characters */
+}
+
+/*
+ * prints out actual debug level
+ */
+
+static int
+debug_prolog_level_fn(debug_info_t * id, struct debug_view *view, char *out_buf)
 {
        int rc = 0;
 
-       if(id->level == -1) rc = sprintf(out_buf,"-\n");
-       else rc = sprintf(out_buf, "%i\n", id->level);
+       if(id->level == DEBUG_OFF_LEVEL) {
+               rc = sprintf(out_buf,"-\n");
+       }
+       else {
+               rc = sprintf(out_buf, "%i\n", id->level);
+       }
        return rc;
 }
 
@@ -1025,30 +1249,43 @@ static int debug_prolog_level_fn(debug_info_t * id,
  * reads new debug level
  */
 
-static int debug_input_level_fn(debug_info_t * id, struct debug_view *view,
-                               struct file *file, const char __user *user_buf,
-                               size_t in_buf_size, loff_t * offset)
+static int
+debug_input_level_fn(debug_info_t * id, struct debug_view *view,
+                       struct file *file, const char __user *user_buf,
+                       size_t user_len, loff_t * offset)
 {
-       char input_buf[1];
-       int rc = in_buf_size;
+       char *str;
+       int rc,new_level;
 
-       if (*offset != 0)
+       if (user_len > 0x10000)
+                user_len = 0x10000;
+       if (*offset != 0){
+               rc = -EPIPE;
                goto out;
-       if (copy_from_user(input_buf, user_buf, 1)){
-               rc = -EFAULT;
+       }
+       str = debug_get_user_string(user_buf,user_len);
+       if(IS_ERR(str)){
+               rc = PTR_ERR(str);
                goto out;
        }
-       if (isdigit(input_buf[0])) {
-               int new_level = ((int) input_buf[0] - (int) '0');
-               debug_set_level(id, new_level);
-       } else if(input_buf[0] == '-') {
+       if(str[0] == '-'){
                debug_set_level(id, DEBUG_OFF_LEVEL);
+               rc = user_len;
+               goto free_str;
        } else {
-               printk(KERN_INFO "debug: level `%c` is not valid\n",
-                      input_buf[0]);
+               new_level = debug_get_uint(str);
        }
-      out:
-       *offset += in_buf_size;
+       if(new_level < 0) {
+               printk(KERN_INFO "debug: level `%s` is not valid\n", str);
+               rc = -EINVAL;
+       } else {
+               debug_set_level(id, new_level);
+               rc = user_len;
+       }
+free_str:
+       kfree(str);
+out:
+       *offset += user_len;
        return rc;              /* number of input characters */
 }
 
@@ -1057,29 +1294,36 @@ static int debug_input_level_fn(debug_info_t * id, struct debug_view *view,
  * flushes debug areas
  */
  
-void debug_flush(debug_info_t* id, int area)
+void
+debug_flush(debug_info_t* id, int area)
 {
         unsigned long flags;
-        int i;
+        int i,j;
 
-        if(!id)
+        if(!id || !id->areas)
                 return;
         spin_lock_irqsave(&id->lock,flags);
         if(area == DEBUG_FLUSH_ALL){
                 id->active_area = 0;
-                memset(id->active_entry, 0, id->nr_areas * sizeof(int));
-                for (i = 0; i < id->nr_areas; i++) 
-                        memset(id->areas[i], 0, PAGE_SIZE << id->page_order);
+                memset(id->active_entries, 0, id->nr_areas * sizeof(int));
+                for (i = 0; i < id->nr_areas; i++) {
+                       id->active_pages[i] = 0;
+                       for(j = 0; j < id->pages_per_area; j++) {
+                               memset(id->areas[i][j], 0, PAGE_SIZE);
+                       }
+               }
                 printk(KERN_INFO "debug: %s: all areas flushed\n",id->name);
         } else if(area >= 0 && area < id->nr_areas) {
-                id->active_entry[area] = 0;
-                memset(id->areas[area], 0, PAGE_SIZE << id->page_order);
-                printk(KERN_INFO
-                        "debug: %s: area %i has been flushed\n",
+                id->active_entries[area] = 0;
+               id->active_pages[area] = 0;
+               for(i = 0; i < id->pages_per_area; i++) {
+                       memset(id->areas[area][i],0,PAGE_SIZE);
+               }
+                printk(KERN_INFO "debug: %s: area %i has been flushed\n",
                         id->name, area);
         } else {
                 printk(KERN_INFO
-                        "debug: %s: area %i cannot be flushed (range: %i - %i)\n",
+                      "debug: %s: area %i cannot be flushed (range: %i - %i)\n",
                         id->name, area, 0, id->nr_areas-1);
         }
         spin_unlock_irqrestore(&id->lock,flags);
@@ -1089,15 +1333,20 @@ void debug_flush(debug_info_t* id, int area)
  * view function: flushes debug areas 
  */
 
-static int debug_input_flush_fn(debug_info_t * id, struct debug_view *view,
-                                struct file *file, const char __user *user_buf,
-                                size_t in_buf_size, loff_t * offset)
+static int
+debug_input_flush_fn(debug_info_t * id, struct debug_view *view,
+                       struct file *file, const char __user *user_buf,
+                       size_t user_len, loff_t * offset)
 {
         char input_buf[1];
-        int rc = in_buf_size;
-        if (*offset != 0)
+        int rc = user_len;
+
+       if (user_len > 0x10000)
+                user_len = 0x10000;
+        if (*offset != 0){
+               rc = -EPIPE;
                 goto out;
+       }
         if (copy_from_user(input_buf, user_buf, 1)){
                 rc = -EFAULT;
                 goto out;
@@ -1114,8 +1363,8 @@ static int debug_input_flush_fn(debug_info_t * id, struct debug_view *view,
 
         printk(KERN_INFO "debug: area `%c` is not valid\n", input_buf[0]);
 
-      out:
-        *offset += in_buf_size;
+out:
+        *offset += user_len;
         return rc;              /* number of input characters */
 }
 
@@ -1123,8 +1372,9 @@ static int debug_input_flush_fn(debug_info_t * id, struct debug_view *view,
  * prints debug header in raw format
  */
 
-int debug_raw_header_fn(debug_info_t * id, struct debug_view *view,
-                         int area, debug_entry_t * entry, char *out_buf)
+static int
+debug_raw_header_fn(debug_info_t * id, struct debug_view *view,
+                       int area, debug_entry_t * entry, char *out_buf)
 {
         int rc;
 
@@ -1137,7 +1387,8 @@ int debug_raw_header_fn(debug_info_t * id, struct debug_view *view,
  * prints debug data in raw format
  */
 
-static int debug_raw_format_fn(debug_info_t * id, struct debug_view *view,
+static int
+debug_raw_format_fn(debug_info_t * id, struct debug_view *view,
                               char *out_buf, const char *in_buf)
 {
        int rc;
@@ -1151,8 +1402,9 @@ static int debug_raw_format_fn(debug_info_t * id, struct debug_view *view,
  * prints debug data in hex/ascii format
  */
 
-static int debug_hex_ascii_format_fn(debug_info_t * id, struct debug_view *view,
-                                 char *out_buf, const char *in_buf)
+static int
+debug_hex_ascii_format_fn(debug_info_t * id, struct debug_view *view,
+                         char *out_buf, const char *in_buf)
 {
        int i, rc = 0;
 
@@ -1176,7 +1428,8 @@ static int debug_hex_ascii_format_fn(debug_info_t * id, struct debug_view *view,
  * prints header for debug entry
  */
 
-int debug_dflt_header_fn(debug_info_t * id, struct debug_view *view,
+int
+debug_dflt_header_fn(debug_info_t * id, struct debug_view *view,
                         int area, debug_entry_t * entry, char *out_buf)
 {
        struct timeval time_val;
@@ -1210,8 +1463,9 @@ int debug_dflt_header_fn(debug_info_t * id, struct debug_view *view,
 
 #define DEBUG_SPRINTF_MAX_ARGS 10
 
-int debug_sprintf_format_fn(debug_info_t * id, struct debug_view *view,
-                            char *out_buf, debug_sprintf_entry_t *curr_event)
+static int
+debug_sprintf_format_fn(debug_info_t * id, struct debug_view *view,
+                        char *out_buf, debug_sprintf_entry_t *curr_event)
 {
        int num_longs, num_used_args = 0,i, rc = 0;
        int index[DEBUG_SPRINTF_MAX_ARGS];
@@ -1251,14 +1505,10 @@ out:
 /*
  * clean up module
  */
-void __exit debug_exit(void)
+void
+__exit debug_exit(void)
 {
-#ifdef DEBUG
-       printk("debug_cleanup_module: \n");
-#endif
-#ifdef CONFIG_PROC_FS
-       remove_proc_entry(debug_proc_root_entry->name, NULL);
-#endif /* CONFIG_PROC_FS */
+       debugfs_remove(debug_debugfs_root_entry);
        unregister_sysctl_table(s390dbf_sysctl_header);
        return;
 }
@@ -1266,7 +1516,7 @@ void __exit debug_exit(void)
 /*
  * module definitions
  */
-core_initcall(debug_init);
+postcore_initcall(debug_init);
 module_exit(debug_exit);
 MODULE_LICENSE("GPL");
 
index c0e09b33febe6fc265cc8a30a0a0bda6c7891e45..5b262b5d869f7625f5262b2e0d50137838a37aa1 100644 (file)
@@ -7,6 +7,7 @@
  *    Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com),
  *               Hartmut Penner (hp@de.ibm.com),
  *               Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com),
+ *              Heiko Carstens <heiko.carstens@de.ibm.com>
  */
 
 #include <linux/sys.h>
@@ -49,9 +50,9 @@ SP_ILC       =  STACK_FRAME_OVERHEAD + __PT_ILC
 SP_TRAP      =  STACK_FRAME_OVERHEAD + __PT_TRAP
 SP_SIZE      =  STACK_FRAME_OVERHEAD + __PT_SIZE
 
-_TIF_WORK_SVC = (_TIF_SIGPENDING | _TIF_NEED_RESCHED | \
+_TIF_WORK_SVC = (_TIF_SIGPENDING | _TIF_NEED_RESCHED | _TIF_MCCK_PENDING | \
                 _TIF_RESTART_SVC | _TIF_SINGLE_STEP )
-_TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_NEED_RESCHED)
+_TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_NEED_RESCHED | _TIF_MCCK_PENDING)
 
 STACK_SHIFT = PAGE_SHIFT + THREAD_ORDER
 STACK_SIZE  = 1 << STACK_SHIFT
@@ -121,7 +122,11 @@ STACK_SIZE  = 1 << STACK_SHIFT
        bz      BASED(stack_overflow)
 3:
 #endif
-2:     s       %r15,BASED(.Lc_spsize)  # make room for registers & psw
+2:
+       .endm
+
+       .macro  CREATE_STACK_FRAME psworg,savearea
+       s       %r15,BASED(.Lc_spsize)  # make room for registers & psw
        mvc     SP_PSW(8,%r15),0(%r12)  # move user PSW to stack
        la      %r12,\psworg
        st      %r2,SP_ORIG_R2(%r15)    # store original content of gpr 2
@@ -161,6 +166,13 @@ __switch_to_base:
         be      __switch_to_noper-__switch_to_base(%r1)        # we got away w/o bashing TLB's
         lctl    %c9,%c11,__THREAD_per(%r3)     # Nope we didn't
 __switch_to_noper:
+       l       %r4,__THREAD_info(%r2)          # get thread_info of prev
+       tm      __TI_flags+3(%r4),_TIF_MCCK_PENDING # machine check pending?
+       bz      __switch_to_no_mcck-__switch_to_base(%r1)
+       ni      __TI_flags+3(%r4),255-_TIF_MCCK_PENDING # clear flag in prev
+       l       %r4,__THREAD_info(%r3)          # get thread_info of next
+       oi      __TI_flags+3(%r4),_TIF_MCCK_PENDING # set it in next
+__switch_to_no_mcck:
         stm     %r6,%r15,__SF_GPRS(%r15)# store __switch_to registers of prev task
        st      %r15,__THREAD_ksp(%r2)  # store kernel stack to prev->tss.ksp
        l       %r15,__THREAD_ksp(%r3)  # load kernel stack from next->tss.ksp
@@ -185,6 +197,7 @@ system_call:
 sysc_saveall:
        SAVE_ALL_BASE __LC_SAVE_AREA
         SAVE_ALL __LC_SVC_OLD_PSW,__LC_SAVE_AREA,1
+       CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA
        lh      %r7,0x8a          # get svc number from lowcore
 #ifdef CONFIG_VIRT_CPU_ACCOUNTING
 sysc_vtime:
@@ -234,6 +247,8 @@ sysc_work_loop:
 # One of the work bits is on. Find out which one.
 #
 sysc_work:
+       tm      __TI_flags+3(%r9),_TIF_MCCK_PENDING
+       bo      BASED(sysc_mcck_pending)
        tm      __TI_flags+3(%r9),_TIF_NEED_RESCHED
        bo      BASED(sysc_reschedule)
        tm      __TI_flags+3(%r9),_TIF_SIGPENDING
@@ -252,6 +267,14 @@ sysc_reschedule:
        la      %r14,BASED(sysc_work_loop)
        br      %r1                    # call scheduler
 
+#
+# _TIF_MCCK_PENDING is set, call handler
+#
+sysc_mcck_pending:
+       l       %r1,BASED(.Ls390_handle_mcck)
+       la      %r14,BASED(sysc_work_loop)
+       br      %r1                     # TIF bit will be cleared by handler
+
 #
 # _TIF_SIGPENDING is set, call do_signal
 #
@@ -430,6 +453,7 @@ pgm_check_handler:
         tm      __LC_PGM_INT_CODE+1,0x80 # check whether we got a per exception
         bnz     BASED(pgm_per)           # got per exception -> special case
        SAVE_ALL __LC_PGM_OLD_PSW,__LC_SAVE_AREA,1
+       CREATE_STACK_FRAME __LC_PGM_OLD_PSW,__LC_SAVE_AREA
 #ifdef CONFIG_VIRT_CPU_ACCOUNTING
        tm      SP_PSW+1(%r15),0x01     # interrupting from user ?
        bz      BASED(pgm_no_vtime)
@@ -468,6 +492,7 @@ pgm_per:
 #
 pgm_per_std:
        SAVE_ALL __LC_PGM_OLD_PSW,__LC_SAVE_AREA,1
+       CREATE_STACK_FRAME __LC_PGM_OLD_PSW,__LC_SAVE_AREA
 #ifdef CONFIG_VIRT_CPU_ACCOUNTING
        tm      SP_PSW+1(%r15),0x01     # interrupting from user ?
        bz      BASED(pgm_no_vtime2)
@@ -493,6 +518,7 @@ pgm_no_vtime2:
 #
 pgm_svcper:
        SAVE_ALL __LC_SVC_OLD_PSW,__LC_SAVE_AREA,1
+       CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA
 #ifdef CONFIG_VIRT_CPU_ACCOUNTING
        tm      SP_PSW+1(%r15),0x01     # interrupting from user ?
        bz      BASED(pgm_no_vtime3)
@@ -521,6 +547,7 @@ io_int_handler:
        stck    __LC_INT_CLOCK
        SAVE_ALL_BASE __LC_SAVE_AREA+16
         SAVE_ALL __LC_IO_OLD_PSW,__LC_SAVE_AREA+16,0
+       CREATE_STACK_FRAME __LC_IO_OLD_PSW,__LC_SAVE_AREA+16
 #ifdef CONFIG_VIRT_CPU_ACCOUNTING
        tm      SP_PSW+1(%r15),0x01     # interrupting from user ?
        bz      BASED(io_no_vtime)
@@ -578,15 +605,25 @@ io_work:
        lr      %r15,%r1
 #
 # One of the work bits is on. Find out which one.
-# Checked are: _TIF_SIGPENDING and _TIF_NEED_RESCHED
+# Checked are: _TIF_SIGPENDING, _TIF_NEED_RESCHED and _TIF_MCCK_PENDING
 #
 io_work_loop:
+       tm      __TI_flags+3(%r9),_TIF_MCCK_PENDING
+       bo      BASED(io_mcck_pending)
        tm      __TI_flags+3(%r9),_TIF_NEED_RESCHED
        bo      BASED(io_reschedule)
        tm      __TI_flags+3(%r9),_TIF_SIGPENDING
        bo      BASED(io_sigpending)
        b       BASED(io_leave)
 
+#
+# _TIF_MCCK_PENDING is set, call handler
+#
+io_mcck_pending:
+       l       %r1,BASED(.Ls390_handle_mcck)
+       l       %r14,BASED(io_work_loop)
+       br      %r1                    # TIF bit will be cleared by handler
+
 #
 # _TIF_NEED_RESCHED is set, call schedule
 #      
@@ -621,6 +658,7 @@ ext_int_handler:
        stck    __LC_INT_CLOCK
        SAVE_ALL_BASE __LC_SAVE_AREA+16
         SAVE_ALL __LC_EXT_OLD_PSW,__LC_SAVE_AREA+16,0
+       CREATE_STACK_FRAME __LC_EXT_OLD_PSW,__LC_SAVE_AREA+16
 #ifdef CONFIG_VIRT_CPU_ACCOUNTING
        tm      SP_PSW+1(%r15),0x01     # interrupting from user ?
        bz      BASED(ext_no_vtime)
@@ -642,19 +680,62 @@ ext_no_vtime:
 
         .globl mcck_int_handler
 mcck_int_handler:
-       STORE_TIMER __LC_ASYNC_ENTER_TIMER
+       spt     __LC_CPU_TIMER_SAVE_AREA        # revalidate cpu timer
+       lm      %r0,%r15,__LC_GPREGS_SAVE_AREA  # revalidate gprs
        SAVE_ALL_BASE __LC_SAVE_AREA+32
-        SAVE_ALL __LC_MCK_OLD_PSW,__LC_SAVE_AREA+32,0
+       la      %r12,__LC_MCK_OLD_PSW
+       tm      __LC_MCCK_CODE,0x80     # system damage?
+       bo      BASED(mcck_int_main)    # yes -> rest of mcck code invalid
+       tm      __LC_MCCK_CODE+5,0x02   # stored cpu timer value valid?
+       bo      BASED(0f)
+       spt     __LC_LAST_UPDATE_TIMER  # revalidate cpu timer
 #ifdef CONFIG_VIRT_CPU_ACCOUNTING
-       tm      SP_PSW+1(%r15),0x01     # interrupting from user ?
+       mvc     __LC_LAST_UPDATE_TIMER(8),__LC_ASYNC_ENTER_TIMER
+       mvc     __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER
+       mvc     __LC_LAST_UPDATE_TIMER(8),__LC_EXIT_TIMER
+0:     tm      __LC_MCCK_CODE+2,0x08   # mwp of old psw valid?
+       bno     BASED(mcck_no_vtime)    # no -> skip cleanup critical
+       tm      __LC_MCK_OLD_PSW+1,0x01 # interrupting from user ?
        bz      BASED(mcck_no_vtime)
        UPDATE_VTIME __LC_EXIT_TIMER,__LC_ASYNC_ENTER_TIMER,__LC_USER_TIMER
        UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER
        mvc     __LC_LAST_UPDATE_TIMER(8),__LC_ASYNC_ENTER_TIMER
 mcck_no_vtime:
 #endif
+0:
+       tm      __LC_MCCK_CODE+2,0x09   # mwp + ia of old psw valid?
+       bno     BASED(mcck_int_main)    # no -> skip cleanup critical
+       tm      __LC_MCK_OLD_PSW+1,0x01 # test problem state bit
+       bnz     BASED(mcck_int_main)    # from user -> load async stack
+       clc     __LC_MCK_OLD_PSW+4(4),BASED(.Lcritical_end)
+       bhe     BASED(mcck_int_main)
+       clc     __LC_MCK_OLD_PSW+4(4),BASED(.Lcritical_start)
+       bl      BASED(mcck_int_main)
+       l       %r14,BASED(.Lcleanup_critical)
+       basr    %r14,%r14
+mcck_int_main:
+       l       %r14,__LC_PANIC_STACK   # are we already on the panic stack?
+       slr     %r14,%r15
+       sra     %r14,PAGE_SHIFT
+       be      BASED(0f)
+       l       %r15,__LC_PANIC_STACK   # load panic stack
+0:     CREATE_STACK_FRAME __LC_MCK_OLD_PSW,__LC_SAVE_AREA+32
+       l       %r9,__LC_THREAD_INFO    # load pointer to thread_info struct
+       la      %r2,SP_PTREGS(%r15)     # load pt_regs
        l       %r1,BASED(.Ls390_mcck)
-       basr    %r14,%r1          # call machine check handler
+       basr    %r14,%r1                # call machine check handler
+       tm      SP_PSW+1(%r15),0x01     # returning to user ?
+       bno     BASED(mcck_return)
+       l       %r1,__LC_KERNEL_STACK   # switch to kernel stack
+       s       %r1,BASED(.Lc_spsize)
+       mvc     SP_PTREGS(__PT_SIZE,%r1),SP_PTREGS(%r15)
+       xc      __SF_BACKCHAIN(4,%r1),__SF_BACKCHAIN(%r1) # clear back chain
+       lr      %r15,%r1
+       stosm   __SF_EMPTY(%r15),0x04   # turn dat on
+       tm      __TI_flags+3(%r9),_TIF_MCCK_PENDING
+       bno     BASED(mcck_return)
+       l       %r1,BASED(.Ls390_handle_mcck)
+       basr    %r14,%r1                # call machine check handler
 mcck_return:
         RESTORE_ALL 0
 
@@ -742,7 +823,7 @@ cleanup_critical:
        clc     4(4,%r12),BASED(cleanup_table_sysc_work_loop)
        bl      BASED(0f)
        clc     4(4,%r12),BASED(cleanup_table_sysc_work_loop+4)
-       bl      BASED(cleanup_sysc_leave)
+       bl      BASED(cleanup_sysc_return)
 0:
        br      %r14
 
@@ -760,6 +841,7 @@ cleanup_system_call:
        mvc     __LC_SAVE_AREA(16),__LC_SAVE_AREA+16
 0:     st      %r13,__LC_SAVE_AREA+20
        SAVE_ALL __LC_SVC_OLD_PSW,__LC_SAVE_AREA,1
+       CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA
        st      %r15,__LC_SAVE_AREA+28
        lh      %r7,0x8a
 #ifdef CONFIG_VIRT_CPU_ACCOUNTING
@@ -834,6 +916,8 @@ cleanup_sysc_leave_insn:
  * Symbol constants
  */
 .Ls390_mcck:   .long  s390_do_machine_check
+.Ls390_handle_mcck:
+              .long  s390_handle_mcck
 .Ldo_IRQ:      .long  do_IRQ
 .Ldo_extint:   .long  do_extint
 .Ldo_signal:   .long  do_signal
index 51527ab8c8f974b646fe92e599fc513fefc869d3..57ca75d0ad7f4af184d9003f6dfb7b3e7513e306 100644 (file)
@@ -7,6 +7,7 @@
  *    Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com),
  *               Hartmut Penner (hp@de.ibm.com),
  *               Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com),
+ *              Heiko Carstens <heiko.carstens@de.ibm.com>
  */
 
 #include <linux/sys.h>
@@ -52,9 +53,9 @@ SP_SIZE      =  STACK_FRAME_OVERHEAD + __PT_SIZE
 STACK_SHIFT = PAGE_SHIFT + THREAD_ORDER
 STACK_SIZE  = 1 << STACK_SHIFT
 
-_TIF_WORK_SVC = (_TIF_SIGPENDING | _TIF_NEED_RESCHED | \
+_TIF_WORK_SVC = (_TIF_SIGPENDING | _TIF_NEED_RESCHED | _TIF_MCCK_PENDING | \
                 _TIF_RESTART_SVC | _TIF_SINGLE_STEP )
-_TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_NEED_RESCHED)
+_TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_NEED_RESCHED | _TIF_MCCK_PENDING)
 
 #define BASED(name) name-system_call(%r13)
 
@@ -114,7 +115,11 @@ _TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_NEED_RESCHED)
        jz      stack_overflow
 3:
 #endif
-2:     aghi    %r15,-SP_SIZE           # make room for registers & psw
+2:
+       .endm
+
+       .macro  CREATE_STACK_FRAME psworg,savearea
+       aghi    %r15,-SP_SIZE           # make room for registers & psw
        mvc     SP_PSW(16,%r15),0(%r12) # move user PSW to stack
        la      %r12,\psworg
        stg     %r2,SP_ORIG_R2(%r15)    # store original content of gpr 2
@@ -152,6 +157,13 @@ __switch_to:
         je      __switch_to_noper            # we got away without bashing TLB's
         lctlg   %c9,%c11,__THREAD_per(%r3)     # Nope we didn't
 __switch_to_noper:
+       lg      %r4,__THREAD_info(%r2)              # get thread_info of prev
+       tm      __TI_flags+7(%r4),_TIF_MCCK_PENDING # machine check pending?
+       jz      __switch_to_no_mcck
+       ni      __TI_flags+7(%r4),255-_TIF_MCCK_PENDING # clear flag in prev
+       lg      %r4,__THREAD_info(%r3)              # get thread_info of next
+       oi      __TI_flags+7(%r4),_TIF_MCCK_PENDING # set it in next
+__switch_to_no_mcck:
         stmg    %r6,%r15,__SF_GPRS(%r15)# store __switch_to registers of prev task
        stg     %r15,__THREAD_ksp(%r2)  # store kernel stack to prev->tss.ksp
        lg      %r15,__THREAD_ksp(%r3)  # load kernel stack from next->tss.ksp
@@ -176,6 +188,7 @@ system_call:
 sysc_saveall:
        SAVE_ALL_BASE __LC_SAVE_AREA
         SAVE_ALL __LC_SVC_OLD_PSW,__LC_SAVE_AREA,1
+        CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA
        llgh    %r7,__LC_SVC_INT_CODE # get svc number from lowcore
 #ifdef CONFIG_VIRT_CPU_ACCOUNTING
 sysc_vtime:
@@ -232,6 +245,8 @@ sysc_work_loop:
 # One of the work bits is on. Find out which one.
 #
 sysc_work:
+       tm      __TI_flags+7(%r9),_TIF_MCCK_PENDING
+       jo      sysc_mcck_pending
        tm      __TI_flags+7(%r9),_TIF_NEED_RESCHED
        jo      sysc_reschedule
        tm      __TI_flags+7(%r9),_TIF_SIGPENDING
@@ -249,6 +264,13 @@ sysc_reschedule:
        larl    %r14,sysc_work_loop
         jg      schedule            # return point is sysc_return
 
+#
+# _TIF_MCCK_PENDING is set, call handler
+#
+sysc_mcck_pending:
+       larl    %r14,sysc_work_loop
+       jg      s390_handle_mcck    # TIF bit will be cleared by handler
+
 #
 # _TIF_SIGPENDING is set, call do_signal
 #
@@ -474,6 +496,7 @@ pgm_check_handler:
         tm      __LC_PGM_INT_CODE+1,0x80 # check whether we got a per exception
         jnz     pgm_per                  # got per exception -> special case
        SAVE_ALL __LC_PGM_OLD_PSW,__LC_SAVE_AREA,1
+       CREATE_STACK_FRAME __LC_PGM_OLD_PSW,__LC_SAVE_AREA
 #ifdef CONFIG_VIRT_CPU_ACCOUNTING
        tm      SP_PSW+1(%r15),0x01     # interrupting from user ?
        jz      pgm_no_vtime
@@ -512,6 +535,7 @@ pgm_per:
 #
 pgm_per_std:
        SAVE_ALL __LC_PGM_OLD_PSW,__LC_SAVE_AREA,1
+       CREATE_STACK_FRAME __LC_PGM_OLD_PSW,__LC_SAVE_AREA
 #ifdef CONFIG_VIRT_CPU_ACCOUNTING
        tm      SP_PSW+1(%r15),0x01     # interrupting from user ?
        jz      pgm_no_vtime2
@@ -537,6 +561,7 @@ pgm_no_vtime2:
 #
 pgm_svcper:
        SAVE_ALL __LC_SVC_OLD_PSW,__LC_SAVE_AREA,1
+       CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA
 #ifdef CONFIG_VIRT_CPU_ACCOUNTING
        tm      SP_PSW+1(%r15),0x01     # interrupting from user ?
        jz      pgm_no_vtime3
@@ -564,6 +589,7 @@ io_int_handler:
        stck    __LC_INT_CLOCK
        SAVE_ALL_BASE __LC_SAVE_AREA+32
         SAVE_ALL __LC_IO_OLD_PSW,__LC_SAVE_AREA+32,0
+       CREATE_STACK_FRAME __LC_IO_OLD_PSW,__LC_SAVE_AREA+32
 #ifdef CONFIG_VIRT_CPU_ACCOUNTING
        tm      SP_PSW+1(%r15),0x01     # interrupting from user ?
        jz      io_no_vtime
@@ -621,15 +647,24 @@ io_work:
        lgr     %r15,%r1
 #
 # One of the work bits is on. Find out which one.
-# Checked are: _TIF_SIGPENDING and _TIF_NEED_RESCHED
+# Checked are: _TIF_SIGPENDING, _TIF_NEED_RESCHED and _TIF_MCCK_PENDING
 #
 io_work_loop:
+       tm      __TI_flags+7(%r9),_TIF_MCCK_PENDING
+       jo      io_mcck_pending
        tm      __TI_flags+7(%r9),_TIF_NEED_RESCHED
        jo      io_reschedule
        tm      __TI_flags+7(%r9),_TIF_SIGPENDING
        jo      io_sigpending
        j       io_leave
 
+#
+# _TIF_MCCK_PENDING is set, call handler
+#
+io_mcck_pending:
+       larl    %r14,io_work_loop
+       jg      s390_handle_mcck        # TIF bit will be cleared by handler
+
 #
 # _TIF_NEED_RESCHED is set, call schedule
 #      
@@ -661,6 +696,7 @@ ext_int_handler:
        stck    __LC_INT_CLOCK
        SAVE_ALL_BASE __LC_SAVE_AREA+32
         SAVE_ALL __LC_EXT_OLD_PSW,__LC_SAVE_AREA+32,0
+       CREATE_STACK_FRAME __LC_EXT_OLD_PSW,__LC_SAVE_AREA+32
 #ifdef CONFIG_VIRT_CPU_ACCOUNTING
        tm      SP_PSW+1(%r15),0x01     # interrupting from user ?
        jz      ext_no_vtime
@@ -680,18 +716,60 @@ ext_no_vtime:
  */
         .globl mcck_int_handler
 mcck_int_handler:
-       STORE_TIMER __LC_ASYNC_ENTER_TIMER
+       la      %r1,4095                # revalidate r1
+       spt     __LC_CPU_TIMER_SAVE_AREA-4095(%r1)      # revalidate cpu timer
+       lmg     %r0,%r15,__LC_GPREGS_SAVE_AREA-4095(%r1)# revalidate gprs
        SAVE_ALL_BASE __LC_SAVE_AREA+64
-        SAVE_ALL __LC_MCK_OLD_PSW,__LC_SAVE_AREA+64,0
+       la      %r12,__LC_MCK_OLD_PSW
+       tm      __LC_MCCK_CODE,0x80     # system damage?
+       jo      mcck_int_main           # yes -> rest of mcck code invalid
+       tm      __LC_MCCK_CODE+5,0x02   # stored cpu timer value valid?
+       jo      0f
+       spt     __LC_LAST_UPDATE_TIMER
 #ifdef CONFIG_VIRT_CPU_ACCOUNTING
-       tm      SP_PSW+1(%r15),0x01     # interrupting from user ?
+       mvc     __LC_LAST_UPDATE_TIMER(8),__LC_ASYNC_ENTER_TIMER
+       mvc     __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER
+       mvc     __LC_LAST_UPDATE_TIMER(8),__LC_EXIT_TIMER
+0:     tm      __LC_MCCK_CODE+2,0x08   # mwp of old psw valid?
+       jno     mcck_no_vtime           # no -> no timer update
+       tm      __LC_MCK_OLD_PSW+1,0x01 # interrupting from user ?
        jz      mcck_no_vtime
        UPDATE_VTIME __LC_EXIT_TIMER,__LC_ASYNC_ENTER_TIMER,__LC_USER_TIMER
        UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER
        mvc     __LC_LAST_UPDATE_TIMER(8),__LC_ASYNC_ENTER_TIMER
 mcck_no_vtime:
 #endif
-       brasl   %r14,s390_do_machine_check
+0:
+       tm      __LC_MCCK_CODE+2,0x09   # mwp + ia of old psw valid?
+       jno     mcck_int_main           # no -> skip cleanup critical
+       tm      __LC_MCK_OLD_PSW+1,0x01 # test problem state bit
+       jnz     mcck_int_main           # from user -> load kernel stack
+       clc     __LC_MCK_OLD_PSW+8(8),BASED(.Lcritical_end)
+       jhe     mcck_int_main
+       clc     __LC_MCK_OLD_PSW+8(8),BASED(.Lcritical_start)
+       jl      mcck_int_main
+       brasl   %r14,cleanup_critical
+mcck_int_main:
+       lg      %r14,__LC_PANIC_STACK   # are we already on the panic stack?
+       slgr    %r14,%r15
+       srag    %r14,%r14,PAGE_SHIFT
+       jz      0f
+       lg      %r15,__LC_PANIC_STACK   # load panic stack
+0:     CREATE_STACK_FRAME __LC_MCK_OLD_PSW,__LC_SAVE_AREA+64
+       lg      %r9,__LC_THREAD_INFO    # load pointer to thread_info struct
+       la      %r2,SP_PTREGS(%r15)     # load pt_regs
+       brasl   %r14,s390_do_machine_check
+       tm      SP_PSW+1(%r15),0x01     # returning to user ?
+       jno     mcck_return
+       lg      %r1,__LC_KERNEL_STACK   # switch to kernel stack
+       aghi    %r1,-SP_SIZE
+       mvc     SP_PTREGS(__PT_SIZE,%r1),SP_PTREGS(%r15)
+       xc      __SF_BACKCHAIN(8,%r1),__SF_BACKCHAIN(%r1) # clear back chain
+       lgr     %r15,%r1
+       stosm   __SF_EMPTY(%r15),0x04   # turn dat on
+       tm      __TI_flags+7(%r9),_TIF_MCCK_PENDING
+       jno     mcck_return
+       brasl   %r14,s390_handle_mcck
 mcck_return:
         RESTORE_ALL 0
 
@@ -775,7 +853,7 @@ cleanup_critical:
        clc     8(8,%r12),BASED(cleanup_table_sysc_work_loop)
        jl      0f
        clc     8(8,%r12),BASED(cleanup_table_sysc_work_loop+8)
-       jl      cleanup_sysc_leave
+       jl      cleanup_sysc_return
 0:
        br      %r14
 
@@ -793,6 +871,7 @@ cleanup_system_call:
        mvc     __LC_SAVE_AREA(32),__LC_SAVE_AREA+32
 0:     stg     %r13,__LC_SAVE_AREA+40
        SAVE_ALL __LC_SVC_OLD_PSW,__LC_SAVE_AREA,1
+       CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA
        stg     %r15,__LC_SAVE_AREA+56
        llgh    %r7,__LC_SVC_INT_CODE
 #ifdef CONFIG_VIRT_CPU_ACCOUNTING
diff --git a/arch/s390/kernel/machine_kexec.c b/arch/s390/kernel/machine_kexec.c
new file mode 100644 (file)
index 0000000..2721c3a
--- /dev/null
@@ -0,0 +1,98 @@
+/*
+ * arch/s390/kernel/machine_kexec.c
+ *
+ * (C) Copyright IBM Corp. 2005
+ *
+ * Author(s): Rolf Adelsberger <adelsberger@de.ibm.com>
+ *
+ */
+
+/*
+ * s390_machine_kexec.c - handle the transition of Linux booting another kernel
+ * on the S390 architecture.
+ */
+
+#include <asm/cio.h>
+#include <asm/setup.h>
+#include <linux/device.h>
+#include <linux/mm.h>
+#include <linux/kexec.h>
+#include <linux/delay.h>
+#include <asm/pgtable.h>
+#include <asm/pgalloc.h>
+#include <asm/system.h>
+
+static void kexec_halt_all_cpus(void *);
+
+typedef void (*relocate_kernel_t) (kimage_entry_t *, unsigned long);
+
+const extern unsigned char relocate_kernel[];
+const extern unsigned long long relocate_kernel_len;
+
+int
+machine_kexec_prepare(struct kimage *image)
+{
+       unsigned long reboot_code_buffer;
+
+       /* We don't support anything but the default image type for now. */
+       if (image->type != KEXEC_TYPE_DEFAULT)
+               return -EINVAL;
+
+       /* Get the destination where the assembler code should be copied to.*/
+       reboot_code_buffer = page_to_pfn(image->control_code_page)<<PAGE_SHIFT;
+
+       /* Then copy it */
+       memcpy((void *) reboot_code_buffer, relocate_kernel,
+              relocate_kernel_len);
+       return 0;
+}
+
+void
+machine_kexec_cleanup(struct kimage *image)
+{
+}
+
+void
+machine_shutdown(void)
+{
+       printk(KERN_INFO "kexec: machine_shutdown called\n");
+}
+
+NORET_TYPE void
+machine_kexec(struct kimage *image)
+{
+       clear_all_subchannels();
+
+       /* Disable lowcore protection */
+       ctl_clear_bit(0,28);
+
+       on_each_cpu(kexec_halt_all_cpus, image, 0, 0);
+       for (;;);
+}
+
+static void
+kexec_halt_all_cpus(void *kernel_image)
+{
+       static atomic_t cpuid = ATOMIC_INIT(-1);
+       int cpu;
+       struct kimage *image;
+       relocate_kernel_t data_mover;
+
+       if (atomic_compare_and_swap(-1, smp_processor_id(), &cpuid))
+               signal_processor(smp_processor_id(), sigp_stop);
+
+       /* Wait for all other cpus to enter stopped state */
+       for_each_online_cpu(cpu) {
+               if (cpu == smp_processor_id())
+                       continue;
+               while (!smp_cpu_not_running(cpu))
+                       cpu_relax();
+       }
+
+       image = (struct kimage *) kernel_image;
+       data_mover = (relocate_kernel_t)
+               (page_to_pfn(image->control_code_page) << PAGE_SHIFT);
+
+       /* Call the moving routine */
+       (*data_mover) (&image->head, image->start);
+}
index 7aea25d6e3003744758cc62542b56e3a5a8ef2c8..9f3dff6c0b72286a7c769787dcb0d9046bc29d93 100644 (file)
@@ -91,13 +91,12 @@ void do_monitor_call(struct pt_regs *regs, long interruption_code)
                            (void *)(long) smp_processor_id());
 }
 
+extern void s390_handle_mcck(void);
 /*
  * The idle loop on a S390...
  */
 void default_idle(void)
 {
-       psw_t wait_psw;
-       unsigned long reg;
        int cpu, rc;
 
        local_irq_disable();
@@ -125,38 +124,17 @@ void default_idle(void)
                cpu_die();
 #endif
 
-       /* 
-        * Wait for external, I/O or machine check interrupt and
-        * switch off machine check bit after the wait has ended.
-        */
-       wait_psw.mask = PSW_KERNEL_BITS | PSW_MASK_MCHECK | PSW_MASK_WAIT |
-               PSW_MASK_IO | PSW_MASK_EXT;
-#ifndef CONFIG_ARCH_S390X
-       asm volatile (
-               "    basr %0,0\n"
-               "0:  la   %0,1f-0b(%0)\n"
-               "    st   %0,4(%1)\n"
-               "    oi   4(%1),0x80\n"
-               "    lpsw 0(%1)\n"
-               "1:  la   %0,2f-1b(%0)\n"
-               "    st   %0,4(%1)\n"
-               "    oi   4(%1),0x80\n"
-               "    ni   1(%1),0xf9\n"
-               "    lpsw 0(%1)\n"
-               "2:"
-               : "=&a" (reg) : "a" (&wait_psw) : "memory", "cc" );
-#else /* CONFIG_ARCH_S390X */
-       asm volatile (
-               "    larl  %0,0f\n"
-               "    stg   %0,8(%1)\n"
-               "    lpswe 0(%1)\n"
-               "0:  larl  %0,1f\n"
-               "    stg   %0,8(%1)\n"
-               "    ni    1(%1),0xf9\n"
-               "    lpswe 0(%1)\n"
-               "1:"
-               : "=&a" (reg) : "a" (&wait_psw) : "memory", "cc" );
-#endif /* CONFIG_ARCH_S390X */
+       local_mcck_disable();
+       if (test_thread_flag(TIF_MCCK_PENDING)) {
+               local_mcck_enable();
+               local_irq_enable();
+               s390_handle_mcck();
+               return;
+       }
+
+       /* Wait for external, I/O or machine check interrupt. */
+       __load_psw_mask(PSW_KERNEL_BITS | PSW_MASK_WAIT |
+                       PSW_MASK_IO | PSW_MASK_EXT);
 }
 
 void cpu_idle(void)
diff --git a/arch/s390/kernel/relocate_kernel.S b/arch/s390/kernel/relocate_kernel.S
new file mode 100644 (file)
index 0000000..d5e4a62
--- /dev/null
@@ -0,0 +1,81 @@
+/*
+ * arch/s390/kernel/relocate_kernel.S
+ *
+ * (C) Copyright IBM Corp. 2005
+ *
+ * Author(s): Rolf Adelsberger <adelsberger@de.ibm.com>
+ *
+ */
+
+/*
+ * moves the new kernel to its destination...
+ * %r2 = pointer to first kimage_entry_t
+ * %r3 = start address - where to jump to after the job is done...
+ *
+ * %r5 will be used as temp. storage
+ * %r6 holds the destination address
+ * %r7 = PAGE_SIZE
+ * %r8 holds the source address
+ * %r9 = PAGE_SIZE
+ * %r10 is a page mask
+ */
+
+       .text
+       .globl          relocate_kernel
+       relocate_kernel:
+               basr    %r13,0          #base address
+       .base:
+               spx     zero64-.base(%r13)      #absolute addressing mode
+               stnsm   sys_msk-.base(%r13),0xf8        #disable DAT and IRQ (external)
+               lhi     %r10,-1         #preparing the mask
+               sll     %r10,12         #shift it such that it becomes 0xf000
+       .top:
+               lhi     %r7,4096        #load PAGE_SIZE in r7
+               lhi     %r9,4096        #load PAGE_SIZE in r9
+               l       %r5,0(%r2)      #read another word for indirection page
+               ahi     %r2,4           #increment pointer
+               tml     %r5,0x1         #is it a destination page?
+               je      .indir_check    #NO, goto "indir_check"
+               lr      %r6,%r5         #r6 = r5
+               nr      %r6,%r10        #mask it out and...
+               j       .top            #...next iteration
+       .indir_check:
+               tml     %r5,0x2         #is it a indirection page?
+               je      .done_test      #NO, goto "done_test"
+               nr      %r5,%r10        #YES, mask out,
+               lr      %r2,%r5         #move it into the right register,
+               j       .top            #and read next...
+       .done_test:
+               tml     %r5,0x4         #is it the done indicator?
+               je      .source_test    #NO! Well, then it should be the source indicator...
+               j       .done           #ok, lets finish it here...
+       .source_test:
+               tml     %r5,0x8         #it should be a source indicator...
+               je      .top            #NO, ignore it...
+               lr      %r8,%r5         #r8 = r5
+               nr      %r8,%r10        #masking
+       0:      mvcle   %r6,%r8,0x0     #copy PAGE_SIZE bytes from r8 to r6 - pad with 0
+               jo      0b
+               j       .top
+       .done:
+               sr      %r0,%r0         #clear register r0
+               la      %r4,load_psw-.base(%r13)        #load psw-address into the register
+               o       %r3,4(%r4)      #or load address into psw
+               st      %r3,4(%r4)
+               mvc     0(8,%r0),0(%r4) #copy psw to absolute address 0
+               sr      %r1,%r1         #clear %r1
+               sr      %r2,%r2         #clear %r2
+               sigp    %r1,%r2,0x12    #set cpuid to zero
+               lpsw    0               #hopefully start new kernel...
+
+               .align  8
+       zero64:
+               .quad   0
+       load_psw:
+               .long   0x00080000,0x80000000
+       sys_msk:
+               .quad   0
+       relocate_kernel_end:
+       .globl  relocate_kernel_len
+       relocate_kernel_len:
+               .quad   relocate_kernel_end - relocate_kernel
diff --git a/arch/s390/kernel/relocate_kernel64.S b/arch/s390/kernel/relocate_kernel64.S
new file mode 100644 (file)
index 0000000..96290cc
--- /dev/null
@@ -0,0 +1,82 @@
+/*
+ * arch/s390/kernel/relocate_kernel64.S
+ *
+ * (C) Copyright IBM Corp. 2005
+ *
+ * Author(s): Rolf Adelsberger <adelsberger@de.ibm.com>
+ *
+ */
+
+/*
+ * moves the new kernel to its destination...
+ * %r2 = pointer to first kimage_entry_t
+ * %r3 = start address - where to jump to after the job is done...
+ *
+ * %r5 will be used as temp. storage
+ * %r6 holds the destination address
+ * %r7 = PAGE_SIZE
+ * %r8 holds the source address
+ * %r9 = PAGE_SIZE
+ *
+ * 0xf000 is a page_mask
+ */
+
+       .text
+       .globl          relocate_kernel
+       relocate_kernel:
+               basr    %r13,0          #base address
+       .base:
+               spx     zero64-.base(%r13)      #absolute addressing mode
+               stnsm   sys_msk-.base(%r13),0xf8        #disable DAT and IRQ (external)
+       .top:
+               lghi    %r7,4096        #load PAGE_SIZE in r7
+               lghi    %r9,4096        #load PAGE_SIZE in r9
+               lg      %r5,0(%r2)      #read another word for indirection page
+               aghi    %r2,8           #increment pointer
+               tml     %r5,0x1         #is it a destination page?
+               je      .indir_check    #NO, goto "indir_check"
+               lgr     %r6,%r5         #r6 = r5
+               nill    %r6,0xf000      #mask it out and...
+               j       .top            #...next iteration
+       .indir_check:
+               tml     %r5,0x2         #is it a indirection page?
+               je      .done_test      #NO, goto "done_test"
+               nill    %r5,0xf000      #YES, mask out,
+               lgr     %r2,%r5         #move it into the right register,
+               j       .top            #and read next...
+       .done_test:
+               tml     %r5,0x4         #is it the done indicator?
+               je      .source_test    #NO! Well, then it should be the source indicator...
+               j       .done           #ok, lets finish it here...
+       .source_test:
+               tml     %r5,0x8         #it should be a source indicator...
+               je      .top            #NO, ignore it...
+               lgr     %r8,%r5         #r8 = r5
+               nill    %r8,0xf000      #masking
+       0:      mvcle   %r6,%r8,0x0     #copy PAGE_SIZE bytes from r8 to r6 - pad with 0
+               jo      0b
+               j       .top
+       .done:
+               sgr     %r0,%r0         #clear register r0
+               la      %r4,load_psw-.base(%r13)        #load psw-address into the register
+               o       %r3,4(%r4)      #or load address into psw
+               st      %r3,4(%r4)
+               mvc     0(8,%r0),0(%r4) #copy psw to absolute address 0
+               sam31                   #31 bit mode
+               sr      %r1,%r1         #erase register r1
+               sr      %r2,%r2         #erase register r2
+               sigp    %r1,%r2,0x12    #set cpuid to zero
+               lpsw    0               #hopefully start new kernel...
+
+               .align  8
+       zero64:
+               .quad   0
+       load_psw:
+               .long   0x00080000,0x80000000
+       sys_msk:
+               .quad   0
+       relocate_kernel_end:
+       .globl  relocate_kernel_len
+       relocate_kernel_len:
+               .quad   relocate_kernel_end - relocate_kernel
+
index df83215beac34740263366f121b14d1ce6a0738c..b6d740ac0e6eedb8f0d1d7255b4d872463acc702 100644 (file)
@@ -198,11 +198,11 @@ static void __init conmode_default(void)
        char *ptr;
 
         if (MACHINE_IS_VM) {
-               __cpcmd("QUERY CONSOLE", query_buffer, 1024);
+               __cpcmd("QUERY CONSOLE", query_buffer, 1024, NULL);
                console_devno = simple_strtoul(query_buffer + 5, NULL, 16);
                ptr = strstr(query_buffer, "SUBCHANNEL =");
                console_irq = simple_strtoul(ptr + 13, NULL, 16);
-               __cpcmd("QUERY TERM", query_buffer, 1024);
+               __cpcmd("QUERY TERM", query_buffer, 1024, NULL);
                ptr = strstr(query_buffer, "CONMODE");
                /*
                 * Set the conmode to 3215 so that the device recognition 
@@ -211,7 +211,7 @@ static void __init conmode_default(void)
                 * 3215 and the 3270 driver will try to access the console
                 * device (3215 as console and 3270 as normal tty).
                 */
-               __cpcmd("TERM CONMODE 3215", NULL, 0);
+               __cpcmd("TERM CONMODE 3215", NULL, 0, NULL);
                if (ptr == NULL) {
 #if defined(CONFIG_SCLP_CONSOLE)
                        SET_CONSOLE_SCLP;
@@ -414,7 +414,8 @@ setup_lowcore(void)
        lc->program_new_psw.mask = PSW_KERNEL_BITS;
        lc->program_new_psw.addr =
                PSW_ADDR_AMODE | (unsigned long)pgm_check_handler;
-       lc->mcck_new_psw.mask = PSW_KERNEL_BITS;
+       lc->mcck_new_psw.mask =
+               PSW_KERNEL_BITS & ~PSW_MASK_MCHECK & ~PSW_MASK_DAT;
        lc->mcck_new_psw.addr =
                PSW_ADDR_AMODE | (unsigned long) mcck_int_handler;
        lc->io_new_psw.mask = PSW_KERNEL_BITS;
@@ -424,12 +425,18 @@ setup_lowcore(void)
        lc->kernel_stack = ((unsigned long) &init_thread_union) + THREAD_SIZE;
        lc->async_stack = (unsigned long)
                __alloc_bootmem(ASYNC_SIZE, ASYNC_SIZE, 0) + ASYNC_SIZE;
-#ifdef CONFIG_CHECK_STACK
        lc->panic_stack = (unsigned long)
                __alloc_bootmem(PAGE_SIZE, PAGE_SIZE, 0) + PAGE_SIZE;
-#endif
        lc->current_task = (unsigned long) init_thread_union.thread_info.task;
        lc->thread_info = (unsigned long) &init_thread_union;
+#ifndef CONFIG_ARCH_S390X
+       if (MACHINE_HAS_IEEE) {
+               lc->extended_save_area_addr = (__u32)
+                       __alloc_bootmem(PAGE_SIZE, PAGE_SIZE, 0);
+               /* enable extended save area */
+               ctl_set_bit(14, 29);
+       }
+#endif
 #ifdef CONFIG_ARCH_S390X
        if (MACHINE_HAS_DIAG44)
                lc->diag44_opcode = 0x83000044;
index fdfcf0488b49b3b8d94d21afaa7442b828565739..642572a8e334d435e988c935673437b666ceda95 100644 (file)
@@ -284,7 +284,7 @@ static void do_machine_restart(void * __unused)
         * locks are always held disabled).
         */
        if (MACHINE_IS_VM)
-               cpcmd ("IPL", NULL, 0);
+               cpcmd ("IPL", NULL, 0, NULL);
        else
                reipl (0x10000 | S390_lowcore.ipl_device);
 }
@@ -313,7 +313,7 @@ static void do_machine_halt(void * __unused)
        if (atomic_compare_and_swap(-1, smp_processor_id(), &cpuid) == 0) {
                smp_send_stop();
                if (MACHINE_IS_VM && strlen(vmhalt_cmd) > 0)
-                       cpcmd(vmhalt_cmd, NULL, 0);
+                       cpcmd(vmhalt_cmd, NULL, 0, NULL);
                signal_processor(smp_processor_id(),
                                 sigp_stop_and_store_status);
        }
@@ -332,7 +332,7 @@ static void do_machine_power_off(void * __unused)
        if (atomic_compare_and_swap(-1, smp_processor_id(), &cpuid) == 0) {
                smp_send_stop();
                if (MACHINE_IS_VM && strlen(vmpoff_cmd) > 0)
-                       cpcmd(vmpoff_cmd, NULL, 0);
+                       cpcmd(vmpoff_cmd, NULL, 0, NULL);
                signal_processor(smp_processor_id(),
                                 sigp_stop_and_store_status);
        }
@@ -679,12 +679,14 @@ __cpu_disable(void)
 {
        unsigned long flags;
        ec_creg_mask_parms cr_parms;
+       int cpu = smp_processor_id();
 
        spin_lock_irqsave(&smp_reserve_lock, flags);
-       if (smp_cpu_reserved[smp_processor_id()] != 0) {
+       if (smp_cpu_reserved[cpu] != 0) {
                spin_unlock_irqrestore(&smp_reserve_lock, flags);
                return -EBUSY;
        }
+       cpu_clear(cpu, cpu_online_map);
 
 #ifdef CONFIG_PFAULT
        /* Disable pfault pseudo page faults on this cpu. */
@@ -771,13 +773,24 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
 
                *(lowcore_ptr[i]) = S390_lowcore;
                lowcore_ptr[i]->async_stack = stack + (ASYNC_SIZE);
-#ifdef CONFIG_CHECK_STACK
                stack = __get_free_pages(GFP_KERNEL,0);
                if (stack == 0ULL)
                        panic("smp_boot_cpus failed to allocate memory\n");
                lowcore_ptr[i]->panic_stack = stack + (PAGE_SIZE);
+#ifndef __s390x__
+               if (MACHINE_HAS_IEEE) {
+                       lowcore_ptr[i]->extended_save_area_addr =
+                               (__u32) __get_free_pages(GFP_KERNEL,0);
+                       if (lowcore_ptr[i]->extended_save_area_addr == 0)
+                               panic("smp_boot_cpus failed to "
+                                     "allocate memory\n");
+               }
 #endif
        }
+#ifndef __s390x__
+       if (MACHINE_HAS_IEEE)
+               ctl_set_bit(14, 29); /* enable extended save area */
+#endif
        set_prefix((u32)(unsigned long) lowcore_ptr[smp_processor_id()]);
 
        for_each_cpu(cpu)
index 515938628f82c75a7d80367568e933cfc4e0783c..a8668afb5f87d2b5b3324a8dae1802eab7aedcdf 100644 (file)
@@ -285,7 +285,7 @@ SYSCALL(sys_mq_timedsend,sys_mq_timedsend,compat_sys_mq_timedsend_wrapper)
 SYSCALL(sys_mq_timedreceive,sys_mq_timedreceive,compat_sys_mq_timedreceive_wrapper)
 SYSCALL(sys_mq_notify,sys_mq_notify,compat_sys_mq_notify_wrapper) /* 275 */
 SYSCALL(sys_mq_getsetattr,sys_mq_getsetattr,compat_sys_mq_getsetattr_wrapper)
-NI_SYSCALL                                                     /* reserved for kexec */
+SYSCALL(sys_kexec_load,sys_kexec_load,compat_sys_kexec_load_wrapper)
 SYSCALL(sys_add_key,sys_add_key,compat_sys_add_key_wrapper)
 SYSCALL(sys_request_key,sys_request_key,compat_sys_request_key_wrapper)
 SYSCALL(sys_keyctl,sys_keyctl,compat_sys_keyctl)               /* 280 */
index ca34b6f34b38e9efc78fc2a418d8390d9174233f..bc7b7be7acbe7b9858992e75fcc86309d59de79b 100644 (file)
@@ -735,7 +735,7 @@ void __init trap_init(void)
                                                    &ext_int_pfault);
 #endif
 #ifndef CONFIG_ARCH_S390X
-               cpcmd("SET PAGEX ON", NULL, 0);
+               cpcmd("SET PAGEX ON", NULL, 0, NULL);
 #endif
        }
 }
index 648deed17e25f8c2e39e97f01141bc0e09d496a2..c5348108ca3ce23e8da4a6681c32330ebad73122 100644 (file)
@@ -576,8 +576,8 @@ segment_save(char *name)
                        segtype_string[seg->range[i].start & 0xff]);
        }
        sprintf(cmd2, "SAVESEG %s", name);
-       cpcmd(cmd1, NULL, 0);
-       cpcmd(cmd2, NULL, 0);
+       cpcmd(cmd1, NULL, 0, NULL);
+       cpcmd(cmd2, NULL, 0, NULL);
        spin_unlock(&dcss_lock);
 }
 
index cf15b4a8b517556c1f498822b24c0a8af79d57a7..c1b03f7c1daa962195a6e8ee26d09580abfab615 100644 (file)
@@ -157,9 +157,9 @@ static void daemon_remove(void *data)
 
        os_close_file(pri->fd);
        os_close_file(pri->control);
-       if(pri->data_addr != NULL) kfree(pri->data_addr);
-       if(pri->ctl_addr != NULL) kfree(pri->ctl_addr);
-       if(pri->local_addr != NULL) kfree(pri->local_addr);
+       kfree(pri->data_addr);
+       kfree(pri->ctl_addr);
+       kfree(pri->local_addr);
 }
 
 int daemon_user_write(int fd, void *buf, int len, struct daemon_data *pri)
index 0f59736db329587d079b910279a035d409f4e884..2bb4c4f5dec4f08cd420caaf19d0bf75dcd77bef 100644 (file)
@@ -602,11 +602,26 @@ int line_get_config(char *name, struct line *lines, unsigned int num, char *str,
        return n;
 }
 
-int line_remove(struct line *lines, unsigned int num, char *str)
+int line_id(char **str, int *start_out, int *end_out)
+{
+       char *end;
+        int n;
+
+       n = simple_strtoul(*str, &end, 0);
+       if((*end != '\0') || (end == *str))
+                return -1;
+
+        *str = end;
+        *start_out = n;
+        *end_out = n;
+        return n;
+}
+
+int line_remove(struct line *lines, unsigned int num, int n)
 {
        char config[sizeof("conxxxx=none\0")];
 
-       sprintf(config, "%s=none", str);
+       sprintf(config, "%d=none", n);
        return !line_setup(lines, num, config, 0);
 }
 
index d7c7adcc0a6731a2acec59eceffdb18a949ffcad..404de41a4f677cf664b740ff38a3a2e327e42a4e 100644 (file)
@@ -419,8 +419,9 @@ void mconsole_config(struct mc_request *req)
 void mconsole_remove(struct mc_request *req)
 {
        struct mc_device *dev;  
-       char *ptr = req->request.data;
-       int err;
+       char *ptr = req->request.data, *err_msg = "";
+        char error[256];
+       int err, start, end, n;
 
        ptr += strlen("remove");
        while(isspace(*ptr)) ptr++;
@@ -429,8 +430,35 @@ void mconsole_remove(struct mc_request *req)
                mconsole_reply(req, "Bad remove option", 1, 0);
                return;
        }
-       err = (*dev->remove)(&ptr[strlen(dev->name)]);
-       mconsole_reply(req, "", err, 0);
+
+        ptr = &ptr[strlen(dev->name)];
+
+        err = 1;
+        n = (*dev->id)(&ptr, &start, &end);
+        if(n < 0){
+                err_msg = "Couldn't parse device number";
+                goto out;
+        }
+        else if((n < start) || (n > end)){
+                sprintf(error, "Invalid device number - must be between "
+                        "%d and %d", start, end);
+                err_msg = error;
+                goto out;
+        }
+
+       err = (*dev->remove)(n);
+        switch(err){
+        case -ENODEV:
+                err_msg = "Device doesn't exist";
+                break;
+        case -EBUSY:
+                err_msg = "Device is currently open";
+                break;
+        default:
+                break;
+        }
+ out:
+       mconsole_reply(req, err_msg, err, 0);
 }
 
 #ifdef CONFIG_MAGIC_SYSRQ
index 5388a7428691a2c4c12791b0e5370cd0b31685ba..1495007bf6c07df5061526d554382287d95e27e2 100644 (file)
@@ -612,25 +612,35 @@ static int net_config(char *str)
        return(err);
 }
 
-static int net_remove(char *str)
+static int net_id(char **str, int *start_out, int *end_out)
+{
+        char *end;
+        int n;
+
+       n = simple_strtoul(*str, &end, 0);
+       if((*end != '\0') || (end == *str))
+               return -1;
+
+        *start_out = n;
+        *end_out = n;
+        *str = end;
+        return n;
+}
+
+static int net_remove(int n)
 {
        struct uml_net *device;
        struct net_device *dev;
        struct uml_net_private *lp;
-       char *end;
-       int n;
-
-       n = simple_strtoul(str, &end, 0);
-       if((*end != '\0') || (end == str))
-               return(-1);
 
        device = find_device(n);
        if(device == NULL)
-               return(0);
+               return -ENODEV;
 
        dev = device->dev;
        lp = dev->priv;
-       if(lp->fd > 0) return(-1);
+       if(lp->fd > 0)
+                return -EBUSY;
        if(lp->remove != NULL) (*lp->remove)(&lp->user);
        unregister_netdev(dev);
        platform_device_unregister(&device->pdev);
@@ -638,13 +648,14 @@ static int net_remove(char *str)
        list_del(&device->list);
        kfree(device);
        free_netdev(dev);
-       return(0);
+       return 0;
 }
 
 static struct mc_device net_mc = {
        .name           = "eth",
        .config         = net_config,
        .get_config     = NULL,
+        .id            = net_id,
        .remove         = net_remove,
 };
 
index b32a77010fbe5743aace38839dcf21f477c7da25..62e04ecfada85746c044a381724902d9440a4757 100644 (file)
@@ -49,7 +49,7 @@ static struct chan_opts opts = {
 
 static int ssl_config(char *str);
 static int ssl_get_config(char *dev, char *str, int size, char **error_out);
-static int ssl_remove(char *str);
+static int ssl_remove(int n);
 
 static struct line_driver driver = {
        .name                   = "UML serial line",
@@ -69,6 +69,7 @@ static struct line_driver driver = {
                .name           = "ssl",
                .config         = ssl_config,
                .get_config     = ssl_get_config,
+                .id            = line_id,
                .remove         = ssl_remove,
        },
 };
@@ -94,10 +95,10 @@ static int ssl_get_config(char *dev, char *str, int size, char **error_out)
                               str, size, error_out));
 }
 
-static int ssl_remove(char *str)
+static int ssl_remove(int n)
 {
-       return(line_remove(serial_lines, 
-                          sizeof(serial_lines)/sizeof(serial_lines[0]), str));
+        return line_remove(serial_lines,
+                           sizeof(serial_lines)/sizeof(serial_lines[0]), n);
 }
 
 int ssl_open(struct tty_struct *tty, struct file *filp)
index afbe1e71ed8310f36b2be4f8f633b61ca84af0a2..005aa6333b6e5ff59d957e201b8a6df15175888b 100644 (file)
@@ -55,7 +55,7 @@ static struct chan_opts opts = {
 
 static int con_config(char *str);
 static int con_get_config(char *dev, char *str, int size, char **error_out);
-static int con_remove(char *str);
+static int con_remove(int n);
 
 static struct line_driver driver = {
        .name                   = "UML console",
@@ -75,6 +75,7 @@ static struct line_driver driver = {
                .name           = "con",
                .config         = con_config,
                .get_config     = con_get_config,
+                .id            = line_id,
                .remove         = con_remove,
        },
 };
@@ -99,9 +100,9 @@ static int con_get_config(char *dev, char *str, int size, char **error_out)
                               size, error_out));
 }
 
-static int con_remove(char *str)
+static int con_remove(int n)
 {
-       return(line_remove(vts, sizeof(vts)/sizeof(vts[0]), str));
+        return line_remove(vts, sizeof(vts)/sizeof(vts[0]), n);
 }
 
 static int con_open(struct tty_struct *tty, struct file *filp)
index 2a7f6892c55c203d66c03640acdccb8a3655b8e3..344b24d09a7c07a773f81ab99ab6b4688675b6d9 100644 (file)
@@ -754,24 +754,34 @@ static int ubd_get_config(char *name, char *str, int size, char **error_out)
        return(len);
 }
 
-static int ubd_remove(char *str)
+static int ubd_id(char **str, int *start_out, int *end_out)
+{
+        int n;
+
+       n = parse_unit(str);
+        *start_out = 0;
+        *end_out = MAX_DEV - 1;
+        return n;
+}
+
+static int ubd_remove(int n)
 {
        struct ubd *dev;
-       int n, err = -ENODEV;
+       int err = -ENODEV;
 
-       n = parse_unit(&str);
+       spin_lock(&ubd_lock);
 
-       if((n < 0) || (n >= MAX_DEV))
-               return(err);
+       if(ubd_gendisk[n] == NULL)
+               goto out;
 
        dev = &ubd_dev[n];
-       if(dev->count > 0)
-               return(-EBUSY); /* you cannot remove a open disk */
 
-       err = 0;
-       spin_lock(&ubd_lock);
+       if(dev->file == NULL)
+               goto out;
 
-       if(ubd_gendisk[n] == NULL)
+       /* you cannot remove a open disk */
+       err = -EBUSY;
+       if(dev->count > 0)
                goto out;
 
        del_gendisk(ubd_gendisk[n]);
@@ -787,15 +797,16 @@ static int ubd_remove(char *str)
        platform_device_unregister(&dev->pdev);
        *dev = ((struct ubd) DEFAULT_UBD);
        err = 0;
- out:
-       spin_unlock(&ubd_lock);
-       return(err);
+out:
+       spin_unlock(&ubd_lock);
+       return err;
 }
 
 static struct mc_device ubd_mc = {
        .name           = "ubd",
        .config         = ubd_config,
        .get_config     = ubd_get_config,
+       .id             = ubd_id,
        .remove         = ubd_remove,
 };
 
index 4c5e92c04ccba6c6471befbc835293155322d308..5323d22a6ca701c97e6fcfc163ce8102890c0901 100644 (file)
@@ -101,7 +101,8 @@ extern void lines_init(struct line *lines, int nlines);
 extern void close_lines(struct line *lines, int nlines);
 
 extern int line_config(struct line *lines, unsigned int sizeof_lines, char *str);
-extern int line_remove(struct line *lines, unsigned int sizeof_lines, char *str);
+extern int line_id(char **str, int *start_out, int *end_out);
+extern int line_remove(struct line *lines, unsigned int sizeof_lines, int n);
 extern int line_get_config(char *dev, struct line *lines, unsigned int sizeof_lines, char *str,
                           int size, char **error_out);
 
index 61c274fcee5d539e6062023d013bd1b7aa51ae8a..d86ee14260ce463e44a965725d995c2ad8a9e069 100644 (file)
@@ -20,7 +20,8 @@ struct mc_device {
        char *name;
        int (*config)(char *);
        int (*get_config)(char *, char *, int, char **);
-       int (*remove)(char *);
+        int (*id)(char **, int *, int *);
+       int (*remove)(int);
 };
 
 #define CONFIG_CHUNK(str, size, current, chunk, end) \
index 6793a2fcd0aeed91c48d3182515bd09c2d1e45d6..f64ef77019a33af160e919baee0632a7e0957c4d 100644 (file)
@@ -8,11 +8,11 @@
 
 extern void timer(void);
 extern void switch_timers(int to_real);
-extern void set_interval(int timer_type);
 extern void idle_sleep(int secs);
 extern void enable_timer(void);
 extern void disable_timer(void);
 extern unsigned long time_lock(void);
 extern void time_unlock(unsigned long);
+extern void user_time_init(void);
 
 #endif
index e59f581526782adca0763540a98bc80505a7a79a..1e1a87f1c510cbc7a2d3a4ea472bd6395f6e4bb2 100644 (file)
@@ -69,7 +69,6 @@ static __init void do_uml_initcalls(void)
 
 static void last_ditch_exit(int sig)
 {
-        kmalloc_ok = 0;
        signal(SIGINT, SIG_DFL);
        signal(SIGTERM, SIG_DFL);
        signal(SIGHUP, SIG_DFL);
index 157584ae4792b46176031ac54e1437f7d43c317a..d4036ed680bcd408e82f1afd6871d77915792939 100644 (file)
@@ -96,8 +96,8 @@ int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
 
        current->thread.request.u.thread.proc = fn;
        current->thread.request.u.thread.arg = arg;
-       pid = do_fork(CLONE_VM | CLONE_UNTRACED | flags, 0, NULL, 0, NULL,
-                     NULL);
+       pid = do_fork(CLONE_VM | CLONE_UNTRACED | flags, 0,
+                     &current->thread.regs, 0, NULL, NULL);
        if(pid < 0)
                panic("do_fork failed in kernel_thread, errno = %d", pid);
        return(pid);
@@ -169,7 +169,7 @@ int current_pid(void)
 
 void default_idle(void)
 {
-       uml_idle_timer();
+       CHOOSE_MODE(uml_idle_timer(), (void) 0);
 
        atomic_inc(&init_mm.mm_count);
        current->mm = &init_mm;
index 207f89d749080a596954a6ac7adbf2fd68fd88cb..fcec51da1d3771abe84944ca1138853417df6bec 100644 (file)
@@ -38,14 +38,14 @@ static void kill_off_processes(void)
 
 void uml_cleanup(void)
 {
-       kill_off_processes();
+        kmalloc_ok = 0;
        do_uml_exitcalls();
+       kill_off_processes();
 }
 
 void machine_restart(char * __unused)
 {
-       do_uml_exitcalls();
-       kill_off_processes();
+        uml_cleanup();
        CHOOSE_MODE(reboot_tt(), reboot_skas());
 }
 
@@ -53,8 +53,7 @@ EXPORT_SYMBOL(machine_restart);
 
 void machine_power_off(void)
 {
-       do_uml_exitcalls();
-       kill_off_processes();
+        uml_cleanup();
        CHOOSE_MODE(halt_tt(), halt_skas());
 }
 
index d37d1bfcd6f73916266be72a6fd733d3443d0239..ff69c4b312c0c01bf471df0ebc2ee406bb2f7e13 100644 (file)
@@ -4,10 +4,10 @@
 #
 
 obj-y := exec_kern.o mem.o mem_user.o mmu.o process.o process_kern.o \
-       syscall_kern.o syscall_user.o time.o tlb.o trap_user.o uaccess.o \
+       syscall_kern.o syscall_user.o tlb.o trap_user.o uaccess.o \
 
 subdir- := util
 
-USER_OBJS := process.o time.o
+USER_OBJS := process.o
 
 include arch/um/scripts/Makefile.rules
index c1e33bd788dbff1524dc77b0e891b5e3b7322ff6..bcd26a6a3888cce3a09df6f4fb9f8177d4d71219 100644 (file)
@@ -13,7 +13,6 @@ extern unsigned long exec_fp_regs[];
 extern unsigned long exec_fpx_regs[];
 extern int have_fpx_regs;
 
-extern void user_time_init_skas(void);
 extern void sig_handler_common_skas(int sig, void *sc_ptr);
 extern void halt_skas(void);
 extern void reboot_skas(void);
index fc71ef295782296d10d118f3cc95b336e6b01fcb..0a7b8aa55db8342b905a6f8b6f395e2a4a9ad9dd 100644 (file)
@@ -111,8 +111,7 @@ int copy_thread_skas(int nr, unsigned long clone_flags, unsigned long sp,
        void (*handler)(int);
 
        if(current->thread.forking){
-               memcpy(&p->thread.regs.regs.skas, 
-                      &current->thread.regs.regs.skas, 
+               memcpy(&p->thread.regs.regs.skas, &regs->regs.skas,
                       sizeof(p->thread.regs.regs.skas));
                REGS_SET_SYSCALL_RETURN(p->thread.regs.regs.skas.regs, 0);
                if(sp != 0) REGS_SP(p->thread.regs.regs.skas.regs) = sp;
@@ -181,7 +180,6 @@ int start_uml_skas(void)
        start_userspace(0);
 
        init_new_thread_signals(1);
-       uml_idle_timer();
 
        init_task.thread.request.u.thread.proc = start_kernel_proc;
        init_task.thread.request.u.thread.arg = NULL;
@@ -201,14 +199,3 @@ int thread_pid_skas(struct task_struct *task)
 #warning Need to look up userspace_pid by cpu
        return(userspace_pid[0]);
 }
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/kernel/skas/time.c b/arch/um/kernel/skas/time.c
deleted file mode 100644 (file)
index 9809149..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-/* 
- * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
- * Licensed under the GPL
- */
-
-#include <sys/signal.h>
-#include <sys/time.h>
-#include "time_user.h"
-#include "process.h"
-#include "user.h"
-
-void user_time_init_skas(void)
-{
-        if(signal(SIGALRM, (__sighandler_t) alarm_handler) == SIG_ERR)
-                panic("Couldn't set SIGALRM handler");
-       if(signal(SIGVTALRM, (__sighandler_t) alarm_handler) == SIG_ERR)
-               panic("Couldn't set SIGVTALRM handler");
-       set_interval(ITIMER_VIRTUAL);
-}
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
index b7a55251e89727d44cf7ba841b309091034edcdb..8e1a3501ff46362814c0bb83b974951cbafbe9e2 100644 (file)
@@ -31,7 +31,8 @@ long sys_fork(void)
        long ret;
 
        current->thread.forking = 1;
-        ret = do_fork(SIGCHLD, 0, NULL, 0, NULL, NULL);
+       ret = do_fork(SIGCHLD, UPT_SP(&current->thread.regs.regs),
+                     &current->thread.regs, 0, NULL, NULL);
        current->thread.forking = 0;
        return(ret);
 }
@@ -41,8 +42,9 @@ long sys_vfork(void)
        long ret;
 
        current->thread.forking = 1;
-       ret = do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, 0, NULL, 0, NULL,
-                     NULL);
+       ret = do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD,
+                     UPT_SP(&current->thread.regs.regs),
+                     &current->thread.regs, 0, NULL, NULL);
        current->thread.forking = 0;
        return(ret);
 }
@@ -162,14 +164,3 @@ int next_syscall_index(int limit)
        spin_unlock(&syscall_lock);
        return(ret);
 }
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
index c40c86a3f918b491b04e1d1f05e235fedf22c599..f829b309b63c7d7c27dd36ba87363130695ca887 100644 (file)
@@ -33,7 +33,7 @@ void timer(void)
        timeradd(&xtime, &local_offset, &xtime);
 }
 
-void set_interval(int timer_type)
+static void set_interval(int timer_type)
 {
        int usec = 1000000/hz();
        struct itimerval interval = ((struct itimerval) { { 0, usec },
@@ -45,12 +45,7 @@ void set_interval(int timer_type)
 
 void enable_timer(void)
 {
-       int usec = 1000000/hz();
-       struct itimerval enable = ((struct itimerval) { { 0, usec },
-                                                       { 0, usec }});
-       if(setitimer(ITIMER_VIRTUAL, &enable, NULL))
-               printk("enable_timer - setitimer failed, errno = %d\n",
-                      errno);
+       set_interval(ITIMER_VIRTUAL);
 }
 
 void disable_timer(void)
@@ -155,13 +150,15 @@ void idle_sleep(int secs)
        nanosleep(&ts, NULL);
 }
 
-/*
- * 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:
- */
+/* XXX This partly duplicates init_irq_signals */
+
+void user_time_init(void)
+{
+       set_handler(SIGVTALRM, (__sighandler_t) alarm_handler,
+                   SA_ONSTACK | SA_RESTART, SIGUSR1, SIGIO, SIGWINCH,
+                   SIGALRM, SIGUSR2, -1);
+       set_handler(SIGALRM, (__sighandler_t) alarm_handler,
+                   SA_ONSTACK | SA_RESTART, SIGUSR1, SIGIO, SIGWINCH,
+                   SIGVTALRM, SIGUSR2, -1);
+       set_interval(ITIMER_VIRTUAL);
+}
index 6516fc52afe01f23ecfbe0365cb251e9d3c8635d..a8b4ef601f5964d236360e8ae5bb1d4f49dbc56d 100644 (file)
@@ -162,7 +162,7 @@ int __init timer_init(void)
 {
        int err;
 
-       CHOOSE_MODE(user_time_init_tt(), user_time_init_skas());
+       user_time_init();
        err = request_irq(TIMER_IRQ, um_timer, SA_INTERRUPT, "timer", NULL);
        if(err != 0)
                printk(KERN_ERR "timer_init : request_irq failed - "
index 3fd2554e60b6e58ff35b7af3b4141421f69ef1f1..6939e5af8472ceecf90fa878c72a4b0e927ec76e 100644 (file)
@@ -4,11 +4,11 @@
 #
 
 obj-y = exec_kern.o exec_user.o gdb.o ksyms.o mem.o mem_user.o process_kern.o \
-       syscall_kern.o syscall_user.o time.o tlb.o tracer.o trap_user.o \
+       syscall_kern.o syscall_user.o tlb.o tracer.o trap_user.o \
        uaccess.o uaccess_user.o
 
 obj-$(CONFIG_PT_PROXY) += gdb_kern.o ptproxy/
 
-USER_OBJS := gdb.o time.o tracer.o
+USER_OBJS := gdb.o tracer.o
 
 include arch/um/scripts/Makefile.rules
index 19a0ad7b35b3c0d7a819e540c288f546ac5efbec..37e22d71a0d9d5c546326e5a19276ec54524ac14 100644 (file)
@@ -153,10 +153,10 @@ void remove_gdb_cb(void *unused)
        exit_debugger_cb(NULL);
 }
 
-int gdb_remove(char *unused)
+int gdb_remove(int unused)
 {
        initial_thread_cb(remove_gdb_cb, NULL);
-       return(0);
+        return 0;
 }
 
 void signal_usr1(int sig)
index 93fb121f86af5c34213d44c430b398f027c227b1..26506388a6aa66cbc64552153ccd822f33c81cf3 100644 (file)
@@ -10,7 +10,7 @@
 #ifdef CONFIG_MCONSOLE
 
 extern int gdb_config(char *str);
-extern int gdb_remove(char *unused);
+extern int gdb_remove(int n);
 
 static struct mc_device gdb_mc = {
        .name           = "gdb",
index 8eff674107cac331259fcc8387cebfb77ce941bb..738435461e137ddf51ec54ca395677b5965ef037 100644 (file)
@@ -4,8 +4,8 @@
  * Licensed under the GPL
  */
 
-#ifndef __DEBUG_H
-#define __DEBUG_H
+#ifndef __UML_TT_DEBUG_H
+#define __UML_TT_DEBUG_H
 
 extern int debugger_proxy(int status, pid_t pid);
 extern void child_proxy(pid_t pid, int status);
@@ -13,17 +13,6 @@ extern void init_proxy (pid_t pid, int waiting, int status);
 extern int start_debugger(char *prog, int startup, int stop, int *debugger_fd);
 extern void fake_child_exit(void);
 extern int gdb_config(char *str);
-extern int gdb_remove(char *unused);
+extern int gdb_remove(int unused);
 
 #endif
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
index efe4620190699cda8c9274d4838e98890b249dd0..e171e15fead527e0f37a8d52ab9cdff939e58dc7 100644 (file)
@@ -13,7 +13,6 @@ enum { OP_NONE, OP_EXEC, OP_FORK, OP_TRACE_ON, OP_REBOOT, OP_HALT, OP_CB };
 extern int tracing_pid;
 
 extern int tracer(int (*init_proc)(void *), void *sp);
-extern void user_time_init_tt(void);
 extern void sig_handler_common_tt(int sig, void *sc);
 extern void syscall_handler_tt(int sig, union uml_pt_regs *regs);
 extern void reboot_tt(void);
index 776310fd5b8b7e34d4b651b5fd2216a27b0a8935..a189a2b92935973123f8a855ca75832e4651e78c 100644 (file)
@@ -266,10 +266,10 @@ int copy_thread_tt(int nr, unsigned long clone_flags, unsigned long sp,
        }
 
        if(current->thread.forking){
-               sc_to_sc(UPT_SC(&p->thread.regs.regs), 
-                        UPT_SC(&current->thread.regs.regs));
+               sc_to_sc(UPT_SC(&p->thread.regs.regs), UPT_SC(&regs->regs));
                SC_SET_SYSCALL_RETURN(UPT_SC(&p->thread.regs.regs), 0);
-               if(sp != 0) SC_SP(UPT_SC(&p->thread.regs.regs)) = sp;
+               if(sp != 0)
+                       SC_SP(UPT_SC(&p->thread.regs.regs)) = sp;
        }
        p->thread.mode.tt.extern_pid = new_pid;
 
@@ -459,14 +459,3 @@ int is_valid_pid(int pid)
        read_unlock(&tasklist_lock);
        return(0);
 }
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/kernel/tt/time.c b/arch/um/kernel/tt/time.c
deleted file mode 100644 (file)
index 8565b71..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-/* 
- * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
- * Licensed under the GPL
- */
-
-#include <signal.h>
-#include <sys/time.h>
-#include <time_user.h>
-#include "process.h"
-#include "user.h"
-
-void user_time_init_tt(void)
-{
-       if(signal(SIGVTALRM, (__sighandler_t) alarm_handler) == SIG_ERR)
-               panic("Couldn't set SIGVTALRM handler");
-       set_interval(ITIMER_VIRTUAL);
-}
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
index 03913ca5d256ac2f7c699e57dde29523dd51b52b..4efc69a039d70022592cec5430a46a1c9a08c826 100644 (file)
@@ -312,7 +312,7 @@ long sys_sigreturn(struct pt_regs regs)
        unsigned long __user *extramask = frame->extramask;
        int sig_size = (_NSIG_WORDS - 1) * sizeof(unsigned long);
 
-       if(copy_from_user(&set.sig[0], oldmask, sizeof(&set.sig[0])) ||
+       if(copy_from_user(&set.sig[0], oldmask, sizeof(set.sig[0])) ||
           copy_from_user(&set.sig[1], extramask, sig_size))
                goto segfault;
 
index 335e2d89504d8992f6f12f784bf325cec48ab081..83e9be820a86991b50ccf25de396c5f0cd626088 100644 (file)
@@ -69,15 +69,11 @@ long sys_clone(unsigned long clone_flags, unsigned long newsp,
 {
        long ret;
 
-       /* XXX: normal arch do here this pass, and also pass the regs to
-        * do_fork, instead of NULL. Currently the arch-independent code
-        * ignores these values, while the UML code (actually it's
-        * copy_thread) does the right thing. But this should change,
-        probably. */
-       /*if (!newsp)
-               newsp = UPT_SP(current->thread.regs);*/
+       if (!newsp)
+               newsp = UPT_SP(&current->thread.regs.regs);
        current->thread.forking = 1;
-       ret = do_fork(clone_flags, newsp, NULL, 0, parent_tid, child_tid);
+       ret = do_fork(clone_flags, newsp, &current->thread.regs, 0, parent_tid,
+                     child_tid);
        current->thread.forking = 0;
        return(ret);
 }
@@ -197,14 +193,3 @@ long sys_sigaction(int sig, const struct old_sigaction __user *act,
 
        return ret;
 }
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
index 6f44f40204ed0947ffe93f6358a0a517649b6fd8..3259a4db453462e0d50b438ae295ff8cf9568326 100644 (file)
@@ -174,26 +174,11 @@ long sys_clone(unsigned long clone_flags, unsigned long newsp,
 {
        long ret;
 
-       /* XXX: normal arch do here this pass, and also pass the regs to
-        * do_fork, instead of NULL. Currently the arch-independent code
-        * ignores these values, while the UML code (actually it's
-        * copy_thread) does the right thing. But this should change,
-        probably. */
-       /*if (!newsp)
-               newsp = UPT_SP(current->thread.regs);*/
+       if (!newsp)
+               newsp = UPT_SP(&current->thread.regs.regs);
        current->thread.forking = 1;
-       ret = do_fork(clone_flags, newsp, NULL, 0, parent_tid, child_tid);
+       ret = do_fork(clone_flags, newsp, &current->thread.regs, 0, parent_tid,
+                     child_tid);
        current->thread.forking = 0;
        return(ret);
 }
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
index db259757dc8a4f97af912c8d56f5e0ae8d4ab81a..d09437b5c48f06f2b7d22fc801db069402183738 100644 (file)
@@ -207,33 +207,6 @@ config SMP
 
          If you don't know what to do here, say N.
 
-config PREEMPT
-       bool "Preemptible Kernel"
-       ---help---
-         This option reduces the latency of the kernel when reacting to
-         real-time or interactive events by allowing a low priority process to
-         be preempted even if it is in kernel mode executing a system call.
-         This allows applications to run more reliably even when the system is
-         under load. On contrary it may also break your drivers and add
-         priority inheritance problems to your system. Don't select it if
-         you rely on a stable system or have slightly obscure hardware.
-         It's also not very well tested on x86-64 currently.
-         You have been warned.
-
-         Say Y here if you are feeling brave and building a kernel for a
-         desktop, embedded or real-time system.  Say N if you are unsure.
-
-config PREEMPT_BKL
-       bool "Preempt The Big Kernel Lock"
-       depends on PREEMPT
-       default y
-       help
-         This option reduces the latency of the kernel by making the
-         big kernel lock preemptible.
-
-         Say Y here if you are building a kernel for a desktop system.
-         Say N if you are unsure.
-
 config SCHED_SMT
        bool "SMT (Hyperthreading) scheduler support"
        depends on SMP
@@ -244,6 +217,8 @@ config SCHED_SMT
          cost of slightly increased overhead in some places. If unsure say
          N here.
 
+source "kernel/Kconfig.preempt"
+
 config K8_NUMA
        bool "K8 NUMA support"
        select NUMA
@@ -313,6 +288,15 @@ config NR_CPUS
          This is purely to save memory - each supported CPU requires
          memory in the static kernel configuration.
 
+config HOTPLUG_CPU
+       bool "Support for hot-pluggable CPUs (EXPERIMENTAL)"
+       depends on SMP && HOTPLUG && EXPERIMENTAL
+       help
+               Say Y here to experiment with turning CPUs off and on.  CPUs
+               can be controlled through /sys/devices/system/cpu/cpu#.
+               Say N if you want to disable CPU hotplug.
+
+
 config HPET_TIMER
        bool
        default y
@@ -385,6 +369,34 @@ config X86_MCE_INTEL
           Additional support for intel specific MCE features such as
           the thermal monitor.
 
+config PHYSICAL_START
+       hex "Physical address where the kernel is loaded" if EMBEDDED
+       default "0x100000"
+       help
+         This gives the physical address where the kernel is loaded.
+         Primarily used in the case of kexec on panic where the
+         fail safe kernel needs to run at a different address than
+         the panic-ed kernel.
+
+         Don't change this unless you know what you are doing.
+
+config KEXEC
+       bool "kexec system call (EXPERIMENTAL)"
+       depends on EXPERIMENTAL
+       help
+         kexec is a system call that implements the ability to shutdown your
+         current kernel, and to start another kernel.  It is like a reboot
+         but it is indepedent of the system firmware.   And like a reboot
+         you can start any kernel with it, not just Linux.
+
+         The name comes from the similiarity to the exec system call.
+
+         It is an ongoing process to be certain the hardware in a machine
+         is properly shutdown, so do not be surprised if this code does not
+         initially work for you.  It may help to enable device hotplugging
+         support.  As of this writing the exact hardware interface is
+         strongly in flux, so no good recommendation can be made.
+
 config SECCOMP
        bool "Enable seccomp to safely compute untrusted bytecode"
        depends on PROC_FS
index 6f90c246c4189989d6fcaadc7cff0e9ed18cd905..8a73794f9b9022dba5b6085fab84a81556dc8d0c 100644 (file)
@@ -35,7 +35,7 @@ export IA32_CC IA32_LD IA32_AS IA32_OBJCOPY IA32_CPP
 
 LDFLAGS                := -m elf_x86_64
 OBJCOPYFLAGS   := -O binary -R .note -R .comment -S
-LDFLAGS_vmlinux := -e stext
+LDFLAGS_vmlinux :=
 
 CHECKFLAGS      += -D__x86_64__ -m64
 
index 27264dbd575c222f0fd02c8758d7edf459e34adb..6f55565e4d4213cbfd295000bc88b70f742f8425 100644 (file)
@@ -2,8 +2,6 @@
  *  linux/boot/head.S
  *
  *  Copyright (C) 1991, 1992, 1993  Linus Torvalds
- *
- *  $Id: head.S,v 1.3 2001/04/20 00:59:28 ak Exp $                     
  */
 
 /*
  */
 
 /*
- * High loaded stuff by Hans Lermen & Werner Almesberger, Feb. 1996    
+ * High loaded stuff by Hans Lermen & Werner Almesberger, Feb. 1996
  */
 .code32
 .text
 
 #include <linux/linkage.h>
 #include <asm/segment.h>
+#include <asm/page.h>
 
        .code32
        .globl startup_32
@@ -77,7 +76,7 @@ startup_32:
        jnz  3f
        addl $8,%esp
        xorl %ebx,%ebx
-       ljmp $(__KERNEL_CS), $0x100000
+       ljmp $(__KERNEL_CS), $__PHYSICAL_START
 
 /*
  * We come here, if we were loaded high.
@@ -103,7 +102,7 @@ startup_32:
        popl %ecx       # lcount
        popl %edx       # high_buffer_start
        popl %eax       # hcount
-       movl $0x100000,%edi
+       movl $__PHYSICAL_START,%edi
        cli             # make sure we don't get interrupted
        ljmp $(__KERNEL_CS), $0x1000 # and jump to the move routine
 
@@ -128,7 +127,7 @@ move_routine_start:
        movsl
        movl %ebx,%esi  # Restore setup pointer
        xorl %ebx,%ebx
-       ljmp $(__KERNEL_CS), $0x100000
+       ljmp $(__KERNEL_CS), $__PHYSICAL_START
 move_routine_end:
 
 
index c8b9216f9e634c365dc49eaf25ef96f234544249..b38d5b8b5fb844ebf92ed2221faa1bcf2d274e6a 100644 (file)
@@ -11,6 +11,7 @@
 
 #include "miscsetup.h"
 #include <asm/io.h>
+#include <asm/page.h>
 
 /*
  * gzip declarations
@@ -92,8 +93,11 @@ static unsigned long output_ptr = 0;
 static void *malloc(int size);
 static void free(void *where);
  
+void* memset(void* s, int c, unsigned n);
+void* memcpy(void* dest, const void* src, unsigned n);
+
 static void putstr(const char *);
-  
+
 extern int end;
 static long free_mem_ptr = (long)&end;
 static long free_mem_end_ptr;
@@ -284,7 +288,7 @@ void setup_normal_output_buffer(void)
 #else
        if ((ALT_MEM_K > EXT_MEM_K ? ALT_MEM_K : EXT_MEM_K) < 1024) error("Less than 2MB of memory");
 #endif
-       output_data = (char *)0x100000; /* Points to 1M */
+       output_data = (char *)__PHYSICAL_START; /* Normally Points to 1M */
        free_mem_end_ptr = (long)real_mode;
 }
 
@@ -307,8 +311,8 @@ void setup_output_buffer_if_we_run_high(struct moveparams *mv)
        low_buffer_size = low_buffer_end - LOW_BUFFER_START;
        high_loaded = 1;
        free_mem_end_ptr = (long)high_buffer_start;
-       if ( (0x100000 + low_buffer_size) > ((ulg)high_buffer_start)) {
-               high_buffer_start = (uch *)(0x100000 + low_buffer_size);
+       if ( (__PHYSICAL_START + low_buffer_size) > ((ulg)high_buffer_start)) {
+               high_buffer_start = (uch *)(__PHYSICAL_START + low_buffer_size);
                mv->hcount = 0; /* say: we need not to move high_buffer */
        }
        else mv->hcount = -1;
index f17b40dfc0f4bde512541ded9c67a88570eb3460..198af15a77586c1abb2cd9c0159cb3e0e0da1643 100644 (file)
@@ -1,6 +1,6 @@
 #!/bin/sh
 #
-# arch/i386/boot/install.sh
+# arch/x86_64/boot/install.sh
 #
 # This file is subject to the terms and conditions of the GNU General Public
 # License.  See the file "COPYING" in the main directory of this archive
index 75d4d2ad93b363a83f3a66346644a8ea716ea64f..ff58b2832b75d5b54df35e57a60fc9dd398c16cd 100644 (file)
@@ -33,7 +33,7 @@
  * Transcribed from Intel (as86) -> AT&T (gas) by Chris Noe, May 1999.
  * <stiker@northlink.com>
  *
- * Fix to work around buggy BIOSes which dont use carry bit correctly
+ * Fix to work around buggy BIOSes which don't use carry bit correctly
  * and/or report extended memory in CX/DX for e801h memory size detection 
  * call.  As a result the kernel got wrong figures.  The int15/e801h docs
  * from Ralf Brown interrupt list seem to indicate AX/BX should be used
@@ -383,7 +383,7 @@ sse_ok:
 # a whole bunch of different types, and allows memory holes and
 # everything.  We scan through this memory map and build a list
 # of the first 32 memory areas, which we return at [E820MAP].
-# This is documented at http://www.teleport.com/~acpi/acpihtml/topic245.htm
+# This is documented at http://www.acpi.info/, in the ACPI 2.0 specification.
 
 #define SMAP  0x534d4150
 
@@ -436,7 +436,7 @@ bail820:
 
 meme801:
        stc                                     # fix to work around buggy
-       xorw    %cx,%cx                         # BIOSes which dont clear/set
+       xorw    %cx,%cx                         # BIOSes which don't clear/set
        xorw    %dx,%dx                         # carry on pass/error of
                                                # e801h memory size call
                                                # or merely pass cx,dx though
@@ -733,7 +733,7 @@ flush_instr:
 #
 #      but we yet haven't reloaded the CS register, so the default size 
 #      of the target offset still is 16 bit.
-#       However, using an operant prefix (0x66), the CPU will properly
+#      However, using an operand prefix (0x66), the CPU will properly
 #      take our 48 bit far pointer. (INTeL 80386 Programmer's Reference
 #      Manual, Mixing 16-bit and 32-bit code, page 16-6)
 
index c2fa66313170767827c6a2af0afeedca9b813ce2..18b5bac1c4282fb94a8bb71afbc79a383164246a 100644 (file)
@@ -1,6 +1,4 @@
 /*
- *  $Id: build.c,v 1.3 2001/06/26 15:14:50 pavel Exp $
- *
  *  Copyright (C) 1991, 1992  Linus Torvalds
  *  Copyright (C) 1997 Martin Mares
  */
@@ -8,7 +6,8 @@
 /*
  * This file builds a disk-image from three different files:
  *
- * - bootsect: exactly 512 bytes of 8086 machine code, loads the rest
+ * - bootsect: compatibility mbr which prints an error message if
+ *             someone tries to boot the kernel directly.
  * - setup: 8086 machine code, sets up system parm
  * - system: 80386 code for actual system
  *
index f3ca0db85b5b54b286fc5e72aa75e559bedbb61c..cc935427d532355672d06034a644bcbc142e4342 100644 (file)
@@ -589,7 +589,7 @@ ia32_sys_call_table:
        .quad compat_sys_mq_timedreceive        /* 280 */
        .quad compat_sys_mq_notify
        .quad compat_sys_mq_getsetattr
-       .quad quiet_ni_syscall          /* reserved for kexec */
+       .quad compat_sys_kexec_load     /* reserved for kexec */
        .quad compat_sys_waitid
        .quad quiet_ni_syscall          /* sys_altroot */
        .quad sys_add_key
index 5ca4a4598fdad807b5aa0e8143c2aa55525fced2..48f9e2c19cd6f78a4cdc21efdec7afec0da19277 100644 (file)
@@ -20,6 +20,7 @@ obj-$(CONFIG_SMP)             += smp.o smpboot.o trampoline.o
 obj-$(CONFIG_X86_LOCAL_APIC)   += apic.o  nmi.o
 obj-$(CONFIG_X86_IO_APIC)      += io_apic.o mpparse.o \
                genapic.o genapic_cluster.o genapic_flat.o
+obj-$(CONFIG_KEXEC)            += machine_kexec.o relocate_kernel.o crash.o
 obj-$(CONFIG_PM)               += suspend.o
 obj-$(CONFIG_SOFTWARE_SUSPEND) += suspend_asm.o
 obj-$(CONFIG_CPU_FREQ)         += cpufreq/
index a4c630034cd43041f9e10614b040512cc345fa95..185faa911db592b26483bda86a6760a9fd044d63 100644 (file)
@@ -67,7 +67,7 @@ wakeup_code:
        shll    $4, %eax
        addl    $(gdta - wakeup_code), %eax
        movl    %eax, gdt_48a +2 - wakeup_code
-       lgdt    %ds:gdt_48a - wakeup_code               # load gdt with whatever is
+       lgdtl   %ds:gdt_48a - wakeup_code       # load gdt with whatever is
                                                # appropriate
 
        movl    $1, %eax                        # protected mode (PE) bit
index f8e6cc4fecd4887acc244fee292f401a96aac59b..375d369570ca3dbbb365b363585d5b6ecff1ef57 100644 (file)
@@ -133,7 +133,7 @@ void __init connect_bsp_APIC(void)
        }
 }
 
-void disconnect_bsp_APIC(void)
+void disconnect_bsp_APIC(int virt_wire_setup)
 {
        if (pic_mode) {
                /*
@@ -146,6 +146,42 @@ void disconnect_bsp_APIC(void)
                outb(0x70, 0x22);
                outb(0x00, 0x23);
        }
+       else {
+               /* Go back to Virtual Wire compatibility mode */
+               unsigned long value;
+
+               /* For the spurious interrupt use vector F, and enable it */
+               value = apic_read(APIC_SPIV);
+               value &= ~APIC_VECTOR_MASK;
+               value |= APIC_SPIV_APIC_ENABLED;
+               value |= 0xf;
+               apic_write_around(APIC_SPIV, value);
+
+               if (!virt_wire_setup) {
+                       /* For LVT0 make it edge triggered, active high, external and enabled */
+                       value = apic_read(APIC_LVT0);
+                       value &= ~(APIC_MODE_MASK | APIC_SEND_PENDING |
+                               APIC_INPUT_POLARITY | APIC_LVT_REMOTE_IRR |
+                               APIC_LVT_LEVEL_TRIGGER | APIC_LVT_MASKED );
+                       value |= APIC_LVT_REMOTE_IRR | APIC_SEND_PENDING;
+                       value = SET_APIC_DELIVERY_MODE(value, APIC_MODE_EXTINT);
+                       apic_write_around(APIC_LVT0, value);
+               }
+               else {
+                       /* Disable LVT0 */
+                       apic_write_around(APIC_LVT0, APIC_LVT_MASKED);
+               }
+
+               /* For LVT1 make it edge triggered, active high, nmi and enabled */
+               value = apic_read(APIC_LVT1);
+               value &= ~(
+                       APIC_MODE_MASK | APIC_SEND_PENDING |
+                       APIC_INPUT_POLARITY | APIC_LVT_REMOTE_IRR |
+                       APIC_LVT_LEVEL_TRIGGER | APIC_LVT_MASKED);
+               value |= APIC_LVT_REMOTE_IRR | APIC_SEND_PENDING;
+               value = SET_APIC_DELIVERY_MODE(value, APIC_MODE_NMI);
+               apic_write_around(APIC_LVT1, value);
+       }
 }
 
 void disable_local_APIC(void)
@@ -285,7 +321,7 @@ void __init init_bsp_APIC(void)
        apic_write_around(APIC_LVT1, value);
 }
 
-void __init setup_local_APIC (void)
+void __cpuinit setup_local_APIC (void)
 {
        unsigned int value, ver, maxlvt;
 
@@ -534,7 +570,7 @@ static struct sys_device device_lapic = {
        .cls            = &lapic_sysclass,
 };
 
-static void __init apic_pm_activate(void)
+static void __cpuinit apic_pm_activate(void)
 {
        apic_pm_state.active = 1;
 }
@@ -774,14 +810,14 @@ void __init setup_boot_APIC_clock (void)
        local_irq_enable();
 }
 
-void __init setup_secondary_APIC_clock(void)
+void __cpuinit setup_secondary_APIC_clock(void)
 {
        local_irq_disable(); /* FIXME: Do we need this? --RR */
        setup_APIC_timer(calibration_result);
        local_irq_enable();
 }
 
-void __init disable_APIC_timer(void)
+void __cpuinit disable_APIC_timer(void)
 {
        if (using_apic_timer) {
                unsigned long v;
diff --git a/arch/x86_64/kernel/crash.c b/arch/x86_64/kernel/crash.c
new file mode 100644 (file)
index 0000000..d7fa424
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * Architecture specific (x86_64) functions for kexec based crash dumps.
+ *
+ * Created by: Hariprasad Nellitheertha (hari@in.ibm.com)
+ *
+ * Copyright (C) IBM Corporation, 2004. All rights reserved.
+ *
+ */
+
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/smp.h>
+#include <linux/irq.h>
+#include <linux/reboot.h>
+#include <linux/kexec.h>
+
+#include <asm/processor.h>
+#include <asm/hardirq.h>
+#include <asm/nmi.h>
+#include <asm/hw_irq.h>
+
+note_buf_t crash_notes[NR_CPUS];
+
+void machine_crash_shutdown(struct pt_regs *regs)
+{
+       /* This function is only called after the system
+        * has paniced or is otherwise in a critical state.
+        * The minimum amount of code to allow a kexec'd kernel
+        * to run successfully needs to happen here.
+        *
+        * In practice this means shooting down the other cpus in
+        * an SMP system.
+        */
+}
index 7c154dfff64aa406b15294236eee46a738837ee8..6ded3a50dfe63682174470acc3e78e2cfdbfd8b5 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/bootmem.h>
 #include <linux/ioport.h>
 #include <linux/string.h>
+#include <linux/kexec.h>
 #include <asm/page.h>
 #include <asm/e820.h>
 #include <asm/proto.h>
@@ -191,8 +192,6 @@ void __init e820_reserve_resources(void)
        int i;
        for (i = 0; i < e820.nr_map; i++) {
                struct resource *res;
-               if (e820.map[i].addr + e820.map[i].size > 0x100000000ULL)
-                       continue;
                res = alloc_bootmem_low(sizeof(struct resource));
                switch (e820.map[i].type) {
                case E820_RAM:  res->name = "System RAM"; break;
@@ -212,6 +211,9 @@ void __init e820_reserve_resources(void)
                         */
                        request_resource(res, &code_resource);
                        request_resource(res, &data_resource);
+#ifdef CONFIG_KEXEC
+                       request_resource(res, &crashk_res);
+#endif
                }
        }
 }
index b4cbbad0422624aca80206bb15b89f826a8014dd..282846965080ee90ac4388618de7a4b2a2fbedae 100644 (file)
@@ -7,6 +7,8 @@
  * Hacked for x86-64 by James Cleverdon from i386 architecture code by
  * Martin Bligh, Andi Kleen, James Bottomley, John Stultz, and
  * James Cleverdon.
+ * Ashok Raj <ashok.raj@intel.com>
+ *     Removed IPI broadcast shortcut to support CPU hotplug
  */
 #include <linux/config.h>
 #include <linux/threads.h>
 #include <asm/smp.h>
 #include <asm/ipi.h>
 
+/*
+ * The following permit choosing broadcast IPI shortcut v.s sending IPI only
+ * to online cpus via the send_IPI_mask varient.
+ * The mask version is my preferred option, since it eliminates a lot of
+ * other extra code that would need to be written to cleanup intrs sent
+ * to a CPU while offline.
+ *
+ * Sending broadcast introduces lots of trouble in CPU hotplug situations.
+ * These IPI's are delivered to cpu's irrespective of their offline status
+ * and could pickup stale intr data when these CPUS are turned online.
+ *
+ * Not using broadcast is a cleaner approach IMO, but Andi Kleen disagrees with
+ * the idea of not using broadcast IPI's anymore. Hence the run time check
+ * is introduced, on his request so we can choose an alternate mechanism.
+ *
+ * Initial wacky performance tests that collect cycle counts show
+ * no increase in using mask v.s broadcast version. In fact they seem
+ * identical in terms of cycle counts.
+ *
+ * if we need to use broadcast, we need to do the following.
+ *
+ * cli;
+ * hold call_lock;
+ * clear any pending IPI, just ack and clear all pending intr
+ * set cpu_online_map;
+ * release call_lock;
+ * sti;
+ *
+ * The complicated dummy irq processing shown above is not required if
+ * we didnt sent IPI's to wrong CPU's in the first place.
+ *
+ * - Ashok Raj <ashok.raj@intel.com>
+ */
+#ifdef CONFIG_HOTPLUG_CPU
+#define DEFAULT_SEND_IPI       (1)
+#else
+#define DEFAULT_SEND_IPI       (0)
+#endif
+
+static int no_broadcast=DEFAULT_SEND_IPI;
 
 static cpumask_t flat_target_cpus(void)
 {
@@ -45,22 +87,6 @@ static void flat_init_apic_ldr(void)
        apic_write_around(APIC_LDR, val);
 }
 
-static void flat_send_IPI_allbutself(int vector)
-{
-       /*
-        * if there are no other CPUs in the system then
-        * we get an APIC send error if we try to broadcast.
-        * thus we have to avoid sending IPIs in this case.
-        */
-       if (num_online_cpus() > 1)
-               __send_IPI_shortcut(APIC_DEST_ALLBUT, vector, APIC_DEST_LOGICAL);
-}
-
-static void flat_send_IPI_all(int vector)
-{
-       __send_IPI_shortcut(APIC_DEST_ALLINC, vector, APIC_DEST_LOGICAL);
-}
-
 static void flat_send_IPI_mask(cpumask_t cpumask, int vector)
 {
        unsigned long mask = cpus_addr(cpumask)[0];
@@ -93,6 +119,39 @@ static void flat_send_IPI_mask(cpumask_t cpumask, int vector)
        local_irq_restore(flags);
 }
 
+static inline void __local_flat_send_IPI_allbutself(int vector)
+{
+       if (no_broadcast) {
+               cpumask_t mask = cpu_online_map;
+               int this_cpu = get_cpu();
+
+               cpu_clear(this_cpu, mask);
+               flat_send_IPI_mask(mask, vector);
+               put_cpu();
+       }
+       else
+               __send_IPI_shortcut(APIC_DEST_ALLBUT, vector, APIC_DEST_LOGICAL);
+}
+
+static inline void __local_flat_send_IPI_all(int vector)
+{
+       if (no_broadcast)
+               flat_send_IPI_mask(cpu_online_map, vector);
+       else
+               __send_IPI_shortcut(APIC_DEST_ALLINC, vector, APIC_DEST_LOGICAL);
+}
+
+static void flat_send_IPI_allbutself(int vector)
+{
+       if (((num_online_cpus()) - 1) >= 1)
+               __local_flat_send_IPI_allbutself(vector);
+}
+
+static void flat_send_IPI_all(int vector)
+{
+       __local_flat_send_IPI_all(vector);
+}
+
 static int flat_apic_id_registered(void)
 {
        return physid_isset(GET_APIC_ID(apic_read(APIC_ID)), phys_cpu_present_map);
@@ -111,6 +170,16 @@ static unsigned int phys_pkg_id(int index_msb)
        return ((ebx >> 24) & 0xFF) >> index_msb;
 }
 
+static __init int no_ipi_broadcast(char *str)
+{
+       get_option(&str, &no_broadcast);
+       printk ("Using %s mode\n", no_broadcast ? "No IPI Broadcast" :
+                                                                                       "IPI Broadcast");
+       return 1;
+}
+
+__setup("no_ipi_broadcast", no_ipi_broadcast);
+
 struct genapic apic_flat =  {
        .name = "flat",
        .int_delivery_mode = dest_LowestPrio,
@@ -125,3 +194,12 @@ struct genapic apic_flat =  {
        .cpu_mask_to_apicid = flat_cpu_mask_to_apicid,
        .phys_pkg_id = phys_pkg_id,
 };
+
+static int __init print_ipi_mode(void)
+{
+       printk ("Using IPI %s mode\n", no_broadcast ? "No-Shortcut" :
+                                                                                       "Shortcut");
+       return 0;
+}
+
+late_initcall(print_ipi_mode);
index 9bd2e7a4b81e196d89856871397d6300c2e4d2bb..8d765aa77a266e980c8edaae33a8c11ffdd42e9c 100644 (file)
@@ -248,23 +248,23 @@ ENTRY(_stext)
         */
 .org 0x1000
 ENTRY(init_level4_pgt)
-       .quad   0x0000000000102007              /* -> level3_ident_pgt */
+       .quad   0x0000000000002007 + __PHYSICAL_START   /* -> level3_ident_pgt */
        .fill   255,8,0
-       .quad   0x000000000010a007
+       .quad   0x000000000000a007 + __PHYSICAL_START
        .fill   254,8,0
        /* (2^48-(2*1024*1024*1024))/(2^39) = 511 */
-       .quad   0x0000000000103007              /* -> level3_kernel_pgt */
+       .quad   0x0000000000003007 + __PHYSICAL_START   /* -> level3_kernel_pgt */
 
 .org 0x2000
 ENTRY(level3_ident_pgt)
-       .quad   0x0000000000104007
+       .quad   0x0000000000004007 + __PHYSICAL_START
        .fill   511,8,0
 
 .org 0x3000
 ENTRY(level3_kernel_pgt)
        .fill   510,8,0
        /* (2^48-(2*1024*1024*1024)-((2^39)*511))/(2^30) = 510 */
-       .quad   0x0000000000105007              /* -> level2_kernel_pgt */
+       .quad   0x0000000000005007 + __PHYSICAL_START   /* -> level2_kernel_pgt */
        .fill   1,8,0
 
 .org 0x4000
@@ -337,17 +337,17 @@ ENTRY(empty_bad_pmd_table)
 
 .org 0xa000
 ENTRY(level3_physmem_pgt)
-       .quad   0x0000000000105007              /* -> level2_kernel_pgt (so that __va works even before pagetable_init) */
+       .quad   0x0000000000005007 + __PHYSICAL_START   /* -> level2_kernel_pgt (so that __va works even before pagetable_init) */
 
        .org 0xb000
 #ifdef CONFIG_ACPI_SLEEP
 ENTRY(wakeup_level4_pgt)
-       .quad   0x0000000000102007              /* -> level3_ident_pgt */
+       .quad   0x0000000000002007 + __PHYSICAL_START   /* -> level3_ident_pgt */
        .fill   255,8,0
-       .quad   0x000000000010a007
+       .quad   0x000000000000a007 + __PHYSICAL_START
        .fill   254,8,0
        /* (2^48-(2*1024*1024*1024))/(2^39) = 511 */
-       .quad   0x0000000000103007              /* -> level3_kernel_pgt */
+       .quad   0x0000000000003007 + __PHYSICAL_START   /* -> level3_kernel_pgt */
 #endif
 
        .data
index ba139cac57cef085252f30c97d7296fd87c8210e..d9b22b633e390c0739fdd33ba64b121982b8925f 100644 (file)
@@ -42,7 +42,7 @@ void mxcsr_feature_mask_init(void)
  * Called at bootup to set up the initial FPU state that is later cloned
  * into all processes.
  */
-void __init fpu_init(void)
+void __cpuinit fpu_init(void)
 {
        unsigned long oldcr0 = read_cr0();
        extern void __bad_fxsave_alignment(void);
index 19eafa0aa95c4dc1aa822f44fac760c8e2e15ef4..a891690951299912495b8da4915210e73b524988 100644 (file)
@@ -414,10 +414,22 @@ static int i8259A_suspend(struct sys_device *dev, pm_message_t state)
        return 0;
 }
 
+static int i8259A_shutdown(struct sys_device *dev)
+{
+       /* Put the i8259A into a quiescent state that
+        * the kernel initialization code can get it
+        * out of.
+        */
+       outb(0xff, 0x21);       /* mask all of 8259A-1 */
+       outb(0xff, 0xA1);       /* mask all of 8259A-1 */
+       return 0;
+}
+
 static struct sysdev_class i8259_sysdev_class = {
        set_kset_name("i8259"),
        .suspend = i8259A_suspend,
        .resume = i8259A_resume,
+       .shutdown = i8259A_shutdown,
 };
 
 static struct sys_device device_i8259A = {
index afd87e64d0a870c43eaab0a6a99882c9d1c12281..157190d986bbdb405d132a0b7230ea9a32792bfe 100644 (file)
@@ -330,7 +330,7 @@ static int find_irq_entry(int apic, int pin, int type)
 /*
  * Find the pin to which IRQ[irq] (ISA) is connected
  */
-static int __init find_isa_irq_pin(int irq, int type)
+static int find_isa_irq_pin(int irq, int type)
 {
        int i;
 
@@ -1132,12 +1132,44 @@ static void __init enable_IO_APIC(void)
  */
 void disable_IO_APIC(void)
 {
+       int pin;
        /*
         * Clear the IO-APIC before rebooting:
         */
        clear_IO_APIC();
 
-       disconnect_bsp_APIC();
+       /*
+        * If the i82559 is routed through an IOAPIC
+        * Put that IOAPIC in virtual wire mode
+        * so legacy interrups can be delivered.
+        */
+       pin = find_isa_irq_pin(0, mp_ExtINT);
+       if (pin != -1) {
+               struct IO_APIC_route_entry entry;
+               unsigned long flags;
+
+               memset(&entry, 0, sizeof(entry));
+               entry.mask            = 0; /* Enabled */
+               entry.trigger         = 0; /* Edge */
+               entry.irr             = 0;
+               entry.polarity        = 0; /* High */
+               entry.delivery_status = 0;
+               entry.dest_mode       = 0; /* Physical */
+               entry.delivery_mode   = 7; /* ExtInt */
+               entry.vector          = 0;
+               entry.dest.physical.physical_dest = 0;
+
+
+               /*
+                * Add it to the IO-APIC irq-routing table:
+                */
+               spin_lock_irqsave(&ioapic_lock, flags);
+               io_apic_write(0, 0x11+2*pin, *(((int *)&entry)+1));
+               io_apic_write(0, 0x10+2*pin, *(((int *)&entry)+0));
+               spin_unlock_irqrestore(&ioapic_lock, flags);
+       }
+
+       disconnect_bsp_APIC(pin != -1);
 }
 
 /*
index 62b112e4deb40aa873f7782babe5782a8955e191..cc3fb85f51459141be2519243b8e752d5371f3d9 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/interrupt.h>
 #include <linux/seq_file.h>
 #include <linux/module.h>
+#include <linux/delay.h>
 #include <asm/uaccess.h>
 #include <asm/io_apic.h>
 
@@ -106,3 +107,31 @@ asmlinkage unsigned int do_IRQ(struct pt_regs *regs)
        return 1;
 }
 
+#ifdef CONFIG_HOTPLUG_CPU
+void fixup_irqs(cpumask_t map)
+{
+       unsigned int irq;
+       static int warned;
+
+       for (irq = 0; irq < NR_IRQS; irq++) {
+               cpumask_t mask;
+               if (irq == 2)
+                       continue;
+
+               cpus_and(mask, irq_affinity[irq], map);
+               if (any_online_cpu(mask) == NR_CPUS) {
+                       printk("Breaking affinity for irq %i\n", irq);
+                       mask = map;
+               }
+               if (irq_desc[irq].handler->set_affinity)
+                       irq_desc[irq].handler->set_affinity(irq, mask);
+               else if (irq_desc[irq].action && !(warned++))
+                       printk("Cannot set affinity for irq %i\n", irq);
+       }
+
+       /* That doesn't seem sufficient.  Give it 1ms. */
+       local_irq_enable();
+       mdelay(1);
+       local_irq_disable();
+}
+#endif
diff --git a/arch/x86_64/kernel/machine_kexec.c b/arch/x86_64/kernel/machine_kexec.c
new file mode 100644 (file)
index 0000000..60d1eff
--- /dev/null
@@ -0,0 +1,250 @@
+/*
+ * machine_kexec.c - handle transition of Linux booting another kernel
+ * Copyright (C) 2002-2005 Eric Biederman  <ebiederm@xmission.com>
+ *
+ * This source code is licensed under the GNU General Public License,
+ * Version 2.  See the file COPYING for more details.
+ */
+
+#include <linux/mm.h>
+#include <linux/kexec.h>
+#include <linux/delay.h>
+#include <linux/string.h>
+#include <linux/reboot.h>
+#include <asm/pda.h>
+#include <asm/pgtable.h>
+#include <asm/pgalloc.h>
+#include <asm/tlbflush.h>
+#include <asm/mmu_context.h>
+#include <asm/io.h>
+#include <asm/apic.h>
+#include <asm/cpufeature.h>
+#include <asm/hw_irq.h>
+
+#define LEVEL0_SIZE (1UL << 12UL)
+#define LEVEL1_SIZE (1UL << 21UL)
+#define LEVEL2_SIZE (1UL << 30UL)
+#define LEVEL3_SIZE (1UL << 39UL)
+#define LEVEL4_SIZE (1UL << 48UL)
+
+#define L0_ATTR (_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED | _PAGE_DIRTY)
+#define L1_ATTR (_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED | _PAGE_DIRTY | _PAGE_PSE)
+#define L2_ATTR (_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED | _PAGE_DIRTY)
+#define L3_ATTR (_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED | _PAGE_DIRTY)
+
+static void init_level2_page(u64 *level2p, unsigned long addr)
+{
+       unsigned long end_addr;
+
+       addr &= PAGE_MASK;
+       end_addr = addr + LEVEL2_SIZE;
+       while (addr < end_addr) {
+               *(level2p++) = addr | L1_ATTR;
+               addr += LEVEL1_SIZE;
+       }
+}
+
+static int init_level3_page(struct kimage *image, u64 *level3p,
+                               unsigned long addr, unsigned long last_addr)
+{
+       unsigned long end_addr;
+       int result;
+
+       result = 0;
+       addr &= PAGE_MASK;
+       end_addr = addr + LEVEL3_SIZE;
+       while ((addr < last_addr) && (addr < end_addr)) {
+               struct page *page;
+               u64 *level2p;
+
+               page = kimage_alloc_control_pages(image, 0);
+               if (!page) {
+                       result = -ENOMEM;
+                       goto out;
+               }
+               level2p = (u64 *)page_address(page);
+               init_level2_page(level2p, addr);
+               *(level3p++) = __pa(level2p) | L2_ATTR;
+               addr += LEVEL2_SIZE;
+       }
+       /* clear the unused entries */
+       while (addr < end_addr) {
+               *(level3p++) = 0;
+               addr += LEVEL2_SIZE;
+       }
+out:
+       return result;
+}
+
+
+static int init_level4_page(struct kimage *image, u64 *level4p,
+                               unsigned long addr, unsigned long last_addr)
+{
+       unsigned long end_addr;
+       int result;
+
+       result = 0;
+       addr &= PAGE_MASK;
+       end_addr = addr + LEVEL4_SIZE;
+       while ((addr < last_addr) && (addr < end_addr)) {
+               struct page *page;
+               u64 *level3p;
+
+               page = kimage_alloc_control_pages(image, 0);
+               if (!page) {
+                       result = -ENOMEM;
+                       goto out;
+               }
+               level3p = (u64 *)page_address(page);
+               result = init_level3_page(image, level3p, addr, last_addr);
+               if (result) {
+                       goto out;
+               }
+               *(level4p++) = __pa(level3p) | L3_ATTR;
+               addr += LEVEL3_SIZE;
+       }
+       /* clear the unused entries */
+       while (addr < end_addr) {
+               *(level4p++) = 0;
+               addr += LEVEL3_SIZE;
+       }
+out:
+       return result;
+}
+
+
+static int init_pgtable(struct kimage *image, unsigned long start_pgtable)
+{
+       u64 *level4p;
+       level4p = (u64 *)__va(start_pgtable);
+       return init_level4_page(image, level4p, 0, end_pfn << PAGE_SHIFT);
+}
+
+static void set_idt(void *newidt, u16 limit)
+{
+       unsigned char curidt[10];
+
+       /* x86-64 supports unaliged loads & stores */
+       (*(u16 *)(curidt)) = limit;
+       (*(u64 *)(curidt +2)) = (unsigned long)(newidt);
+
+       __asm__ __volatile__ (
+               "lidt %0\n"
+               : "=m" (curidt)
+               );
+};
+
+
+static void set_gdt(void *newgdt, u16 limit)
+{
+       unsigned char curgdt[10];
+
+       /* x86-64 supports unaligned loads & stores */
+       (*(u16 *)(curgdt)) = limit;
+       (*(u64 *)(curgdt +2)) = (unsigned long)(newgdt);
+
+       __asm__ __volatile__ (
+               "lgdt %0\n"
+               : "=m" (curgdt)
+               );
+};
+
+static void load_segments(void)
+{
+       __asm__ __volatile__ (
+               "\tmovl $"STR(__KERNEL_DS)",%eax\n"
+               "\tmovl %eax,%ds\n"
+               "\tmovl %eax,%es\n"
+               "\tmovl %eax,%ss\n"
+               "\tmovl %eax,%fs\n"
+               "\tmovl %eax,%gs\n"
+               );
+#undef STR
+#undef __STR
+}
+
+typedef NORET_TYPE void (*relocate_new_kernel_t)(unsigned long indirection_page,
+                                       unsigned long control_code_buffer,
+                                       unsigned long start_address,
+                                       unsigned long pgtable) ATTRIB_NORET;
+
+const extern unsigned char relocate_new_kernel[];
+const extern unsigned long relocate_new_kernel_size;
+
+int machine_kexec_prepare(struct kimage *image)
+{
+       unsigned long start_pgtable, control_code_buffer;
+       int result;
+
+       /* Calculate the offsets */
+       start_pgtable = page_to_pfn(image->control_code_page) << PAGE_SHIFT;
+       control_code_buffer = start_pgtable + 4096UL;
+
+       /* Setup the identity mapped 64bit page table */
+       result = init_pgtable(image, start_pgtable);
+       if (result)
+               return result;
+
+       /* Place the code in the reboot code buffer */
+       memcpy(__va(control_code_buffer), relocate_new_kernel,
+                                               relocate_new_kernel_size);
+
+       return 0;
+}
+
+void machine_kexec_cleanup(struct kimage *image)
+{
+       return;
+}
+
+/*
+ * Do not allocate memory (or fail in any way) in machine_kexec().
+ * We are past the point of no return, committed to rebooting now.
+ */
+NORET_TYPE void machine_kexec(struct kimage *image)
+{
+       unsigned long page_list;
+       unsigned long control_code_buffer;
+       unsigned long start_pgtable;
+       relocate_new_kernel_t rnk;
+
+       /* Interrupts aren't acceptable while we reboot */
+       local_irq_disable();
+
+       /* Calculate the offsets */
+       page_list = image->head;
+       start_pgtable = page_to_pfn(image->control_code_page) << PAGE_SHIFT;
+       control_code_buffer = start_pgtable + 4096UL;
+
+       /* Set the low half of the page table to my identity mapped
+        * page table for kexec.  Leave the high half pointing at the
+        * kernel pages.   Don't bother to flush the global pages
+        * as that will happen when I fully switch to my identity mapped
+        * page table anyway.
+        */
+       memcpy(__va(read_cr3()), __va(start_pgtable), PAGE_SIZE/2);
+       __flush_tlb();
+
+
+       /* The segment registers are funny things, they are
+        * automatically loaded from a table, in memory wherever you
+        * set them to a specific selector, but this table is never
+        * accessed again unless you set the segment to a different selector.
+        *
+        * The more common model are caches where the behide
+        * the scenes work is done, but is also dropped at arbitrary
+        * times.
+        *
+        * I take advantage of this here by force loading the
+        * segments, before I zap the gdt with an invalid value.
+        */
+       load_segments();
+       /* The gdt & idt are now invalid.
+        * If you want to load them you must set up your own idt & gdt.
+        */
+       set_gdt(phys_to_virt(0),0);
+       set_idt(phys_to_virt(0),0);
+       /* now call it */
+       rnk = (relocate_new_kernel_t) control_code_buffer;
+       (*rnk)(page_list, control_code_buffer, image->start, start_pgtable);
+}
index 3a89d735a4f60f7203d8b0d2e5df2d2685d299fa..21e70625a4953e26361c060c432f1803393952c5 100644 (file)
@@ -327,7 +327,7 @@ static void mce_init(void *dummy)
 }
 
 /* Add per CPU specific workarounds here */
-static void __init mce_cpu_quirks(struct cpuinfo_x86 *c) 
+static void __cpuinit mce_cpu_quirks(struct cpuinfo_x86 *c)
 { 
        /* This should be disabled by the BIOS, but isn't always */
        if (c->x86_vendor == X86_VENDOR_AMD && c->x86 == 15) {
@@ -337,7 +337,7 @@ static void __init mce_cpu_quirks(struct cpuinfo_x86 *c)
        }
 }                      
 
-static void __init mce_cpu_features(struct cpuinfo_x86 *c)
+static void __cpuinit mce_cpu_features(struct cpuinfo_x86 *c)
 {
        switch (c->x86_vendor) {
        case X86_VENDOR_INTEL:
@@ -352,7 +352,7 @@ static void __init mce_cpu_features(struct cpuinfo_x86 *c)
  * Called for each booted CPU to set up machine checks.
  * Must be called with preempt off. 
  */
-void __init mcheck_init(struct cpuinfo_x86 *c)
+void __cpuinit mcheck_init(struct cpuinfo_x86 *c)
 {
        static cpumask_t mce_cpus __initdata = CPU_MASK_NONE;
 
@@ -411,7 +411,7 @@ static ssize_t mce_read(struct file *filp, char __user *ubuf, size_t usize, loff
        memset(mcelog.entry, 0, next * sizeof(struct mce));
        mcelog.next = 0;
 
-       synchronize_kernel();   
+       synchronize_sched();
 
        /* Collect entries that were still getting written before the synchronize. */
 
@@ -542,7 +542,7 @@ ACCESSOR(bank4ctl,bank[4],mce_restart())
 ACCESSOR(tolerant,tolerant,)
 ACCESSOR(check_interval,check_interval,mce_restart())
 
-static __init int mce_init_device(void)
+static __cpuinit int mce_init_device(void)
 {
        int err;
        if (!mce_available(&boot_cpu_data))
index 4db9a640069fe02def836ef0f14340b92c55b84d..0be0a795981418750d322dced63743ee97b4e201 100644 (file)
@@ -42,7 +42,7 @@ done:
        irq_exit();
 }
 
-static void __init intel_init_thermal(struct cpuinfo_x86 *c)
+static void __cpuinit intel_init_thermal(struct cpuinfo_x86 *c)
 {
        u32 l, h;
        int tm2 = 0;
@@ -93,7 +93,7 @@ static void __init intel_init_thermal(struct cpuinfo_x86 *c)
        return;
 }
 
-void __init mce_intel_feature_init(struct cpuinfo_x86 *c)
+void __cpuinit mce_intel_feature_init(struct cpuinfo_x86 *c)
 {
        intel_init_thermal(c);
 }
index 31c0f2e6ac916c8f1cd93f025cf3182b92f1fa3e..4e44d6e6b7e52f35d55993ea9616d4ef39a165fa 100644 (file)
@@ -98,7 +98,7 @@ static unsigned int nmi_p4_cccr_val;
        (P4_CCCR_OVF_PMI0|P4_CCCR_THRESHOLD(15)|P4_CCCR_COMPLEMENT|     \
         P4_CCCR_COMPARE|P4_CCCR_REQUIRED|P4_CCCR_ESCR_SELECT(4)|P4_CCCR_ENABLE)
 
-static __init inline int nmi_known_cpu(void)
+static __cpuinit inline int nmi_known_cpu(void)
 {
        switch (boot_cpu_data.x86_vendor) {
        case X86_VENDOR_AMD:
@@ -110,7 +110,7 @@ static __init inline int nmi_known_cpu(void)
 }
 
 /* Run after command line and cpu_init init, but before all other checks */
-void __init nmi_watchdog_default(void)
+void __cpuinit nmi_watchdog_default(void)
 {
        if (nmi_watchdog != NMI_DEFAULT)
                return;
index e59d1f9d616396172129d91524196d4551324f1f..1d91271796e56725e6a0d51474215830362d2ddc 100644 (file)
@@ -8,7 +8,8 @@
  * 
  *  X86-64 port
  *     Andi Kleen.
- * 
+ *
+ *     CPU hotplug support - ashok.raj@intel.com
  *  $Id: process.c,v 1.38 2002/01/15 10:08:03 ak Exp $
  */
 
@@ -18,6 +19,7 @@
 
 #include <stdarg.h>
 
+#include <linux/cpu.h>
 #include <linux/errno.h>
 #include <linux/sched.h>
 #include <linux/kernel.h>
@@ -154,6 +156,29 @@ void cpu_idle_wait(void)
 }
 EXPORT_SYMBOL_GPL(cpu_idle_wait);
 
+#ifdef CONFIG_HOTPLUG_CPU
+DECLARE_PER_CPU(int, cpu_state);
+
+#include <asm/nmi.h>
+/* We don't actually take CPU down, just spin without interrupts. */
+static inline void play_dead(void)
+{
+       idle_task_exit();
+       wbinvd();
+       mb();
+       /* Ack it */
+       __get_cpu_var(cpu_state) = CPU_DEAD;
+
+       while (1)
+               safe_halt();
+}
+#else
+static inline void play_dead(void)
+{
+       BUG();
+}
+#endif /* CONFIG_HOTPLUG_CPU */
+
 /*
  * The idle thread. There's no useful work to be
  * done, so just try to conserve power and have a
@@ -174,6 +199,8 @@ void cpu_idle (void)
                        idle = pm_idle;
                        if (!idle)
                                idle = default_idle;
+                       if (cpu_is_offline(smp_processor_id()))
+                               play_dead();
                        idle();
                }
 
@@ -204,7 +231,7 @@ static void mwait_idle(void)
        }
 }
 
-void __init select_idle_routine(const struct cpuinfo_x86 *c)
+void __cpuinit select_idle_routine(const struct cpuinfo_x86 *c)
 {
        static int printed;
        if (cpu_has(c, X86_FEATURE_MWAIT)) {
index be4b36f762cf42adb461ec5ea51ea75da45e0e02..57e71dbdfd69952732a24fa8c4ac54a234e49d80 100644 (file)
@@ -66,41 +66,47 @@ static int __init reboot_setup(char *str)
 
 __setup("reboot=", reboot_setup);
 
-#ifdef CONFIG_SMP
-static void smp_halt(void)
+static inline void kb_wait(void)
 {
-       int cpuid = safe_smp_processor_id(); 
-       static int first_entry = 1;
+       int i;
 
-       if (reboot_force)
-               return;
+       for (i=0; i<0x10000; i++)
+               if ((inb_p(0x64) & 0x02) == 0)
+                       break;
+}
 
-       if (first_entry) {
-               first_entry = 0;
-               smp_call_function((void *)machine_restart, NULL, 1, 0);
-       }
-                       
-       smp_stop_cpu(); 
+void machine_shutdown(void)
+{
+       /* Stop the cpus and apics */
+#ifdef CONFIG_SMP
+       int reboot_cpu_id;
 
-       /* AP calling this. Just halt */
-       if (cpuid != boot_cpu_id) { 
-               for (;;) 
-                       asm("hlt");
+       /* The boot cpu is always logical cpu 0 */
+       reboot_cpu_id = 0;
+
+       /* Make certain the cpu I'm about to reboot on is online */
+       if (!cpu_isset(reboot_cpu_id, cpu_online_map)) {
+               reboot_cpu_id = smp_processor_id();
        }
 
-       /* Wait for all other CPUs to have run smp_stop_cpu */
-       while (!cpus_empty(cpu_online_map))
-               rep_nop(); 
-}
+       /* Make certain I only run on the appropriate processor */
+       set_cpus_allowed(current, cpumask_of_cpu(reboot_cpu_id));
+
+       /* O.K Now that I'm on the appropriate processor,
+        * stop all of the others.
+        */
+       smp_send_stop();
 #endif
 
-static inline void kb_wait(void)
-{
-       int i;
+       local_irq_disable();
 
-       for (i=0; i<0x10000; i++)
-               if ((inb_p(0x64) & 0x02) == 0)
-                       break;
+#ifndef CONFIG_SMP
+       disable_local_APIC();
+#endif
+
+       disable_IO_APIC();
+
+       local_irq_enable();
 }
 
 void machine_restart(char * __unused)
@@ -109,9 +115,7 @@ void machine_restart(char * __unused)
 
        printk("machine restart\n");
 
-#ifdef CONFIG_SMP
-       smp_halt(); 
-#endif
+       machine_shutdown();
 
        if (!reboot_force) {
                local_irq_disable();
diff --git a/arch/x86_64/kernel/relocate_kernel.S b/arch/x86_64/kernel/relocate_kernel.S
new file mode 100644 (file)
index 0000000..d24fa9b
--- /dev/null
@@ -0,0 +1,143 @@
+/*
+ * relocate_kernel.S - put the kernel image in place to boot
+ * Copyright (C) 2002-2005 Eric Biederman  <ebiederm@xmission.com>
+ *
+ * This source code is licensed under the GNU General Public License,
+ * Version 2.  See the file COPYING for more details.
+ */
+
+#include <linux/linkage.h>
+
+       /*
+        * Must be relocatable PIC code callable as a C function, that once
+        * it starts can not use the previous processes stack.
+        */
+       .globl relocate_new_kernel
+       .code64
+relocate_new_kernel:
+       /* %rdi page_list
+        * %rsi reboot_code_buffer
+        * %rdx start address
+        * %rcx page_table
+        * %r8  arg5
+        * %r9  arg6
+        */
+
+       /* zero out flags, and disable interrupts */
+       pushq $0
+       popfq
+
+       /* set a new stack at the bottom of our page... */
+       lea   4096(%rsi), %rsp
+
+       /* store the parameters back on the stack */
+       pushq   %rdx /* store the start address */
+
+       /* Set cr0 to a known state:
+        * 31 1 == Paging enabled
+        * 18 0 == Alignment check disabled
+        * 16 0 == Write protect disabled
+        * 3  0 == No task switch
+        * 2  0 == Don't do FP software emulation.
+        * 0  1 == Proctected mode enabled
+        */
+       movq    %cr0, %rax
+       andq    $~((1<<18)|(1<<16)|(1<<3)|(1<<2)), %rax
+       orl     $((1<<31)|(1<<0)), %eax
+       movq    %rax, %cr0
+
+       /* Set cr4 to a known state:
+        * 10 0 == xmm exceptions disabled
+        * 9  0 == xmm registers instructions disabled
+        * 8  0 == performance monitoring counter disabled
+        * 7  0 == page global disabled
+        * 6  0 == machine check exceptions disabled
+        * 5  1 == physical address extension enabled
+        * 4  0 == page size extensions disabled
+        * 3  0 == Debug extensions disabled
+        * 2  0 == Time stamp disable (disabled)
+        * 1  0 == Protected mode virtual interrupts disabled
+        * 0  0 == VME disabled
+        */
+
+       movq    $((1<<5)), %rax
+       movq    %rax, %cr4
+
+       jmp 1f
+1:
+
+       /* Switch to the identity mapped page tables,
+        * and flush the TLB.
+       */
+       movq    %rcx, %cr3
+
+       /* Do the copies */
+       movq    %rdi, %rcx      /* Put the page_list in %rcx */
+       xorq    %rdi, %rdi
+       xorq    %rsi, %rsi
+       jmp     1f
+
+0:     /* top, read another word for the indirection page */
+
+       movq    (%rbx), %rcx
+       addq    $8,     %rbx
+1:
+       testq   $0x1,   %rcx  /* is it a destination page? */
+       jz      2f
+       movq    %rcx,   %rdi
+       andq    $0xfffffffffffff000, %rdi
+       jmp     0b
+2:
+       testq   $0x2,   %rcx  /* is it an indirection page? */
+       jz      2f
+       movq    %rcx,   %rbx
+       andq    $0xfffffffffffff000, %rbx
+       jmp     0b
+2:
+       testq   $0x4,   %rcx  /* is it the done indicator? */
+       jz      2f
+       jmp     3f
+2:
+       testq   $0x8,   %rcx  /* is it the source indicator? */
+       jz      0b            /* Ignore it otherwise */
+       movq    %rcx,   %rsi  /* For ever source page do a copy */
+       andq    $0xfffffffffffff000, %rsi
+
+       movq    $512,   %rcx
+       rep ; movsq
+       jmp     0b
+3:
+
+       /* To be certain of avoiding problems with self-modifying code
+        * I need to execute a serializing instruction here.
+        * So I flush the TLB by reloading %cr3 here, it's handy,
+        * and not processor dependent.
+        */
+       movq    %cr3, %rax
+       movq    %rax, %cr3
+
+       /* set all of the registers to known values */
+       /* leave %rsp alone */
+
+       xorq    %rax, %rax
+       xorq    %rbx, %rbx
+       xorq    %rcx, %rcx
+       xorq    %rdx, %rdx
+       xorq    %rsi, %rsi
+       xorq    %rdi, %rdi
+       xorq    %rbp, %rbp
+       xorq    %r8,  %r8
+       xorq    %r9,  %r9
+       xorq    %r10, %r9
+       xorq    %r11, %r11
+       xorq    %r12, %r12
+       xorq    %r13, %r13
+       xorq    %r14, %r14
+       xorq    %r15, %r15
+
+       ret
+relocate_new_kernel_end:
+
+       .globl relocate_new_kernel_size
+relocate_new_kernel_size:
+       .quad relocate_new_kernel_end - relocate_new_kernel
index 000015dd5a8be5770bb3d845cda66b716d6fe5a8..b02d921da4f72267cf9e7fb534fccf5a33001456 100644 (file)
@@ -41,6 +41,7 @@
 #include <linux/kallsyms.h>
 #include <linux/edd.h>
 #include <linux/mmzone.h>
+#include <linux/kexec.h>
 
 #include <asm/mtrr.h>
 #include <asm/uaccess.h>
@@ -367,6 +368,27 @@ static __init void parse_cmdline_early (char ** cmdline_p)
                if (!memcmp(from, "noexec=", 7))
                        nonx_setup(from + 7);
 
+#ifdef CONFIG_KEXEC
+               /* crashkernel=size@addr specifies the location to reserve for
+                * a crash kernel.  By reserving this memory we guarantee
+                * that linux never set's it up as a DMA target.
+                * Useful for holding code to do something appropriate
+                * after a kernel panic.
+                */
+               else if (!memcmp(from, "crashkernel=", 12)) {
+                       unsigned long size, base;
+                       size = memparse(from+12, &from);
+                       if (*from == '@') {
+                               base = memparse(from+1, &from);
+                               /* FIXME: Do I want a sanity check
+                                * to validate the memory range?
+                                */
+                               crashk_res.start = base;
+                               crashk_res.end   = base + size - 1;
+                       }
+               }
+#endif
+
        next_char:
                c = *(from++);
                if (!c)
@@ -625,6 +647,13 @@ void __init setup_arch(char **cmdline_p)
 #endif
 
        sparse_init();
+
+#ifdef CONFIG_KEXEC
+       if (crashk_res.start != crashk_res.end) {
+               reserve_bootmem(crashk_res.start,
+                       crashk_res.end - crashk_res.start + 1);
+       }
+#endif
        paging_init();
 
        check_ioapic();
@@ -676,7 +705,7 @@ void __init setup_arch(char **cmdline_p)
 #endif
 }
 
-static int __init get_model_name(struct cpuinfo_x86 *c)
+static int __cpuinit get_model_name(struct cpuinfo_x86 *c)
 {
        unsigned int *v;
 
@@ -692,7 +721,7 @@ static int __init get_model_name(struct cpuinfo_x86 *c)
 }
 
 
-static void __init display_cacheinfo(struct cpuinfo_x86 *c)
+static void __cpuinit display_cacheinfo(struct cpuinfo_x86 *c)
 {
        unsigned int n, dummy, eax, ebx, ecx, edx;
 
@@ -803,7 +832,7 @@ static int __init init_amd(struct cpuinfo_x86 *c)
        return r;
 }
 
-static void __init detect_ht(struct cpuinfo_x86 *c)
+static void __cpuinit detect_ht(struct cpuinfo_x86 *c)
 {
 #ifdef CONFIG_SMP
        u32     eax, ebx, ecx, edx;
@@ -864,7 +893,7 @@ static void __init detect_ht(struct cpuinfo_x86 *c)
 /*
  * find out the number of processor cores on the die
  */
-static int __init intel_num_cpu_cores(struct cpuinfo_x86 *c)
+static int __cpuinit intel_num_cpu_cores(struct cpuinfo_x86 *c)
 {
        unsigned int eax;
 
@@ -882,7 +911,7 @@ static int __init intel_num_cpu_cores(struct cpuinfo_x86 *c)
                return 1;
 }
 
-static void __init init_intel(struct cpuinfo_x86 *c)
+static void __cpuinit init_intel(struct cpuinfo_x86 *c)
 {
        /* Cache sizes */
        unsigned n;
@@ -902,7 +931,7 @@ static void __init init_intel(struct cpuinfo_x86 *c)
        c->x86_num_cores = intel_num_cpu_cores(c);
 }
 
-void __init get_cpu_vendor(struct cpuinfo_x86 *c)
+void __cpuinit get_cpu_vendor(struct cpuinfo_x86 *c)
 {
        char *v = c->x86_vendor_id;
 
@@ -923,7 +952,7 @@ struct cpu_model_info {
 /* Do some early cpuid on the boot CPU to get some parameter that are
    needed before check_bugs. Everything advanced is in identify_cpu
    below. */
-void __init early_identify_cpu(struct cpuinfo_x86 *c)
+void __cpuinit early_identify_cpu(struct cpuinfo_x86 *c)
 {
        u32 tfms;
 
@@ -977,7 +1006,7 @@ void __init early_identify_cpu(struct cpuinfo_x86 *c)
 /*
  * This does the hard work of actually picking apart the CPU stuff...
  */
-void __init identify_cpu(struct cpuinfo_x86 *c)
+void __cpuinit identify_cpu(struct cpuinfo_x86 *c)
 {
        int i;
        u32 xlvl;
@@ -1054,7 +1083,7 @@ void __init identify_cpu(struct cpuinfo_x86 *c)
 }
  
 
-void __init print_cpu_info(struct cpuinfo_x86 *c)
+void __cpuinit print_cpu_info(struct cpuinfo_x86 *c)
 {
        if (c->x86_model_id[0])
                printk("%s", c->x86_model_id);
index 678b7ac33b8b3cbf6a824750fc42b982dc50e79f..f2b9c6bc999a09753d75bd6e07390913f88e8702 100644 (file)
@@ -29,7 +29,7 @@
 
 char x86_boot_params[BOOT_PARAM_SIZE] __initdata = {0,};
 
-cpumask_t cpu_initialized __initdata = CPU_MASK_NONE;
+cpumask_t cpu_initialized __cpuinitdata = CPU_MASK_NONE;
 
 struct x8664_pda cpu_pda[NR_CPUS] __cacheline_aligned; 
 
@@ -171,7 +171,7 @@ void syscall_init(void)
        wrmsrl(MSR_SYSCALL_MASK, EF_TF|EF_DF|EF_IE|0x3000); 
 }
 
-void __init check_efer(void)
+void __cpuinit check_efer(void)
 {
        unsigned long efer;
 
@@ -188,7 +188,7 @@ void __init check_efer(void)
  * 'CPU state barrier', nothing should get across.
  * A lot of state is already set up in PDA init.
  */
-void __init cpu_init (void)
+void __cpuinit cpu_init (void)
 {
 #ifdef CONFIG_SMP
        int cpu = stack_smp_processor_id();
index 98b7ba95d581519edb84a263d5f18f8cca8e12df..98590a989f3d759311935f6142191761bd42c376 100644 (file)
@@ -425,7 +425,7 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset)
        if (!user_mode(regs))
                return 1;
 
-       if (try_to_freeze(0))
+       if (try_to_freeze())
                goto no_signal;
 
        if (!oldset)
index 1e379ed17b1d7549a3bf48f8c772d4751e516baa..ccae392886af214cdb5c54f8dc261798ac0fe0b2 100644 (file)
@@ -283,6 +283,16 @@ struct call_data_struct {
 
 static struct call_data_struct * call_data;
 
+void lock_ipi_call_lock(void)
+{
+       spin_lock_irq(&call_lock);
+}
+
+void unlock_ipi_call_lock(void)
+{
+       spin_unlock_irq(&call_lock);
+}
+
 /*
  * this function sends a 'generic call function' IPI to all other CPUs
  * in the system.
index f1ec0f34594124f73feb76dcf0f270dc420dfca5..b969ee12872847024e7e32ef96776485a99f501f 100644 (file)
@@ -34,6 +34,7 @@
  *      Andi Kleen              :       Converted to new state machine.
  *                                     Various cleanups.
  *                                     Probably mostly hotplug CPU ready now.
+ *     Ashok Raj                       : CPU hotplug support
  */
 
 
 #include <asm/proto.h>
 #include <asm/nmi.h>
 
-/* Change for real CPU hotplug. Note other files need to be fixed
-   first too. */
-#define __cpuinit __init
-#define __cpuinitdata __initdata
-
 /* Number of siblings per CPU package */
 int smp_num_siblings = 1;
 /* Package ID of each logical CPU */
@@ -103,6 +99,37 @@ EXPORT_SYMBOL(cpu_core_map);
 extern unsigned char trampoline_data[];
 extern unsigned char trampoline_end[];
 
+/* State of each CPU */
+DEFINE_PER_CPU(int, cpu_state) = { 0 };
+
+/*
+ * Store all idle threads, this can be reused instead of creating
+ * a new thread. Also avoids complicated thread destroy functionality
+ * for idle threads.
+ */
+struct task_struct *idle_thread_array[NR_CPUS] __cpuinitdata ;
+
+#define get_idle_for_cpu(x)     (idle_thread_array[(x)])
+#define set_idle_for_cpu(x,p)   (idle_thread_array[(x)] = (p))
+
+/*
+ * cpu_possible_map should be static, it cannot change as cpu's
+ * are onlined, or offlined. The reason is per-cpu data-structures
+ * are allocated by some modules at init time, and dont expect to
+ * do this dynamically on cpu arrival/departure.
+ * cpu_present_map on the other hand can change dynamically.
+ * In case when cpu_hotplug is not compiled, then we resort to current
+ * behaviour, which is cpu_possible == cpu_present.
+ * If cpu-hotplug is supported, then we need to preallocate for all
+ * those NR_CPUS, hence cpu_possible_map represents entire NR_CPUS range.
+ * - Ashok Raj
+ */
+#ifdef CONFIG_HOTPLUG_CPU
+#define fixup_cpu_possible_map(x)      cpu_set((x), cpu_possible_map)
+#else
+#define fixup_cpu_possible_map(x)
+#endif
+
 /*
  * Currently trivial. Write the real->protected mode
  * bootstrap into the page concerned. The caller
@@ -418,6 +445,33 @@ void __cpuinit smp_callin(void)
        cpu_set(cpuid, cpu_callin_map);
 }
 
+static inline void set_cpu_sibling_map(int cpu)
+{
+       int i;
+
+       if (smp_num_siblings > 1) {
+               for_each_cpu(i) {
+                       if (cpu_core_id[cpu] == cpu_core_id[i]) {
+                               cpu_set(i, cpu_sibling_map[cpu]);
+                               cpu_set(cpu, cpu_sibling_map[i]);
+                       }
+               }
+       } else {
+               cpu_set(cpu, cpu_sibling_map[cpu]);
+       }
+
+       if (current_cpu_data.x86_num_cores > 1) {
+               for_each_cpu(i) {
+                       if (phys_proc_id[cpu] == phys_proc_id[i]) {
+                               cpu_set(i, cpu_core_map[cpu]);
+                               cpu_set(cpu, cpu_core_map[i]);
+                       }
+               }
+       } else {
+               cpu_core_map[cpu] = cpu_sibling_map[cpu];
+       }
+}
+
 /*
  * Setup code on secondary processor (after comming out of the trampoline)
  */
@@ -447,10 +501,29 @@ void __cpuinit start_secondary(void)
 
        enable_APIC_timer();
 
+       /*
+        * The sibling maps must be set before turing the online map on for
+        * this cpu
+        */
+       set_cpu_sibling_map(smp_processor_id());
+
+       /*
+        * We need to hold call_lock, so there is no inconsistency
+        * between the time smp_call_function() determines number of
+        * IPI receipients, and the time when the determination is made
+        * for which cpus receive the IPI in genapic_flat.c. Holding this
+        * lock helps us to not include this cpu in a currently in progress
+        * smp_call_function().
+        */
+       lock_ipi_call_lock();
+
        /*
         * Allow the master to continue.
         */
        cpu_set(smp_processor_id(), cpu_online_map);
+       per_cpu(cpu_state, smp_processor_id()) = CPU_ONLINE;
+       unlock_ipi_call_lock();
+
        mb();
 
        /* Wait for TSC sync to not schedule things before.
@@ -628,33 +701,77 @@ static int __cpuinit wakeup_secondary_via_INIT(int phys_apicid, unsigned int sta
        return (send_status | accept_status);
 }
 
+struct create_idle {
+       struct task_struct *idle;
+       struct completion done;
+       int cpu;
+};
+
+void do_fork_idle(void *_c_idle)
+{
+       struct create_idle *c_idle = _c_idle;
+
+       c_idle->idle = fork_idle(c_idle->cpu);
+       complete(&c_idle->done);
+}
+
 /*
  * Boot one CPU.
  */
 static int __cpuinit do_boot_cpu(int cpu, int apicid)
 {
-       struct task_struct *idle;
        unsigned long boot_error;
        int timeout;
        unsigned long start_rip;
+       struct create_idle c_idle = {
+               .cpu = cpu,
+               .done = COMPLETION_INITIALIZER(c_idle.done),
+       };
+       DECLARE_WORK(work, do_fork_idle, &c_idle);
+
+       c_idle.idle = get_idle_for_cpu(cpu);
+
+       if (c_idle.idle) {
+               c_idle.idle->thread.rsp = (unsigned long) (((struct pt_regs *)
+                       (THREAD_SIZE + (unsigned long) c_idle.idle->thread_info)) - 1);
+               init_idle(c_idle.idle, cpu);
+               goto do_rest;
+       }
+
        /*
-        * We can't use kernel_thread since we must avoid to
-        * reschedule the child.
+        * During cold boot process, keventd thread is not spun up yet.
+        * When we do cpu hot-add, we create idle threads on the fly, we should
+        * not acquire any attributes from the calling context. Hence the clean
+        * way to create kernel_threads() is to do that from keventd().
+        * We do the current_is_keventd() due to the fact that ACPI notifier
+        * was also queuing to keventd() and when the caller is already running
+        * in context of keventd(), we would end up with locking up the keventd
+        * thread.
         */
-       idle = fork_idle(cpu);
-       if (IS_ERR(idle)) {
+       if (!keventd_up() || current_is_keventd())
+               work.func(work.data);
+       else {
+               schedule_work(&work);
+               wait_for_completion(&c_idle.done);
+       }
+
+       if (IS_ERR(c_idle.idle)) {
                printk("failed fork for CPU %d\n", cpu);
-               return PTR_ERR(idle);
+               return PTR_ERR(c_idle.idle);
        }
 
-       cpu_pda[cpu].pcurrent = idle;
+       set_idle_for_cpu(cpu, c_idle.idle);
+
+do_rest:
+
+       cpu_pda[cpu].pcurrent = c_idle.idle;
 
        start_rip = setup_trampoline();
 
-       init_rsp = idle->thread.rsp;
+       init_rsp = c_idle.idle->thread.rsp;
        per_cpu(init_tss,cpu).rsp0 = init_rsp;
        initial_code = start_secondary;
-       clear_ti_thread_flag(idle->thread_info, TIF_FORK);
+       clear_ti_thread_flag(c_idle.idle->thread_info, TIF_FORK);
 
        printk(KERN_INFO "Booting processor %d/%d rip %lx rsp %lx\n", cpu, apicid,
               start_rip, init_rsp);
@@ -745,51 +862,6 @@ static int __cpuinit do_boot_cpu(int cpu, int apicid)
 cycles_t cacheflush_time;
 unsigned long cache_decay_ticks;
 
-/*
- * Construct cpu_sibling_map[], so that we can tell the sibling CPU
- * on SMT systems efficiently.
- */
-static __cpuinit void detect_siblings(void)
-{
-       int cpu;
-
-       for (cpu = 0; cpu < NR_CPUS; cpu++) {
-               cpus_clear(cpu_sibling_map[cpu]);
-               cpus_clear(cpu_core_map[cpu]);
-       }
-
-       for_each_online_cpu (cpu) {
-               struct cpuinfo_x86 *c = cpu_data + cpu;
-               int siblings = 0;
-               int i;
-               if (smp_num_siblings > 1) {
-                       for_each_online_cpu (i) {
-                               if (cpu_core_id[cpu] == cpu_core_id[i]) {
-                                       siblings++;
-                                       cpu_set(i, cpu_sibling_map[cpu]);
-                               }
-                       }
-               } else {
-                       siblings++;
-                       cpu_set(cpu, cpu_sibling_map[cpu]);
-               }
-
-               if (siblings != smp_num_siblings) {
-                       printk(KERN_WARNING
-              "WARNING: %d siblings found for CPU%d, should be %d\n",
-                              siblings, cpu, smp_num_siblings);
-                       smp_num_siblings = siblings;
-               }
-               if (c->x86_num_cores > 1) {
-                       for_each_online_cpu(i) {
-                               if (phys_proc_id[cpu] == phys_proc_id[i])
-                                       cpu_set(i, cpu_core_map[cpu]);
-                       }
-               } else
-                       cpu_core_map[cpu] = cpu_sibling_map[cpu];
-       }
-}
-
 /*
  * Cleanup possible dangling ends...
  */
@@ -823,7 +895,7 @@ static __cpuinit void smp_cleanup_boot(void)
  *
  * RED-PEN audit/test this more. I bet there is more state messed up here.
  */
-static __cpuinit void disable_smp(void)
+static __init void disable_smp(void)
 {
        cpu_present_map = cpumask_of_cpu(0);
        cpu_possible_map = cpumask_of_cpu(0);
@@ -838,7 +910,7 @@ static __cpuinit void disable_smp(void)
 /*
  * Handle user cpus=... parameter.
  */
-static __cpuinit void enforce_max_cpus(unsigned max_cpus)
+static __init void enforce_max_cpus(unsigned max_cpus)
 {
        int i, k;
        k = 0;
@@ -855,7 +927,7 @@ static __cpuinit void enforce_max_cpus(unsigned max_cpus)
 /*
  * Various sanity checks.
  */
-static int __cpuinit smp_sanity_check(unsigned max_cpus)
+static int __init smp_sanity_check(unsigned max_cpus)
 {
        if (!physid_isset(hard_smp_processor_id(), phys_cpu_present_map)) {
                printk("weird, boot CPU (#%d) not listed by the BIOS.\n",
@@ -913,7 +985,7 @@ static int __cpuinit smp_sanity_check(unsigned max_cpus)
  * Prepare for SMP bootup.  The MP table or ACPI has been read
  * earlier.  Just do some sanity checking here and enable APIC mode.
  */
-void __cpuinit smp_prepare_cpus(unsigned int max_cpus)
+void __init smp_prepare_cpus(unsigned int max_cpus)
 {
        int i;
 
@@ -930,10 +1002,9 @@ void __cpuinit smp_prepare_cpus(unsigned int max_cpus)
                int apicid = cpu_present_to_apicid(i);
                if (physid_isset(apicid, phys_cpu_present_map)) {
                        cpu_set(i, cpu_present_map);
-                       /* possible map would be different if we supported real
-                          CPU hotplug. */
                        cpu_set(i, cpu_possible_map);
                }
+               fixup_cpu_possible_map(i);
        }
 
        if (smp_sanity_check(max_cpus) < 0) {
@@ -978,13 +1049,13 @@ void __init smp_prepare_boot_cpu(void)
        int me = smp_processor_id();
        cpu_set(me, cpu_online_map);
        cpu_set(me, cpu_callout_map);
+       cpu_set(0, cpu_sibling_map[0]);
+       cpu_set(0, cpu_core_map[0]);
+       per_cpu(cpu_state, me) = CPU_ONLINE;
 }
 
 /*
  * Entry point to boot a CPU.
- *
- * This is all __cpuinit, not __devinit for now because we don't support
- * CPU hotplug (yet).
  */
 int __cpuinit __cpu_up(unsigned int cpu)
 {
@@ -1001,6 +1072,15 @@ int __cpuinit __cpu_up(unsigned int cpu)
                return -EINVAL;
        }
 
+       /*
+        * Already booted CPU?
+        */
+       if (cpu_isset(cpu, cpu_callin_map)) {
+               Dprintk("do_boot_cpu %d Already started\n", cpu);
+               return -ENOSYS;
+       }
+
+       per_cpu(cpu_state, cpu) = CPU_UP_PREPARE;
        /* Boot it! */
        err = do_boot_cpu(cpu, apicid);
        if (err < 0) {
@@ -1013,23 +1093,118 @@ int __cpuinit __cpu_up(unsigned int cpu)
 
        while (!cpu_isset(cpu, cpu_online_map))
                cpu_relax();
-       return 0;
+       err = 0;
+
+       return err;
 }
 
 /*
  * Finish the SMP boot.
  */
-void __cpuinit smp_cpus_done(unsigned int max_cpus)
+void __init smp_cpus_done(unsigned int max_cpus)
 {
+#ifndef CONFIG_HOTPLUG_CPU
        zap_low_mappings();
+#endif
        smp_cleanup_boot();
 
 #ifdef CONFIG_X86_IO_APIC
        setup_ioapic_dest();
 #endif
 
-       detect_siblings();
        time_init_gtod();
 
        check_nmi_watchdog();
 }
+
+#ifdef CONFIG_HOTPLUG_CPU
+
+static void remove_siblinginfo(int cpu)
+{
+       int sibling;
+
+       for_each_cpu_mask(sibling, cpu_sibling_map[cpu])
+               cpu_clear(cpu, cpu_sibling_map[sibling]);
+       for_each_cpu_mask(sibling, cpu_core_map[cpu])
+               cpu_clear(cpu, cpu_core_map[sibling]);
+       cpus_clear(cpu_sibling_map[cpu]);
+       cpus_clear(cpu_core_map[cpu]);
+       phys_proc_id[cpu] = BAD_APICID;
+       cpu_core_id[cpu] = BAD_APICID;
+}
+
+void remove_cpu_from_maps(void)
+{
+       int cpu = smp_processor_id();
+
+       cpu_clear(cpu, cpu_callout_map);
+       cpu_clear(cpu, cpu_callin_map);
+       clear_bit(cpu, &cpu_initialized); /* was set by cpu_init() */
+}
+
+int __cpu_disable(void)
+{
+       int cpu = smp_processor_id();
+
+       /*
+        * Perhaps use cpufreq to drop frequency, but that could go
+        * into generic code.
+        *
+        * We won't take down the boot processor on i386 due to some
+        * interrupts only being able to be serviced by the BSP.
+        * Especially so if we're not using an IOAPIC   -zwane
+        */
+       if (cpu == 0)
+               return -EBUSY;
+
+       disable_APIC_timer();
+
+       /*
+        * HACK:
+        * Allow any queued timer interrupts to get serviced
+        * This is only a temporary solution until we cleanup
+        * fixup_irqs as we do for IA64.
+        */
+       local_irq_enable();
+       mdelay(1);
+
+       local_irq_disable();
+       remove_siblinginfo(cpu);
+
+       /* It's now safe to remove this processor from the online map */
+       cpu_clear(cpu, cpu_online_map);
+       remove_cpu_from_maps();
+       fixup_irqs(cpu_online_map);
+       return 0;
+}
+
+void __cpu_die(unsigned int cpu)
+{
+       /* We don't do anything here: idle task is faking death itself. */
+       unsigned int i;
+
+       for (i = 0; i < 10; i++) {
+               /* They ack this in play_dead by setting CPU_DEAD */
+               if (per_cpu(cpu_state, cpu) == CPU_DEAD) {
+                       printk ("CPU %d is now offline\n", cpu);
+                       return;
+               }
+               current->state = TASK_UNINTERRUPTIBLE;
+               schedule_timeout(HZ/10);
+       }
+       printk(KERN_ERR "CPU %u didn't die...\n", cpu);
+}
+
+#else /* ... !CONFIG_HOTPLUG_CPU */
+
+int __cpu_disable(void)
+{
+       return -ENOSYS;
+}
+
+void __cpu_die(unsigned int cpu)
+{
+       /* We said "no" in __cpu_disable */
+       BUG();
+}
+#endif /* CONFIG_HOTPLUG_CPU */
index ebaa1e37d6579b7e0912e093fc1daa4fc186646d..6c0f402e3a889c9b7234a6ed8de80b259bd12a38 100644 (file)
@@ -44,7 +44,6 @@ void __save_processor_state(struct saved_context *ctxt)
         */
        asm volatile ("sgdt %0" : "=m" (ctxt->gdt_limit));
        asm volatile ("sidt %0" : "=m" (ctxt->idt_limit));
-       asm volatile ("sldt %0" : "=m" (ctxt->ldt));
        asm volatile ("str %0"  : "=m" (ctxt->tr));
 
        /* XMM0..XMM15 should be handled by kernel_fpu_begin(). */
@@ -69,6 +68,7 @@ void __save_processor_state(struct saved_context *ctxt)
        asm volatile ("movq %%cr2, %0" : "=r" (ctxt->cr2));
        asm volatile ("movq %%cr3, %0" : "=r" (ctxt->cr3));
        asm volatile ("movq %%cr4, %0" : "=r" (ctxt->cr4));
+       asm volatile ("movq %%cr8, %0" : "=r" (ctxt->cr8));
 }
 
 void save_processor_state(void)
@@ -90,11 +90,19 @@ void __restore_processor_state(struct saved_context *ctxt)
        /*
         * control registers
         */
+       asm volatile ("movq %0, %%cr8" :: "r" (ctxt->cr8));
        asm volatile ("movq %0, %%cr4" :: "r" (ctxt->cr4));
        asm volatile ("movq %0, %%cr3" :: "r" (ctxt->cr3));
        asm volatile ("movq %0, %%cr2" :: "r" (ctxt->cr2));
        asm volatile ("movq %0, %%cr0" :: "r" (ctxt->cr0));
 
+       /*
+        * now restore the descriptor tables to their proper values
+        * ltr is done i fix_processor_context().
+        */
+       asm volatile ("lgdt %0" :: "m" (ctxt->gdt_limit));
+       asm volatile ("lidt %0" :: "m" (ctxt->idt_limit));
+
        /*
         * segment registers
         */
@@ -108,14 +116,6 @@ void __restore_processor_state(struct saved_context *ctxt)
        wrmsrl(MSR_GS_BASE, ctxt->gs_base);
        wrmsrl(MSR_KERNEL_GS_BASE, ctxt->gs_kernel_base);
 
-       /*
-        * now restore the descriptor tables to their proper values
-        * ltr is done i fix_processor_context().
-        */
-       asm volatile ("lgdt %0" :: "m" (ctxt->gdt_limit));
-       asm volatile ("lidt %0" :: "m" (ctxt->idt_limit));
-       asm volatile ("lldt %0" :: "m" (ctxt->ldt));
-
        fix_processor_context();
 
        do_fpu_end();
index 121646fc43f62e399cc39a87d397e6ae4948b944..1027366300022f8846f9bd9a573d0c528f4261e0 100644 (file)
@@ -586,11 +586,17 @@ static void unknown_nmi_error(unsigned char reason, struct pt_regs * regs)
 asmlinkage void default_do_nmi(struct pt_regs *regs)
 {
        unsigned char reason = 0;
+       int cpu;
+
+       cpu = smp_processor_id();
 
        /* Only the BSP gets external NMIs from the system.  */
-       if (!smp_processor_id())
+       if (!cpu)
                reason = get_nmi_reason();
 
+       if (!cpu_online(cpu))
+               return;
+
        if (!(reason & 0xc0)) {
                if (notify_die(DIE_NMI_IPI, "nmi_ipi", regs, reason, 0, SIGINT)
                                                                == NOTIFY_STOP)
index 59ebd5beda8743b6937ca6897d987a9d2ad78b02..73389f51c4e5b2d841619e22e3e27af9ddbbdf24 100644 (file)
@@ -2,7 +2,10 @@
  * Written by Martin Mares <mj@atrey.karlin.mff.cuni.cz>;
  */
 
+#define LOAD_OFFSET __START_KERNEL_map
+
 #include <asm-generic/vmlinux.lds.h>
+#include <asm/page.h>
 #include <linux/config.h>
 
 OUTPUT_FORMAT("elf64-x86-64", "elf64-x86-64", "elf64-x86-64")
@@ -11,28 +14,30 @@ ENTRY(phys_startup_64)
 jiffies_64 = jiffies;
 SECTIONS
 {
-  . = 0xffffffff80100000;
+  . = __START_KERNEL;
   phys_startup_64 = startup_64 - LOAD_OFFSET;
   _text = .;                   /* Text and read-only data */
-  .text : {
+  .text :  AT(ADDR(.text) - LOAD_OFFSET) {
        *(.text)
        SCHED_TEXT
        LOCK_TEXT
        *(.fixup)
        *(.gnu.warning)
        } = 0x9090
-  .text.lock : { *(.text.lock) }       /* out-of-line lock text */
+                               /* out-of-line lock text */
+  .text.lock : AT(ADDR(.text.lock) - LOAD_OFFSET) { *(.text.lock) }
 
   _etext = .;                  /* End of text section */
 
   . = ALIGN(16);               /* Exception table */
   __start___ex_table = .;
-  __ex_table : { *(__ex_table) }
+  __ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) { *(__ex_table) }
   __stop___ex_table = .;
 
   RODATA
 
-  .data : {                    /* Data */
+                               /* Data */
+  .data : AT(ADDR(.data) - LOAD_OFFSET) {
        *(.data)
        CONSTRUCTORS
        }
@@ -40,62 +45,95 @@ SECTIONS
   _edata = .;                  /* End of data section */
 
   __bss_start = .;             /* BSS */
-  .bss : {
+  .bss : AT(ADDR(.bss) - LOAD_OFFSET) {
        *(.bss.page_aligned)    
        *(.bss)
        }
   __bss_end = .;
 
+  . = ALIGN(PAGE_SIZE);
   . = ALIGN(CONFIG_X86_L1_CACHE_BYTES);
-  .data.cacheline_aligned : { *(.data.cacheline_aligned) }
+  .data.cacheline_aligned : AT(ADDR(.data.cacheline_aligned) - LOAD_OFFSET) {
+       *(.data.cacheline_aligned)
+  }
+
+#define VSYSCALL_ADDR (-10*1024*1024)
+#define VSYSCALL_PHYS_ADDR ((LOADADDR(.data.cacheline_aligned) + SIZEOF(.data.cacheline_aligned) + 4095) & ~(4095))
+#define VSYSCALL_VIRT_ADDR ((ADDR(.data.cacheline_aligned) + SIZEOF(.data.cacheline_aligned) + 4095) & ~(4095))
+
+#define VLOAD_OFFSET (VSYSCALL_ADDR - VSYSCALL_PHYS_ADDR)
+#define VLOAD(x) (ADDR(x) - VLOAD_OFFSET)
+
+#define VVIRT_OFFSET (VSYSCALL_ADDR - VSYSCALL_VIRT_ADDR)
+#define VVIRT(x) (ADDR(x) - VVIRT_OFFSET)
 
-#define AFTER(x)      BINALIGN(LOADADDR(x) + SIZEOF(x), 16)
-#define BINALIGN(x,y) (((x) + (y) - 1)  & ~((y) - 1))
-#define CACHE_ALIGN(x) BINALIGN(x, CONFIG_X86_L1_CACHE_BYTES)
+  . = VSYSCALL_ADDR;
+  .vsyscall_0 :         AT(VSYSCALL_PHYS_ADDR) { *(.vsyscall_0) }
+  __vsyscall_0 = VSYSCALL_VIRT_ADDR;
 
-  .vsyscall_0 -10*1024*1024: AT ((LOADADDR(.data.cacheline_aligned) + SIZEOF(.data.cacheline_aligned) + 4095) & ~(4095)) { *(.vsyscall_0) }
-  __vsyscall_0 = LOADADDR(.vsyscall_0);
   . = ALIGN(CONFIG_X86_L1_CACHE_BYTES);
-  .xtime_lock : AT CACHE_ALIGN(AFTER(.vsyscall_0)) { *(.xtime_lock) }
-  xtime_lock = LOADADDR(.xtime_lock);
-  .vxtime : AT AFTER(.xtime_lock) { *(.vxtime) }
-  vxtime = LOADADDR(.vxtime);
-  .wall_jiffies : AT AFTER(.vxtime) { *(.wall_jiffies) }
-  wall_jiffies = LOADADDR(.wall_jiffies);
-  .sys_tz : AT AFTER(.wall_jiffies) { *(.sys_tz) }
-  sys_tz = LOADADDR(.sys_tz);
-  .sysctl_vsyscall : AT AFTER(.sys_tz) { *(.sysctl_vsyscall) }
-  sysctl_vsyscall = LOADADDR(.sysctl_vsyscall); 
-  .xtime : AT AFTER(.sysctl_vsyscall) { *(.xtime) }
-  xtime = LOADADDR(.xtime);
+  .xtime_lock : AT(VLOAD(.xtime_lock)) { *(.xtime_lock) }
+  xtime_lock = VVIRT(.xtime_lock);
+
+  .vxtime : AT(VLOAD(.vxtime)) { *(.vxtime) }
+  vxtime = VVIRT(.vxtime);
+
+  .wall_jiffies : AT(VLOAD(.wall_jiffies)) { *(.wall_jiffies) }
+  wall_jiffies = VVIRT(.wall_jiffies);
+
+  .sys_tz : AT(VLOAD(.sys_tz)) { *(.sys_tz) }
+  sys_tz = VVIRT(.sys_tz);
+
+  .sysctl_vsyscall : AT(VLOAD(.sysctl_vsyscall)) { *(.sysctl_vsyscall) }
+  sysctl_vsyscall = VVIRT(.sysctl_vsyscall);
+
+  .xtime : AT(VLOAD(.xtime)) { *(.xtime) }
+  xtime = VVIRT(.xtime);
+
   . = ALIGN(CONFIG_X86_L1_CACHE_BYTES);
-  .jiffies : AT CACHE_ALIGN(AFTER(.xtime)) { *(.jiffies) }
-  jiffies = LOADADDR(.jiffies);
-  .vsyscall_1 ADDR(.vsyscall_0) + 1024: AT (LOADADDR(.vsyscall_0) + 1024) { *(.vsyscall_1) }
-  . = LOADADDR(.vsyscall_0) + 4096;
+  .jiffies : AT(VLOAD(.jiffies)) { *(.jiffies) }
+  jiffies = VVIRT(.jiffies);
+
+  .vsyscall_1 ADDR(.vsyscall_0) + 1024: AT(VLOAD(.vsyscall_1)) { *(.vsyscall_1) }
+  .vsyscall_2 ADDR(.vsyscall_0) + 2048: AT(VLOAD(.vsyscall_2)) { *(.vsyscall_2) }
+  .vsyscall_3 ADDR(.vsyscall_0) + 3072: AT(VLOAD(.vsyscall_3)) { *(.vsyscall_3) }
+
+  . = VSYSCALL_VIRT_ADDR + 4096;
+
+#undef VSYSCALL_ADDR
+#undef VSYSCALL_PHYS_ADDR
+#undef VSYSCALL_VIRT_ADDR
+#undef VLOAD_OFFSET
+#undef VLOAD
+#undef VVIRT_OFFSET
+#undef VVIRT
 
   . = ALIGN(8192);             /* init_task */
-  .data.init_task : { *(.data.init_task) }
+  .data.init_task : AT(ADDR(.data.init_task) - LOAD_OFFSET) {
+       *(.data.init_task)
+  }
 
   . = ALIGN(4096);
-  .data.page_aligned : { *(.data.page_aligned) }
+  .data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET) {
+       *(.data.page_aligned)
+  }
 
   . = ALIGN(4096);             /* Init code and data */
   __init_begin = .;
-  .init.text : 
+  .init.text : AT(ADDR(.init.text) - LOAD_OFFSET) {
        _sinittext = .;
        *(.init.text)
        _einittext = .;
   }
   __initdata_begin = .;
-  .init.data : { *(.init.data) }
+  .init.data : AT(ADDR(.init.data) - LOAD_OFFSET) { *(.init.data) }
   __initdata_end = .;
   . = ALIGN(16);
   __setup_start = .;
-  .init.setup : { *(.init.setup) }
+  .init.setup : AT(ADDR(.init.setup) - LOAD_OFFSET) { *(.init.setup) }
   __setup_end = .;
   __initcall_start = .;
-  .initcall.init : {
+  .initcall.init : AT(ADDR(.initcall.init) - LOAD_OFFSET) {
        *(.initcall1.init) 
        *(.initcall2.init) 
        *(.initcall3.init) 
@@ -106,32 +144,38 @@ SECTIONS
   }
   __initcall_end = .;
   __con_initcall_start = .;
-  .con_initcall.init : { *(.con_initcall.init) }
+  .con_initcall.init : AT(ADDR(.con_initcall.init) - LOAD_OFFSET) {
+       *(.con_initcall.init)
+  }
   __con_initcall_end = .;
   SECURITY_INIT
   . = ALIGN(8);
   __alt_instructions = .;
-  .altinstructions : { *(.altinstructions) } 
+  .altinstructions : AT(ADDR(.altinstructions) - LOAD_OFFSET) {
+       *(.altinstructions)
+  }
   __alt_instructions_end = .; 
- .altinstr_replacement : { *(.altinstr_replacement) }
+  .altinstr_replacement : AT(ADDR(.altinstr_replacement) - LOAD_OFFSET) {
+       *(.altinstr_replacement)
+  }
   /* .exit.text is discard at runtime, not link time, to deal with references
      from .altinstructions and .eh_frame */
-  .exit.text : { *(.exit.text) }
-  .exit.data : { *(.exit.data) }       
+  .exit.text : AT(ADDR(.exit.text) - LOAD_OFFSET) { *(.exit.text) }
+  .exit.data : AT(ADDR(.exit.data) - LOAD_OFFSET) { *(.exit.data) }
   . = ALIGN(4096);
   __initramfs_start = .;
-  .init.ramfs : { *(.init.ramfs) }
+  .init.ramfs : AT(ADDR(.init.ramfs) - LOAD_OFFSET) { *(.init.ramfs) }
   __initramfs_end = .; 
   . = ALIGN(32);
   __per_cpu_start = .;
-  .data.percpu  : { *(.data.percpu) }
+  .data.percpu  : AT(ADDR(.data.percpu) - LOAD_OFFSET) { *(.data.percpu) }
   __per_cpu_end = .;
   . = ALIGN(4096);
   __init_end = .;
 
   . = ALIGN(4096);
   __nosave_begin = .;
-  .data_nosave : { *(.data.nosave) }
+  .data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) { *(.data.nosave) }
   . = ALIGN(4096);
   __nosave_end = .;
 
index 84cde796ecb133ebfaf145262323d7ab20379482..ac61c186eb0218862f59e8638bef6ef918e11064 100644 (file)
@@ -251,7 +251,7 @@ void __init numa_initmem_init(unsigned long start_pfn, unsigned long end_pfn)
        setup_node_bootmem(0, start_pfn << PAGE_SHIFT, end_pfn << PAGE_SHIFT);
 }
 
-__init void numa_add_cpu(int cpu)
+__cpuinit void numa_add_cpu(int cpu)
 {
        /* BP is initialized elsewhere */
        if (cpu) 
index 9e2b53f6a90740dde96fb39cda854705715414cd..4fbddf92a921e9d0c32b33e259c5a5f1026c72a2 100644 (file)
@@ -198,9 +198,6 @@ static int rs_read_proc(char *page, char **start, off_t off, int count,
 }
 
 
-int register_serial(struct serial_struct*);
-void unregister_serial(int);
-
 static struct tty_operations serial_ops = {
        .open = rs_open,
        .close = rs_close,
index 670fdb5142d17d3da59717b844560c861bbad8a5..86c52520ed348aa5049823dd2c5a55cfcb40513f 100644 (file)
@@ -55,7 +55,7 @@ if ACPI_INTERPRETER
 
 config ACPI_SLEEP
        bool "Sleep States (EXPERIMENTAL)"
-       depends on X86
+       depends on X86 && (!SMP || SUSPEND_SMP)
        depends on EXPERIMENTAL && PM
        default y
        ---help---
index 8093f2e003215156d376c9a8c086e8d9dfaf9d30..8dbf802ee7f819d9c885247a35d0d736ca4a5979 100644 (file)
@@ -435,6 +435,7 @@ acpi_pci_irq_enable (
                /* Interrupt Line values above 0xF are forbidden */
                if (dev->irq >= 0 && (dev->irq <= 0xF)) {
                        printk(" - using IRQ %d\n", dev->irq);
+                       acpi_register_gsi(dev->irq, ACPI_LEVEL_SENSITIVE, ACPI_ACTIVE_LOW);
                        return_VALUE(0);
                }
                else {
index 6ef3069b57107f2e12c5d2c7f238b77f5dacd97c..b79badd0f1588dea649df9033652f0f5d2afbacf 100644 (file)
@@ -16,6 +16,11 @@ struct sysdev_class cpu_sysdev_class = {
 EXPORT_SYMBOL(cpu_sysdev_class);
 
 #ifdef CONFIG_HOTPLUG_CPU
+int __attribute__((weak)) smp_prepare_cpu (int cpu)
+{
+       return 0;
+}
+
 static ssize_t show_online(struct sys_device *dev, char *buf)
 {
        struct cpu *cpu = container_of(dev, struct cpu, sysdev);
@@ -36,7 +41,11 @@ static ssize_t store_online(struct sys_device *dev, const char *buf,
                        kobject_hotplug(&dev->kobj, KOBJ_OFFLINE);
                break;
        case '1':
-               ret = cpu_up(cpu->sysdev.id);
+               ret = smp_prepare_cpu(cpu->sysdev.id);
+               if (!ret)
+                       ret = cpu_up(cpu->sysdev.id);
+               if (!ret)
+                       kobject_hotplug(&dev->kobj, KOBJ_ONLINE);
                break;
        default:
                ret = -EINVAL;
index fd94ea27d594f39473546477f81486c22cdf17c3..60e64091de1b34df8b5a0cd27c9a952b6b33ac86 100644 (file)
@@ -37,6 +37,7 @@
 
 static void blk_unplug_work(void *data);
 static void blk_unplug_timeout(unsigned long data);
+static void drive_stat_acct(struct request *rq, int nr_sectors, int new_io);
 
 /*
  * For the allocated request tables
@@ -1137,7 +1138,7 @@ new_hw_segment:
 }
 
 
-int blk_phys_contig_segment(request_queue_t *q, struct bio *bio,
+static int blk_phys_contig_segment(request_queue_t *q, struct bio *bio,
                                   struct bio *nxt)
 {
        if (!(q->queue_flags & (1 << QUEUE_FLAG_CLUSTER)))
@@ -1158,9 +1159,7 @@ int blk_phys_contig_segment(request_queue_t *q, struct bio *bio,
        return 0;
 }
 
-EXPORT_SYMBOL(blk_phys_contig_segment);
-
-int blk_hw_contig_segment(request_queue_t *q, struct bio *bio,
+static int blk_hw_contig_segment(request_queue_t *q, struct bio *bio,
                                 struct bio *nxt)
 {
        if (unlikely(!bio_flagged(bio, BIO_SEG_VALID)))
@@ -1176,8 +1175,6 @@ int blk_hw_contig_segment(request_queue_t *q, struct bio *bio,
        return 1;
 }
 
-EXPORT_SYMBOL(blk_hw_contig_segment);
-
 /*
  * map a request to scatterlist, return number of sg entries setup. Caller
  * must make sure sg can hold rq->nr_phys_segments entries
@@ -1347,8 +1344,8 @@ static int ll_front_merge_fn(request_queue_t *q, struct request *req,
 static int ll_merge_requests_fn(request_queue_t *q, struct request *req,
                                struct request *next)
 {
-       int total_phys_segments = req->nr_phys_segments +next->nr_phys_segments;
-       int total_hw_segments = req->nr_hw_segments + next->nr_hw_segments;
+       int total_phys_segments;
+       int total_hw_segments;
 
        /*
         * First check if the either of the requests are re-queued
@@ -1358,7 +1355,7 @@ static int ll_merge_requests_fn(request_queue_t *q, struct request *req,
                return 0;
 
        /*
-        * Will it become to large?
+        * Will it become too large?
         */
        if ((req->nr_sectors + next->nr_sectors) > q->max_sectors)
                return 0;
@@ -1825,7 +1822,7 @@ static inline int ioc_batching(request_queue_t *q, struct io_context *ioc)
  * is the behaviour we want though - once it gets a wakeup it should be given
  * a nice run.
  */
-void ioc_set_batching(request_queue_t *q, struct io_context *ioc)
+static void ioc_set_batching(request_queue_t *q, struct io_context *ioc)
 {
        if (!ioc || ioc_batching(q, ioc))
                return;
@@ -2254,45 +2251,7 @@ int blkdev_issue_flush(struct block_device *bdev, sector_t *error_sector)
 
 EXPORT_SYMBOL(blkdev_issue_flush);
 
-/**
- * blkdev_scsi_issue_flush_fn - issue flush for SCSI devices
- * @q:         device queue
- * @disk:      gendisk
- * @error_sector:      error offset
- *
- * Description:
- *    Devices understanding the SCSI command set, can use this function as
- *    a helper for issuing a cache flush. Note: driver is required to store
- *    the error offset (in case of error flushing) in ->sector of struct
- *    request.
- */
-int blkdev_scsi_issue_flush_fn(request_queue_t *q, struct gendisk *disk,
-                              sector_t *error_sector)
-{
-       struct request *rq = blk_get_request(q, WRITE, __GFP_WAIT);
-       int ret;
-
-       rq->flags |= REQ_BLOCK_PC | REQ_SOFTBARRIER;
-       rq->sector = 0;
-       memset(rq->cmd, 0, sizeof(rq->cmd));
-       rq->cmd[0] = 0x35;
-       rq->cmd_len = 12;
-       rq->data = NULL;
-       rq->data_len = 0;
-       rq->timeout = 60 * HZ;
-
-       ret = blk_execute_rq(q, disk, rq);
-
-       if (ret && error_sector)
-               *error_sector = rq->sector;
-
-       blk_put_request(rq);
-       return ret;
-}
-
-EXPORT_SYMBOL(blkdev_scsi_issue_flush_fn);
-
-void drive_stat_acct(struct request *rq, int nr_sectors, int new_io)
+static void drive_stat_acct(struct request *rq, int nr_sectors, int new_io)
 {
        int rw = rq_data_dir(rq);
 
@@ -2551,16 +2510,6 @@ void blk_attempt_remerge(request_queue_t *q, struct request *rq)
 
 EXPORT_SYMBOL(blk_attempt_remerge);
 
-/*
- * Non-locking blk_attempt_remerge variant.
- */
-void __blk_attempt_remerge(request_queue_t *q, struct request *rq)
-{
-       attempt_back_merge(q, rq);
-}
-
-EXPORT_SYMBOL(__blk_attempt_remerge);
-
 static int __make_request(request_queue_t *q, struct bio *bio)
 {
        struct request *req, *freereq = NULL;
@@ -2971,7 +2920,7 @@ void submit_bio(int rw, struct bio *bio)
 
 EXPORT_SYMBOL(submit_bio);
 
-void blk_recalc_rq_segments(struct request *rq)
+static void blk_recalc_rq_segments(struct request *rq)
 {
        struct bio *bio, *prevbio = NULL;
        int nr_phys_segs, nr_hw_segs;
@@ -3013,7 +2962,7 @@ void blk_recalc_rq_segments(struct request *rq)
        rq->nr_hw_segments = nr_hw_segs;
 }
 
-void blk_recalc_rq_sectors(struct request *rq, int nsect)
+static void blk_recalc_rq_sectors(struct request *rq, int nsect)
 {
        if (blk_fs_request(rq)) {
                rq->hard_sector += nsect;
@@ -3601,7 +3550,7 @@ static struct sysfs_ops queue_sysfs_ops = {
        .store  = queue_attr_store,
 };
 
-struct kobj_type queue_ktype = {
+static struct kobj_type queue_ktype = {
        .sysfs_ops      = &queue_sysfs_ops,
        .default_attrs  = default_attrs,
 };
index 7f3d78de265c389af02d763ba0ddb0ea339404b3..7b838342f0a353939324c228212074b15ea48c76 100644 (file)
@@ -1251,8 +1251,7 @@ static int kcdrwd(void *foobar)
                        VPRINTK("kcdrwd: wake up\n");
 
                        /* make swsusp happy with our thread */
-                       if (current->flags & PF_FREEZE)
-                               refrigerator(PF_FREEZE);
+                       try_to_freeze();
 
                        list_for_each_entry(pkt, &pd->cdrw.pkt_active_list, list) {
                                if (!pkt->sleep_time)
index da80b14335a524d532ef9086d19a7e4ac26e81c3..01f0351733285520f1394d6a86a67b69d8dcab85 100644 (file)
@@ -307,7 +307,7 @@ static DEFINE_SPINLOCK(cm206_lock);
 /* First, we define some polling functions. These are actually
    only being used in the initialization. */
 
-void send_command_polled(int command)
+static void send_command_polled(int command)
 {
        int loop = POLLOOP;
        while (!(inw(r_line_status) & ls_transmitter_buffer_empty)
@@ -318,7 +318,7 @@ void send_command_polled(int command)
        outw(command, r_uart_transmit);
 }
 
-uch receive_echo_polled(void)
+static uch receive_echo_polled(void)
 {
        int loop = POLLOOP;
        while (!(inw(r_line_status) & ls_receive_buffer_full) && loop > 0) {
@@ -328,13 +328,13 @@ uch receive_echo_polled(void)
        return ((uch) inw(r_uart_receive));
 }
 
-uch send_receive_polled(int command)
+static uch send_receive_polled(int command)
 {
        send_command_polled(command);
        return receive_echo_polled();
 }
 
-inline void clear_ur(void)
+static inline void clear_ur(void)
 {
        if (cd->ur_r != cd->ur_w) {
                debug(("Deleting bytes from fifo:"));
@@ -439,7 +439,7 @@ static irqreturn_t cm206_interrupt(int sig, void *dev_id, struct pt_regs *regs)
 }
 
 /* we have put the address of the wait queue in who */
-void cm206_timeout(unsigned long who)
+static void cm206_timeout(unsigned long who)
 {
        cd->timed_out = 1;
        debug(("Timing out\n"));
@@ -448,7 +448,7 @@ void cm206_timeout(unsigned long who)
 
 /* This function returns 1 if a timeout occurred, 0 if an interrupt
    happened */
-int sleep_or_timeout(wait_queue_head_t * wait, int timeout)
+static int sleep_or_timeout(wait_queue_head_t * wait, int timeout)
 {
        cd->timed_out = 0;
        init_timer(&cd->timer);
@@ -465,13 +465,7 @@ int sleep_or_timeout(wait_queue_head_t * wait, int timeout)
                return 0;
 }
 
-void cm206_delay(int nr_jiffies)
-{
-       DECLARE_WAIT_QUEUE_HEAD(wait);
-       sleep_or_timeout(&wait, nr_jiffies);
-}
-
-void send_command(int command)
+static void send_command(int command)
 {
        debug(("Sending 0x%x\n", command));
        if (!(inw(r_line_status) & ls_transmitter_buffer_empty)) {
@@ -490,7 +484,7 @@ void send_command(int command)
                outw(command, r_uart_transmit);
 }
 
-uch receive_byte(int timeout)
+static uch receive_byte(int timeout)
 {
        uch ret;
        cli();
@@ -521,23 +515,23 @@ uch receive_byte(int timeout)
        return ret;
 }
 
-inline uch receive_echo(void)
+static inline uch receive_echo(void)
 {
        return receive_byte(UART_TIMEOUT);
 }
 
-inline uch send_receive(int command)
+static inline uch send_receive(int command)
 {
        send_command(command);
        return receive_echo();
 }
 
-inline uch wait_dsb(void)
+static inline uch wait_dsb(void)
 {
        return receive_byte(DSB_TIMEOUT);
 }
 
-int type_0_command(int command, int expect_dsb)
+static int type_0_command(int command, int expect_dsb)
 {
        int e;
        clear_ur();
@@ -552,7 +546,7 @@ int type_0_command(int command, int expect_dsb)
        return 0;
 }
 
-int type_1_command(int command, int bytes, uch * status)
+static int type_1_command(int command, int bytes, uch * status)
 {                              /* returns info */
        int i;
        if (type_0_command(command, 0))
@@ -564,7 +558,7 @@ int type_1_command(int command, int bytes, uch * status)
 
 /* This function resets the adapter card. We'd better not do this too
  * often, because it tends to generate `lost interrupts.' */
-void reset_cm260(void)
+static void reset_cm260(void)
 {
        outw(dc_normal | dc_initialize | READ_AHEAD, r_data_control);
        udelay(10);             /* 3.3 mu sec minimum */
@@ -572,7 +566,7 @@ void reset_cm260(void)
 }
 
 /* fsm: frame-sec-min from linear address; one of many */
-void fsm(int lba, uch * fsm)
+static void fsm(int lba, uch * fsm)
 {
        fsm[0] = lba % 75;
        lba /= 75;
@@ -581,17 +575,17 @@ void fsm(int lba, uch * fsm)
        fsm[2] = lba / 60;
 }
 
-inline int fsm2lba(uch * fsm)
+static inline int fsm2lba(uch * fsm)
 {
        return fsm[0] + 75 * (fsm[1] - 2 + 60 * fsm[2]);
 }
 
-inline int f_s_m2lba(uch f, uch s, uch m)
+static inline int f_s_m2lba(uch f, uch s, uch m)
 {
        return f + 75 * (s - 2 + 60 * m);
 }
 
-int start_read(int start)
+static int start_read(int start)
 {
        uch read_sector[4] = { c_read_data, };
        int i, e;
@@ -613,7 +607,7 @@ int start_read(int start)
        return 0;
 }
 
-int stop_read(void)
+static int stop_read(void)
 {
        int e;
        type_0_command(c_stop, 0);
@@ -630,7 +624,7 @@ int stop_read(void)
    routine takes care of this. Set a flag `background' in the cd
    struct to indicate the process. */
 
-int read_background(int start, int reading)
+static int read_background(int start, int reading)
 {
        if (cd->background)
                return -1;      /* can't do twice */
@@ -658,7 +652,7 @@ void transport_data(int port, ush * dest, int count)
 
 
 #define MAX_TRIES 100
-int read_sector(int start)
+static int read_sector(int start)
 {
        int tries = 0;
        if (cd->background) {
@@ -753,7 +747,7 @@ static DECLARE_TASKLET(cm206_tasklet, cm206_tasklet_func, 0);
 /* This command clears the dsb_possible_media_change flag, so we must 
  * retain it.
  */
-void get_drive_status(void)
+static void get_drive_status(void)
 {
        uch status[2];
        type_1_command(c_drive_status, 2, status);      /* this might be done faster */
@@ -764,7 +758,7 @@ void get_drive_status(void)
                          dsb_drive_not_ready | dsb_tray_not_closed));
 }
 
-void get_disc_status(void)
+static void get_disc_status(void)
 {
        if (type_1_command(c_disc_status, 7, cd->disc_status)) {
                debug(("get_disc_status: error\n"));
@@ -801,7 +795,7 @@ static void cm206_release(struct cdrom_device_info *cdi)
 
 /* Empty buffer empties $sectors$ sectors of the adapter card buffer,
  * and then reads a sector in kernel memory.  */
-void empty_buffer(int sectors)
+static void empty_buffer(int sectors)
 {
        while (sectors >= 0) {
                transport_data(r_fifo_output_buffer,
@@ -819,7 +813,7 @@ void empty_buffer(int sectors)
 /* try_adapter. This function determines if the requested sector is
    in adapter memory, or will appear there soon. Returns 0 upon
    success */
-int try_adapter(int sector)
+static int try_adapter(int sector)
 {
        if (cd->adapter_first <= sector && sector < cd->adapter_last) {
                /* sector is in adapter memory */
@@ -910,7 +904,7 @@ static void do_cm206_request(request_queue_t * q)
 */
 
 /* seek seeks to address lba. It does wait to arrive there. */
-void seek(int lba)
+static void seek(int lba)
 {
        int i;
        uch seek_command[4] = { c_seek, };
@@ -926,7 +920,7 @@ uch bcdbin(unsigned char bcd)
        return (bcd >> 4) * 10 + (bcd & 0xf);
 }
 
-inline uch normalize_track(uch track)
+static inline uch normalize_track(uch track)
 {
        if (track < 1)
                return 1;
@@ -939,7 +933,7 @@ inline uch normalize_track(uch track)
  * tracks seen in the process. Input $track$ must be between 1 and
  * #-of-tracks+1.  Note that the start of the disc must be in toc[1].fsm. 
  */
-int get_toc_lba(uch track)
+static int get_toc_lba(uch track)
 {
        int max = 74 * 60 * 75 - 150, min = fsm2lba(cd->toc[1].fsm);
        int i, lba, l, old_lba = 0;
@@ -991,7 +985,7 @@ int get_toc_lba(uch track)
        return lba;
 }
 
-void update_toc_entry(uch track)
+static void update_toc_entry(uch track)
 {
        track = normalize_track(track);
        if (!cd->toc[track].track)
@@ -999,7 +993,7 @@ void update_toc_entry(uch track)
 }
 
 /* return 0 upon success */
-int read_toc_header(struct cdrom_tochdr *hp)
+static int read_toc_header(struct cdrom_tochdr *hp)
 {
        if (!FIRST_TRACK)
                get_disc_status();
@@ -1016,7 +1010,7 @@ int read_toc_header(struct cdrom_tochdr *hp)
        return -1;
 }
 
-void play_from_to_msf(struct cdrom_msf *msfp)
+static void play_from_to_msf(struct cdrom_msf *msfp)
 {
        uch play_command[] = { c_play,
                msfp->cdmsf_frame0, msfp->cdmsf_sec0, msfp->cdmsf_min0,
@@ -1032,7 +1026,7 @@ void play_from_to_msf(struct cdrom_msf *msfp)
        cd->dsb = wait_dsb();
 }
 
-void play_from_to_track(int from, int to)
+static void play_from_to_track(int from, int to)
 {
        uch play_command[8] = { c_play, };
        int i;
@@ -1059,7 +1053,7 @@ void play_from_to_track(int from, int to)
        cd->dsb = wait_dsb();
 }
 
-int get_current_q(struct cdrom_subchnl *qp)
+static int get_current_q(struct cdrom_subchnl *qp)
 {
        int i;
        uch *q = cd->q;
@@ -1093,14 +1087,14 @@ int get_current_q(struct cdrom_subchnl *qp)
        return 0;
 }
 
-void invalidate_toc(void)
+static void invalidate_toc(void)
 {
        memset(cd->toc, 0, sizeof(cd->toc));
        memset(cd->disc_status, 0, sizeof(cd->disc_status));
 }
 
 /* cdrom.c guarantees that cdte_format == CDROM_MSF */
-void get_toc_entry(struct cdrom_tocentry *ep)
+static void get_toc_entry(struct cdrom_tocentry *ep)
 {
        uch track = normalize_track(ep->cdte_track);
        update_toc_entry(track);
@@ -1117,8 +1111,8 @@ void get_toc_entry(struct cdrom_tocentry *ep)
  * upon success. Memory checking has been done by cdrom_ioctl(), the
  * calling function, as well as LBA/MSF sanitization.
 */
-int cm206_audio_ioctl(struct cdrom_device_info *cdi, unsigned int cmd,
-                     void *arg)
+static int cm206_audio_ioctl(struct cdrom_device_info *cdi, unsigned int cmd,
+                            void *arg)
 {
        switch (cmd) {
        case CDROMREADTOCHDR:
@@ -1189,7 +1183,7 @@ static int cm206_ioctl(struct cdrom_device_info *cdi, unsigned int cmd,
        }
 }
 
-int cm206_media_changed(struct cdrom_device_info *cdi, int disc_nr)
+static int cm206_media_changed(struct cdrom_device_info *cdi, int disc_nr)
 {
        if (cd != NULL) {
                int r;
@@ -1204,16 +1198,9 @@ int cm206_media_changed(struct cdrom_device_info *cdi, int disc_nr)
 /* The new generic cdrom support. Routines should be concise, most of
    the logic should be in cdrom.c */
 
-/* returns number of times device is in use */
-int cm206_open_files(struct cdrom_device_info *cdi)
-{
-       if (cd)
-               return cd->openfiles;
-       return -1;
-}
 
 /* controls tray movement */
-int cm206_tray_move(struct cdrom_device_info *cdi, int position)
+static int cm206_tray_move(struct cdrom_device_info *cdi, int position)
 {
        if (position) {         /* 1: eject */
                type_0_command(c_open_tray, 1);
@@ -1224,7 +1211,7 @@ int cm206_tray_move(struct cdrom_device_info *cdi, int position)
 }
 
 /* gives current state of the drive */
-int cm206_drive_status(struct cdrom_device_info *cdi, int slot_nr)
+static int cm206_drive_status(struct cdrom_device_info *cdi, int slot_nr)
 {
        get_drive_status();
        if (cd->dsb & dsb_tray_not_closed)
@@ -1237,7 +1224,7 @@ int cm206_drive_status(struct cdrom_device_info *cdi, int slot_nr)
 }
 
 /* locks or unlocks door lock==1: lock; return 0 upon success */
-int cm206_lock_door(struct cdrom_device_info *cdi, int lock)
+static int cm206_lock_door(struct cdrom_device_info *cdi, int lock)
 {
        uch command = (lock) ? c_lock_tray : c_unlock_tray;
        type_0_command(command, 1);     /* wait and get dsb */
@@ -1248,8 +1235,8 @@ int cm206_lock_door(struct cdrom_device_info *cdi, int lock)
 /* Although a session start should be in LBA format, we return it in 
    MSF format because it is slightly easier, and the new generic ioctl
    will take care of the necessary conversion. */
-int cm206_get_last_session(struct cdrom_device_info *cdi,
-                          struct cdrom_multisession *mssp)
+static int cm206_get_last_session(struct cdrom_device_info *cdi,
+                                 struct cdrom_multisession *mssp)
 {
        if (!FIRST_TRACK)
                get_disc_status();
@@ -1268,7 +1255,7 @@ int cm206_get_last_session(struct cdrom_device_info *cdi,
        return 0;
 }
 
-int cm206_get_upc(struct cdrom_device_info *cdi, struct cdrom_mcn *mcn)
+static int cm206_get_upc(struct cdrom_device_info *cdi, struct cdrom_mcn *mcn)
 {
        uch upc[10];
        char *ret = mcn->medium_catalog_number;
@@ -1287,7 +1274,7 @@ int cm206_get_upc(struct cdrom_device_info *cdi, struct cdrom_mcn *mcn)
        return 0;
 }
 
-int cm206_reset(struct cdrom_device_info *cdi)
+static int cm206_reset(struct cdrom_device_info *cdi)
 {
        stop_read();
        reset_cm260();
@@ -1300,7 +1287,7 @@ int cm206_reset(struct cdrom_device_info *cdi)
        return 0;
 }
 
-int cm206_select_speed(struct cdrom_device_info *cdi, int speed)
+static int cm206_select_speed(struct cdrom_device_info *cdi, int speed)
 {
        int r;
        switch (speed) {
@@ -1392,7 +1379,7 @@ static struct gendisk *cm206_gendisk;
    request_region, 15 bits of one port and 6 of another make things
    likely enough to accept the region on the first hit...
  */
-int __init probe_base_port(int base)
+static int __init probe_base_port(int base)
 {
        int b = 0x300, e = 0x370;       /* this is the range of start addresses */
        volatile int fool, i;
@@ -1416,7 +1403,7 @@ int __init probe_base_port(int base)
 
 #if !defined(MODULE) || defined(AUTO_PROBE_MODULE)
 /* Probe for irq# nr. If nr==0, probe for all possible irq's. */
-int __init probe_irq(int nr)
+static int __init probe_irq(int nr)
 {
        int irqs, irq;
        outw(dc_normal | READ_AHEAD, r_data_control);   /* disable irq-generation */
@@ -1558,7 +1545,7 @@ static void __init parse_options(void)
        }
 }
 
-int __cm206_init(void)
+static int __cm206_init(void)
 {
        parse_options();
 #if !defined(AUTO_PROBE_MODULE)
@@ -1567,7 +1554,7 @@ int __cm206_init(void)
        return cm206_init();
 }
 
-void __exit cm206_exit(void)
+static void __exit cm206_exit(void)
 {
        del_gendisk(cm206_gendisk);
        put_disk(cm206_gendisk);
index f4be7bfd6675ee4ef7f2c024404c0ab64abfe5c3..9f22e8f1f6c0182dbbbb9ecd5689d01235f53404 100644 (file)
@@ -1605,8 +1605,7 @@ out7:
        put_disk(cdu_disk);
 out6:
        for (i = 0; i < sony_buffer_sectors; i++)
-               if (sony_buffer[i]) 
-                       kfree(sony_buffer[i]);
+               kfree(sony_buffer[i]);
 out5:
        kfree(sony_buffer);
 out4:
index 7ccf871d3c9dd77178fa9ca46fb3e5def6c33a0e..43d0cb19ef6ad839c391e2ad8aa65a0c425de60d 100644 (file)
@@ -940,8 +940,8 @@ config RAW_DRIVER
          Once bound, I/O against /dev/raw/rawN uses efficient zero-copy I/O. 
          See the raw(8) manpage for more details.
 
-          The raw driver is deprecated and may be removed from 2.7
-          kernels.  Applications should simply open the device (eg /dev/hda1)
+          The raw driver is deprecated and will be removed soon.
+          Applications should simply open the device (eg /dev/hda1)
           with the O_DIRECT flag.
 
 config HPET
index 777bc499bbbd103fcb9246b9b65c72a1514a0eb6..2a36561eec68dab6efc8e690167df7a78668f1eb 100644 (file)
@@ -1973,10 +1973,6 @@ static _INLINE_ void show_serial_version(void)
 }
 
 
-int register_serial(struct serial_struct *req);
-void unregister_serial(int line);
-
-
 static struct tty_operations serial_ops = {
        .open = rs_open,
        .close = rs_close,
index 6bf2e27dc23ad9371aaeacaee12a2eb72d81cebe..11f9ee5811242973f15bc0232d1e15fbee33373e 100644 (file)
@@ -599,7 +599,7 @@ static ssize_t ac_read (struct file *filp, char __user *buf, size_t count, loff_
 
 #ifdef DEBUG
                if (loopcount++ > 2) {
-                       printk("Looping in ac_read. loopcount %d\n", loopcount);
+                       printk(KERN_DEBUG "Looping in ac_read. loopcount %d\n", loopcount);
                }
 #endif
        } 
index d9a02993467873505e71bc3b849bcd3733520cbb..c2b12eab67c9de8361ad8bc839877049bbf3df26 100644 (file)
@@ -6,7 +6,7 @@
 #
 config DRM
        tristate "Direct Rendering Manager (XFree86 4.1.0 and higher DRI support)"
-       depends on AGP || AGP=n
+       depends on (AGP || AGP=n) && PCI
        help
          Kernel-level support for the Direct Rendering Infrastructure (DRI)
          introduced in XFree86 4.0. If you say Y here, you need to select
index 23ab26321e9a6410b5cdc8bdd4320d778ff66dc4..7444dec40b9488cd874c408696694940cdccfdfd 100644 (file)
@@ -19,6 +19,11 @@ radeon-objs := radeon_drv.o radeon_cp.o radeon_state.o radeon_mem.o radeon_irq.o
 ffb-objs    := ffb_drv.o ffb_context.o
 sis-objs    := sis_drv.o sis_ds.o sis_mm.o
 
+ifeq ($(CONFIG_COMPAT),y)
+drm-objs    += drm_ioc32.o
+radeon-objs += radeon_ioc32.o
+endif
+
 obj-$(CONFIG_DRM)      += drm.o
 obj-$(CONFIG_DRM_GAMMA) += gamma.o
 obj-$(CONFIG_DRM_TDFX) += tdfx.o
index 21f4c54e1a8d7143c9a102696bccd0bce3e8950b..b04ddf12a0ff7b0890347ad19688a5ee018594f2 100644 (file)
@@ -316,6 +316,9 @@ do {                                                                        \
 typedef int drm_ioctl_t( struct inode *inode, struct file *filp,
                         unsigned int cmd, unsigned long arg );
 
+typedef int drm_ioctl_compat_t(struct file *filp, unsigned int cmd,
+                              unsigned long arg);
+
 typedef struct drm_ioctl_desc {
        drm_ioctl_t          *func;
        int                  auth_needed;
@@ -775,6 +778,8 @@ extern int           drm_version(struct inode *inode, struct file *filp,
                                  unsigned int cmd, unsigned long arg);
 extern int           drm_ioctl(struct inode *inode, struct file *filp,
                                unsigned int cmd, unsigned long arg);
+extern long         drm_compat_ioctl(struct file *filp,
+                               unsigned int cmd, unsigned long arg);
 extern int           drm_takedown(drm_device_t * dev);
 
                                /* Device support (drm_fops.h) */
index 4113bcba67fe080e92adeb7054e089832ec4d571..3407380b865a5953ff4d13b1a086a0c93f315f6d 100644 (file)
@@ -60,6 +60,15 @@ int drm_order( unsigned long size )
 }
 EXPORT_SYMBOL(drm_order);
 
+#ifdef CONFIG_COMPAT
+/*
+ * Used to allocate 32-bit handles for _DRM_SHM regions
+ * The 0x10000000 value is chosen to be out of the way of
+ * FB/register and GART physical addresses.
+ */
+static unsigned int map32_handle = 0x10000000;
+#endif
+
 /**
  * Ioctl to specify a range of memory that is available for mapping by a non-root process.
  *
@@ -187,16 +196,18 @@ int drm_addmap( struct inode *inode, struct file *filp,
 
        down(&dev->struct_sem);
        list_add(&list->head, &dev->maplist->head);
+#ifdef CONFIG_COMPAT
+       /* Assign a 32-bit handle for _DRM_SHM mappings */
+       /* We do it here so that dev->struct_sem protects the increment */
+       if (map->type == _DRM_SHM)
+               map->offset = map32_handle += PAGE_SIZE;
+#endif
        up(&dev->struct_sem);
 
        if ( copy_to_user( argp, map, sizeof(*map) ) )
                return -EFAULT;
-       if ( map->type != _DRM_SHM ) {
-               if ( copy_to_user( &argp->handle,
-                                  &map->offset,
-                                  sizeof(map->offset) ) )
-                       return -EFAULT;
-       }
+       if (copy_to_user(&argp->handle, &map->offset, sizeof(map->offset)))
+               return -EFAULT;
        return 0;
 }
 
@@ -240,7 +251,7 @@ int drm_rmmap(struct inode *inode, struct file *filp,
                r_list = list_entry(list, drm_map_list_t, head);
 
                if(r_list->map &&
-                  r_list->map->handle == request.handle &&
+                  r_list->map->offset == (unsigned long) request.handle &&
                   r_list->map->flags & _DRM_REMOVABLE) break;
        }
 
index f15c86c578757f82ccbeec7e698e57f8c314a0fd..fdf661f234ed304b070cc8fe3e48769c609cca5e 100644 (file)
@@ -225,7 +225,7 @@ int drm_getsareactx(struct inode *inode, struct file *filp,
        map = dev->context_sareas[request.ctx_id];
        up(&dev->struct_sem);
 
-       request.handle = map->handle;
+       request.handle = (void *) map->offset;
        if (copy_to_user(argp, &request, sizeof(request)))
                return -EFAULT;
        return 0;
@@ -261,8 +261,8 @@ int drm_setsareactx(struct inode *inode, struct file *filp,
        down(&dev->struct_sem);
        list_for_each(list, &dev->maplist->head) {
                r_list = list_entry(list, drm_map_list_t, head);
-               if(r_list->map &&
-                  r_list->map->handle == request.handle)
+               if (r_list->map
+                   && r_list->map->offset == (unsigned long) request.handle)
                        goto found;
        }
 bad:
diff --git a/drivers/char/drm/drm_ioc32.c b/drivers/char/drm/drm_ioc32.c
new file mode 100644 (file)
index 0000000..8087a96
--- /dev/null
@@ -0,0 +1,1069 @@
+/**
+ * \file drm_ioc32.c
+ *
+ * 32-bit ioctl compatibility routines for the DRM.
+ *
+ * \author Paul Mackerras <paulus@samba.org>
+ *
+ * Copyright (C) Paul Mackerras 2005.
+ * All Rights Reserved.
+ *
+ * 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 (including the next
+ * paragraph) 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 AUTHOR 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 <linux/compat.h>
+#include <linux/ioctl32.h>
+
+#include "drmP.h"
+#include "drm_core.h"
+
+#define DRM_IOCTL_VERSION32            DRM_IOWR(0x00, drm_version32_t)
+#define DRM_IOCTL_GET_UNIQUE32         DRM_IOWR(0x01, drm_unique32_t)
+#define DRM_IOCTL_GET_MAP32            DRM_IOWR(0x04, drm_map32_t)
+#define DRM_IOCTL_GET_CLIENT32         DRM_IOWR(0x05, drm_client32_t)
+#define DRM_IOCTL_GET_STATS32          DRM_IOR( 0x06, drm_stats32_t)
+
+#define DRM_IOCTL_SET_UNIQUE32         DRM_IOW( 0x10, drm_unique32_t)
+#define DRM_IOCTL_ADD_MAP32            DRM_IOWR(0x15, drm_map32_t)
+#define DRM_IOCTL_ADD_BUFS32           DRM_IOWR(0x16, drm_buf_desc32_t)
+#define DRM_IOCTL_MARK_BUFS32          DRM_IOW( 0x17, drm_buf_desc32_t)
+#define DRM_IOCTL_INFO_BUFS32          DRM_IOWR(0x18, drm_buf_info32_t)
+#define DRM_IOCTL_MAP_BUFS32           DRM_IOWR(0x19, drm_buf_map32_t)
+#define DRM_IOCTL_FREE_BUFS32          DRM_IOW( 0x1a, drm_buf_free32_t)
+
+#define DRM_IOCTL_RM_MAP32             DRM_IOW( 0x1b, drm_map32_t)
+
+#define DRM_IOCTL_SET_SAREA_CTX32      DRM_IOW( 0x1c, drm_ctx_priv_map32_t)
+#define DRM_IOCTL_GET_SAREA_CTX32      DRM_IOWR(0x1d, drm_ctx_priv_map32_t)
+
+#define DRM_IOCTL_RES_CTX32            DRM_IOWR(0x26, drm_ctx_res32_t)
+#define DRM_IOCTL_DMA32                        DRM_IOWR(0x29, drm_dma32_t)
+
+#define DRM_IOCTL_AGP_ENABLE32         DRM_IOW( 0x32, drm_agp_mode32_t)
+#define DRM_IOCTL_AGP_INFO32           DRM_IOR( 0x33, drm_agp_info32_t)
+#define DRM_IOCTL_AGP_ALLOC32          DRM_IOWR(0x34, drm_agp_buffer32_t)
+#define DRM_IOCTL_AGP_FREE32           DRM_IOW( 0x35, drm_agp_buffer32_t)
+#define DRM_IOCTL_AGP_BIND32           DRM_IOW( 0x36, drm_agp_binding32_t)
+#define DRM_IOCTL_AGP_UNBIND32         DRM_IOW( 0x37, drm_agp_binding32_t)
+
+#define DRM_IOCTL_SG_ALLOC32           DRM_IOW( 0x38, drm_scatter_gather32_t)
+#define DRM_IOCTL_SG_FREE32            DRM_IOW( 0x39, drm_scatter_gather32_t)
+
+#define DRM_IOCTL_WAIT_VBLANK32                DRM_IOWR(0x3a, drm_wait_vblank32_t)
+
+typedef struct drm_version_32 {
+       int     version_major;    /**< Major version */
+       int     version_minor;    /**< Minor version */
+       int     version_patchlevel;/**< Patch level */
+       u32     name_len;         /**< Length of name buffer */
+       u32     name;             /**< Name of driver */
+       u32     date_len;         /**< Length of date buffer */
+       u32     date;             /**< User-space buffer to hold date */
+       u32     desc_len;         /**< Length of desc buffer */
+       u32     desc;             /**< User-space buffer to hold desc */
+} drm_version32_t;
+
+static int compat_drm_version(struct file *file, unsigned int cmd,
+                             unsigned long arg)
+{
+       drm_version32_t v32;
+       drm_version_t __user *version;
+       int err;
+
+       if (copy_from_user(&v32, (void __user *) arg, sizeof(v32)))
+               return -EFAULT;
+
+       version = compat_alloc_user_space(sizeof(*version));
+       if (!access_ok(VERIFY_WRITE, version, sizeof(*version)))
+               return -EFAULT;
+       if (__put_user(v32.name_len, &version->name_len)
+           || __put_user((void __user *)(unsigned long)v32.name,
+                         &version->name)
+           || __put_user(v32.date_len, &version->date_len)
+           || __put_user((void __user *)(unsigned long)v32.date,
+                         &version->date)
+           || __put_user(v32.desc_len, &version->desc_len)
+           || __put_user((void __user *)(unsigned long)v32.desc,
+                         &version->desc))
+               return -EFAULT;
+
+       err = drm_ioctl(file->f_dentry->d_inode, file,
+                       DRM_IOCTL_VERSION, (unsigned long) version);
+       if (err)
+               return err;
+
+       if (__get_user(v32.version_major, &version->version_major)
+           || __get_user(v32.version_minor, &version->version_minor)
+           || __get_user(v32.version_patchlevel, &version->version_patchlevel)
+           || __get_user(v32.name_len, &version->name_len)
+           || __get_user(v32.date_len, &version->date_len)
+           || __get_user(v32.desc_len, &version->desc_len))
+               return -EFAULT;
+
+       if (copy_to_user((void __user *) arg, &v32, sizeof(v32)))
+               return -EFAULT;
+       return 0;
+}
+
+typedef struct drm_unique32 {
+       u32 unique_len; /**< Length of unique */
+       u32 unique;     /**< Unique name for driver instantiation */
+} drm_unique32_t;
+
+static int compat_drm_getunique(struct file *file, unsigned int cmd,
+                               unsigned long arg)
+{
+       drm_unique32_t uq32;
+       drm_unique_t __user *u;
+       int err;
+
+       if (copy_from_user(&uq32, (void __user *) arg, sizeof(uq32)))
+               return -EFAULT;
+
+       u = compat_alloc_user_space(sizeof(*u));
+       if (!access_ok(VERIFY_WRITE, u, sizeof(*u)))
+               return -EFAULT;
+       if (__put_user(uq32.unique_len, &u->unique_len)
+           || __put_user((void __user *)(unsigned long) uq32.unique,
+                         &u->unique))
+               return -EFAULT;
+
+       err = drm_ioctl(file->f_dentry->d_inode, file,
+                       DRM_IOCTL_GET_UNIQUE, (unsigned long) u);
+       if (err)
+               return err;
+
+       if (__get_user(uq32.unique_len, &u->unique_len))
+               return -EFAULT;
+       if (copy_to_user((void __user *) arg, &uq32, sizeof(uq32)))
+               return -EFAULT;
+       return 0;
+}
+
+static int compat_drm_setunique(struct file *file, unsigned int cmd,
+                               unsigned long arg)
+{
+       drm_unique32_t uq32;
+       drm_unique_t __user *u;
+
+       if (copy_from_user(&uq32, (void __user *) arg, sizeof(uq32)))
+               return -EFAULT;
+
+       u = compat_alloc_user_space(sizeof(*u));
+       if (!access_ok(VERIFY_WRITE, u, sizeof(*u)))
+               return -EFAULT;
+       if (__put_user(uq32.unique_len, &u->unique_len)
+           || __put_user((void __user *)(unsigned long) uq32.unique,
+                         &u->unique))
+               return -EFAULT;
+
+       return drm_ioctl(file->f_dentry->d_inode, file,
+                        DRM_IOCTL_SET_UNIQUE, (unsigned long) u);
+}
+
+typedef struct drm_map32 {
+       u32     offset;         /**< Requested physical address (0 for SAREA)*/
+       u32     size;           /**< Requested physical size (bytes) */
+       drm_map_type_t  type;   /**< Type of memory to map */
+       drm_map_flags_t flags;  /**< Flags */
+       u32     handle;         /**< User-space: "Handle" to pass to mmap() */
+       int     mtrr;           /**< MTRR slot used */
+} drm_map32_t;
+
+static int compat_drm_getmap(struct file *file, unsigned int cmd,
+                            unsigned long arg)
+{
+       drm_map32_t __user *argp = (void __user *)arg;
+       drm_map32_t m32;
+       drm_map_t __user *map;
+       int idx, err;
+       void *handle;
+
+       if (get_user(idx, &argp->offset))
+               return -EFAULT;
+
+       map = compat_alloc_user_space(sizeof(*map));
+       if (!access_ok(VERIFY_WRITE, map, sizeof(*map)))
+               return -EFAULT;
+       if (__put_user(idx, &map->offset))
+               return -EFAULT;
+
+       err = drm_ioctl(file->f_dentry->d_inode, file,
+                       DRM_IOCTL_GET_MAP, (unsigned long) map);
+       if (err)
+               return err;
+
+       if (__get_user(m32.offset, &map->offset)
+           || __get_user(m32.size, &map->size)
+           || __get_user(m32.type, &map->type)
+           || __get_user(m32.flags, &map->flags)
+           || __get_user(handle, &map->handle)
+           || __get_user(m32.mtrr, &map->mtrr))
+               return -EFAULT;
+
+       m32.handle = (unsigned long) handle;
+       if (copy_to_user(argp, &m32, sizeof(m32)))
+               return -EFAULT;
+       return 0;
+
+}
+
+static int compat_drm_addmap(struct file *file, unsigned int cmd,
+                            unsigned long arg)
+{
+       drm_map32_t __user *argp = (void __user *)arg;
+       drm_map32_t m32;
+       drm_map_t __user *map;
+       int err;
+       void *handle;
+
+       if (copy_from_user(&m32, argp, sizeof(m32)))
+               return -EFAULT;
+
+       map = compat_alloc_user_space(sizeof(*map));
+       if (!access_ok(VERIFY_WRITE, map, sizeof(*map)))
+               return -EFAULT;
+       if (__put_user(m32.offset, &map->offset)
+           || __put_user(m32.size, &map->size)
+           || __put_user(m32.type, &map->type)
+           || __put_user(m32.flags, &map->flags))
+               return -EFAULT;
+
+       err = drm_ioctl(file->f_dentry->d_inode, file,
+                       DRM_IOCTL_ADD_MAP, (unsigned long) map);
+       if (err)
+               return err;
+
+       if (__get_user(m32.offset, &map->offset)
+           || __get_user(m32.mtrr, &map->mtrr)
+           || __get_user(handle, &map->handle))
+               return -EFAULT;
+
+       m32.handle = (unsigned long) handle;
+       if (m32.handle != (unsigned long) handle && printk_ratelimit())
+               printk(KERN_ERR "compat_drm_addmap truncated handle"
+                      " %p for type %d offset %x\n",
+                      handle, m32.type, m32.offset);
+
+       if (copy_to_user(argp, &m32, sizeof(m32)))
+               return -EFAULT;
+
+       return 0;
+}
+
+static int compat_drm_rmmap(struct file *file, unsigned int cmd,
+                           unsigned long arg)
+{
+       drm_map32_t __user *argp = (void __user *)arg;
+       drm_map_t __user *map;
+       u32 handle;
+
+       if (get_user(handle, &argp->handle))
+               return -EFAULT;
+
+       map = compat_alloc_user_space(sizeof(*map));
+       if (!access_ok(VERIFY_WRITE, map, sizeof(*map)))
+               return -EFAULT;
+       if (__put_user((void *)(unsigned long) handle, &map->handle))
+               return -EFAULT;
+
+       return drm_ioctl(file->f_dentry->d_inode, file,
+                        DRM_IOCTL_RM_MAP, (unsigned long) map);
+}
+
+typedef struct drm_client32 {
+       int     idx;    /**< Which client desired? */
+       int     auth;   /**< Is client authenticated? */
+       u32     pid;    /**< Process ID */
+       u32     uid;    /**< User ID */
+       u32     magic;  /**< Magic */
+       u32     iocs;   /**< Ioctl count */
+} drm_client32_t;
+
+static int compat_drm_getclient(struct file *file, unsigned int cmd,
+                               unsigned long arg)
+{
+       drm_client32_t c32;
+       drm_client32_t __user *argp = (void __user *)arg;
+       drm_client_t __user *client;
+       int idx, err;
+
+       if (get_user(idx, &argp->idx))
+               return -EFAULT;
+
+       client = compat_alloc_user_space(sizeof(*client));
+       if (!access_ok(VERIFY_WRITE, client, sizeof(*client)))
+               return -EFAULT;
+       if (__put_user(idx, &client->idx))
+               return -EFAULT;
+
+       err = drm_ioctl(file->f_dentry->d_inode, file,
+                       DRM_IOCTL_GET_CLIENT, (unsigned long) client);
+       if (err)
+               return err;
+
+       if (__get_user(c32.auth, &client->auth)
+           || __get_user(c32.pid, &client->pid)
+           || __get_user(c32.uid, &client->uid)
+           || __get_user(c32.magic, &client->magic)
+           || __get_user(c32.iocs, &client->iocs))
+               return -EFAULT;
+
+       if (copy_to_user(argp, &c32, sizeof(c32)))
+               return -EFAULT;
+       return 0;
+}
+
+typedef struct drm_stats32 {
+       u32 count;
+       struct {
+               u32 value;
+               drm_stat_type_t type;
+       } data[15];
+} drm_stats32_t;
+
+static int compat_drm_getstats(struct file *file, unsigned int cmd,
+                              unsigned long arg)
+{
+       drm_stats32_t s32;
+       drm_stats32_t __user *argp = (void __user *)arg;
+       drm_stats_t __user *stats;
+       int i, err;
+
+       stats = compat_alloc_user_space(sizeof(*stats));
+       if (!access_ok(VERIFY_WRITE, stats, sizeof(*stats)))
+               return -EFAULT;
+
+       err = drm_ioctl(file->f_dentry->d_inode, file,
+                       DRM_IOCTL_GET_STATS, (unsigned long) stats);
+       if (err)
+               return err;
+
+       if (__get_user(s32.count, &stats->count))
+               return -EFAULT;
+       for (i = 0; i < 15; ++i)
+               if (__get_user(s32.data[i].value, &stats->data[i].value)
+                   || __get_user(s32.data[i].type, &stats->data[i].type))
+                       return -EFAULT;
+
+       if (copy_to_user(argp, &s32, sizeof(s32)))
+               return -EFAULT;
+       return 0;
+}
+
+typedef struct drm_buf_desc32 {
+       int           count;     /**< Number of buffers of this size */
+       int           size;      /**< Size in bytes */
+       int           low_mark;  /**< Low water mark */
+       int           high_mark; /**< High water mark */
+       int           flags;
+       u32           agp_start; /**< Start address in the AGP aperture */
+} drm_buf_desc32_t;
+
+static int compat_drm_addbufs(struct file *file, unsigned int cmd,
+                             unsigned long arg)
+{
+       drm_buf_desc32_t __user *argp = (void __user *)arg;
+       drm_buf_desc_t __user *buf;
+       int err;
+       unsigned long agp_start;
+
+       buf = compat_alloc_user_space(sizeof(*buf));
+       if (!access_ok(VERIFY_WRITE, buf, sizeof(*buf))
+           || !access_ok(VERIFY_WRITE, argp, sizeof(*argp)))
+               return -EFAULT;
+
+       if (__copy_in_user(buf, argp, offsetof(drm_buf_desc32_t, agp_start))
+           || __get_user(agp_start, &argp->agp_start)
+           || __put_user(agp_start, &buf->agp_start))
+               return -EFAULT;
+
+       err = drm_ioctl(file->f_dentry->d_inode, file,
+                       DRM_IOCTL_ADD_BUFS, (unsigned long) buf);
+       if (err)
+               return err;
+
+       if (__copy_in_user(argp, buf, offsetof(drm_buf_desc32_t, agp_start))
+           || __get_user(agp_start, &buf->agp_start)
+           || __put_user(agp_start, &argp->agp_start))
+               return -EFAULT;
+
+       return 0;
+}
+
+static int compat_drm_markbufs(struct file *file, unsigned int cmd,
+                              unsigned long arg)
+{
+       drm_buf_desc32_t b32;
+       drm_buf_desc32_t __user *argp = (void __user *)arg;
+       drm_buf_desc_t __user *buf;
+
+       if (copy_from_user(&b32, argp, sizeof(b32)))
+               return -EFAULT;
+
+       buf = compat_alloc_user_space(sizeof(*buf));
+       if (!access_ok(VERIFY_WRITE, buf, sizeof(*buf)))
+               return -EFAULT;
+
+       if (__put_user(b32.size, &buf->size)
+           || __put_user(b32.low_mark, &buf->low_mark)
+           || __put_user(b32.high_mark, &buf->high_mark))
+               return -EFAULT;
+
+       return drm_ioctl(file->f_dentry->d_inode, file,
+                        DRM_IOCTL_MARK_BUFS, (unsigned long) buf);
+}
+
+typedef struct drm_buf_info32 {
+       int            count;   /**< Entries in list */
+       u32            list;
+} drm_buf_info32_t;
+
+static int compat_drm_infobufs(struct file *file, unsigned int cmd,
+                              unsigned long arg)
+{
+       drm_buf_info32_t req32;
+       drm_buf_info32_t __user *argp = (void __user *)arg;
+       drm_buf_desc32_t __user *to;
+       drm_buf_info_t __user *request;
+       drm_buf_desc_t __user *list;
+       size_t nbytes;
+       int i, err;
+       int count, actual;
+
+       if (copy_from_user(&req32, argp, sizeof(req32)))
+               return -EFAULT;
+
+       count = req32.count;
+       to = (drm_buf_desc32_t __user *)(unsigned long) req32.list;
+       if (count < 0)
+               count = 0;
+       if (count > 0
+           && !access_ok(VERIFY_WRITE, to, count * sizeof(drm_buf_desc32_t)))
+               return -EFAULT;
+
+       nbytes = sizeof(*request) + count * sizeof(drm_buf_desc_t);
+       request = compat_alloc_user_space(nbytes);
+       if (!access_ok(VERIFY_WRITE, request, nbytes))
+               return -EFAULT;
+       list = (drm_buf_desc_t *) (request + 1);
+
+       if (__put_user(count, &request->count)
+           || __put_user(list, &request->list))
+               return -EFAULT;
+
+       err = drm_ioctl(file->f_dentry->d_inode, file,
+                       DRM_IOCTL_INFO_BUFS, (unsigned long) request);
+       if (err)
+               return err;
+
+       if (__get_user(actual, &request->count))
+               return -EFAULT;
+       if (count >= actual)
+               for (i = 0; i < actual; ++i)
+                       if (__copy_in_user(&to[i], &list[i],
+                                          offsetof(drm_buf_desc_t, flags)))
+                               return -EFAULT;
+
+       if (__put_user(actual, &argp->count))
+               return -EFAULT;
+
+       return 0;
+}
+
+typedef struct drm_buf_pub32 {
+       int     idx;            /**< Index into the master buffer list */
+       int     total;          /**< Buffer size */
+       int     used;           /**< Amount of buffer in use (for DMA) */
+       u32     address;        /**< Address of buffer */
+} drm_buf_pub32_t;
+
+typedef struct drm_buf_map32 {
+       int     count;          /**< Length of the buffer list */
+       u32     virtual;        /**< Mmap'd area in user-virtual */
+       u32     list;           /**< Buffer information */
+} drm_buf_map32_t;
+
+static int compat_drm_mapbufs(struct file *file, unsigned int cmd,
+                             unsigned long arg)
+{
+       drm_buf_map32_t __user *argp = (void __user *)arg;
+       drm_buf_map32_t req32;
+       drm_buf_pub32_t __user *list32;
+       drm_buf_map_t __user *request;
+       drm_buf_pub_t __user *list;
+       int i, err;
+       int count, actual;
+       size_t nbytes;
+       void __user *addr;
+
+       if (copy_from_user(&req32, argp, sizeof(req32)))
+               return -EFAULT;
+       count = req32.count;
+       list32 = (void __user *)(unsigned long)req32.list;
+
+       if (count < 0)
+               return -EINVAL;
+       nbytes = sizeof(*request) + count * sizeof(drm_buf_pub_t);
+       request = compat_alloc_user_space(nbytes);
+       if (!access_ok(VERIFY_WRITE, request, nbytes))
+               return -EFAULT;
+       list = (drm_buf_pub_t *) (request + 1);
+
+       if (__put_user(count, &request->count)
+           || __put_user(list, &request->list))
+               return -EFAULT;
+
+       err = drm_ioctl(file->f_dentry->d_inode, file,
+                       DRM_IOCTL_MAP_BUFS, (unsigned long) request);
+       if (err)
+               return err;
+
+       if (__get_user(actual, &request->count))
+               return -EFAULT;
+       if (count >= actual)
+               for (i = 0; i < actual; ++i)
+                       if (__copy_in_user(&list32[i], &list[i],
+                                          offsetof(drm_buf_pub_t, address))
+                           || __get_user(addr, &list[i].address)
+                           || __put_user((unsigned long) addr,
+                                         &list32[i].address))
+                               return -EFAULT;
+
+       if (__put_user(actual, &argp->count)
+           || __get_user(addr, &request->virtual)
+           || __put_user((unsigned long) addr, &argp->virtual))
+               return -EFAULT;
+
+       return 0;
+}
+
+typedef struct drm_buf_free32 {
+       int     count;
+       u32     list;
+} drm_buf_free32_t;
+
+static int compat_drm_freebufs(struct file *file, unsigned int cmd,
+                              unsigned long arg)
+{
+       drm_buf_free32_t req32;
+       drm_buf_free_t __user *request;
+       drm_buf_free32_t __user *argp = (void __user *)arg;
+
+       if (copy_from_user(&req32, argp, sizeof(req32)))
+               return -EFAULT;
+
+       request = compat_alloc_user_space(sizeof(*request));
+       if (!access_ok(VERIFY_WRITE, request, sizeof(*request)))
+               return -EFAULT;
+       if (__put_user(req32.count, &request->count)
+           || __put_user((int __user *)(unsigned long) req32.list,
+                         &request->list))
+               return -EFAULT;
+
+       return drm_ioctl(file->f_dentry->d_inode, file,
+                        DRM_IOCTL_FREE_BUFS, (unsigned long) request);
+}
+
+typedef struct drm_ctx_priv_map32 {
+       unsigned int    ctx_id;  /**< Context requesting private mapping */
+       u32             handle; /**< Handle of map */
+} drm_ctx_priv_map32_t;
+
+static int compat_drm_setsareactx(struct file *file, unsigned int cmd,
+                                 unsigned long arg)
+{
+       drm_ctx_priv_map32_t req32;
+       drm_ctx_priv_map_t __user *request;
+       drm_ctx_priv_map32_t __user *argp = (void __user *)arg;
+
+       if (copy_from_user(&req32, argp, sizeof(req32)))
+               return -EFAULT;
+
+       request = compat_alloc_user_space(sizeof(*request));
+       if (!access_ok(VERIFY_WRITE, request, sizeof(*request)))
+               return -EFAULT;
+       if (__put_user(req32.ctx_id, &request->ctx_id)
+           || __put_user((void *)(unsigned long) req32.handle,
+                         &request->handle))
+               return -EFAULT;
+
+       return drm_ioctl(file->f_dentry->d_inode, file,
+                        DRM_IOCTL_SET_SAREA_CTX, (unsigned long) request);
+}
+
+static int compat_drm_getsareactx(struct file *file, unsigned int cmd,
+                                 unsigned long arg)
+{
+       drm_ctx_priv_map_t __user *request;
+       drm_ctx_priv_map32_t __user *argp = (void __user *)arg;
+       int err;
+       unsigned int ctx_id;
+       void *handle;
+
+       if (!access_ok(VERIFY_WRITE, argp, sizeof(*argp))
+           || __get_user(ctx_id, &argp->ctx_id))
+               return -EFAULT;
+
+       request = compat_alloc_user_space(sizeof(*request));
+       if (!access_ok(VERIFY_WRITE, request, sizeof(*request)))
+               return -EFAULT;
+       if (__put_user(ctx_id, &request->ctx_id))
+               return -EFAULT;
+
+       err = drm_ioctl(file->f_dentry->d_inode, file,
+                       DRM_IOCTL_GET_SAREA_CTX, (unsigned long) request);
+       if (err)
+               return err;
+
+       if (__get_user(handle, &request->handle)
+           || __put_user((unsigned long) handle, &argp->handle))
+               return -EFAULT;
+
+       return 0;
+}
+
+typedef struct drm_ctx_res32 {
+       int     count;
+       u32     contexts;
+} drm_ctx_res32_t;
+
+static int compat_drm_resctx(struct file *file, unsigned int cmd,
+                            unsigned long arg)
+{
+       drm_ctx_res32_t __user *argp = (void __user *)arg;
+       drm_ctx_res32_t res32;
+       drm_ctx_res_t __user *res;
+       int err;
+
+       if (copy_from_user(&res32, argp, sizeof(res32)))
+               return -EFAULT;
+
+       res = compat_alloc_user_space(sizeof(*res));
+       if (!access_ok(VERIFY_WRITE, res, sizeof(*res)))
+               return -EFAULT;
+       if (__put_user(res32.count, &res->count)
+           || __put_user((drm_ctx_t __user *)(unsigned long) res32.contexts,
+                         &res->contexts))
+               return -EFAULT;
+
+       err = drm_ioctl(file->f_dentry->d_inode, file,
+                       DRM_IOCTL_RES_CTX, (unsigned long) res);
+       if (err)
+               return err;
+
+       if (__get_user(res32.count, &res->count)
+           || __put_user(res32.count, &argp->count))
+               return -EFAULT;
+
+       return 0;
+}
+
+typedef struct drm_dma32 {
+       int     context;          /**< Context handle */
+       int     send_count;       /**< Number of buffers to send */
+       u32     send_indices;     /**< List of handles to buffers */
+       u32     send_sizes;       /**< Lengths of data to send */
+       drm_dma_flags_t flags;            /**< Flags */
+       int     request_count;    /**< Number of buffers requested */
+       int     request_size;     /**< Desired size for buffers */
+       u32     request_indices;  /**< Buffer information */
+       u32     request_sizes;
+       int     granted_count;    /**< Number of buffers granted */
+} drm_dma32_t;
+
+static int compat_drm_dma(struct file *file, unsigned int cmd,
+                         unsigned long arg)
+{
+       drm_dma32_t d32;
+       drm_dma32_t __user *argp = (void __user *) arg;
+       drm_dma_t __user *d;
+       int err;
+
+       if (copy_from_user(&d32, argp, sizeof(d32)))
+               return -EFAULT;
+
+       d = compat_alloc_user_space(sizeof(*d));
+       if (!access_ok(VERIFY_WRITE, d, sizeof(*d)))
+               return -EFAULT;
+
+       if (__put_user(d32.context, &d->context)
+           || __put_user(d32.send_count, &d->send_count)
+           || __put_user((int __user *)(unsigned long) d32.send_indices,
+                         &d->send_indices)
+           || __put_user((int __user *)(unsigned long) d32.send_sizes,
+                         &d->send_sizes)
+           || __put_user(d32.flags, &d->flags)
+           || __put_user(d32.request_count, &d->request_count)
+           || __put_user((int __user *)(unsigned long) d32.request_indices,
+                         &d->request_indices)
+           || __put_user((int __user *)(unsigned long) d32.request_sizes,
+                         &d->request_sizes))
+               return -EFAULT;
+
+       err = drm_ioctl(file->f_dentry->d_inode, file,
+                       DRM_IOCTL_DMA, (unsigned long) d);
+       if (err)
+               return err;
+
+       if (__get_user(d32.request_size, &d->request_size)
+           || __get_user(d32.granted_count, &d->granted_count)
+           || __put_user(d32.request_size, &argp->request_size)
+           || __put_user(d32.granted_count, &argp->granted_count))
+               return -EFAULT;
+
+       return 0;
+}
+
+#if __OS_HAS_AGP
+typedef struct drm_agp_mode32 {
+       u32 mode;       /**< AGP mode */
+} drm_agp_mode32_t;
+
+static int compat_drm_agp_enable(struct file *file, unsigned int cmd,
+                                unsigned long arg)
+{
+       drm_agp_mode32_t __user *argp = (void __user *)arg;
+       drm_agp_mode32_t m32;
+       drm_agp_mode_t __user *mode;
+
+       if (get_user(m32.mode, &argp->mode))
+               return -EFAULT;
+
+       mode = compat_alloc_user_space(sizeof(*mode));
+       if (put_user(m32.mode, &mode->mode))
+               return -EFAULT;
+
+       return drm_ioctl(file->f_dentry->d_inode, file,
+                        DRM_IOCTL_AGP_ENABLE, (unsigned long) mode);
+}
+
+typedef struct drm_agp_info32 {
+       int       agp_version_major;
+       int       agp_version_minor;
+       u32       mode;
+       u32       aperture_base;  /* physical address */
+       u32       aperture_size;  /* bytes */
+       u32       memory_allowed; /* bytes */
+       u32       memory_used;
+
+                               /* PCI information */
+       unsigned short id_vendor;
+       unsigned short id_device;
+} drm_agp_info32_t;
+
+static int compat_drm_agp_info(struct file *file, unsigned int cmd,
+                              unsigned long arg)
+{
+       drm_agp_info32_t __user *argp = (void __user *)arg;
+       drm_agp_info32_t i32;
+       drm_agp_info_t __user *info;
+       int err;
+
+       info = compat_alloc_user_space(sizeof(*info));
+       if (!access_ok(VERIFY_WRITE, info, sizeof(*info)))
+               return -EFAULT;
+
+       err = drm_ioctl(file->f_dentry->d_inode, file,
+                       DRM_IOCTL_AGP_INFO, (unsigned long) info);
+       if (err)
+               return err;
+
+       if (__get_user(i32.agp_version_major, &info->agp_version_major)
+           || __get_user(i32.agp_version_minor, &info->agp_version_minor)
+           || __get_user(i32.mode, &info->mode)
+           || __get_user(i32.aperture_base, &info->aperture_base)
+           || __get_user(i32.aperture_size, &info->aperture_size)
+           || __get_user(i32.memory_allowed, &info->memory_allowed)
+           || __get_user(i32.memory_used, &info->memory_used)
+           || __get_user(i32.id_vendor, &info->id_vendor)
+           || __get_user(i32.id_device, &info->id_device))
+               return -EFAULT;
+
+       if (copy_to_user(argp, &i32, sizeof(i32)))
+               return -EFAULT;
+
+       return 0;
+}
+
+typedef struct drm_agp_buffer32 {
+       u32 size;       /**< In bytes -- will round to page boundary */
+       u32 handle;     /**< Used for binding / unbinding */
+       u32 type;       /**< Type of memory to allocate */
+        u32 physical;  /**< Physical used by i810 */
+} drm_agp_buffer32_t;
+
+static int compat_drm_agp_alloc(struct file *file, unsigned int cmd,
+                               unsigned long arg)
+{
+       drm_agp_buffer32_t __user *argp = (void __user *)arg;
+       drm_agp_buffer32_t req32;
+       drm_agp_buffer_t __user *request;
+       int err;
+
+       if (copy_from_user(&req32, argp, sizeof(req32)))
+               return -EFAULT;
+
+       request = compat_alloc_user_space(sizeof(*request));
+       if (!access_ok(VERIFY_WRITE, request, sizeof(*request))
+           || __put_user(req32.size, &request->size)
+           || __put_user(req32.type, &request->type))
+               return -EFAULT;
+
+       err = drm_ioctl(file->f_dentry->d_inode, file,
+                       DRM_IOCTL_AGP_ALLOC, (unsigned long) request);
+       if (err)
+               return err;
+
+       if (__get_user(req32.handle, &request->handle)
+           || __get_user(req32.physical, &request->physical)
+           || copy_to_user(argp, &req32, sizeof(req32))) {
+               drm_ioctl(file->f_dentry->d_inode, file,
+                         DRM_IOCTL_AGP_FREE, (unsigned long) request);
+               return -EFAULT;
+       }
+
+       return 0;
+}
+
+static int compat_drm_agp_free(struct file *file, unsigned int cmd,
+                              unsigned long arg)
+{
+       drm_agp_buffer32_t __user *argp = (void __user *)arg;
+       drm_agp_buffer_t __user *request;
+       u32 handle;
+
+       request = compat_alloc_user_space(sizeof(*request));
+       if (!access_ok(VERIFY_WRITE, request, sizeof(*request))
+           || get_user(handle, &argp->handle)
+           || __put_user(handle, &request->handle))
+               return -EFAULT;
+
+       return drm_ioctl(file->f_dentry->d_inode, file,
+                        DRM_IOCTL_AGP_FREE, (unsigned long) request);
+}
+
+typedef struct drm_agp_binding32 {
+       u32 handle;     /**< From drm_agp_buffer */
+       u32 offset;     /**< In bytes -- will round to page boundary */
+} drm_agp_binding32_t;
+
+static int compat_drm_agp_bind(struct file *file, unsigned int cmd,
+                              unsigned long arg)
+{
+       drm_agp_binding32_t __user *argp = (void __user *)arg;
+       drm_agp_binding32_t req32;
+       drm_agp_binding_t __user *request;
+
+       if (copy_from_user(&req32, argp, sizeof(req32)))
+               return -EFAULT;
+
+       request = compat_alloc_user_space(sizeof(*request));
+       if (!access_ok(VERIFY_WRITE, request, sizeof(*request))
+           || __put_user(req32.handle, &request->handle)
+           || __put_user(req32.offset, &request->offset))
+               return -EFAULT;
+
+       return drm_ioctl(file->f_dentry->d_inode, file,
+                        DRM_IOCTL_AGP_BIND, (unsigned long) request);
+}
+
+static int compat_drm_agp_unbind(struct file *file, unsigned int cmd,
+                                unsigned long arg)
+{
+       drm_agp_binding32_t __user *argp = (void __user *)arg;
+       drm_agp_binding_t __user *request;
+       u32 handle;
+
+       request = compat_alloc_user_space(sizeof(*request));
+       if (!access_ok(VERIFY_WRITE, request, sizeof(*request))
+           || get_user(handle, &argp->handle)
+           || __put_user(handle, &request->handle))
+               return -EFAULT;
+
+       return drm_ioctl(file->f_dentry->d_inode, file,
+                        DRM_IOCTL_AGP_UNBIND, (unsigned long) request);
+}
+#endif /* __OS_HAS_AGP */
+
+typedef struct drm_scatter_gather32 {
+       u32 size;       /**< In bytes -- will round to page boundary */
+       u32 handle;     /**< Used for mapping / unmapping */
+} drm_scatter_gather32_t;
+
+static int compat_drm_sg_alloc(struct file *file, unsigned int cmd,
+                              unsigned long arg)
+{
+       drm_scatter_gather32_t __user *argp = (void __user *)arg;
+       drm_scatter_gather_t __user *request;
+       int err;
+       unsigned long x;
+
+       request = compat_alloc_user_space(sizeof(*request));
+       if (!access_ok(VERIFY_WRITE, request, sizeof(*request))
+           || !access_ok(VERIFY_WRITE, argp, sizeof(*argp))
+           || __get_user(x, &argp->size)
+           || __put_user(x, &request->size))
+               return -EFAULT;
+
+       err = drm_ioctl(file->f_dentry->d_inode, file,
+                       DRM_IOCTL_SG_ALLOC, (unsigned long) request);
+       if (err)
+               return err;
+
+       /* XXX not sure about the handle conversion here... */
+       if (__get_user(x, &request->handle)
+           || __put_user(x >> PAGE_SHIFT, &argp->handle))
+               return -EFAULT;
+
+       return 0;
+}
+
+static int compat_drm_sg_free(struct file *file, unsigned int cmd,
+                             unsigned long arg)
+{
+       drm_scatter_gather32_t __user *argp = (void __user *)arg;
+       drm_scatter_gather_t __user *request;
+       unsigned long x;
+
+       request = compat_alloc_user_space(sizeof(*request));
+       if (!access_ok(VERIFY_WRITE, request, sizeof(*request))
+           || !access_ok(VERIFY_WRITE, argp, sizeof(*argp))
+           || __get_user(x, &argp->handle)
+           || __put_user(x << PAGE_SHIFT, &request->handle))
+               return -EFAULT;
+
+       return drm_ioctl(file->f_dentry->d_inode, file,
+                        DRM_IOCTL_SG_FREE, (unsigned long) request);
+}
+
+struct drm_wait_vblank_request32 {
+       drm_vblank_seq_type_t type;
+       unsigned int sequence;
+       u32 signal;
+};
+
+struct drm_wait_vblank_reply32 {
+       drm_vblank_seq_type_t type;
+       unsigned int sequence;
+       s32 tval_sec;
+       s32 tval_usec;
+};
+
+typedef union drm_wait_vblank32 {
+       struct drm_wait_vblank_request32 request;
+       struct drm_wait_vblank_reply32 reply;
+} drm_wait_vblank32_t;
+
+static int compat_drm_wait_vblank(struct file *file, unsigned int cmd,
+                                 unsigned long arg)
+{
+       drm_wait_vblank32_t __user *argp = (void __user *)arg;
+       drm_wait_vblank32_t req32;
+       drm_wait_vblank_t __user *request;
+       int err;
+
+       if (copy_from_user(&req32, argp, sizeof(req32)))
+               return -EFAULT;
+
+       request = compat_alloc_user_space(sizeof(*request));
+       if (!access_ok(VERIFY_WRITE, request, sizeof(*request))
+           || __put_user(req32.request.type, &request->request.type)
+           || __put_user(req32.request.sequence, &request->request.sequence)
+           || __put_user(req32.request.signal, &request->request.signal))
+               return -EFAULT;
+
+       err = drm_ioctl(file->f_dentry->d_inode, file,
+                       DRM_IOCTL_WAIT_VBLANK, (unsigned long) request);
+       if (err)
+               return err;
+
+       if (__get_user(req32.reply.type, &request->reply.type)
+           || __get_user(req32.reply.sequence, &request->reply.sequence)
+           || __get_user(req32.reply.tval_sec, &request->reply.tval_sec)
+           || __get_user(req32.reply.tval_usec, &request->reply.tval_usec))
+               return -EFAULT;
+
+       if (copy_to_user(argp, &req32, sizeof(req32)))
+               return -EFAULT;
+
+       return 0;
+}
+
+drm_ioctl_compat_t *drm_compat_ioctls[] = {
+       [DRM_IOCTL_NR(DRM_IOCTL_VERSION32)] = compat_drm_version,
+       [DRM_IOCTL_NR(DRM_IOCTL_GET_UNIQUE32)] = compat_drm_getunique,
+       [DRM_IOCTL_NR(DRM_IOCTL_GET_MAP32)] = compat_drm_getmap,
+       [DRM_IOCTL_NR(DRM_IOCTL_GET_CLIENT32)] = compat_drm_getclient,
+       [DRM_IOCTL_NR(DRM_IOCTL_GET_STATS32)] = compat_drm_getstats,
+       [DRM_IOCTL_NR(DRM_IOCTL_SET_UNIQUE32)] = compat_drm_setunique,
+       [DRM_IOCTL_NR(DRM_IOCTL_ADD_MAP32)] = compat_drm_addmap,
+       [DRM_IOCTL_NR(DRM_IOCTL_ADD_BUFS32)] = compat_drm_addbufs,
+       [DRM_IOCTL_NR(DRM_IOCTL_MARK_BUFS32)] = compat_drm_markbufs,
+       [DRM_IOCTL_NR(DRM_IOCTL_INFO_BUFS32)] = compat_drm_infobufs,
+       [DRM_IOCTL_NR(DRM_IOCTL_MAP_BUFS32)] = compat_drm_mapbufs,
+       [DRM_IOCTL_NR(DRM_IOCTL_FREE_BUFS32)] = compat_drm_freebufs,
+       [DRM_IOCTL_NR(DRM_IOCTL_RM_MAP32)] = compat_drm_rmmap,
+       [DRM_IOCTL_NR(DRM_IOCTL_SET_SAREA_CTX32)] = compat_drm_setsareactx,
+       [DRM_IOCTL_NR(DRM_IOCTL_GET_SAREA_CTX32)] = compat_drm_getsareactx,
+       [DRM_IOCTL_NR(DRM_IOCTL_RES_CTX32)] = compat_drm_resctx,
+       [DRM_IOCTL_NR(DRM_IOCTL_DMA32)] = compat_drm_dma,
+#if __OS_HAS_AGP
+       [DRM_IOCTL_NR(DRM_IOCTL_AGP_ENABLE32)] = compat_drm_agp_enable,
+       [DRM_IOCTL_NR(DRM_IOCTL_AGP_INFO32)] = compat_drm_agp_info,
+       [DRM_IOCTL_NR(DRM_IOCTL_AGP_ALLOC32)] = compat_drm_agp_alloc,
+       [DRM_IOCTL_NR(DRM_IOCTL_AGP_FREE32)] = compat_drm_agp_free,
+       [DRM_IOCTL_NR(DRM_IOCTL_AGP_BIND32)] = compat_drm_agp_bind,
+       [DRM_IOCTL_NR(DRM_IOCTL_AGP_UNBIND32)] = compat_drm_agp_unbind,
+#endif
+       [DRM_IOCTL_NR(DRM_IOCTL_SG_ALLOC32)] = compat_drm_sg_alloc,
+       [DRM_IOCTL_NR(DRM_IOCTL_SG_FREE32)] = compat_drm_sg_free,
+       [DRM_IOCTL_NR(DRM_IOCTL_WAIT_VBLANK32)] = compat_drm_wait_vblank,
+};
+
+/**
+ * Called whenever a 32-bit process running under a 64-bit kernel
+ * performs an ioctl on /dev/drm.
+ *
+ * \param filp file pointer.
+ * \param cmd command.
+ * \param arg user argument.
+ * \return zero on success or negative number on failure.
+ */
+long drm_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
+{
+       unsigned int nr = DRM_IOCTL_NR(cmd);
+       drm_ioctl_compat_t *fn;
+       int ret;
+
+       if (nr >= DRM_ARRAY_SIZE(drm_compat_ioctls))
+               return -ENOTTY;
+
+       fn = drm_compat_ioctls[nr];
+
+       lock_kernel();          /* XXX for now */
+       if (fn != NULL)
+               ret = (*fn)(filp, cmd, arg);
+       else
+               ret = drm_ioctl(filp->f_dentry->d_inode, filp, cmd, arg);
+       unlock_kernel();
+
+       return ret;
+}
+EXPORT_SYMBOL(drm_compat_ioctl);
index 7300a09dbd5c2102b6d3762b854fe8edd5a3d03b..b5903f9f14236a0fe0223db59ab5c0b39241cb43 100644 (file)
@@ -1,10 +1,30 @@
 /* i915_dma.c -- DMA support for the I915 -*- linux-c -*-
  */
 /**************************************************************************
- * 
+ *
  * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
  * All Rights Reserved.
- * 
+ *
+ * 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, sub license, 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 (including the
+ * next paragraph) 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 NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS 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 "drmP.h"
index 7e55edf45c4fd8c6fe87dacaa28d6eae3214fa82..23e027d2908069af6f71a8d592669e5adbca3c6b 100644 (file)
@@ -1,3 +1,30 @@
+/**************************************************************************
+ *
+ * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * 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, sub license, 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 (including the
+ * next paragraph) 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 NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS 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.
+ *
+ **************************************************************************/
+
 #ifndef _I915_DRM_H_
 #define _I915_DRM_H_
 
index 002b7082e21b00ee633f63889afe488bdfecd0e8..e6a9e1d1d2831a6fa17ff660c12146359a58e33a 100644 (file)
@@ -1,11 +1,30 @@
 /* i915_drv.c -- i830,i845,i855,i865,i915 driver -*- linux-c -*-
  */
-
 /**************************************************************************
- * 
+ *
  * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
  * All Rights Reserved.
- * 
+ *
+ * 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, sub license, 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 (including the
+ * next paragraph) 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 NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS 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 "drmP.h"
index f6ca92a565db7bc64ab5d0a50d1e7282747f8255..fa940d64b85d6da335a2ea2a21b84a8079d1ceac 100644 (file)
@@ -1,10 +1,30 @@
 /* i915_drv.h -- Private header for the I915 driver -*- linux-c -*-
  */
 /**************************************************************************
- * 
+ *
  * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
  * All Rights Reserved.
- * 
+ *
+ * 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, sub license, 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 (including the
+ * next paragraph) 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 NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS 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.
+ *
  **************************************************************************/
 
 #ifndef _I915_DRV_H_
index b0239262a84ae9515124afd41517e0c10de05bdf..a101cc9cfd7e1441e0010a501943ae70efb72eae 100644 (file)
@@ -1,10 +1,30 @@
 /* i915_dma.c -- DMA support for the I915 -*- linux-c -*-
  */
 /**************************************************************************
- * 
+ *
  * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
  * All Rights Reserved.
- * 
+ *
+ * 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, sub license, 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 (including the
+ * next paragraph) 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 NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS 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 "drmP.h"
index d54a3005946b724a8b3deb1a5f8dbf9188cb8b76..9b1698f521befabc199c8c4ea1bb21b0c968e37e 100644 (file)
@@ -1,10 +1,30 @@
 /* i915_mem.c -- Simple agp/fb memory manager for i915 -*- linux-c -*-
  */
 /**************************************************************************
- * 
+ *
  * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
  * All Rights Reserved.
- * 
+ *
+ * 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, sub license, 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 (including the
+ * next paragraph) 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 NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS 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 "drmP.h"
index 7b983d96e53b7a7589bb51a02af90a84539d7f4f..18e4e5b0952f4f60c5143253f57b476949fd23c2 100644 (file)
@@ -101,6 +101,9 @@ static struct drm_driver driver = {
                .mmap = drm_mmap,
                .poll = drm_poll,
                .fasync = drm_fasync,
+#ifdef CONFIG_COMPAT
+               .compat_ioctl = radeon_compat_ioctl,
+#endif
        },
        .pci_driver = {
                .name          = DRIVER_NAME,
index 5837098afae81f91e42706dd0fb2f440eae43b1f..771aa80a5e8c24233193b0c73566e03f4ebc1248 100644 (file)
@@ -317,6 +317,9 @@ extern int radeon_preinit( struct drm_device *dev, unsigned long flags );
 extern int radeon_postinit( struct drm_device *dev, unsigned long flags );
 extern int radeon_postcleanup( struct drm_device *dev );
 
+extern long radeon_compat_ioctl(struct file *filp, unsigned int cmd,
+                               unsigned long arg);
+
 /* Flags for stats.boxes
  */
 #define RADEON_BOX_DMA_IDLE      0x1
diff --git a/drivers/char/drm/radeon_ioc32.c b/drivers/char/drm/radeon_ioc32.c
new file mode 100644 (file)
index 0000000..bfe6122
--- /dev/null
@@ -0,0 +1,395 @@
+/**
+ * \file radeon_ioc32.c
+ *
+ * 32-bit ioctl compatibility routines for the Radeon DRM.
+ *
+ * \author Paul Mackerras <paulus@samba.org>
+ *
+ * Copyright (C) Paul Mackerras 2005
+ * All Rights Reserved.
+ *
+ * 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 (including the next
+ * paragraph) 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 AUTHOR 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 <linux/compat.h>
+#include <linux/ioctl32.h>
+
+#include "drmP.h"
+#include "drm.h"
+#include "radeon_drm.h"
+#include "radeon_drv.h"
+
+typedef struct drm_radeon_init32 {
+       int func;
+       u32 sarea_priv_offset;
+       int is_pci;
+       int cp_mode;
+       int gart_size;
+       int ring_size;
+       int usec_timeout;
+
+       unsigned int fb_bpp;
+       unsigned int front_offset, front_pitch;
+       unsigned int back_offset, back_pitch;
+       unsigned int depth_bpp;
+       unsigned int depth_offset, depth_pitch;
+
+       u32 fb_offset;
+       u32 mmio_offset;
+       u32 ring_offset;
+       u32 ring_rptr_offset;
+       u32 buffers_offset;
+       u32 gart_textures_offset;
+} drm_radeon_init32_t;
+
+static int compat_radeon_cp_init(struct file *file, unsigned int cmd,
+                                unsigned long arg)
+{
+       drm_radeon_init32_t init32;
+       drm_radeon_init_t __user *init;
+
+       if (copy_from_user(&init32, (void __user *)arg, sizeof(init32)))
+               return -EFAULT;
+
+       init = compat_alloc_user_space(sizeof(*init));
+       if (!access_ok(VERIFY_WRITE, init, sizeof(*init))
+           || __put_user(init32.func, &init->func)
+           || __put_user(init32.sarea_priv_offset, &init->sarea_priv_offset)
+           || __put_user(init32.is_pci, &init->is_pci)
+           || __put_user(init32.cp_mode, &init->cp_mode)
+           || __put_user(init32.gart_size, &init->gart_size)
+           || __put_user(init32.ring_size, &init->ring_size)
+           || __put_user(init32.usec_timeout, &init->usec_timeout)
+           || __put_user(init32.fb_bpp, &init->fb_bpp)
+           || __put_user(init32.front_offset, &init->front_offset)
+           || __put_user(init32.front_pitch, &init->front_pitch)
+           || __put_user(init32.back_offset, &init->back_offset)
+           || __put_user(init32.back_pitch, &init->back_pitch)
+           || __put_user(init32.depth_bpp, &init->depth_bpp)
+           || __put_user(init32.depth_offset, &init->depth_offset)
+           || __put_user(init32.depth_pitch, &init->depth_pitch)
+           || __put_user(init32.fb_offset, &init->fb_offset)
+           || __put_user(init32.mmio_offset, &init->mmio_offset)
+           || __put_user(init32.ring_offset, &init->ring_offset)
+           || __put_user(init32.ring_rptr_offset, &init->ring_rptr_offset)
+           || __put_user(init32.buffers_offset, &init->buffers_offset)
+           || __put_user(init32.gart_textures_offset,
+                         &init->gart_textures_offset))
+               return -EFAULT;
+
+       return drm_ioctl(file->f_dentry->d_inode, file,
+                        DRM_IOCTL_RADEON_CP_INIT, (unsigned long) init);
+}
+
+typedef struct drm_radeon_clear32 {
+       unsigned int flags;
+       unsigned int clear_color;
+       unsigned int clear_depth;
+       unsigned int color_mask;
+       unsigned int depth_mask;   /* misnamed field:  should be stencil */
+       u32          depth_boxes;
+} drm_radeon_clear32_t;
+
+static int compat_radeon_cp_clear(struct file *file, unsigned int cmd,
+                                 unsigned long arg)
+{
+       drm_radeon_clear32_t clr32;
+       drm_radeon_clear_t __user *clr;
+
+       if (copy_from_user(&clr32, (void __user *)arg, sizeof(clr32)))
+               return -EFAULT;
+
+       clr = compat_alloc_user_space(sizeof(*clr));
+       if (!access_ok(VERIFY_WRITE, clr, sizeof(*clr))
+           || __put_user(clr32.flags, &clr->flags)
+           || __put_user(clr32.clear_color, &clr->clear_color)
+           || __put_user(clr32.clear_depth, &clr->clear_depth)
+           || __put_user(clr32.color_mask, &clr->color_mask)
+           || __put_user(clr32.depth_mask, &clr->depth_mask)
+           || __put_user((void __user *)(unsigned long)clr32.depth_boxes,
+                         &clr->depth_boxes))
+               return -EFAULT;
+
+       return drm_ioctl(file->f_dentry->d_inode, file,
+                        DRM_IOCTL_RADEON_CLEAR, (unsigned long) clr);
+}
+
+typedef struct drm_radeon_stipple32 {
+       u32 mask;
+} drm_radeon_stipple32_t;
+
+static int compat_radeon_cp_stipple(struct file *file, unsigned int cmd,
+                                   unsigned long arg)
+{
+       drm_radeon_stipple32_t __user *argp = (void __user *) arg;
+       drm_radeon_stipple_t __user *request;
+       u32 mask;
+
+       if (get_user(mask, &argp->mask))
+               return -EFAULT;
+
+       request = compat_alloc_user_space(sizeof(*request));
+       if (!access_ok(VERIFY_WRITE, request, sizeof(*request))
+           || __put_user((unsigned int __user *)(unsigned long) mask,
+                         &request->mask))
+               return -EFAULT;
+
+       return drm_ioctl(file->f_dentry->d_inode, file,
+                        DRM_IOCTL_RADEON_STIPPLE, (unsigned long) request);
+}
+
+typedef struct drm_radeon_tex_image32 {
+       unsigned int x, y;              /* Blit coordinates */
+       unsigned int width, height;
+       u32 data;
+} drm_radeon_tex_image32_t;
+
+typedef struct drm_radeon_texture32 {
+       unsigned int offset;
+       int pitch;
+       int format;
+       int width;                      /* Texture image coordinates */
+       int height;
+       u32 image;
+} drm_radeon_texture32_t;
+
+static int compat_radeon_cp_texture(struct file *file, unsigned int cmd,
+                                   unsigned long arg)
+{
+       drm_radeon_texture32_t req32;
+       drm_radeon_texture_t __user *request;
+       drm_radeon_tex_image32_t img32;
+       drm_radeon_tex_image_t __user *image;
+
+       if (copy_from_user(&req32, (void __user *) arg, sizeof(req32)))
+               return -EFAULT;
+       if (req32.image == 0)
+               return -EINVAL;
+       if (copy_from_user(&img32, (void __user *)(unsigned long)req32.image,
+                          sizeof(img32)))
+               return -EFAULT;
+
+       request = compat_alloc_user_space(sizeof(*request) + sizeof(*image));
+       if (!access_ok(VERIFY_WRITE, request,
+                      sizeof(*request) + sizeof(*image)))
+               return -EFAULT;
+       image = (drm_radeon_tex_image_t __user *) (request + 1);
+
+       if (__put_user(req32.offset, &request->offset)
+           || __put_user(req32.pitch, &request->pitch)
+           || __put_user(req32.format, &request->format)
+           || __put_user(req32.width, &request->width)
+           || __put_user(req32.height, &request->height)
+           || __put_user(image, &request->image)
+           || __put_user(img32.x, &image->x)
+           || __put_user(img32.y, &image->y)
+           || __put_user(img32.width, &image->width)
+           || __put_user(img32.height, &image->height)
+           || __put_user((const void __user *)(unsigned long)img32.data,
+                         &image->data))
+               return -EFAULT;
+
+       return drm_ioctl(file->f_dentry->d_inode, file,
+                        DRM_IOCTL_RADEON_TEXTURE, (unsigned long) request);
+}
+
+typedef struct drm_radeon_vertex2_32 {
+       int idx;                        /* Index of vertex buffer */
+       int discard;                    /* Client finished with buffer? */
+       int nr_states;
+       u32 state;
+       int nr_prims;
+       u32 prim;
+} drm_radeon_vertex2_32_t;
+
+static int compat_radeon_cp_vertex2(struct file *file, unsigned int cmd,
+                                   unsigned long arg)
+{
+       drm_radeon_vertex2_32_t req32;
+       drm_radeon_vertex2_t __user *request;
+
+       if (copy_from_user(&req32, (void __user *) arg, sizeof(req32)))
+               return -EFAULT;
+
+       request = compat_alloc_user_space(sizeof(*request));
+       if (!access_ok(VERIFY_WRITE, request, sizeof(*request))
+           || __put_user(req32.idx, &request->idx)
+           || __put_user(req32.discard, &request->discard)
+           || __put_user(req32.nr_states, &request->nr_states)
+           || __put_user((void __user *)(unsigned long)req32.state,
+                         &request->state)
+           || __put_user(req32.nr_prims, &request->nr_prims)
+           || __put_user((void __user *)(unsigned long)req32.prim,
+                         &request->prim))
+               return -EFAULT;
+
+       return drm_ioctl(file->f_dentry->d_inode, file,
+                        DRM_IOCTL_RADEON_VERTEX2, (unsigned long) request);
+}
+
+typedef struct drm_radeon_cmd_buffer32 {
+       int bufsz;
+       u32 buf;
+       int nbox;
+       u32 boxes;
+} drm_radeon_cmd_buffer32_t;
+
+static int compat_radeon_cp_cmdbuf(struct file *file, unsigned int cmd,
+                                  unsigned long arg)
+{
+       drm_radeon_cmd_buffer32_t req32;
+       drm_radeon_cmd_buffer_t __user *request;
+
+       if (copy_from_user(&req32, (void __user *) arg, sizeof(req32)))
+               return -EFAULT;
+
+       request = compat_alloc_user_space(sizeof(*request));
+       if (!access_ok(VERIFY_WRITE, request, sizeof(*request))
+           || __put_user(req32.bufsz, &request->bufsz)
+           || __put_user((void __user *)(unsigned long)req32.buf,
+                         &request->buf)
+           || __put_user(req32.nbox, &request->nbox)
+           || __put_user((void __user *)(unsigned long)req32.boxes,
+                         &request->boxes))
+               return -EFAULT;
+
+       return drm_ioctl(file->f_dentry->d_inode, file,
+                        DRM_IOCTL_RADEON_CMDBUF, (unsigned long) request);
+}
+
+typedef struct drm_radeon_getparam32 {
+       int param;
+       u32 value;
+} drm_radeon_getparam32_t;
+
+static int compat_radeon_cp_getparam(struct file *file, unsigned int cmd,
+                                    unsigned long arg)
+{
+       drm_radeon_getparam32_t req32;
+       drm_radeon_getparam_t __user *request;
+
+       if (copy_from_user(&req32, (void __user *) arg, sizeof(req32)))
+               return -EFAULT;
+
+       request = compat_alloc_user_space(sizeof(*request));
+       if (!access_ok(VERIFY_WRITE, request, sizeof(*request))
+           || __put_user(req32.param, &request->param)
+           || __put_user((void __user *)(unsigned long)req32.value,
+                         &request->value))
+               return -EFAULT;
+
+       return drm_ioctl(file->f_dentry->d_inode, file,
+                        DRM_IOCTL_RADEON_GETPARAM, (unsigned long) request);
+}
+
+typedef struct drm_radeon_mem_alloc32 {
+       int region;
+       int alignment;
+       int size;
+       u32 region_offset;      /* offset from start of fb or GART */
+} drm_radeon_mem_alloc32_t;
+
+static int compat_radeon_mem_alloc(struct file *file, unsigned int cmd,
+                                  unsigned long arg)
+{
+       drm_radeon_mem_alloc32_t req32;
+       drm_radeon_mem_alloc_t __user *request;
+
+       if (copy_from_user(&req32, (void __user *) arg, sizeof(req32)))
+               return -EFAULT;
+
+       request = compat_alloc_user_space(sizeof(*request));
+       if (!access_ok(VERIFY_WRITE, request, sizeof(*request))
+           || __put_user(req32.region, &request->region)
+           || __put_user(req32.alignment, &request->alignment)
+           || __put_user(req32.size, &request->size)
+           || __put_user((int __user *)(unsigned long)req32.region_offset,
+                         &request->region_offset))
+               return -EFAULT;
+
+       return drm_ioctl(file->f_dentry->d_inode, file,
+                        DRM_IOCTL_RADEON_ALLOC, (unsigned long) request);
+}
+
+typedef struct drm_radeon_irq_emit32 {
+       u32 irq_seq;
+} drm_radeon_irq_emit32_t;
+
+static int compat_radeon_irq_emit(struct file *file, unsigned int cmd,
+                                 unsigned long arg)
+{
+       drm_radeon_irq_emit32_t req32;
+       drm_radeon_irq_emit_t __user *request;
+
+       if (copy_from_user(&req32, (void __user *) arg, sizeof(req32)))
+               return -EFAULT;
+
+       request = compat_alloc_user_space(sizeof(*request));
+       if (!access_ok(VERIFY_WRITE, request, sizeof(*request))
+           || __put_user((int __user *)(unsigned long)req32.irq_seq,
+                         &request->irq_seq))
+               return -EFAULT;
+
+       return drm_ioctl(file->f_dentry->d_inode, file,
+                        DRM_IOCTL_RADEON_IRQ_EMIT, (unsigned long) request);
+}
+
+drm_ioctl_compat_t *radeon_compat_ioctls[] = {
+       [DRM_RADEON_CP_INIT] = compat_radeon_cp_init,
+       [DRM_RADEON_CLEAR] = compat_radeon_cp_clear,
+       [DRM_RADEON_STIPPLE] = compat_radeon_cp_stipple,
+       [DRM_RADEON_TEXTURE] = compat_radeon_cp_texture,
+       [DRM_RADEON_VERTEX2] = compat_radeon_cp_vertex2,
+       [DRM_RADEON_CMDBUF] = compat_radeon_cp_cmdbuf,
+       [DRM_RADEON_GETPARAM] = compat_radeon_cp_getparam,
+       [DRM_RADEON_ALLOC] = compat_radeon_mem_alloc,
+       [DRM_RADEON_IRQ_EMIT] = compat_radeon_irq_emit,
+};
+
+/**
+ * Called whenever a 32-bit process running under a 64-bit kernel
+ * performs an ioctl on /dev/dri/card<n>.
+ *
+ * \param filp file pointer.
+ * \param cmd command.
+ * \param arg user argument.
+ * \return zero on success or negative number on failure.
+ */
+long radeon_compat_ioctl(struct file *filp, unsigned int cmd,
+                        unsigned long arg)
+{
+       unsigned int nr = DRM_IOCTL_NR(cmd);
+       drm_ioctl_compat_t *fn = NULL;
+       int ret;
+
+       if (nr < DRM_COMMAND_BASE)
+               return drm_compat_ioctl(filp, cmd, arg);
+
+       if (nr < DRM_COMMAND_BASE + DRM_ARRAY_SIZE(radeon_compat_ioctls))
+               fn = radeon_compat_ioctls[nr - DRM_COMMAND_BASE];
+
+       lock_kernel();          /* XXX for now */
+       if (fn != NULL)
+               ret = (*fn)(filp, cmd, arg);
+       else
+               ret = drm_ioctl(filp->f_dentry->d_inode, filp, cmd, arg);
+       unlock_kernel();
+
+       return ret;
+}
index cd25f28e26a38874738705d935c37d51de4cda42..40474a65f56d1e8dd4d6075d6d4356716560b4e4 100644 (file)
 #include "radeon_drm.h"
 #include "radeon_drv.h"
 
+static __inline__ u32 radeon_acknowledge_irqs(drm_radeon_private_t *dev_priv, u32 mask)
+{
+       u32 irqs = RADEON_READ(RADEON_GEN_INT_STATUS) & mask;
+       if (irqs)
+               RADEON_WRITE(RADEON_GEN_INT_STATUS, irqs);
+       return irqs;
+}
+
 /* Interrupts - Used for device synchronization and flushing in the
  * following circumstances:
  *
@@ -63,8 +71,8 @@ irqreturn_t radeon_driver_irq_handler( DRM_IRQ_ARGS )
        /* Only consider the bits we're interested in - others could be used
         * outside the DRM
         */
-       stat = RADEON_READ(RADEON_GEN_INT_STATUS)
-            & (RADEON_SW_INT_TEST | RADEON_CRTC_VBLANK_STAT);
+       stat = radeon_acknowledge_irqs(dev_priv, (RADEON_SW_INT_TEST_ACK | 
+                                                 RADEON_CRTC_VBLANK_STAT));
        if (!stat)
                return IRQ_NONE;
 
@@ -80,19 +88,9 @@ irqreturn_t radeon_driver_irq_handler( DRM_IRQ_ARGS )
                drm_vbl_send_signals( dev );
        }
 
-       /* Acknowledge interrupts we handle */
-       RADEON_WRITE(RADEON_GEN_INT_STATUS, stat);
        return IRQ_HANDLED;
 }
 
-static __inline__ void radeon_acknowledge_irqs(drm_radeon_private_t *dev_priv)
-{
-       u32 tmp = RADEON_READ( RADEON_GEN_INT_STATUS )
-               & (RADEON_SW_INT_TEST_ACK | RADEON_CRTC_VBLANK_STAT);
-       if (tmp)
-               RADEON_WRITE( RADEON_GEN_INT_STATUS, tmp );
-}
-
 static int radeon_emit_irq(drm_device_t *dev)
 {
        drm_radeon_private_t *dev_priv = dev->dev_private;
@@ -141,7 +139,7 @@ int radeon_driver_vblank_wait(drm_device_t *dev, unsigned int *sequence)
                return DRM_ERR(EINVAL);
        }
 
-       radeon_acknowledge_irqs( dev_priv );
+       radeon_acknowledge_irqs(dev_priv, RADEON_CRTC_VBLANK_STAT);
 
        dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE;
 
@@ -219,7 +217,8 @@ void radeon_driver_irq_preinstall( drm_device_t *dev ) {
        RADEON_WRITE( RADEON_GEN_INT_CNTL, 0 );
 
        /* Clear bits if they're already high */
-       radeon_acknowledge_irqs( dev_priv );
+       radeon_acknowledge_irqs(dev_priv, (RADEON_SW_INT_TEST_ACK |
+                                          RADEON_CRTC_VBLANK_STAT));
 }
 
 void radeon_driver_irq_postinstall( drm_device_t *dev ) {
index 7def6ad517984c27542b8b4942081299119aba2a..62cda25724e30d6501870683c53849f5d8e273a5 100644 (file)
@@ -163,8 +163,7 @@ static void ds1620_out(int cmd, int bits, int value)
        netwinder_ds1620_reset();
        netwinder_unlock(&flags);
 
-       set_current_state(TASK_INTERRUPTIBLE);
-       schedule_timeout(2);
+       msleep(20);
 }
 
 static unsigned int ds1620_in(int cmd, int bits)
index 220a227e606113c8aa4ccd33b2e666daba5d6f03..65ffc0be3df989e30de09e7f8e37b45212d78adc 100644 (file)
@@ -1176,8 +1176,8 @@ KERN_INFO "Compressor for zftape (lzrw3 algorithm)\n");
         }
 #else /* !MODULE */
        /* print a short no-nonsense boot message */
-       printk("zftape compressor v1.00a 970514\n");
-       printk("For use with " FTAPE_VERSION "\n");
+       printk(KERN_INFO "zftape compressor v1.00a 970514\n");
+       printk(KERN_INFO "For use with " FTAPE_VERSION "\n");
 #endif /* MODULE */
        TRACE(ft_t_info, "zft_compressor_init @ 0x%p", zft_compressor_init);
        TRACE(ft_t_info, "installing compressor for zftape ...");
index 5ec732e6ca9221ee3b3ea5fb9aa71c0424e51725..762fa430fb5be3b6a7615eed705e741509475ba7 100644 (file)
@@ -834,7 +834,7 @@ int hpet_alloc(struct hpet_data *hdp)
        printk("\n");
 
        ns = hpetp->hp_period;  /* femptoseconds, 10^-15 */
-       do_div(ns, 1000000);    /* convert to nanoseconds, 10^-9 */
+       ns /= 1000000;          /* convert to nanoseconds, 10^-9 */
        printk(KERN_INFO "hpet%d: %ldns tick, %d %d-bit timers\n",
                hpetp->hp_which, ns, hpetp->hp_ntimer,
                cap & HPET_COUNTER_SIZE_MASK ? 64 : 32);
index a8119764028373dddb9eeffc27b64bfa3cd463de..6c4b3f986d0ccf26828fe08d61a21810786a6287 100644 (file)
 #include <linux/types.h>
 #include <linux/init.h>
 #include <linux/proc_fs.h>
-#include <linux/apm_bios.h>
+#include <linux/seq_file.h>
+#include <linux/dmi.h>
 #include <asm/uaccess.h>
 #include <asm/io.h>
 
 #include <linux/i8k.h>
 
-#define I8K_VERSION            "1.13 14/05/2002"
+#define I8K_VERSION            "1.14 21/02/2005"
 
 #define I8K_SMM_FN_STATUS      0x0025
 #define I8K_SMM_POWER_STATUS   0x0069
@@ -34,7 +35,8 @@
 #define I8K_SMM_GET_FAN                0x00a3
 #define I8K_SMM_GET_SPEED      0x02a3
 #define I8K_SMM_GET_TEMP       0x10a3
-#define I8K_SMM_GET_DELL_SIG   0xffa3
+#define I8K_SMM_GET_DELL_SIG1  0xfea3
+#define I8K_SMM_GET_DELL_SIG2  0xffa3
 #define I8K_SMM_BIOS_VERSION   0x00a6
 
 #define I8K_FAN_MULT           30
 
 #define I8K_TEMPERATURE_BUG    1
 
-#define DELL_SIGNATURE         "Dell Computer"
-
-static char *supported_models[] = {
-    "Inspiron",
-    "Latitude",
-    NULL
-};
-
-static char system_vendor[48] = "?";
-static char product_name [48] = "?";
-static char bios_version [4]  = "?";
-static char serial_number[16] = "?";
+static char bios_version[4];
 
 MODULE_AUTHOR("Massimo Dal Zotto (dz@debian.org)");
 MODULE_DESCRIPTION("Driver for accessing SMM BIOS on Dell laptops");
@@ -73,6 +64,10 @@ static int force;
 module_param(force, bool, 0);
 MODULE_PARM_DESC(force, "Force loading without checking for supported models");
 
+static int ignore_dmi;
+module_param(ignore_dmi, bool, 0);
+MODULE_PARM_DESC(ignore_dmi, "Continue probing hardware even if DMI data does not match");
+
 static int restricted;
 module_param(restricted, bool, 0);
 MODULE_PARM_DESC(restricted, "Allow fan control if SYS_ADMIN capability set");
@@ -81,69 +76,69 @@ static int power_status;
 module_param(power_status, bool, 0600);
 MODULE_PARM_DESC(power_status, "Report power status in /proc/i8k");
 
-static ssize_t i8k_read(struct file *, char __user *, size_t, loff_t *);
+static int i8k_open_fs(struct inode *inode, struct file *file);
 static int i8k_ioctl(struct inode *, struct file *, unsigned int,
                     unsigned long);
 
 static struct file_operations i8k_fops = {
-    .read      = i8k_read,
-    .ioctl     = i8k_ioctl,
+       .open           = i8k_open_fs,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = single_release,
+       .ioctl          = i8k_ioctl,
+};
+
+struct smm_regs {
+       unsigned int eax;
+       unsigned int ebx __attribute__ ((packed));
+       unsigned int ecx __attribute__ ((packed));
+       unsigned int edx __attribute__ ((packed));
+       unsigned int esi __attribute__ ((packed));
+       unsigned int edi __attribute__ ((packed));
 };
 
-typedef struct {
-    unsigned int eax;
-    unsigned int ebx __attribute__ ((packed));
-    unsigned int ecx __attribute__ ((packed));
-    unsigned int edx __attribute__ ((packed));
-    unsigned int esi __attribute__ ((packed));
-    unsigned int edi __attribute__ ((packed));
-} SMMRegisters;
-
-typedef struct {
-    u8 type;
-    u8 length;
-    u16        handle;
-} DMIHeader;
+static inline char *i8k_get_dmi_data(int field)
+{
+       return dmi_get_system_info(field) ? : "N/A";
+}
 
 /*
  * Call the System Management Mode BIOS. Code provided by Jonathan Buzzard.
  */
-static int i8k_smm(SMMRegisters *regs)
+static int i8k_smm(struct smm_regs *regs)
 {
-    int rc;
-    int eax = regs->eax;
-
-    asm("pushl %%eax\n\t" \
-       "movl 0(%%eax),%%edx\n\t" \
-       "push %%edx\n\t" \
-       "movl 4(%%eax),%%ebx\n\t" \
-       "movl 8(%%eax),%%ecx\n\t" \
-       "movl 12(%%eax),%%edx\n\t" \
-       "movl 16(%%eax),%%esi\n\t" \
-       "movl 20(%%eax),%%edi\n\t" \
-       "popl %%eax\n\t" \
-       "out %%al,$0xb2\n\t" \
-       "out %%al,$0x84\n\t" \
-       "xchgl %%eax,(%%esp)\n\t"
-       "movl %%ebx,4(%%eax)\n\t" \
-       "movl %%ecx,8(%%eax)\n\t" \
-       "movl %%edx,12(%%eax)\n\t" \
-       "movl %%esi,16(%%eax)\n\t" \
-       "movl %%edi,20(%%eax)\n\t" \
-       "popl %%edx\n\t" \
-       "movl %%edx,0(%%eax)\n\t" \
-       "lahf\n\t" \
-       "shrl $8,%%eax\n\t" \
-       "andl $1,%%eax\n" \
-       : "=a" (rc)
-       : "a" (regs)
-       : "%ebx", "%ecx", "%edx", "%esi", "%edi", "memory");
-
-    if ((rc != 0) || ((regs->eax & 0xffff) == 0xffff) || (regs->eax == eax)) {
-       return -EINVAL;
-    }
-
-    return 0;
+       int rc;
+       int eax = regs->eax;
+
+       asm("pushl %%eax\n\t"
+           "movl 0(%%eax),%%edx\n\t"
+           "push %%edx\n\t"
+           "movl 4(%%eax),%%ebx\n\t"
+           "movl 8(%%eax),%%ecx\n\t"
+           "movl 12(%%eax),%%edx\n\t"
+           "movl 16(%%eax),%%esi\n\t"
+           "movl 20(%%eax),%%edi\n\t"
+           "popl %%eax\n\t"
+           "out %%al,$0xb2\n\t"
+           "out %%al,$0x84\n\t"
+           "xchgl %%eax,(%%esp)\n\t"
+           "movl %%ebx,4(%%eax)\n\t"
+           "movl %%ecx,8(%%eax)\n\t"
+           "movl %%edx,12(%%eax)\n\t"
+           "movl %%esi,16(%%eax)\n\t"
+           "movl %%edi,20(%%eax)\n\t"
+           "popl %%edx\n\t"
+           "movl %%edx,0(%%eax)\n\t"
+           "lahf\n\t"
+           "shrl $8,%%eax\n\t"
+           "andl $1,%%eax\n":"=a"(rc)
+           :    "a"(regs)
+           :    "%ebx", "%ecx", "%edx", "%esi", "%edi", "memory");
+
+       if (rc != 0 || (regs->eax & 0xffff) == 0xffff || regs->eax == eax)
+               return -EINVAL;
+
+       return 0;
 }
 
 /*
@@ -152,24 +147,9 @@ static int i8k_smm(SMMRegisters *regs)
  */
 static int i8k_get_bios_version(void)
 {
-    SMMRegisters regs = { 0, 0, 0, 0, 0, 0 };
-    int rc;
-
-    regs.eax = I8K_SMM_BIOS_VERSION;
-    if ((rc=i8k_smm(&regs)) < 0) {
-       return rc;
-    }
-
-    return regs.eax;
-}
+       struct smm_regs regs = { .eax = I8K_SMM_BIOS_VERSION, };
 
-/*
- * Read the machine id.
- */
-static int i8k_get_serial_number(unsigned char *buff)
-{
-    strlcpy(buff, serial_number, sizeof(serial_number));
-    return 0;
+       return i8k_smm(&regs) ? : regs.eax;
 }
 
 /*
@@ -177,24 +157,22 @@ static int i8k_get_serial_number(unsigned char *buff)
  */
 static int i8k_get_fn_status(void)
 {
-    SMMRegisters regs = { 0, 0, 0, 0, 0, 0 };
-    int rc;
-
-    regs.eax = I8K_SMM_FN_STATUS;
-    if ((rc=i8k_smm(&regs)) < 0) {
-       return rc;
-    }
-
-    switch ((regs.eax >> I8K_FN_SHIFT) & I8K_FN_MASK) {
-    case I8K_FN_UP:
-       return I8K_VOL_UP;
-    case I8K_FN_DOWN:
-       return I8K_VOL_DOWN;
-    case I8K_FN_MUTE:
-       return I8K_VOL_MUTE;
-    default:
-       return 0;
-    }
+       struct smm_regs regs = { .eax = I8K_SMM_FN_STATUS, };
+       int rc;
+
+       if ((rc = i8k_smm(&regs)) < 0)
+               return rc;
+
+       switch ((regs.eax >> I8K_FN_SHIFT) & I8K_FN_MASK) {
+       case I8K_FN_UP:
+               return I8K_VOL_UP;
+       case I8K_FN_DOWN:
+               return I8K_VOL_DOWN;
+       case I8K_FN_MUTE:
+               return I8K_VOL_MUTE;
+       default:
+               return 0;
+       }
 }
 
 /*
@@ -202,20 +180,13 @@ static int i8k_get_fn_status(void)
  */
 static int i8k_get_power_status(void)
 {
-    SMMRegisters regs = { 0, 0, 0, 0, 0, 0 };
-    int rc;
-
-    regs.eax = I8K_SMM_POWER_STATUS;
-    if ((rc=i8k_smm(&regs)) < 0) {
-       return rc;
-    }
-
-    switch (regs.eax & 0xff) {
-    case I8K_POWER_AC:
-       return I8K_AC;
-    default:
-       return I8K_BATTERY;
-    }
+       struct smm_regs regs = { .eax = I8K_SMM_POWER_STATUS, };
+       int rc;
+
+       if ((rc = i8k_smm(&regs)) < 0)
+               return rc;
+
+       return (regs.eax & 0xff) == I8K_POWER_AC ? I8K_AC : I8K_BATTERY;
 }
 
 /*
@@ -223,16 +194,10 @@ static int i8k_get_power_status(void)
  */
 static int i8k_get_fan_status(int fan)
 {
-    SMMRegisters regs = { 0, 0, 0, 0, 0, 0 };
-    int rc;
-
-    regs.eax = I8K_SMM_GET_FAN;
-    regs.ebx = fan & 0xff;
-    if ((rc=i8k_smm(&regs)) < 0) {
-       return rc;
-    }
+       struct smm_regs regs = { .eax = I8K_SMM_GET_FAN, };
 
-    return (regs.eax & 0xff);
+       regs.ebx = fan & 0xff;
+       return i8k_smm(&regs) ? : regs.eax & 0xff;
 }
 
 /*
@@ -240,16 +205,10 @@ static int i8k_get_fan_status(int fan)
  */
 static int i8k_get_fan_speed(int fan)
 {
-    SMMRegisters regs = { 0, 0, 0, 0, 0, 0 };
-    int rc;
+       struct smm_regs regs = { .eax = I8K_SMM_GET_SPEED, };
 
-    regs.eax = I8K_SMM_GET_SPEED;
-    regs.ebx = fan & 0xff;
-    if ((rc=i8k_smm(&regs)) < 0) {
-       return rc;
-    }
-
-    return (regs.eax & 0xffff) * I8K_FAN_MULT;
+       regs.ebx = fan & 0xff;
+       return i8k_smm(&regs) ? : (regs.eax & 0xffff) * I8K_FAN_MULT;
 }
 
 /*
@@ -257,532 +216,318 @@ static int i8k_get_fan_speed(int fan)
  */
 static int i8k_set_fan(int fan, int speed)
 {
-    SMMRegisters regs = { 0, 0, 0, 0, 0, 0 };
-    int rc;
-
-    speed = (speed < 0) ? 0 : ((speed > I8K_FAN_MAX) ? I8K_FAN_MAX : speed);
+       struct smm_regs regs = { .eax = I8K_SMM_SET_FAN, };
 
-    regs.eax = I8K_SMM_SET_FAN;
-    regs.ebx = (fan & 0xff) | (speed << 8);
-    if ((rc=i8k_smm(&regs)) < 0) {
-       return rc;
-    }
+       speed = (speed < 0) ? 0 : ((speed > I8K_FAN_MAX) ? I8K_FAN_MAX : speed);
+       regs.ebx = (fan & 0xff) | (speed << 8);
 
-    return (i8k_get_fan_status(fan));
+       return i8k_smm(&regs) ? : i8k_get_fan_status(fan);
 }
 
 /*
  * Read the cpu temperature.
  */
-static int i8k_get_cpu_temp(void)
+static int i8k_get_temp(int sensor)
 {
-    SMMRegisters regs = { 0, 0, 0, 0, 0, 0 };
-    int rc;
-    int temp;
+       struct smm_regs regs = { .eax = I8K_SMM_GET_TEMP, };
+       int rc;
+       int temp;
 
 #ifdef I8K_TEMPERATURE_BUG
-    static int prev = 0;
+       static int prev;
 #endif
+       regs.ebx = sensor & 0xff;
+       if ((rc = i8k_smm(&regs)) < 0)
+               return rc;
 
-    regs.eax = I8K_SMM_GET_TEMP;
-    if ((rc=i8k_smm(&regs)) < 0) {
-       return rc;
-    }
-    temp = regs.eax & 0xff;
+       temp = regs.eax & 0xff;
 
 #ifdef I8K_TEMPERATURE_BUG
-    /*
-     * Sometimes the temperature sensor returns 0x99, which is out of range.
-     * In this case we return (once) the previous cached value. For example:
-     # 1003655137 00000058 00005a4b
-     # 1003655138 00000099 00003a80 <--- 0x99 = 153 degrees
-     # 1003655139 00000054 00005c52
-     */
-    if (temp > I8K_MAX_TEMP) {
-       temp = prev;
-       prev = I8K_MAX_TEMP;
-    } else {
-       prev = temp;
-    }
+       /*
+        * Sometimes the temperature sensor returns 0x99, which is out of range.
+        * In this case we return (once) the previous cached value. For example:
+        # 1003655137 00000058 00005a4b
+        # 1003655138 00000099 00003a80 <--- 0x99 = 153 degrees
+        # 1003655139 00000054 00005c52
+        */
+       if (temp > I8K_MAX_TEMP) {
+               temp = prev;
+               prev = I8K_MAX_TEMP;
+       } else {
+               prev = temp;
+       }
 #endif
 
-    return temp;
+       return temp;
 }
 
-static int i8k_get_dell_signature(void)
+static int i8k_get_dell_signature(int req_fn)
 {
-    SMMRegisters regs = { 0, 0, 0, 0, 0, 0 };
-    int rc;
+       struct smm_regs regs = { .eax = req_fn, };
+       int rc;
 
-    regs.eax = I8K_SMM_GET_DELL_SIG;
-    if ((rc=i8k_smm(&regs)) < 0) {
-       return rc;
-    }
+       if ((rc = i8k_smm(&regs)) < 0)
+               return rc;
 
-    if ((regs.eax == 1145651527) && (regs.edx == 1145392204)) {
-       return 0;
-    } else {
-       return -1;
-    }
+       return regs.eax == 1145651527 && regs.edx == 1145392204 ? 0 : -1;
 }
 
 static int i8k_ioctl(struct inode *ip, struct file *fp, unsigned int cmd,
                     unsigned long arg)
 {
-    int val;
-    int speed;
-    unsigned char buff[16];
-    int __user *argp = (int __user *)arg;
-
-    if (!argp)
-       return -EINVAL;
-
-    switch (cmd) {
-    case I8K_BIOS_VERSION:
-       val = i8k_get_bios_version();
-       break;
-
-    case I8K_MACHINE_ID:
-       memset(buff, 0, 16);
-       val = i8k_get_serial_number(buff);
-       break;
-
-    case I8K_FN_STATUS:
-       val = i8k_get_fn_status();
-       break;
-
-    case I8K_POWER_STATUS:
-       val = i8k_get_power_status();
-       break;
-
-    case I8K_GET_TEMP:
-       val = i8k_get_cpu_temp();
-       break;
-
-    case I8K_GET_SPEED:
-       if (copy_from_user(&val, argp, sizeof(int))) {
-           return -EFAULT;
-       }
-       val = i8k_get_fan_speed(val);
-       break;
-
-    case I8K_GET_FAN:
-       if (copy_from_user(&val, argp, sizeof(int))) {
-           return -EFAULT;
-       }
-       val = i8k_get_fan_status(val);
-       break;
+       int val = 0;
+       int speed;
+       unsigned char buff[16];
+       int __user *argp = (int __user *)arg;
 
-    case I8K_SET_FAN:
-       if (restricted && !capable(CAP_SYS_ADMIN)) {
-           return -EPERM;
-       }
-       if (copy_from_user(&val, argp, sizeof(int))) {
-           return -EFAULT;
-       }
-       if (copy_from_user(&speed, argp+1, sizeof(int))) {
-           return -EFAULT;
-       }
-       val = i8k_set_fan(val, speed);
-       break;
+       if (!argp)
+               return -EINVAL;
 
-    default:
-       return -EINVAL;
-    }
+       switch (cmd) {
+       case I8K_BIOS_VERSION:
+               val = i8k_get_bios_version();
+               break;
 
-    if (val < 0) {
-       return val;
-    }
+       case I8K_MACHINE_ID:
+               memset(buff, 0, 16);
+               strlcpy(buff, i8k_get_dmi_data(DMI_PRODUCT_SERIAL), sizeof(buff));
+               break;
 
-    switch (cmd) {
-    case I8K_BIOS_VERSION:
-       if (copy_to_user(argp, &val, 4)) {
-           return -EFAULT;
-       }
-       break;
-    case I8K_MACHINE_ID:
-       if (copy_to_user(argp, buff, 16)) {
-           return -EFAULT;
-       }
-       break;
-    default:
-       if (copy_to_user(argp, &val, sizeof(int))) {
-           return -EFAULT;
-       }
-       break;
-    }
+       case I8K_FN_STATUS:
+               val = i8k_get_fn_status();
+               break;
 
-    return 0;
-}
+       case I8K_POWER_STATUS:
+               val = i8k_get_power_status();
+               break;
 
-/*
- * Print the information for /proc/i8k.
- */
-static int i8k_get_info(char *buffer, char **start, off_t fpos, int length)
-{
-    int n, fn_key, cpu_temp, ac_power;
-    int left_fan, right_fan, left_speed, right_speed;
-
-    cpu_temp     = i8k_get_cpu_temp();                 /* 11100 Âµs */
-    left_fan     = i8k_get_fan_status(I8K_FAN_LEFT);   /*   580 Âµs */
-    right_fan    = i8k_get_fan_status(I8K_FAN_RIGHT);  /*   580 Âµs */
-    left_speed   = i8k_get_fan_speed(I8K_FAN_LEFT);    /*   580 Âµs */
-    right_speed  = i8k_get_fan_speed(I8K_FAN_RIGHT);   /*   580 Âµs */
-    fn_key       = i8k_get_fn_status();                        /*   750 Âµs */
-    if (power_status) {
-       ac_power = i8k_get_power_status();              /* 14700 Âµs */
-    } else {
-       ac_power = -1;
-    }
-
-    /*
-     * Info:
-     *
-     * 1)  Format version (this will change if format changes)
-     * 2)  BIOS version
-     * 3)  BIOS machine ID
-     * 4)  Cpu temperature
-     * 5)  Left fan status
-     * 6)  Right fan status
-     * 7)  Left fan speed
-     * 8)  Right fan speed
-     * 9)  AC power
-     * 10) Fn Key status
-     */
-    n = sprintf(buffer, "%s %s %s %d %d %d %d %d %d %d\n",
-               I8K_PROC_FMT,
-               bios_version,
-               serial_number,
-               cpu_temp,
-               left_fan,
-               right_fan,
-               left_speed,
-               right_speed,
-               ac_power,
-               fn_key);
-
-    return n;
-}
+       case I8K_GET_TEMP:
+               val = i8k_get_temp(0);
+               break;
 
-static ssize_t i8k_read(struct file *f, char __user *buffer, size_t len, loff_t *fpos)
-{
-    int n;
-    char info[128];
+       case I8K_GET_SPEED:
+               if (copy_from_user(&val, argp, sizeof(int)))
+                       return -EFAULT;
 
-    n = i8k_get_info(info, NULL, 0, 128);
-    if (n <= 0) {
-       return n;
-    }
+               val = i8k_get_fan_speed(val);
+               break;
 
-    if (*fpos >= n) {
-       return 0;
-    }
+       case I8K_GET_FAN:
+               if (copy_from_user(&val, argp, sizeof(int)))
+                       return -EFAULT;
 
-    if ((*fpos + len) >= n) {
-       len = n - *fpos;
-    }
+               val = i8k_get_fan_status(val);
+               break;
 
-    if (copy_to_user(buffer, info, len) != 0) {
-       return -EFAULT;
-    }
+       case I8K_SET_FAN:
+               if (restricted && !capable(CAP_SYS_ADMIN))
+                       return -EPERM;
 
-    *fpos += len;
-    return len;
-}
+               if (copy_from_user(&val, argp, sizeof(int)))
+                       return -EFAULT;
 
-static char* __init string_trim(char *s, int size)
-{
-    int len;
-    char *p;
+               if (copy_from_user(&speed, argp + 1, sizeof(int)))
+                       return -EFAULT;
 
-    if ((len = strlen(s)) > size) {
-       len = size;
-    }
+               val = i8k_set_fan(val, speed);
+               break;
 
-    for (p=s+len-1; len && (*p==' '); len--,p--) {
-       *p = '\0';
-    }
+       default:
+               return -EINVAL;
+       }
 
-    return s;
-}
+       if (val < 0)
+               return val;
 
-/* DMI code, stolen from arch/i386/kernel/dmi_scan.c */
+       switch (cmd) {
+       case I8K_BIOS_VERSION:
+               if (copy_to_user(argp, &val, 4))
+                       return -EFAULT;
 
-/*
- * |<-- dmi->length -->|
- * |                   |
- * |dmi header    s=N  | string1,\0, ..., stringN,\0, ..., \0
- *                |                       |
- *                +-----------------------+
- */
-static char* __init dmi_string(DMIHeader *dmi, u8 s)
-{
-    u8 *p;
+               break;
+       case I8K_MACHINE_ID:
+               if (copy_to_user(argp, buff, 16))
+                       return -EFAULT;
 
-    if (!s) {
-       return "";
-    }
-    s--;
+               break;
+       default:
+               if (copy_to_user(argp, &val, sizeof(int)))
+                       return -EFAULT;
 
-    p = (u8 *)dmi + dmi->length;
-    while (s > 0) {
-       p += strlen(p);
-       p++;
-       s--;
-    }
+               break;
+       }
 
-    return p;
+       return 0;
 }
 
-static void __init dmi_decode(DMIHeader *dmi)
+/*
+ * Print the information for /proc/i8k.
+ */
+static int i8k_proc_show(struct seq_file *seq, void *offset)
 {
-    u8 *data = (u8 *) dmi;
-    char *p;
-
-#ifdef I8K_DEBUG
-    int i;
-    printk("%08x ", (int)data);
-    for (i=0; i<data[1] && i<64; i++) {
-       printk("%02x ", data[i]);
-    }
-    printk("\n");
-#endif
-
-    switch (dmi->type) {
-    case  0:   /* BIOS Information */
-       p = dmi_string(dmi,data[5]);
-       if (*p) {
-           strlcpy(bios_version, p, sizeof(bios_version));
-           string_trim(bios_version, sizeof(bios_version));
-       }
-       break;  
-    case 1:    /* System Information */
-       p = dmi_string(dmi,data[4]);
-       if (*p) {
-           strlcpy(system_vendor, p, sizeof(system_vendor));
-           string_trim(system_vendor, sizeof(system_vendor));
-       }
-       p = dmi_string(dmi,data[5]);
-       if (*p) {
-           strlcpy(product_name, p, sizeof(product_name));
-           string_trim(product_name, sizeof(product_name));
-       }
-       p = dmi_string(dmi,data[7]);
-       if (*p) {
-           strlcpy(serial_number, p, sizeof(serial_number));
-           string_trim(serial_number, sizeof(serial_number));
-       }
-       break;
-    }
-}
+       int fn_key, cpu_temp, ac_power;
+       int left_fan, right_fan, left_speed, right_speed;
+
+       cpu_temp        = i8k_get_temp(0);                      /* 11100 Âµs */
+       left_fan        = i8k_get_fan_status(I8K_FAN_LEFT);     /*   580 Âµs */
+       right_fan       = i8k_get_fan_status(I8K_FAN_RIGHT);    /*   580 Âµs */
+       left_speed      = i8k_get_fan_speed(I8K_FAN_LEFT);      /*   580 Âµs */
+       right_speed     = i8k_get_fan_speed(I8K_FAN_RIGHT);     /*   580 Âµs */
+       fn_key          = i8k_get_fn_status();                  /*   750 Âµs */
+       if (power_status)
+               ac_power = i8k_get_power_status();              /* 14700 Âµs */
+       else
+               ac_power = -1;
 
-static int __init dmi_table(u32 base, int len, int num, void (*fn)(DMIHeader*))
-{
-    u8 *buf;
-    u8 *data;
-    DMIHeader *dmi;
-    int i = 1;
-
-    buf = ioremap(base, len);
-    if (buf == NULL) {
-       return -1;
-    }
-    data = buf;
-
-    /*
-     * Stop when we see al the items the table claimed to have
-     * or we run off the end of the table (also happens)
-     */
-    while ((i<num) && ((data-buf) < len)) {
-       dmi = (DMIHeader *)data;
-       /*
-        * Avoid misparsing crud if the length of the last
-        * record is crap
-        */
-       if ((data-buf+dmi->length) >= len) {
-           break;
-       }
-       fn(dmi);
-       data += dmi->length;
        /*
-        * Don't go off the end of the data if there is
-        * stuff looking like string fill past the end
+        * Info:
+        *
+        * 1)  Format version (this will change if format changes)
+        * 2)  BIOS version
+        * 3)  BIOS machine ID
+        * 4)  Cpu temperature
+        * 5)  Left fan status
+        * 6)  Right fan status
+        * 7)  Left fan speed
+        * 8)  Right fan speed
+        * 9)  AC power
+        * 10) Fn Key status
         */
-       while (((data-buf) < len) && (*data || data[1])) {
-           data++;
-       }
-       data += 2;
-       i++;
-    }
-    iounmap(buf);
-
-    return 0;
+       return seq_printf(seq, "%s %s %s %d %d %d %d %d %d %d\n",
+                         I8K_PROC_FMT,
+                         bios_version,
+                         dmi_get_system_info(DMI_PRODUCT_SERIAL) ? : "N/A",
+                         cpu_temp,
+                         left_fan, right_fan, left_speed, right_speed,
+                         ac_power, fn_key);
 }
 
-static int __init dmi_iterate(void (*decode)(DMIHeader *))
+static int i8k_open_fs(struct inode *inode, struct file *file)
 {
-       unsigned char buf[20];
-       void __iomem *p = ioremap(0xe0000, 0x20000), *q;
-
-       if (!p)
-               return -1;
-
-       for (q = p; q < p + 0x20000; q += 16) {
-               memcpy_fromio(buf, q, 20);
-               if (memcmp(buf, "_DMI_", 5)==0) {
-                       u16 num  = buf[13]<<8  | buf[12];
-                       u16 len  = buf [7]<<8  | buf [6];
-                       u32 base = buf[11]<<24 | buf[10]<<16 | buf[9]<<8 | buf[8];
-#ifdef I8K_DEBUG
-                       printk(KERN_INFO "DMI %d.%d present.\n",
-                          buf[14]>>4, buf[14]&0x0F);
-                       printk(KERN_INFO "%d structures occupying %d bytes.\n",
-                          buf[13]<<8 | buf[12],
-                          buf [7]<<8 | buf[6]);
-                       printk(KERN_INFO "DMI table at 0x%08X.\n",
-                          buf[11]<<24 | buf[10]<<16 | buf[9]<<8 | buf[8]);
-#endif
-                       if (dmi_table(base, len, num, decode)==0) {
-                               iounmap(p);
-                               return 0;
-                       }
-               }
-       }
-       iounmap(p);
-       return -1;
+       return single_open(file, i8k_proc_show, NULL);
 }
-/* end of DMI code */
-
-/*
- * Get DMI information.
- */
-static int __init i8k_dmi_probe(void)
-{
-    char **p;
-
-    if (dmi_iterate(dmi_decode) != 0) {
-       printk(KERN_INFO "i8k: unable to get DMI information\n");
-       return -ENODEV;
-    }
-
-    if (strncmp(system_vendor,DELL_SIGNATURE,strlen(DELL_SIGNATURE)) != 0) {
-       printk(KERN_INFO "i8k: not running on a Dell system\n");
-       return -ENODEV;
-    }
-
-    for (p=supported_models; ; p++) {
-       if (!*p) {
-           printk(KERN_INFO "i8k: unsupported model: %s\n", product_name);
-           return -ENODEV;
-       }
-       if (strncmp(product_name,*p,strlen(*p)) == 0) {
-           break;
-       }
-    }
 
-    return 0;
-}
+static struct dmi_system_id __initdata i8k_dmi_table[] = {
+       {
+               .ident = "Dell Inspiron",
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Dell Computer"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron"),
+               },
+       },
+       {
+               .ident = "Dell Latitude",
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Dell Computer"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "Latitude"),
+               },
+       },
+       {
+               .ident = "Dell Inspiron 2",
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron"),
+               },
+       },
+       {
+               .ident = "Dell Latitude 2",
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "Latitude"),
+               },
+       },
+       { }
+};
 
 /*
  * Probe for the presence of a supported laptop.
  */
 static int __init i8k_probe(void)
 {
-    char buff[4];
-    int version;
-    int smm_found = 0;
-
-    /*
-     * Get DMI information
-     */
-    if (i8k_dmi_probe() != 0) {
-       printk(KERN_INFO "i8k: vendor=%s, model=%s, version=%s\n",
-              system_vendor, product_name, bios_version);
-    }
-
-    /*
-     * Get SMM Dell signature
-     */
-    if (i8k_get_dell_signature() != 0) {
-       printk(KERN_INFO "i8k: unable to get SMM Dell signature\n");
-    } else {
-       smm_found = 1;
-    }
-
-    /*
-     * Get SMM BIOS version.
-     */
-    version = i8k_get_bios_version();
-    if (version <= 0) {
-       printk(KERN_INFO "i8k: unable to get SMM BIOS version\n");
-    } else {
-       smm_found = 1;
-       buff[0] = (version >> 16) & 0xff;
-       buff[1] = (version >>  8) & 0xff;
-       buff[2] = (version)       & 0xff;
-       buff[3] = '\0';
+       char buff[4];
+       int version;
+
        /*
-        * If DMI BIOS version is unknown use SMM BIOS version.
+        * Get DMI information
         */
-       if (bios_version[0] == '?') {
-           strcpy(bios_version, buff);
+       if (!dmi_check_system(i8k_dmi_table)) {
+               if (!ignore_dmi && !force)
+                       return -ENODEV;
+
+               printk(KERN_INFO "i8k: not running on a supported Dell system.\n");
+               printk(KERN_INFO "i8k: vendor=%s, model=%s, version=%s\n",
+                       i8k_get_dmi_data(DMI_SYS_VENDOR),
+                       i8k_get_dmi_data(DMI_PRODUCT_NAME),
+                       i8k_get_dmi_data(DMI_BIOS_VERSION));
        }
+
+       strlcpy(bios_version, i8k_get_dmi_data(DMI_BIOS_VERSION), sizeof(bios_version));
+
        /*
-        * Check if the two versions match.
+        * Get SMM Dell signature
         */
-       if (strncmp(buff,bios_version,sizeof(bios_version)) != 0) {
-           printk(KERN_INFO "i8k: BIOS version mismatch: %s != %s\n",
-                  buff, bios_version);
+       if (i8k_get_dell_signature(I8K_SMM_GET_DELL_SIG1) &&
+           i8k_get_dell_signature(I8K_SMM_GET_DELL_SIG2)) {
+               printk(KERN_ERR "i8k: unable to get SMM Dell signature\n");
+               if (!force)
+                       return -ENODEV;
        }
-    }
 
-    if (!smm_found && !force) {
-       return -ENODEV;
-    }
+       /*
+        * Get SMM BIOS version.
+        */
+       version = i8k_get_bios_version();
+       if (version <= 0) {
+               printk(KERN_WARNING "i8k: unable to get SMM BIOS version\n");
+       } else {
+               buff[0] = (version >> 16) & 0xff;
+               buff[1] = (version >> 8) & 0xff;
+               buff[2] = (version) & 0xff;
+               buff[3] = '\0';
+               /*
+                * If DMI BIOS version is unknown use SMM BIOS version.
+                */
+               if (!dmi_get_system_info(DMI_BIOS_VERSION))
+                       strlcpy(bios_version, buff, sizeof(bios_version));
+
+               /*
+                * Check if the two versions match.
+                */
+               if (strncmp(buff, bios_version, sizeof(bios_version)) != 0)
+                       printk(KERN_WARNING "i8k: BIOS version mismatch: %s != %s\n",
+                               buff, bios_version);
+       }
 
-    return 0;
+       return 0;
 }
 
-#ifdef MODULE
-static
-#endif
-int __init i8k_init(void)
+static int __init i8k_init(void)
 {
-    struct proc_dir_entry *proc_i8k;
-
-    /* Are we running on an supported laptop? */
-    if (i8k_probe() != 0) {
-       return -ENODEV;
-    }
-
-    /* Register the proc entry */
-    proc_i8k = create_proc_info_entry("i8k", 0, NULL, i8k_get_info);
-    if (!proc_i8k) {
-       return -ENOENT;
-    }
-    proc_i8k->proc_fops = &i8k_fops;
-    proc_i8k->owner = THIS_MODULE;
-
-    printk(KERN_INFO
-          "Dell laptop SMM driver v%s Massimo Dal Zotto (dz@debian.org)\n",
-          I8K_VERSION);
-
-    return 0;
-}
+       struct proc_dir_entry *proc_i8k;
 
-#ifdef MODULE
-int init_module(void)
-{
-    return i8k_init();
+       /* Are we running on an supported laptop? */
+       if (i8k_probe())
+               return -ENODEV;
+
+       /* Register the proc entry */
+       proc_i8k = create_proc_entry("i8k", 0, NULL);
+       if (!proc_i8k)
+               return -ENOENT;
+
+       proc_i8k->proc_fops = &i8k_fops;
+       proc_i8k->owner = THIS_MODULE;
+
+       printk(KERN_INFO
+              "Dell laptop SMM driver v%s Massimo Dal Zotto (dz@debian.org)\n",
+              I8K_VERSION);
+
+       return 0;
 }
 
-void cleanup_module(void)
+static void __exit i8k_exit(void)
 {
-    /* Remove the proc entry */
-    remove_proc_entry("i8k", NULL);
-
-    printk(KERN_INFO "i8k: module unloaded\n");
+       remove_proc_entry("i8k", NULL);
 }
-#endif
 
-/* end of file */
+module_init(i8k_init);
+module_exit(i8k_exit);
index fd299d6c42ace5165643511d3ce9441b02d32e31..cb8f4198e9a34291b8cd67e41ee0f969741ac0ad 100644 (file)
@@ -97,7 +97,7 @@ static UCHAR ct41[] = { 1, BYP,     0x29                     }; // RESUME
 //static UCHAR ct44[]={ 2, BTH,     0x2C,0                   }; // MS PING
 //static UCHAR ct45[]={ 1, BTH,     0x2D                     }; // HOTENAB
 //static UCHAR ct46[]={ 1, BTH,     0x2E                     }; // HOTDSAB
-static UCHAR ct47[] = { 7, BTH,     0x2F,0,0,0,0,0,0         }; // UNIX FLAGS
+//static UCHAR ct47[]={ 7, BTH,     0x2F,0,0,0,0,0,0         }; // UNIX FLAGS
 //static UCHAR ct48[]={ 1, BTH,     0x30                     }; // DSRFLOWENAB
 //static UCHAR ct49[]={ 1, BTH,     0x31                     }; // DSRFLOWDSAB
 //static UCHAR ct50[]={ 1, BTH,     0x32                     }; // DTRFLOWENAB
@@ -162,6 +162,7 @@ static UCHAR ct89[]={ 1, BYP,     0x59                     }; // DSS_NOW
 // This routine sets the parameters of command 47 and returns a pointer to the
 // appropriate structure.
 //******************************************************************************
+#if 0
 cmdSyntaxPtr
 i2cmdUnixFlags(unsigned short iflag,unsigned short cflag,unsigned short lflag)
 {
@@ -175,6 +176,7 @@ i2cmdUnixFlags(unsigned short iflag,unsigned short cflag,unsigned short lflag)
        pCM->cmd[6] = (unsigned char) (lflag >> 8);
        return pCM;
 }
+#endif  /*  0  */
 
 //******************************************************************************
 // Function:   i2cmdBaudDef(which, rate)
@@ -187,7 +189,7 @@ i2cmdUnixFlags(unsigned short iflag,unsigned short cflag,unsigned short lflag)
 // This routine sets the parameters of commands 54 or 55 (according to the
 // argument which), and returns a pointer to the appropriate structure.
 //******************************************************************************
-cmdSyntaxPtr
+static cmdSyntaxPtr
 i2cmdBaudDef(int which, unsigned short rate)
 {
        cmdSyntaxPtr pCM;
index c41728a857101062c009eae9286a44ade839b166..baa4e721b758d84b5b5d59c7dc943cb33b1fe2d5 100644 (file)
@@ -64,16 +64,6 @@ typedef struct _cmdSyntax
                                                // directly from user-level
 #define VAR 0x10        // This command is of variable length!
 
-//-----------------------------------
-// External declarations for i2cmd.c
-//-----------------------------------
-// Routine to set up parameters for the "define hot-key sequence" command. Since
-// there is more than one parameter to assign, we must use a function rather
-// than a macro (used usually).
-//
-extern cmdSyntaxPtr i2cmdUnixFlags(USHORT iflag,USHORT cflag,USHORT lflag);
-extern cmdSyntaxPtr i2cmdBaudDef(int which, USHORT rate);
-
 // Declarations for the global arrays used to bear the commands and their
 // arguments.
 //
@@ -433,6 +423,7 @@ static UCHAR cc02[];
 #define CMD_HOT_ENAB (cmdSyntaxPtr)(ct45) // Enable Hot-key checking
 #define CMD_HOT_DSAB (cmdSyntaxPtr)(ct46) // Disable Hot-key checking
 
+#if 0
 // COMMAND 47: Send Protocol info via Unix flags:
 // iflag = Unix tty t_iflag
 // cflag = Unix tty t_cflag
@@ -441,6 +432,7 @@ static UCHAR cc02[];
 // within these flags
 //
 #define CMD_UNIX_FLAGS(iflag,cflag,lflag) i2cmdUnixFlags(iflag,cflag,lflag)
+#endif  /*  0  */
 
 #define CMD_DSRFL_ENAB  (cmdSyntaxPtr)(ct48) // Enable  DSR receiver ctrl
 #define CMD_DSRFL_DSAB  (cmdSyntaxPtr)(ct49) // Disable DSR receiver ctrl
index 3b8314b4249ac902b5da172c20a781191956afa2..cf0cd58d630571c44746cc0d7c073c2f916b164b 100644 (file)
@@ -2691,16 +2691,6 @@ no_xon:
                pCh->flags      |= ASYNC_CHECK_CD;
        }
 
-#ifdef XXX
-do_flags_thing:        // This is a test, we don't do the flags thing
-       
-       if ( (cflag & CRTSCTS) ) {
-               cflag |= 014000000000;
-       }
-       i2QueueCommands(PTYPE_BYPASS, pCh, 100, 1, 
-                               CMD_UNIX_FLAGS(iflag,cflag,lflag));
-#endif
-               
 service_it:
        i2DrainOutput( pCh, 100 );              
 }
index 601c7fccb4cfbed7a316507a302953467ccf56fd..1bbf507adda5ee2d43b8d5772dd8e7b273577a93 100644 (file)
@@ -1756,7 +1756,7 @@ static void isicom_flush_buffer(struct tty_struct * tty)
 }
 
 
-static int __init register_ioregion(void)
+static int __devinit register_ioregion(void)
 {
        int count, done=0;
        for (count=0; count < BOARD_COUNT; count++ ) {
@@ -1771,7 +1771,7 @@ static int __init register_ioregion(void)
        return done;
 }
 
-static void __exit unregister_ioregion(void)
+static void unregister_ioregion(void)
 {
        int count;
        for (count=0; count < BOARD_COUNT; count++ ) 
@@ -1803,7 +1803,7 @@ static struct tty_operations isicom_ops = {
        .tiocmset       = isicom_tiocmset,
 };
 
-static int __init register_drivers(void)
+static int __devinit register_drivers(void)
 {
        int error;
 
@@ -1834,7 +1834,7 @@ static int __init register_drivers(void)
        return 0;
 }
 
-static void __exit unregister_drivers(void)
+static void unregister_drivers(void)
 {
        int error = tty_unregister_driver(isicom_normal);
        if (error)
@@ -1842,7 +1842,7 @@ static void __exit unregister_drivers(void)
        put_tty_driver(isicom_normal);
 }
 
-static int __init register_isr(void)
+static int __devinit register_isr(void)
 {
        int count, done=0;
        unsigned long irqflags;
@@ -1883,7 +1883,7 @@ static void __exit unregister_isr(void)
        }
 }
 
-static int __init isicom_init(void)
+static int __devinit isicom_init(void)
 {
        int card, channel, base;
        struct isi_port * port;
index c02a21dbad5d516b400f28fa0f2c601aaa8b7136..52a073eee201d697740fc9cad9530cc38f7e659a 100644 (file)
@@ -407,7 +407,6 @@ static unsigned long        stli_eisamemprobeaddrs[] = {
 };
 
 static int     stli_eisamempsize = sizeof(stli_eisamemprobeaddrs) / sizeof(unsigned long);
-int            stli_eisaprobe = STLI_EISAPROBE;
 
 /*
  *     Define the Stallion PCI vendor and device IDs.
@@ -4685,7 +4684,7 @@ static int stli_initbrds(void)
 #ifdef MODULE
        stli_argbrds();
 #endif
-       if (stli_eisaprobe)
+       if (STLI_EISAPROBE)
                stli_findeisabrds();
 #ifdef CONFIG_PCI
        stli_findpcibrds();
index e3085b22a365b7104fbb6e29483cdf7531121e36..42187381506b7d0ff45dcdcc4df5dc2be7a2867f 100644 (file)
 #include <linux/devfs_fs_kernel.h>
 #include <linux/ptrace.h>
 #include <linux/device.h>
+#include <linux/highmem.h>
+#include <linux/crash_dump.h>
 #include <linux/backing-dev.h>
+#include <linux/bootmem.h>
 
 #include <asm/uaccess.h>
 #include <asm/io.h>
@@ -273,6 +276,40 @@ static int mmap_kmem(struct file * file, struct vm_area_struct * vma)
        return mmap_mem(file, vma);
 }
 
+#ifdef CONFIG_CRASH_DUMP
+/*
+ * Read memory corresponding to the old kernel.
+ */
+static ssize_t read_oldmem(struct file *file, char __user *buf,
+                               size_t count, loff_t *ppos)
+{
+       unsigned long pfn, offset;
+       size_t read = 0, csize;
+       int rc = 0;
+
+       while (count) {
+               pfn = *ppos / PAGE_SIZE;
+               if (pfn > saved_max_pfn)
+                       return read;
+
+               offset = (unsigned long)(*ppos % PAGE_SIZE);
+               if (count > PAGE_SIZE - offset)
+                       csize = PAGE_SIZE - offset;
+               else
+                       csize = count;
+
+               rc = copy_oldmem_page(pfn, buf, csize, offset, 1);
+               if (rc < 0)
+                       return rc;
+               buf += csize;
+               *ppos += csize;
+               read += csize;
+               count -= csize;
+       }
+       return read;
+}
+#endif
+
 extern long vread(char *buf, char *addr, unsigned long count);
 extern long vwrite(char *buf, char *addr, unsigned long count);
 
@@ -721,6 +758,7 @@ static int open_port(struct inode * inode, struct file * filp)
 #define read_full       read_zero
 #define open_mem       open_port
 #define open_kmem      open_mem
+#define open_oldmem    open_mem
 
 static struct file_operations mem_fops = {
        .llseek         = memory_lseek,
@@ -770,6 +808,13 @@ static struct file_operations full_fops = {
        .write          = write_full,
 };
 
+#ifdef CONFIG_CRASH_DUMP
+static struct file_operations oldmem_fops = {
+       .read   = read_oldmem,
+       .open   = open_oldmem,
+};
+#endif
+
 static ssize_t kmsg_write(struct file * file, const char __user * buf,
                          size_t count, loff_t *ppos)
 {
@@ -825,6 +870,11 @@ static int memory_open(struct inode * inode, struct file * filp)
                case 11:
                        filp->f_op = &kmsg_fops;
                        break;
+#ifdef CONFIG_CRASH_DUMP
+               case 12:
+                       filp->f_op = &oldmem_fops;
+                       break;
+#endif
                default:
                        return -ENXIO;
        }
@@ -854,6 +904,9 @@ static const struct {
        {8, "random",  S_IRUGO | S_IWUSR,           &random_fops},
        {9, "urandom", S_IRUGO | S_IWUSR,           &urandom_fops},
        {11,"kmsg",    S_IRUGO | S_IWUSR,           &kmsg_fops},
+#ifdef CONFIG_CRASH_DUMP
+       {12,"oldmem",    S_IRUSR | S_IWUSR | S_IRGRP, &oldmem_fops},
+#endif
 };
 
 static struct class *mem_class;
index 3115d318b9978618784a4ee4f8173070cfcbe023..31cf84d690266652fb2ad57a040b1380123b45f4 100644 (file)
@@ -66,8 +66,6 @@ static unsigned char misc_minors[DYNAMIC_MINORS / 8];
 extern int rtc_DP8570A_init(void);
 extern int rtc_MK48T08_init(void);
 extern int pmu_device_init(void);
-extern int tosh_init(void);
-extern int i8k_init(void);
 
 #ifdef CONFIG_PROC_FS
 static void *misc_seq_start(struct seq_file *seq, loff_t *pos)
@@ -313,12 +311,6 @@ static int __init misc_init(void)
 #endif
 #ifdef CONFIG_PMAC_PBOOK
        pmu_device_init();
-#endif
-#ifdef CONFIG_TOSHIBA
-       tosh_init();
-#endif
-#ifdef CONFIG_I8K
-       i8k_init();
 #endif
        if (register_chrdev(MISC_MAJOR,"misc",&misc_fops)) {
                printk("unable to get major %d for misc devices\n",
index ab00f51475dfbc46dd1e91fa0fbb3da3dfda4e09..613aed9e1840a15e4843e396591dc205a5ceecf1 100644 (file)
@@ -107,8 +107,8 @@ void dsp3780I_WriteMsaCfg(unsigned short usDspBaseIO,
        spin_unlock_irqrestore(&dsp_lock, flags);
 }
 
-void dsp3780I_WriteGenCfg(unsigned short usDspBaseIO, unsigned uIndex,
-                          unsigned char ucValue)
+static void dsp3780I_WriteGenCfg(unsigned short usDspBaseIO, unsigned uIndex,
+                                unsigned char ucValue)
 {
        DSP_ISA_SLAVE_CONTROL rSlaveControl;
        DSP_ISA_SLAVE_CONTROL rSlaveControl_Save;
@@ -141,6 +141,7 @@ void dsp3780I_WriteGenCfg(unsigned short usDspBaseIO, unsigned uIndex,
 
 }
 
+#if 0
 unsigned char dsp3780I_ReadGenCfg(unsigned short usDspBaseIO,
                                   unsigned uIndex)
 {
@@ -167,6 +168,7 @@ unsigned char dsp3780I_ReadGenCfg(unsigned short usDspBaseIO,
 
        return ucValue;
 }
+#endif  /*  0  */
 
 int dsp3780I_EnableDSP(DSP_3780I_CONFIG_SETTINGS * pSettings,
                        unsigned short *pIrqMap,
index 3e7d020d1bf4f2f4d7861a30240c995695eec904..270431ca7dae1ce4ee3755bd608bf496c4822efa 100644 (file)
@@ -338,10 +338,6 @@ unsigned short dsp3780I_ReadMsaCfg(unsigned short usDspBaseIO,
                                    unsigned long ulMsaAddr);
 void dsp3780I_WriteMsaCfg(unsigned short usDspBaseIO,
                           unsigned long ulMsaAddr, unsigned short usValue);
-void dsp3780I_WriteGenCfg(unsigned short usDspBaseIO, unsigned uIndex,
-                          unsigned char ucValue);
-unsigned char dsp3780I_ReadGenCfg(unsigned short usDspBaseIO,
-                                  unsigned uIndex);
 int dsp3780I_GetIPCSource(unsigned short usDspBaseIO,
                           unsigned short *pusIPCSource);
 
index ab650cd6efc0d3e867c121c80d4b406bc78f413a..d6c72e0934e23e7bb805ebf852679d09155a6c3d 100644 (file)
@@ -242,20 +242,14 @@ int tp3780I_ClaimResources(THINKPAD_BD_DATA * pBDData)
 {
        int retval = 0;
        DSP_3780I_CONFIG_SETTINGS *pSettings = &pBDData->rDspSettings;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
        struct resource *pres;
-#endif
 
        PRINTK_2(TRACE_TP3780I,
                "tp3780i::tp3780I_ClaimResources entry pBDData %p\n", pBDData);
 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
        pres = request_region(pSettings->usDspBaseIO, 16, "mwave_3780i");
        if ( pres == NULL ) retval = -EIO;
-#else
-       retval = check_region(pSettings->usDspBaseIO, 16);
-       if (!retval) request_region(pSettings->usDspBaseIO, 16, "mwave_3780i");
-#endif
+
        if (retval) {
                PRINTK_ERROR(KERN_ERR_MWAVE "tp3780i::tp3780I_ClaimResources: Error: Could not claim I/O region starting at %x\n", pSettings->usDspBaseIO);
                retval = -EIO;
@@ -292,7 +286,7 @@ int tp3780I_ReleaseResources(THINKPAD_BD_DATA * pBDData)
 int tp3780I_EnableDSP(THINKPAD_BD_DATA * pBDData)
 {
        DSP_3780I_CONFIG_SETTINGS *pSettings = &pBDData->rDspSettings;
-       BOOLEAN bDSPPoweredUp = FALSE, bDSPEnabled = FALSE, bInterruptAllocated = FALSE;
+       BOOLEAN bDSPPoweredUp = FALSE, bInterruptAllocated = FALSE;
 
        PRINTK_2(TRACE_TP3780I, "tp3780i::tp3780I_EnableDSP entry pBDData %p\n", pBDData);
 
@@ -397,8 +391,6 @@ int tp3780I_EnableDSP(THINKPAD_BD_DATA * pBDData)
        if (dsp3780I_EnableDSP(pSettings, s_ausThinkpadIrqToField, s_ausThinkpadDmaToField)) {
                PRINTK_ERROR("tp3780i::tp3780I_EnableDSP: Error: dsp7880I_EnableDSP() failed\n");
                goto exit_cleanup;
-       } else {
-               bDSPEnabled = TRUE;
        }
 
        EnableSRAM(pBDData);
@@ -411,8 +403,6 @@ int tp3780I_EnableDSP(THINKPAD_BD_DATA * pBDData)
 
 exit_cleanup:
        PRINTK_ERROR("tp3780i::tp3780I_EnableDSP: Cleaning up\n");
-       if (bDSPEnabled)
-               dsp3780I_DisableDSP(pSettings);
        if (bDSPPoweredUp)
                smapi_set_DSP_power_state(FALSE);
        if (bInterruptAllocated) {
index f63a3fd7ca6f18666954f9d2d424926049f7149d..1af733d07321a8f5de4c5412745fd46428ce7332 100644 (file)
@@ -211,12 +211,13 @@ nvram_check_checksum(void)
        return rv;
 }
 
-void
+static void
 __nvram_set_checksum(void)
 {
        mach_set_checksum();
 }
 
+#if 0
 void
 nvram_set_checksum(void)
 {
@@ -226,6 +227,7 @@ nvram_set_checksum(void)
        __nvram_set_checksum();
        spin_unlock_irqrestore(&rtc_lock, flags);
 }
+#endif  /*  0  */
 
 /*
  * The are the file operation function for user access to /dev/nvram
@@ -921,6 +923,4 @@ EXPORT_SYMBOL(__nvram_write_byte);
 EXPORT_SYMBOL(nvram_write_byte);
 EXPORT_SYMBOL(__nvram_check_checksum);
 EXPORT_SYMBOL(nvram_check_checksum);
-EXPORT_SYMBOL(__nvram_set_checksum);
-EXPORT_SYMBOL(nvram_set_checksum);
 MODULE_ALIAS_MISCDEV(NVRAM_MINOR);
index e8f3860f4726c76590c82dff6fbd1892af6ac76e..01987c6dc398d8791af4e2c23c61aedef16f70b3 100644 (file)
@@ -147,7 +147,6 @@ struct rio_info * rio_info_store( int cmd, struct rio_info * p);
 extern int    rio_pcicopy(char *src, char *dst, int n);
 extern int rio_minor (struct tty_struct *tty);
 extern int rio_ismodem (struct tty_struct *tty);
-extern void rio_udelay (int usecs);
 
 extern void rio_start_card_running (struct Host * HostP);
 
index 763893e289b35367f6fb94b7a5cbae73f8892070..7db3370f4972701c674739feeab4f8ecb156d38b 100644 (file)
@@ -354,11 +354,6 @@ int rio_ismodem(struct tty_struct *tty)
 }
 
 
-void rio_udelay (int usecs)
-{
-  udelay (usecs);
-}
-
 static int rio_set_real_termios (void *ptr)
 {
   int rv, modem;
index dca941ed10cfb7e007ae7119b2d4330d086e9a16..898a126ae3e654d0087c41184259127fdc347f97 100644 (file)
@@ -37,6 +37,7 @@ static char *_rioinit_c_sccs_ = "@(#)rioinit.c        1.3";
 #include <linux/module.h>
 #include <linux/slab.h>
 #include <linux/errno.h>
+#include <linux/delay.h>
 #include <asm/io.h>
 #include <asm/system.h>
 #include <asm/string.h>
@@ -1560,14 +1561,14 @@ uint Slot;
                                          INTERRUPT_DISABLE | BYTE_OPERATION |
                                          SLOW_LINKS | SLOW_AT_BUS);
                        WBYTE(DpRamP->DpResetTpu, 0xFF);
-                       rio_udelay (3);
+                       udelay(3);
 
                        rio_dprintk (RIO_DEBUG_INIT,  "RIOHostReset: Don't know if it worked. Try reset again\n");
                        WBYTE(DpRamP->DpControl,  BOOT_FROM_RAM | EXTERNAL_BUS_OFF |
                                          INTERRUPT_DISABLE | BYTE_OPERATION |
                                          SLOW_LINKS | SLOW_AT_BUS);
                        WBYTE(DpRamP->DpResetTpu, 0xFF);
-                       rio_udelay (3);
+                       udelay(3);
                        break;
 #ifdef FUTURE_RELEASE
        case RIO_EISA:
@@ -1599,7 +1600,7 @@ uint Slot;
                DpRamP->DpControl  = RIO_PCI_BOOT_FROM_RAM;
                DpRamP->DpResetInt = 0xFF;
                DpRamP->DpResetTpu = 0xFF;
-               rio_udelay (100);
+               udelay(100);
                /* for (i=0; i<6000; i++);  */
                /* suspend( 3 ); */
                break;
index db655002671f3e0d11139563aeb9ad7adc004b28..78a321afdf4fec6eba9e754dbb0b461fc633a0ad 100644 (file)
@@ -524,16 +524,16 @@ riotclose(void  *ptr)
        register uint SysPort = dev;
        struct ttystatics *tp;          /* pointer to our ttystruct */
 #endif
-       struct Port *PortP =ptr;        /* pointer to the port structure */
+       struct Port *PortP = ptr;       /* pointer to the port structure */
        int deleted = 0;
        int     try = -1; /* Disable the timeouts by setting them to -1 */
        int     repeat_this = -1; /* Congrats to those having 15 years of 
                                     uptime! (You get to break the driver.) */
-       long end_time;
+       unsigned long end_time;
        struct tty_struct * tty;
        unsigned long flags;
        int Modem;
-       int rv =0;
+       int rv = 0;
        
        rio_dprintk (RIO_DEBUG_TTY, "port close SysPort %d\n",PortP->PortNum);
 
@@ -620,7 +620,7 @@ riotclose(void  *ptr)
                if (repeat_this -- <= 0) {
                        rv = -EINTR;
                        rio_dprintk (RIO_DEBUG_TTY, "Waiting for not idle closed broken by signal\n");
-                       RIOPreemptiveCmd(p, PortP, FCLOSE ); 
+                       RIOPreemptiveCmd(p, PortP, FCLOSE);
                        goto close_end;
                }
                rio_dprintk (RIO_DEBUG_TTY, "Calling timeout to flush in closing\n");
@@ -656,14 +656,12 @@ riotclose(void  *ptr)
                goto close_end;
        }
 
-       
-
        /* Can't call RIOShortCommand with the port locked. */
        rio_spin_unlock_irqrestore(&PortP->portSem, flags);
 
        if (RIOShortCommand(p, PortP, CLOSE, 1, 0) == RIO_FAIL) {
-         RIOPreemptiveCmd(p, PortP,FCLOSE);
-         goto close_end;
+               RIOPreemptiveCmd(p, PortP, FCLOSE);
+               goto close_end;
        }
 
        if (!deleted)
@@ -698,7 +696,6 @@ riotclose(void  *ptr)
 */
        PortP->Config &= ~(RIO_CTSFLOW|RIO_RTSFLOW);
 
-
 #ifdef STATS
        PortP->Stat.CloseCnt++;
 #endif
index 5bcbeb0cb9ae8988f09174821ad246d287a1d609..f463d6baa685cb59d848a02294c1d20d468f0510 100644 (file)
@@ -161,6 +161,64 @@ static Word_t upci_aiop_intr_bits[AIOP_CTL_SIZE] = {
        UPCI_AIOP_INTR_BIT_3
 };
 
+static Byte_t RData[RDATASIZE] = {
+       0x00, 0x09, 0xf6, 0x82,
+       0x02, 0x09, 0x86, 0xfb,
+       0x04, 0x09, 0x00, 0x0a,
+       0x06, 0x09, 0x01, 0x0a,
+       0x08, 0x09, 0x8a, 0x13,
+       0x0a, 0x09, 0xc5, 0x11,
+       0x0c, 0x09, 0x86, 0x85,
+       0x0e, 0x09, 0x20, 0x0a,
+       0x10, 0x09, 0x21, 0x0a,
+       0x12, 0x09, 0x41, 0xff,
+       0x14, 0x09, 0x82, 0x00,
+       0x16, 0x09, 0x82, 0x7b,
+       0x18, 0x09, 0x8a, 0x7d,
+       0x1a, 0x09, 0x88, 0x81,
+       0x1c, 0x09, 0x86, 0x7a,
+       0x1e, 0x09, 0x84, 0x81,
+       0x20, 0x09, 0x82, 0x7c,
+       0x22, 0x09, 0x0a, 0x0a
+};
+
+static Byte_t RRegData[RREGDATASIZE] = {
+       0x00, 0x09, 0xf6, 0x82, /* 00: Stop Rx processor */
+       0x08, 0x09, 0x8a, 0x13, /* 04: Tx software flow control */
+       0x0a, 0x09, 0xc5, 0x11, /* 08: XON char */
+       0x0c, 0x09, 0x86, 0x85, /* 0c: XANY */
+       0x12, 0x09, 0x41, 0xff, /* 10: Rx mask char */
+       0x14, 0x09, 0x82, 0x00, /* 14: Compare/Ignore #0 */
+       0x16, 0x09, 0x82, 0x7b, /* 18: Compare #1 */
+       0x18, 0x09, 0x8a, 0x7d, /* 1c: Compare #2 */
+       0x1a, 0x09, 0x88, 0x81, /* 20: Interrupt #1 */
+       0x1c, 0x09, 0x86, 0x7a, /* 24: Ignore/Replace #1 */
+       0x1e, 0x09, 0x84, 0x81, /* 28: Interrupt #2 */
+       0x20, 0x09, 0x82, 0x7c, /* 2c: Ignore/Replace #2 */
+       0x22, 0x09, 0x0a, 0x0a  /* 30: Rx FIFO Enable */
+};
+
+static CONTROLLER_T sController[CTL_SIZE] = {
+       {-1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0},
+        {0, 0, 0, 0}, {-1, -1, -1, -1}, {0, 0, 0, 0}},
+       {-1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0},
+        {0, 0, 0, 0}, {-1, -1, -1, -1}, {0, 0, 0, 0}},
+       {-1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0},
+        {0, 0, 0, 0}, {-1, -1, -1, -1}, {0, 0, 0, 0}},
+       {-1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0},
+        {0, 0, 0, 0}, {-1, -1, -1, -1}, {0, 0, 0, 0}}
+};
+
+static Byte_t sBitMapClrTbl[8] = {
+       0xfe, 0xfd, 0xfb, 0xf7, 0xef, 0xdf, 0xbf, 0x7f
+};
+
+static Byte_t sBitMapSetTbl[8] = {
+       0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80
+};
+
+static int sClockPrescale = 0x14;
+
 /*
  *  Line number is the ttySIx number (x), the Minor number.  We 
  *  assign them sequentially, starting at zero.  The following 
@@ -177,6 +235,26 @@ static void rmSpeakerReset(CONTROLLER_T * CtlP, unsigned long model);
 static unsigned char GetLineNumber(int ctrl, int aiop, int ch);
 static unsigned char SetLineNumber(int ctrl, int aiop, int ch);
 static void rp_start(struct tty_struct *tty);
+static int sInitChan(CONTROLLER_T * CtlP, CHANNEL_T * ChP, int AiopNum,
+                    int ChanNum);
+static void sSetInterfaceMode(CHANNEL_T * ChP, Byte_t mode);
+static void sFlushRxFIFO(CHANNEL_T * ChP);
+static void sFlushTxFIFO(CHANNEL_T * ChP);
+static void sEnInterrupts(CHANNEL_T * ChP, Word_t Flags);
+static void sDisInterrupts(CHANNEL_T * ChP, Word_t Flags);
+static void sModemReset(CONTROLLER_T * CtlP, int chan, int on);
+static void sPCIModemReset(CONTROLLER_T * CtlP, int chan, int on);
+static int sWriteTxPrioByte(CHANNEL_T * ChP, Byte_t Data);
+static int sPCIInitController(CONTROLLER_T * CtlP, int CtlNum,
+                             ByteIO_t * AiopIOList, int AiopIOListSize,
+                             WordIO_t ConfigIO, int IRQNum, Byte_t Frequency,
+                             int PeriodicOnly, int altChanRingIndicator,
+                             int UPCIRingInd);
+static int sInitController(CONTROLLER_T * CtlP, int CtlNum, ByteIO_t MudbacIO,
+                          ByteIO_t * AiopIOList, int AiopIOListSize,
+                          int IRQNum, Byte_t Frequency, int PeriodicOnly);
+static int sReadAiopID(ByteIO_t io);
+static int sReadAiopNumChan(WordIO_t io);
 
 #ifdef MODULE
 MODULE_AUTHOR("Theodore Ts'o");
@@ -1798,7 +1876,7 @@ static void rp_flush_buffer(struct tty_struct *tty)
  *  init's aiopic and serial port hardware.
  *  Inputs:  i is the board number (0-n)
  */
-__init int register_PCI(int i, struct pci_dev *dev)
+static __init int register_PCI(int i, struct pci_dev *dev)
 {
        int num_aiops, aiop, max_num_aiops, num_chan, chan;
        unsigned int aiopio[MAX_AIOPS_PER_BOARD];
@@ -2453,72 +2531,6 @@ static void rp_cleanup_module(void)
 }
 #endif
 
-#ifndef TRUE
-#define TRUE 1
-#endif
-
-#ifndef FALSE
-#define FALSE 0
-#endif
-
-static Byte_t RData[RDATASIZE] = {
-       0x00, 0x09, 0xf6, 0x82,
-       0x02, 0x09, 0x86, 0xfb,
-       0x04, 0x09, 0x00, 0x0a,
-       0x06, 0x09, 0x01, 0x0a,
-       0x08, 0x09, 0x8a, 0x13,
-       0x0a, 0x09, 0xc5, 0x11,
-       0x0c, 0x09, 0x86, 0x85,
-       0x0e, 0x09, 0x20, 0x0a,
-       0x10, 0x09, 0x21, 0x0a,
-       0x12, 0x09, 0x41, 0xff,
-       0x14, 0x09, 0x82, 0x00,
-       0x16, 0x09, 0x82, 0x7b,
-       0x18, 0x09, 0x8a, 0x7d,
-       0x1a, 0x09, 0x88, 0x81,
-       0x1c, 0x09, 0x86, 0x7a,
-       0x1e, 0x09, 0x84, 0x81,
-       0x20, 0x09, 0x82, 0x7c,
-       0x22, 0x09, 0x0a, 0x0a
-};
-
-static Byte_t RRegData[RREGDATASIZE] = {
-       0x00, 0x09, 0xf6, 0x82, /* 00: Stop Rx processor */
-       0x08, 0x09, 0x8a, 0x13, /* 04: Tx software flow control */
-       0x0a, 0x09, 0xc5, 0x11, /* 08: XON char */
-       0x0c, 0x09, 0x86, 0x85, /* 0c: XANY */
-       0x12, 0x09, 0x41, 0xff, /* 10: Rx mask char */
-       0x14, 0x09, 0x82, 0x00, /* 14: Compare/Ignore #0 */
-       0x16, 0x09, 0x82, 0x7b, /* 18: Compare #1 */
-       0x18, 0x09, 0x8a, 0x7d, /* 1c: Compare #2 */
-       0x1a, 0x09, 0x88, 0x81, /* 20: Interrupt #1 */
-       0x1c, 0x09, 0x86, 0x7a, /* 24: Ignore/Replace #1 */
-       0x1e, 0x09, 0x84, 0x81, /* 28: Interrupt #2 */
-       0x20, 0x09, 0x82, 0x7c, /* 2c: Ignore/Replace #2 */
-       0x22, 0x09, 0x0a, 0x0a  /* 30: Rx FIFO Enable */
-};
-
-CONTROLLER_T sController[CTL_SIZE] = {
-       {-1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0},
-        {0, 0, 0, 0}, {-1, -1, -1, -1}, {0, 0, 0, 0}},
-       {-1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0},
-        {0, 0, 0, 0}, {-1, -1, -1, -1}, {0, 0, 0, 0}},
-       {-1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0},
-        {0, 0, 0, 0}, {-1, -1, -1, -1}, {0, 0, 0, 0}},
-       {-1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0},
-        {0, 0, 0, 0}, {-1, -1, -1, -1}, {0, 0, 0, 0}}
-};
-
-Byte_t sBitMapClrTbl[8] = {
-       0xfe, 0xfd, 0xfb, 0xf7, 0xef, 0xdf, 0xbf, 0x7f
-};
-
-Byte_t sBitMapSetTbl[8] = {
-       0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80
-};
-
-int sClockPrescale = 0x14;
-
 /***************************************************************************
 Function: sInitController
 Purpose:  Initialization of controller global registers and controller
@@ -2554,22 +2566,22 @@ Call:     sInitController(CtlP,CtlNum,MudbacIO,AiopIOList,AiopIOListSize,
                       FREQ_4HZ - 4 Hertz
                    If IRQNum is set to 0 the Frequency parameter is
                    overidden, it is forced to a value of FREQ_DIS.
-          int PeriodicOnly: TRUE if all interrupts except the periodic
+          int PeriodicOnly: 1 if all interrupts except the periodic
                                interrupt are to be blocked.
-                            FALSE is both the periodic interrupt and
+                            0 is both the periodic interrupt and
                                other channel interrupts are allowed.
                             If IRQNum is set to 0 the PeriodicOnly parameter is
-                               overidden, it is forced to a value of FALSE.
+                               overidden, it is forced to a value of 0.
 Return:   int: Number of AIOPs on the controller, or CTLID_NULL if controller
                initialization failed.
 
 Comments:
           If periodic interrupts are to be disabled but AIOP interrupts
-          are allowed, set Frequency to FREQ_DIS and PeriodicOnly to FALSE.
+          are allowed, set Frequency to FREQ_DIS and PeriodicOnly to 0.
 
           If interrupts are to be completely disabled set IRQNum to 0.
 
-          Setting Frequency to FREQ_DIS and PeriodicOnly to TRUE is an
+          Setting Frequency to FREQ_DIS and PeriodicOnly to 1 is an
           invalid combination.
 
           This function performs initialization of global interrupt modes,
@@ -2589,9 +2601,9 @@ Warnings: No range checking on any of the parameters is done.
           After this function all AIOPs on the controller are disabled,
           they can be enabled with sEnAiop().
 */
-int sInitController(CONTROLLER_T * CtlP, int CtlNum, ByteIO_t MudbacIO,
-                   ByteIO_t * AiopIOList, int AiopIOListSize, int IRQNum,
-                   Byte_t Frequency, int PeriodicOnly)
+static int sInitController(CONTROLLER_T * CtlP, int CtlNum, ByteIO_t MudbacIO,
+                          ByteIO_t * AiopIOList, int AiopIOListSize,
+                          int IRQNum, Byte_t Frequency, int PeriodicOnly)
 {
        int i;
        ByteIO_t io;
@@ -2687,22 +2699,22 @@ Call:     sPCIInitController(CtlP,CtlNum,AiopIOList,AiopIOListSize,
                       FREQ_4HZ - 4 Hertz
                    If IRQNum is set to 0 the Frequency parameter is
                    overidden, it is forced to a value of FREQ_DIS.
-          int PeriodicOnly: TRUE if all interrupts except the periodic
+          int PeriodicOnly: 1 if all interrupts except the periodic
                                interrupt are to be blocked.
-                            FALSE is both the periodic interrupt and
+                            0 is both the periodic interrupt and
                                other channel interrupts are allowed.
                             If IRQNum is set to 0 the PeriodicOnly parameter is
-                               overidden, it is forced to a value of FALSE.
+                               overidden, it is forced to a value of 0.
 Return:   int: Number of AIOPs on the controller, or CTLID_NULL if controller
                initialization failed.
 
 Comments:
           If periodic interrupts are to be disabled but AIOP interrupts
-          are allowed, set Frequency to FREQ_DIS and PeriodicOnly to FALSE.
+          are allowed, set Frequency to FREQ_DIS and PeriodicOnly to 0.
 
           If interrupts are to be completely disabled set IRQNum to 0.
 
-          Setting Frequency to FREQ_DIS and PeriodicOnly to TRUE is an
+          Setting Frequency to FREQ_DIS and PeriodicOnly to 1 is an
           invalid combination.
 
           This function performs initialization of global interrupt modes,
@@ -2722,11 +2734,11 @@ Warnings: No range checking on any of the parameters is done.
           After this function all AIOPs on the controller are disabled,
           they can be enabled with sEnAiop().
 */
-int sPCIInitController(CONTROLLER_T * CtlP, int CtlNum,
-                      ByteIO_t * AiopIOList, int AiopIOListSize,
-                      WordIO_t ConfigIO, int IRQNum, Byte_t Frequency,
-                      int PeriodicOnly, int altChanRingIndicator,
-                      int UPCIRingInd)
+static int sPCIInitController(CONTROLLER_T * CtlP, int CtlNum,
+                             ByteIO_t * AiopIOList, int AiopIOListSize,
+                             WordIO_t ConfigIO, int IRQNum, Byte_t Frequency,
+                             int PeriodicOnly, int altChanRingIndicator,
+                             int UPCIRingInd)
 {
        int i;
        ByteIO_t io;
@@ -2784,7 +2796,7 @@ Return:   int: Flag AIOPID_XXXX if a valid AIOP is found, where X
 Warnings: No context switches are allowed while executing this function.
 
 */
-int sReadAiopID(ByteIO_t io)
+static int sReadAiopID(ByteIO_t io)
 {
        Byte_t AiopID;          /* ID byte from AIOP */
 
@@ -2810,7 +2822,7 @@ Comments: The number of channels is determined by write/reads from identical
           AIOP, otherwise it is an 8 channel.
 Warnings: No context switches are allowed while executing this function.
 */
-int sReadAiopNumChan(WordIO_t io)
+static int sReadAiopNumChan(WordIO_t io)
 {
        Word_t x;
        static Byte_t R[4] = { 0x00, 0x00, 0x34, 0x12 };
@@ -2834,15 +2846,15 @@ Call:     sInitChan(CtlP,ChP,AiopNum,ChanNum)
           CHANNEL_T *ChP; Ptr to channel structure
           int AiopNum; AIOP number within controller
           int ChanNum; Channel number within AIOP
-Return:   int: TRUE if initialization succeeded, FALSE if it fails because channel
+Return:   int: 1 if initialization succeeded, 0 if it fails because channel
                number exceeds number of channels available in AIOP.
 Comments: This function must be called before a channel can be used.
 Warnings: No range checking on any of the parameters is done.
 
           No context switches are allowed while executing this function.
 */
-int sInitChan(CONTROLLER_T * CtlP, CHANNEL_T * ChP, int AiopNum,
-             int ChanNum)
+static int sInitChan(CONTROLLER_T * CtlP, CHANNEL_T * ChP, int AiopNum,
+                    int ChanNum)
 {
        int i;
        WordIO_t AiopIO;
@@ -2853,7 +2865,7 @@ int sInitChan(CONTROLLER_T * CtlP, CHANNEL_T * ChP, int AiopNum,
        int brd9600;
 
        if (ChanNum >= CtlP->AiopNumChan[AiopNum])
-               return (FALSE); /* exceeds num chans in AIOP */
+               return 0;       /* exceeds num chans in AIOP */
 
        /* Channel, AIOP, and controller identifiers */
        ChP->CtlP = CtlP;
@@ -2968,7 +2980,7 @@ int sInitChan(CONTROLLER_T * CtlP, CHANNEL_T * ChP, int AiopNum,
        ChP->TxPrioBuf = ChOff + _TXP_BUF;
        sEnRxProcessor(ChP);    /* start the Rx processor */
 
-       return (TRUE);
+       return 1;
 }
 
 /***************************************************************************
@@ -2989,7 +3001,7 @@ Warnings: No context switches are allowed while executing this function.
           After calling this function a delay of 4 uS is required to ensure
           that the receive processor is no longer processing this channel.
 */
-void sStopRxProcessor(CHANNEL_T * ChP)
+static void sStopRxProcessor(CHANNEL_T * ChP)
 {
        Byte_t R[4];
 
@@ -3014,18 +3026,18 @@ Comments: To prevent data from being enqueued or dequeued in the Tx FIFO
           this function.
 Warnings: No context switches are allowed while executing this function.
 */
-void sFlushRxFIFO(CHANNEL_T * ChP)
+static void sFlushRxFIFO(CHANNEL_T * ChP)
 {
        int i;
        Byte_t Ch;              /* channel number within AIOP */
-       int RxFIFOEnabled;      /* TRUE if Rx FIFO enabled */
+       int RxFIFOEnabled;      /* 1 if Rx FIFO enabled */
 
        if (sGetRxCnt(ChP) == 0)        /* Rx FIFO empty */
                return;         /* don't need to flush */
 
-       RxFIFOEnabled = FALSE;
+       RxFIFOEnabled = 0;
        if (ChP->R[0x32] == 0x08) {     /* Rx FIFO is enabled */
-               RxFIFOEnabled = TRUE;
+               RxFIFOEnabled = 1;
                sDisRxFIFO(ChP);        /* disable it */
                for (i = 0; i < 2000 / 200; i++)        /* delay 2 uS to allow proc to disable FIFO */
                        sInB(ChP->IntChan);     /* depends on bus i/o timing */
@@ -3056,18 +3068,18 @@ Comments: To prevent data from being enqueued or dequeued in the Tx FIFO
           this function.
 Warnings: No context switches are allowed while executing this function.
 */
-void sFlushTxFIFO(CHANNEL_T * ChP)
+static void sFlushTxFIFO(CHANNEL_T * ChP)
 {
        int i;
        Byte_t Ch;              /* channel number within AIOP */
-       int TxEnabled;          /* TRUE if transmitter enabled */
+       int TxEnabled;          /* 1 if transmitter enabled */
 
        if (sGetTxCnt(ChP) == 0)        /* Tx FIFO empty */
                return;         /* don't need to flush */
 
-       TxEnabled = FALSE;
+       TxEnabled = 0;
        if (ChP->TxControl[3] & TX_ENABLE) {
-               TxEnabled = TRUE;
+               TxEnabled = 1;
                sDisTransmit(ChP);      /* disable transmitter */
        }
        sStopRxProcessor(ChP);  /* stop Rx processor */
@@ -3096,7 +3108,7 @@ Comments: The priority byte is transmitted before any data in the Tx FIFO.
 
 Warnings: No context switches are allowed while executing this function.
 */
-int sWriteTxPrioByte(CHANNEL_T * ChP, Byte_t Data)
+static int sWriteTxPrioByte(CHANNEL_T * ChP, Byte_t Data)
 {
        Byte_t DWBuf[4];        /* buffer for double word writes */
        Word_t *WordPtr;        /* must be far because Win SS != DS */
@@ -3158,7 +3170,7 @@ Comments: If an interrupt enable flag is set in Flags, that interrupt will be
           enable channel interrupts.  This would allow the global interrupt
           status register to be used to determine which AIOPs need service.
 */
-void sEnInterrupts(CHANNEL_T * ChP, Word_t Flags)
+static void sEnInterrupts(CHANNEL_T * ChP, Word_t Flags)
 {
        Byte_t Mask;            /* Interrupt Mask Register */
 
@@ -3202,7 +3214,7 @@ Comments: If an interrupt flag is set in Flags, that interrupt will be
           this channel's bit from being set in the AIOP's Interrupt Channel
           Register.
 */
-void sDisInterrupts(CHANNEL_T * ChP, Word_t Flags)
+static void sDisInterrupts(CHANNEL_T * ChP, Word_t Flags)
 {
        Byte_t Mask;            /* Interrupt Mask Register */
 
@@ -3218,7 +3230,7 @@ void sDisInterrupts(CHANNEL_T * ChP, Word_t Flags)
        }
 }
 
-void sSetInterfaceMode(CHANNEL_T * ChP, Byte_t mode)
+static void sSetInterfaceMode(CHANNEL_T * ChP, Byte_t mode)
 {
        sOutB(ChP->CtlP->AiopIO[2], (mode & 0x18) | ChP->ChanNum);
 }
@@ -3227,7 +3239,7 @@ void sSetInterfaceMode(CHANNEL_T * ChP, Byte_t mode)
  *  Not an official SSCI function, but how to reset RocketModems.
  *  ISA bus version
  */
-void sModemReset(CONTROLLER_T * CtlP, int chan, int on)
+static void sModemReset(CONTROLLER_T * CtlP, int chan, int on)
 {
        ByteIO_t addr;
        Byte_t val;
@@ -3252,7 +3264,7 @@ void sModemReset(CONTROLLER_T * CtlP, int chan, int on)
  *  Not an official SSCI function, but how to reset RocketModems.
  *  PCI bus version
  */
-void sPCIModemReset(CONTROLLER_T * CtlP, int chan, int on)
+static void sPCIModemReset(CONTROLLER_T * CtlP, int chan, int on)
 {
        ByteIO_t addr;
 
index 802687290ee1f7d28393e0da74adc5632cc75a0b..3a8bcc85bc14c8bbedbf552a379d0c89cca35b1b 100644 (file)
@@ -1130,46 +1130,6 @@ Warnings: This function writes the data byte without checking to see if
 */
 #define sWriteTxByte(IO,DATA) sOutB(IO,DATA)
 
-int sInitController(CONTROLLER_T * CtlP,
-                   int CtlNum,
-                   ByteIO_t MudbacIO,
-                   ByteIO_t * AiopIOList,
-                   int AiopIOListSize,
-                   int IRQNum, Byte_t Frequency, int PeriodicOnly);
-
-int sPCIInitController(CONTROLLER_T * CtlP,
-                      int CtlNum,
-                      ByteIO_t * AiopIOList,
-                      int AiopIOListSize,
-                      WordIO_t ConfigIO,
-                      int IRQNum,
-                      Byte_t Frequency,
-                      int PeriodicOnly,
-                      int altChanRingIndicator, int UPCIRingInd);
-
-int sReadAiopID(ByteIO_t io);
-int sReadAiopNumChan(WordIO_t io);
-int sInitChan(CONTROLLER_T * CtlP,
-             CHANNEL_T * ChP, int AiopNum, int ChanNum);
-Byte_t sGetRxErrStatus(CHANNEL_T * ChP);
-void sStopRxProcessor(CHANNEL_T * ChP);
-void sStopSWInFlowCtl(CHANNEL_T * ChP);
-void sFlushRxFIFO(CHANNEL_T * ChP);
-void sFlushTxFIFO(CHANNEL_T * ChP);
-int sWriteTxPrioByte(CHANNEL_T * ChP, Byte_t Data);
-void sEnInterrupts(CHANNEL_T * ChP, Word_t Flags);
-void sDisInterrupts(CHANNEL_T * ChP, Word_t Flags);
-void sModemReset(CONTROLLER_T * CtlP, int chan, int on);
-void sPCIModemReset(CONTROLLER_T * CtlP, int chan, int on);
-void sSetInterfaceMode(CHANNEL_T * ChP, Byte_t mode);
-
-extern Byte_t R[RDATASIZE];
-extern CONTROLLER_T sController[CTL_SIZE];
-extern Byte_t sIRQMap[16];
-extern Byte_t sBitMapClrTbl[8];
-extern Byte_t sBitMapSetTbl[8];
-extern int sClockPrescale;
-
 /*
  * Begin Linux specific definitions for the Rocketport driver
  *
index f59f7cbd525bcd587ec799b3050aa5d8852e75f8..af79805b5576f4b08ca02b357cd4f3fb96d23ec6 100644 (file)
@@ -35,6 +35,7 @@
 #include <linux/spinlock.h>
 #include <linux/vt_kern.h>
 #include <linux/workqueue.h>
+#include <linux/kexec.h>
 
 #include <asm/ptrace.h>
 
@@ -94,6 +95,21 @@ static struct sysrq_key_op sysrq_unraw_op = {
 };
 #endif /* CONFIG_VT */
 
+#ifdef CONFIG_KEXEC
+/* crashdump sysrq handler */
+static void sysrq_handle_crashdump(int key, struct pt_regs *pt_regs,
+                               struct tty_struct *tty)
+{
+       crash_kexec(pt_regs);
+}
+static struct sysrq_key_op sysrq_crashdump_op = {
+       .handler        = sysrq_handle_crashdump,
+       .help_msg       = "Crashdump",
+       .action_msg     = "Trigger a crashdump",
+       .enable_mask    = SYSRQ_ENABLE_DUMP,
+};
+#endif
+
 /* reboot sysrq handler */
 static void sysrq_handle_reboot(int key, struct pt_regs *pt_regs,
                                struct tty_struct *tty) 
@@ -273,8 +289,12 @@ static struct sysrq_key_op *sysrq_key_table[SYSRQ_KEY_TABLE_LENGTH] = {
                 it is handled specially on the sparc
                 and will never arrive */
 /* b */        &sysrq_reboot_op,
-/* c */ NULL,
-/* d */        NULL,
+#ifdef CONFIG_KEXEC
+/* c */ &sysrq_crashdump_op,
+#else
+/* c */        NULL,
+#endif
+/* d */ NULL,
 /* e */        &sysrq_term_op,
 /* f */        &sysrq_moom_op,
 /* g */        NULL,
index 58e21fe4426243f721001637a6d57f6f6ced7d6e..0c6f521abd0e37ec25c0f726d4fa26661475fcda 100644 (file)
 
 #define TOSH_MINOR_DEV 181
 
-static int tosh_id = 0x0000;
-static int tosh_bios = 0x0000;
-static int tosh_date = 0x0000;
-static int tosh_sci = 0x0000;
-static int tosh_fan = 0;
-
-static int tosh_fn = 0;
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Jonathan Buzzard <jonathan@buzzard.org.uk>");
+MODULE_DESCRIPTION("Toshiba laptop SMM driver");
+MODULE_SUPPORTED_DEVICE("toshiba");
 
-module_param(tosh_fn, int, 0);
+static int tosh_fn;
+module_param_named(fn, tosh_fn, int, 0);
+MODULE_PARM_DESC(fn, "User specified Fn key detection port");
 
+static int tosh_id;
+static int tosh_bios;
+static int tosh_date;
+static int tosh_sci;
+static int tosh_fan;
 
 static int tosh_ioctl(struct inode *, struct file *, unsigned int,
        unsigned long);
@@ -359,7 +363,7 @@ static int tosh_get_machine_id(void)
        unsigned long address;
 
        id = (0x100*(int) isa_readb(0xffffe))+((int) isa_readb(0xffffa));
-       
+
        /* do we have a SCTTable machine identication number on our hands */
 
        if (id==0xfc2f) {
@@ -424,7 +428,7 @@ static int tosh_probe(void)
        }
 
        /* call the Toshiba SCI support check routine */
-       
+
        regs.eax = 0xf0f0;
        regs.ebx = 0x0000;
        regs.ecx = 0x0000;
@@ -440,7 +444,7 @@ static int tosh_probe(void)
        /* if we get this far then we are running on a Toshiba (probably)! */
 
        tosh_sci = regs.edx & 0xffff;
-       
+
        /* next get the machine ID of the current laptop */
 
        tosh_id = tosh_get_machine_id();
@@ -475,16 +479,15 @@ static int tosh_probe(void)
        return 0;
 }
 
-int __init tosh_init(void)
+static int __init toshiba_init(void)
 {
        int retval;
        /* are we running on a Toshiba laptop */
 
-       if (tosh_probe()!=0)
-               return -EIO;
+       if (tosh_probe())
+               return -ENODEV;
 
-       printk(KERN_INFO "Toshiba System Managment Mode driver v"
-               TOSH_VERSION"\n");
+       printk(KERN_INFO "Toshiba System Managment Mode driver v" TOSH_VERSION "\n");
 
        /* set the port to use for Fn status if not specified as a parameter */
        if (tosh_fn==0x00)
@@ -492,12 +495,12 @@ int __init tosh_init(void)
 
        /* register the device file */
        retval = misc_register(&tosh_device);
-       if(retval < 0)
+       if (retval < 0)
                return retval;
 
 #ifdef CONFIG_PROC_FS
        /* register the proc entry */
-       if(create_proc_info_entry("toshiba", 0, NULL, tosh_get_info) == NULL){
+       if (create_proc_info_entry("toshiba", 0, NULL, tosh_get_info) == NULL) {
                misc_deregister(&tosh_device);
                return -ENOMEM;
        }
@@ -506,27 +509,12 @@ int __init tosh_init(void)
        return 0;
 }
 
-#ifdef MODULE
-int init_module(void)
-{
-       return tosh_init();
-}
-
-void cleanup_module(void)
+static void __exit toshiba_exit(void)
 {
-       /* remove the proc entry */
-
        remove_proc_entry("toshiba", NULL);
-
-       /* unregister the device file */
-
        misc_deregister(&tosh_device);
 }
-#endif
 
-MODULE_LICENSE("GPL");
-MODULE_PARM_DESC(tosh_fn, "User specified Fn key detection port");
-MODULE_AUTHOR("Jonathan Buzzard <jonathan@buzzard.org.uk>");
-MODULE_DESCRIPTION("Toshiba laptop SMM driver");
-MODULE_SUPPORTED_DEVICE("toshiba");
+module_init(toshiba_init);
+module_exit(toshiba_exit);
 
index 5c843c9bf8191ecd987968914256a7ac4ec76388..854475c54f0e78630e19ce098b73ca76511ba9cb 100644 (file)
@@ -233,10 +233,10 @@ ssize_t tpm_show_pubek(struct device *dev, struct device_attribute *attr,
                    data[15], data[16], data[17], data[22], data[23],
                    data[24], data[25], data[26], data[27], data[28],
                    data[29], data[30], data[31], data[32], data[33],
-                   be32_to_cpu(*((__be32 *) (data + 32))));
+                   be32_to_cpu(*((__be32 *) (data + 34))));
 
        for (i = 0; i < 256; i++) {
-               str += sprintf(str, "%02X ", data[i + 39]);
+               str += sprintf(str, "%02X ", data[i + 38]);
                if ((i + 1) % 16 == 0)
                        str += sprintf(str, "\n");
        }
@@ -464,6 +464,7 @@ void __devexit tpm_remove(struct pci_dev *pci_dev)
 
        pci_set_drvdata(pci_dev, NULL);
        misc_deregister(&chip->vendor->miscdev);
+       kfree(&chip->vendor->miscdev.name);
 
        sysfs_remove_group(&pci_dev->dev.kobj, chip->vendor->attr_group);
 
@@ -526,7 +527,9 @@ EXPORT_SYMBOL_GPL(tpm_pm_resume);
 int tpm_register_hardware(struct pci_dev *pci_dev,
                          struct tpm_vendor_specific *entry)
 {
-       char devname[7];
+#define DEVNAME_SIZE 7
+
+       char *devname;
        struct tpm_chip *chip;
        int i, j;
 
@@ -569,7 +572,8 @@ dev_num_search_complete:
        else
                chip->vendor->miscdev.minor = MISC_DYNAMIC_MINOR;
 
-       snprintf(devname, sizeof(devname), "%s%d", "tpm", chip->dev_num);
+       devname = kmalloc(DEVNAME_SIZE, GFP_KERNEL);
+       scnprintf(devname, DEVNAME_SIZE, "%s%d", "tpm", chip->dev_num);
        chip->vendor->miscdev.name = devname;
 
        chip->vendor->miscdev.dev = &(pci_dev->dev);
index 10cb450191a68edf2ced7716d435dababb0fef58..373b41f6b4604168fc24b0e73c2eff2a8ec6aaca 100644 (file)
@@ -31,8 +31,8 @@ enum tpm_timeout {
 
 /* TPM addresses */
 enum tpm_addr {
+       TPM_SUPERIO_ADDR = 0x2E,
        TPM_ADDR = 0x4E,
-       TPM_DATA = 0x4F
 };
 
 extern ssize_t tpm_show_pubek(struct device *, struct device_attribute *attr,
@@ -79,16 +79,16 @@ struct tpm_chip {
        struct list_head list;
 };
 
-static inline int tpm_read_index(int index)
+static inline int tpm_read_index(int base, int index)
 {
-       outb(index, TPM_ADDR);
-       return inb(TPM_DATA) & 0xFF;
+       outb(index, base);
+       return inb(base+1) & 0xFF;
 }
 
-static inline void tpm_write_index(int index, int value)
+static inline void tpm_write_index(int base, int index, int value)
 {
-       outb(index, TPM_ADDR);
-       outb(value & 0xFF, TPM_DATA);
+       outb(index, base);
+       outb(value & 0xFF, base+1);
 }
 
 extern int tpm_register_hardware(struct pci_dev *,
index 61fe14a77124eeb2a8fe1b6847ab1b41880bfd5a..cc2cc77fd174c2e825938c5d436aa7e3db2a39ce 100644 (file)
@@ -163,24 +163,24 @@ static int __devinit tpm_atml_init(struct pci_dev *pci_dev,
        if (pci_enable_device(pci_dev))
                return -EIO;
 
-       lo = tpm_read_index( TPM_ATMEL_BASE_ADDR_LO );
-       hi = tpm_read_index( TPM_ATMEL_BASE_ADDR_HI );
+       lo = tpm_read_index(TPM_ADDR, TPM_ATMEL_BASE_ADDR_LO);
+       hi = tpm_read_index(TPM_ADDR, TPM_ATMEL_BASE_ADDR_HI);
 
        tpm_atmel.base = (hi<<8)|lo;
        dev_dbg( &pci_dev->dev, "Operating with base: 0x%x\n", tpm_atmel.base);
 
        /* verify that it is an Atmel part */
-       if (tpm_read_index(4) != 'A' || tpm_read_index(5) != 'T'
-           || tpm_read_index(6) != 'M' || tpm_read_index(7) != 'L') {
+       if (tpm_read_index(TPM_ADDR, 4) != 'A' || tpm_read_index(TPM_ADDR, 5) != 'T'
+           || tpm_read_index(TPM_ADDR, 6) != 'M' || tpm_read_index(TPM_ADDR, 7) != 'L') {
                rc = -ENODEV;
                goto out_err;
        }
 
        /* query chip for its version number */
-       if ((version[0] = tpm_read_index(0x00)) != 0xFF) {
-               version[1] = tpm_read_index(0x01);
-               version[2] = tpm_read_index(0x02);
-               version[3] = tpm_read_index(0x03);
+       if ((version[0] = tpm_read_index(TPM_ADDR, 0x00)) != 0xFF) {
+               version[1] = tpm_read_index(TPM_ADDR, 0x01);
+               version[2] = tpm_read_index(TPM_ADDR, 0x02);
+               version[3] = tpm_read_index(TPM_ADDR, 0x03);
        } else {
                dev_info(&pci_dev->dev, "version query failed\n");
                rc = -ENODEV;
index 1a45e7dfc13b29c827a514b6428b551cd94c9024..b4127348c063279ada48d3af60056e036318ae45 100644 (file)
@@ -23,7 +23,6 @@
 
 /* National definitions */
 enum tpm_nsc_addr{
-       TPM_NSC_BASE = 0x360,
        TPM_NSC_IRQ = 0x07,
        TPM_NSC_BASE0_HI = 0x60,
        TPM_NSC_BASE0_LO = 0x61,
@@ -56,6 +55,7 @@ enum tpm_nsc_status {
        NSC_STATUS_RDY = 0x10,  /* ready to receive command */
        NSC_STATUS_IBR = 0x20   /* ready to receive data */
 };
+
 /* command bits */
 enum tpm_nsc_cmd_mode {
        NSC_COMMAND_NORMAL = 0x01,      /* normal mode */
@@ -150,7 +150,8 @@ static int tpm_nsc_recv(struct tpm_chip *chip, u8 * buf, size_t count)
                *p = inb(chip->vendor->base + NSC_DATA);
        }
 
-       if ((data & NSC_STATUS_F0) == 0) {
+       if ((data & NSC_STATUS_F0) == 0 &&
+       (wait_for_stat(chip, NSC_STATUS_F0, NSC_STATUS_F0, &data) < 0)) {
                dev_err(&chip->pci_dev->dev, "F0 not set\n");
                return -EIO;
        }
@@ -259,85 +260,64 @@ static int __devinit tpm_nsc_init(struct pci_dev *pci_dev,
 {
        int rc = 0;
        int lo, hi;
+       int nscAddrBase = TPM_ADDR;
 
-       hi = tpm_read_index(TPM_NSC_BASE0_HI);
-       lo = tpm_read_index(TPM_NSC_BASE0_LO);
-
-       tpm_nsc.base = (hi<<8) | lo;
 
        if (pci_enable_device(pci_dev))
                return -EIO;
 
+       /* select PM channel 1 */
+       tpm_write_index(nscAddrBase,NSC_LDN_INDEX, 0x12);
+
        /* verify that it is a National part (SID) */
-       if (tpm_read_index(NSC_SID_INDEX) != 0xEF) {
-               rc = -ENODEV;
-               goto out_err;
+       if (tpm_read_index(TPM_ADDR, NSC_SID_INDEX) != 0xEF) {
+               nscAddrBase = (tpm_read_index(TPM_SUPERIO_ADDR, 0x2C)<<8)|
+                       (tpm_read_index(TPM_SUPERIO_ADDR, 0x2B)&0xFE);
+               if (tpm_read_index(nscAddrBase, NSC_SID_INDEX) != 0xF6) {
+                       rc = -ENODEV;
+                       goto out_err;
+               }
        }
 
+       hi = tpm_read_index(nscAddrBase, TPM_NSC_BASE0_HI);
+       lo = tpm_read_index(nscAddrBase, TPM_NSC_BASE0_LO);
+       tpm_nsc.base = (hi<<8) | lo;
+
        dev_dbg(&pci_dev->dev, "NSC TPM detected\n");
        dev_dbg(&pci_dev->dev,
                "NSC LDN 0x%x, SID 0x%x, SRID 0x%x\n",
-               tpm_read_index(0x07), tpm_read_index(0x20),
-               tpm_read_index(0x27));
+               tpm_read_index(nscAddrBase,0x07), tpm_read_index(nscAddrBase,0x20),
+               tpm_read_index(nscAddrBase,0x27));
        dev_dbg(&pci_dev->dev,
                "NSC SIOCF1 0x%x SIOCF5 0x%x SIOCF6 0x%x SIOCF8 0x%x\n",
-               tpm_read_index(0x21), tpm_read_index(0x25),
-               tpm_read_index(0x26), tpm_read_index(0x28));
+               tpm_read_index(nscAddrBase,0x21), tpm_read_index(nscAddrBase,0x25),
+               tpm_read_index(nscAddrBase,0x26), tpm_read_index(nscAddrBase,0x28));
        dev_dbg(&pci_dev->dev, "NSC IO Base0 0x%x\n",
-               (tpm_read_index(0x60) << 8) | tpm_read_index(0x61));
+               (tpm_read_index(nscAddrBase,0x60) << 8) | tpm_read_index(nscAddrBase,0x61));
        dev_dbg(&pci_dev->dev, "NSC IO Base1 0x%x\n",
-               (tpm_read_index(0x62) << 8) | tpm_read_index(0x63));
+               (tpm_read_index(nscAddrBase,0x62) << 8) | tpm_read_index(nscAddrBase,0x63));
        dev_dbg(&pci_dev->dev, "NSC Interrupt number and wakeup 0x%x\n",
-               tpm_read_index(0x70));
+               tpm_read_index(nscAddrBase,0x70));
        dev_dbg(&pci_dev->dev, "NSC IRQ type select 0x%x\n",
-               tpm_read_index(0x71));
+               tpm_read_index(nscAddrBase,0x71));
        dev_dbg(&pci_dev->dev,
                "NSC DMA channel select0 0x%x, select1 0x%x\n",
-               tpm_read_index(0x74), tpm_read_index(0x75));
+               tpm_read_index(nscAddrBase,0x74), tpm_read_index(nscAddrBase,0x75));
        dev_dbg(&pci_dev->dev,
                "NSC Config "
                "0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n",
-               tpm_read_index(0xF0), tpm_read_index(0xF1),
-               tpm_read_index(0xF2), tpm_read_index(0xF3),
-               tpm_read_index(0xF4), tpm_read_index(0xF5),
-               tpm_read_index(0xF6), tpm_read_index(0xF7),
-               tpm_read_index(0xF8), tpm_read_index(0xF9));
+               tpm_read_index(nscAddrBase,0xF0), tpm_read_index(nscAddrBase,0xF1),
+               tpm_read_index(nscAddrBase,0xF2), tpm_read_index(nscAddrBase,0xF3),
+               tpm_read_index(nscAddrBase,0xF4), tpm_read_index(nscAddrBase,0xF5),
+               tpm_read_index(nscAddrBase,0xF6), tpm_read_index(nscAddrBase,0xF7),
+               tpm_read_index(nscAddrBase,0xF8), tpm_read_index(nscAddrBase,0xF9));
 
        dev_info(&pci_dev->dev,
-                "NSC PC21100 TPM revision %d\n",
-                tpm_read_index(0x27) & 0x1F);
-
-       if (tpm_read_index(NSC_LDC_INDEX) == 0)
-               dev_info(&pci_dev->dev, ": NSC TPM not active\n");
-
-       /* select PM channel 1 */
-       tpm_write_index(NSC_LDN_INDEX, 0x12);
-       tpm_read_index(NSC_LDN_INDEX);
-
-       /* disable the DPM module */
-       tpm_write_index(NSC_LDC_INDEX, 0);
-       tpm_read_index(NSC_LDC_INDEX);
-
-       /* set the data register base addresses */
-       tpm_write_index(NSC_DIO_INDEX, TPM_NSC_BASE >> 8);
-       tpm_write_index(NSC_DIO_INDEX + 1, TPM_NSC_BASE);
-       tpm_read_index(NSC_DIO_INDEX);
-       tpm_read_index(NSC_DIO_INDEX + 1);
-
-       /* set the command register base addresses */
-       tpm_write_index(NSC_CIO_INDEX, (TPM_NSC_BASE + 1) >> 8);
-       tpm_write_index(NSC_CIO_INDEX + 1, (TPM_NSC_BASE + 1));
-       tpm_read_index(NSC_DIO_INDEX);
-       tpm_read_index(NSC_DIO_INDEX + 1);
-
-       /* set the interrupt number to be used for the host interface */
-       tpm_write_index(NSC_IRQ_INDEX, TPM_NSC_IRQ);
-       tpm_write_index(NSC_ITS_INDEX, 0x00);
-       tpm_read_index(NSC_IRQ_INDEX);
+                "NSC TPM revision %d\n",
+                tpm_read_index(nscAddrBase, 0x27) & 0x1F);
 
        /* enable the DPM module */
-       tpm_write_index(NSC_LDC_INDEX, 0x01);
-       tpm_read_index(NSC_LDC_INDEX);
+       tpm_write_index(nscAddrBase, NSC_LDC_INDEX, 0x01);
 
        if ((rc = tpm_register_hardware(pci_dev, &tpm_nsc)) < 0)
                goto out_err;
@@ -355,6 +335,9 @@ static struct pci_device_id tpm_pci_tbl[] __devinitdata = {
        {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_0)},
        {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_12)},
        {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_0)},
+       {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_0)},
+       {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_1)},
+       {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_0)},
        {PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8111_LPC)},
        {0,}
 };
index cc4b43bad703c1da6aaf444f0ee3acbca3d4d7c3..6e4be3bb2d89d56b95792bf98e08bb3d201cc3ae 100644 (file)
@@ -94,6 +94,7 @@
 #include <linux/idr.h>
 #include <linux/wait.h>
 #include <linux/bitops.h>
+#include <linux/delay.h>
 
 #include <asm/uaccess.h>
 #include <asm/system.h>
@@ -2180,12 +2181,11 @@ static int tiocsetd(struct tty_struct *tty, int __user *p)
        return tty_set_ldisc(tty, ldisc);
 }
 
-static int send_break(struct tty_struct *tty, int duration)
+static int send_break(struct tty_struct *tty, unsigned int duration)
 {
        tty->driver->break_ctl(tty, -1);
        if (!signal_pending(current)) {
-               set_current_state(TASK_INTERRUPTIBLE);
-               schedule_timeout(duration);
+               msleep_interruptible(duration);
        }
        tty->driver->break_ctl(tty, 0);
        if (signal_pending(current))
@@ -2366,10 +2366,10 @@ int tty_ioctl(struct inode * inode, struct file * file,
                         * all by anyone?
                         */
                        if (!arg)
-                               return send_break(tty, HZ/4);
+                               return send_break(tty, 250);
                        return 0;
                case TCSBRKP:   /* support for POSIX tcsendbreak() */   
-                       return send_break(tty, arg ? arg*(HZ/10) : HZ/4);
+                       return send_break(tty, arg ? arg*100 : 250);
 
                case TIOCMGET:
                        return tty_tiocmget(tty, file, p);
index a3451cb94004dc3a876f5032e6a440b8c6800df5..33b17c6a46fb9a32e7c84b94b6b7970f9862fe45 100644 (file)
@@ -618,8 +618,8 @@ efivar_create_sysfs_entry(unsigned long variable_name_size,
        new_efivar = kmalloc(sizeof(struct efivar_entry), GFP_KERNEL);
 
        if (!short_name || !new_efivar)  {
-               if (short_name)        kfree(short_name);
-               if (new_efivar)        kfree(new_efivar);
+               kfree(short_name);
+               kfree(new_efivar);
                return 1;
        }
        memset(short_name, 0, short_name_size+1);
@@ -644,7 +644,8 @@ efivar_create_sysfs_entry(unsigned long variable_name_size,
        kobj_set_kset_s(new_efivar, vars_subsys);
        kobject_register(&new_efivar->kobj);
 
-       kfree(short_name); short_name = NULL;
+       kfree(short_name);
+       short_name = NULL;
 
        spin_lock(&efivars_lock);
        list_add(&new_efivar->list, &efivar_list);
index d41ca31dbcb2357cf4a37c2028aefae144c966be..03c23ce98edbc6d38c7da10fbf981904b72a1395 100644 (file)
 #include <linux/init.h>
 #include <linux/pci.h>
 #include <asm/io.h>
-#ifdef CONFIG_FSL_OCP
-#include <asm/ocp.h>
-#define FSL_I2C_DEV_SEPARATE_DFSRR FS_I2C_SEPARATE_DFSRR
-#define FSL_I2C_DEV_CLOCK_5200 FS_I2C_CLOCK_5200
-#else
 #include <linux/fsl_devices.h>
-#endif
 #include <linux/i2c.h>
 #include <linux/interrupt.h>
 #include <linux/delay.h>
@@ -294,204 +288,6 @@ static struct i2c_adapter mpc_ops = {
        .retries = 1
 };
 
-#ifdef CONFIG_FSL_OCP
-static int __devinit mpc_i2c_probe(struct ocp_device *ocp)
-{
-       int result = 0;
-       struct mpc_i2c *i2c;
-
-       if (!(i2c = kmalloc(sizeof(*i2c), GFP_KERNEL))) {
-               return -ENOMEM;
-       }
-       memset(i2c, 0, sizeof(*i2c));
-
-       i2c->irq = ocp->def->irq;
-       i2c->flags = ((struct ocp_fs_i2c_data *)ocp->def->additions)->flags;
-       init_waitqueue_head(&i2c->queue);
-
-       if (!request_mem_region(ocp->def->paddr, MPC_I2C_REGION, "i2c-mpc")) {
-               printk(KERN_ERR "i2c-mpc - resource unavailable\n");
-               return -ENODEV;
-       }
-
-       i2c->base = ioremap(ocp->def->paddr, MPC_I2C_REGION);
-
-       if (!i2c->base) {
-               printk(KERN_ERR "i2c-mpc - failed to map controller\n");
-               result = -ENOMEM;
-               goto fail_map;
-       }
-
-       if (i2c->irq != OCP_IRQ_NA)
-       {
-               if ((result = request_irq(ocp->def->irq, mpc_i2c_isr,
-                                         SA_SHIRQ, "i2c-mpc", i2c)) < 0) {
-                       printk(KERN_ERR
-                              "i2c-mpc - failed to attach interrupt\n");
-                       goto fail_irq;
-               }
-       } else
-               i2c->irq = 0;
-
-       mpc_i2c_setclock(i2c);
-       ocp_set_drvdata(ocp, i2c);
-
-       i2c->adap = mpc_ops;
-       i2c_set_adapdata(&i2c->adap, i2c);
-
-       if ((result = i2c_add_adapter(&i2c->adap)) < 0) {
-               printk(KERN_ERR "i2c-mpc - failed to add adapter\n");
-               goto fail_add;
-       }
-
-       return result;
-
-      fail_add:
-       if (ocp->def->irq != OCP_IRQ_NA)
-               free_irq(ocp->def->irq, 0);
-      fail_irq:
-       iounmap(i2c->base);
-      fail_map:
-       release_mem_region(ocp->def->paddr, MPC_I2C_REGION);
-       kfree(i2c);
-       return result;
-}
-static void __devexit mpc_i2c_remove(struct ocp_device *ocp)
-{
-       struct mpc_i2c *i2c = ocp_get_drvdata(ocp);
-       i2c_del_adapter(&i2c->adap);
-       ocp_set_drvdata(ocp, NULL);
-
-       if (ocp->def->irq != OCP_IRQ_NA)
-               free_irq(i2c->irq, i2c);
-       iounmap(i2c->base);
-       release_mem_region(ocp->def->paddr, MPC_I2C_REGION);
-       kfree(i2c);
-}
-
-static struct ocp_device_id mpc_iic_ids[] __devinitdata = {
-       {.vendor = OCP_VENDOR_FREESCALE,.function = OCP_FUNC_IIC},
-       {.vendor = OCP_VENDOR_INVALID}
-};
-
-MODULE_DEVICE_TABLE(ocp, mpc_iic_ids);
-
-static struct ocp_driver mpc_iic_driver = {
-       .name = "iic",
-       .id_table = mpc_iic_ids,
-       .probe = mpc_i2c_probe,
-       .remove = __devexit_p(mpc_i2c_remove)
-};
-
-static int __init iic_init(void)
-{
-       return ocp_register_driver(&mpc_iic_driver);
-}
-
-static void __exit iic_exit(void)
-{
-       ocp_unregister_driver(&mpc_iic_driver);
-}
-
-module_init(iic_init);
-module_exit(iic_exit);
-#else
-static int fsl_i2c_probe(struct device *device)
-{
-       int result = 0;
-       struct mpc_i2c *i2c;
-       struct platform_device *pdev = to_platform_device(device);
-       struct fsl_i2c_platform_data *pdata;
-       struct resource *r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-
-       pdata = (struct fsl_i2c_platform_data *) pdev->dev.platform_data;
-
-       if (!(i2c = kmalloc(sizeof(*i2c), GFP_KERNEL))) {
-               return -ENOMEM;
-       }
-       memset(i2c, 0, sizeof(*i2c));
-
-       i2c->irq = platform_get_irq(pdev, 0);
-       i2c->flags = pdata->device_flags;
-       init_waitqueue_head(&i2c->queue);
-
-       i2c->base = ioremap((phys_addr_t)r->start, MPC_I2C_REGION);
-
-       if (!i2c->base) {
-               printk(KERN_ERR "i2c-mpc - failed to map controller\n");
-               result = -ENOMEM;
-               goto fail_map;
-       }
-
-       if (i2c->irq != 0)
-               if ((result = request_irq(i2c->irq, mpc_i2c_isr,
-                                         SA_SHIRQ, "i2c-mpc", i2c)) < 0) {
-                       printk(KERN_ERR
-                              "i2c-mpc - failed to attach interrupt\n");
-                       goto fail_irq;
-               }
-
-       mpc_i2c_setclock(i2c);
-       dev_set_drvdata(device, i2c);
-
-       i2c->adap = mpc_ops;
-       i2c_set_adapdata(&i2c->adap, i2c);
-       i2c->adap.dev.parent = &pdev->dev;
-       if ((result = i2c_add_adapter(&i2c->adap)) < 0) {
-               printk(KERN_ERR "i2c-mpc - failed to add adapter\n");
-               goto fail_add;
-       }
-
-       return result;
-
-      fail_add:
-       if (i2c->irq != 0)
-               free_irq(i2c->irq, NULL);
-      fail_irq:
-       iounmap(i2c->base);
-      fail_map:
-       kfree(i2c);
-       return result;
-};
-
-static int fsl_i2c_remove(struct device *device)
-{
-       struct mpc_i2c *i2c = dev_get_drvdata(device);
-
-       i2c_del_adapter(&i2c->adap);
-       dev_set_drvdata(device, NULL);
-
-       if (i2c->irq != 0)
-               free_irq(i2c->irq, i2c);
-
-       iounmap(i2c->base);
-       kfree(i2c);
-       return 0;
-};
-
-/* Structure for a device driver */
-static struct device_driver fsl_i2c_driver = {
-       .name = "fsl-i2c",
-       .bus = &platform_bus_type,
-       .probe = fsl_i2c_probe,
-       .remove = fsl_i2c_remove,
-};
-
-static int __init fsl_i2c_init(void)
-{
-       return driver_register(&fsl_i2c_driver);
-}
-
-static void __exit fsl_i2c_exit(void)
-{
-       driver_unregister(&fsl_i2c_driver);
-}
-
-module_init(fsl_i2c_init);
-module_exit(fsl_i2c_exit);
-
-#endif /* CONFIG_FSL_OCP */
-
 MODULE_AUTHOR("Adrian Cox <adrian@humboldt.co.uk>");
 MODULE_DESCRIPTION
     ("I2C-Bus adapter for MPC107 bridge and MPC824x/85xx/52xx processors");
index 2d9a9b74e687ce51a19b7d026ca4b73155083d5f..629070b83a3360c03abc5a76a752e4ed7ba57902 100644 (file)
@@ -1041,10 +1041,8 @@ static int hpsbpkt_thread(void *__hi)
 
        while (1) {
                if (down_interruptible(&khpsbpkt_sig)) {
-                       if (current->flags & PF_FREEZE) {
-                               refrigerator(0);
+                       if (try_to_freeze())
                                continue;
-                       }
                        printk("khpsbpkt: received unexpected signal?!\n" );
                        break;
                }
index 32abb6dda888cbbb480b1ebf19ab3a5f45f24b17..9a46c3b44bf8b616aaf9c8755725b90af433610c 100644 (file)
@@ -1510,7 +1510,7 @@ static int nodemgr_host_thread(void *__hi)
 
                if (down_interruptible(&hi->reset_sem) ||
                    down_interruptible(&nodemgr_serialize)) {
-                       if (try_to_freeze(PF_FREEZE))
+                       if (try_to_freeze())
                                continue;
                        printk("NodeMgr: received unexpected signal?!\n" );
                        break;
index e152d0fa0cdd25d4d4ac4de364eaf80b9502a0cc..c77a82e460554186ecca8550d53d9a3bf3a47b4a 100644 (file)
@@ -439,7 +439,7 @@ static int gameport_thread(void *nothing)
        do {
                gameport_handle_events();
                wait_event_interruptible(gameport_wait, !list_empty(&gameport_event_list));
-               try_to_freeze(PF_FREEZE);
+               try_to_freeze();
        } while (!signal_pending(current));
 
        printk(KERN_DEBUG "gameport: kgameportd exiting\n");
index 5900de3c3f4f04b0936d2788edf5461681dc075e..a9bf549c8dc5b0e8f637f691938d7fd2bd9de2e5 100644 (file)
@@ -396,7 +396,7 @@ static void i8042_stop(struct serio *serio)
        struct i8042_port *port = serio->port_data;
 
        port->exists = 0;
-       synchronize_kernel();
+       synchronize_sched();
        port->serio = NULL;
 }
 
index feab4970406e39423711da9e9b9f55180abea9d7..341824c485293014e93b62ce6f4f5c63bb8a8f8e 100644 (file)
@@ -344,7 +344,7 @@ static int serio_thread(void *nothing)
        do {
                serio_handle_events();
                wait_event_interruptible(serio_wait, !list_empty(&serio_event_list));
-               try_to_freeze(PF_FREEZE);
+               try_to_freeze();
        } while (!signal_pending(current));
 
        printk(KERN_DEBUG "serio: kseriod exiting\n");
index 40395f567231570a10afa5040e09643b108016c0..afa46681f9833c576e3afd7b54f9a74debdac2bc 100644 (file)
@@ -224,6 +224,7 @@ actcapi_manufacturer_req_net(act2000_card *card)
 /*
  * Switch V.42 on or off
  */
+#if 0
 int
 actcapi_manufacturer_req_v42(act2000_card *card, ulong arg)
 {
@@ -242,6 +243,7 @@ actcapi_manufacturer_req_v42(act2000_card *card, ulong arg)
        ACTCAPI_QUEUE_TX;
         return 0;
 }
+#endif  /*  0  */
 
 /*
  * Set error-handler
index 04d2bcdd37a724aac183b1f49de8e4552fb2af33..f6d5f530b86be8e3d434ca17244ff2b9591b2623 100644 (file)
@@ -350,7 +350,6 @@ actcapi_nextsmsg(act2000_card *card)
 extern int actcapi_chkhdr(act2000_card *, actcapi_msghdr *);
 extern int actcapi_listen_req(act2000_card *);
 extern int actcapi_manufacturer_req_net(act2000_card *);
-extern int actcapi_manufacturer_req_v42(act2000_card *, ulong);
 extern int actcapi_manufacturer_req_errh(act2000_card *);
 extern int actcapi_manufacturer_req_msn(act2000_card *);
 extern int actcapi_connect_req(act2000_card *, act2000_chan *, char *, char, int, int);
index 55bed00ca86557ec9d8bf91a69e85cb8aca4cb4a..91dd0551fc7ceacc3e83fe09cdae5dcb9ba867b6 100644 (file)
@@ -955,7 +955,7 @@ EXPORT_SYMBOL(b1dma_release_appl);
 EXPORT_SYMBOL(b1dma_send_message);
 EXPORT_SYMBOL(b1dmactl_read_proc);
 
-int b1dma_init(void)
+static int __init b1dma_init(void)
 {
        char *p;
        char rev[32];
@@ -972,7 +972,7 @@ int b1dma_init(void)
        return 0;
 }
 
-void b1dma_exit(void)
+static void __exit b1dma_exit(void)
 {
 }
 
index fa6b93b1a42d676e12576b6d49ffc50f7b556e6b..724aac2c1ccaf1669de1fb73f04b087d20959d03 100644 (file)
@@ -885,7 +885,7 @@ static int c4_load_firmware(struct capi_ctr *ctrl, capiloaddata *data)
 }
 
 
-void c4_reset_ctr(struct capi_ctr *ctrl)
+static void c4_reset_ctr(struct capi_ctr *ctrl)
 {
        avmcard *card = ((avmctrl_info *)(ctrl->driverdata))->card;
        avmctrl_info *cinfo;
@@ -933,7 +933,7 @@ static void c4_remove(struct pci_dev *pdev)
 /* ------------------------------------------------------------- */
 
 
-void c4_register_appl(struct capi_ctr *ctrl,
+static void c4_register_appl(struct capi_ctr *ctrl,
                                u16 appl,
                                capi_register_params *rp)
 {
@@ -978,7 +978,7 @@ void c4_register_appl(struct capi_ctr *ctrl,
 
 /* ------------------------------------------------------------- */
 
-void c4_release_appl(struct capi_ctr *ctrl, u16 appl)
+static void c4_release_appl(struct capi_ctr *ctrl, u16 appl)
 {
        avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata);
        avmcard *card = cinfo->card;
index cb9d9cee2a648f2ef3793102f74363fbbd8fc865..3b701d97bdf1e150b281badea07301aa57ba323e 100644 (file)
@@ -328,7 +328,7 @@ static int t1isa_load_firmware(struct capi_ctr *ctrl, capiloaddata *data)
        return 0;
 }
 
-void t1isa_reset_ctr(struct capi_ctr *ctrl)
+static void t1isa_reset_ctr(struct capi_ctr *ctrl)
 {
        avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata);
        avmcard *card = cinfo->card;
index 8d6bb56754b8c08a5b0d8d392cc2f35996783a8a..293e27789d54caf983ec2b6d0b53b80548e89e64 100644 (file)
@@ -23,7 +23,7 @@ endif
 # Multipart objects.
 
 hisax_st5481-y                                 := st5481_init.o st5481_usb.o st5481_d.o \
-                                          st5481_b.o st5481_hdlc.o
+                                          st5481_b.o
 
 hisax-y                                        := config.o isdnl1.o tei.o isdnl2.o isdnl3.o \
                                           lmgr.o q931.o callc.o fsm.o
index c4f861a5db25791f3bd9b5fb867cc5dec4ddbae8..8ae08c41c853ef8f65b8010688a658ad9f79957e 100644 (file)
@@ -97,7 +97,7 @@ static WORD initAMD[] = {
 };
 
 
-void /* macro wWordAMD */
+static void /* macro wWordAMD */
 WriteWordAmd7930(struct IsdnCardState *cs, BYTE reg, WORD val)
 {
         wByteAMD(cs, 0x00, reg);
@@ -105,7 +105,7 @@ WriteWordAmd7930(struct IsdnCardState *cs, BYTE reg, WORD val)
         wByteAMD(cs, 0x01, HIBYTE(val));
 }
 
-WORD /* macro rWordAMD */
+static WORD /* macro rWordAMD */
 ReadWordAmd7930(struct IsdnCardState *cs, BYTE reg)
 {
         WORD res;
@@ -665,7 +665,7 @@ Amd7930_l1hw(struct PStack *st, int pr, void *arg)
        }
 }
 
-void
+static void
 setstack_Amd7930(struct PStack *st, struct IsdnCardState *cs)
 {
 
@@ -676,7 +676,7 @@ setstack_Amd7930(struct PStack *st, struct IsdnCardState *cs)
 }
 
 
-void
+static void
 DC_Close_Amd7930(struct IsdnCardState *cs) {
         if (cs->debug & L1_DEB_ISAC)
                debugl1(cs, "Amd7930: DC_Close called");
index 7546e2e4a94ea766b09140a874aef6f1cc93e5fc..a98c5e38bbbc527ac512028887f3f4a645ee509b 100644 (file)
@@ -22,7 +22,7 @@
 
 extern const char *CardType[];
 
-const char *Asuscom_revision = "$Revision: 1.14.2.4 $";
+static const char *Asuscom_revision = "$Revision: 1.14.2.4 $";
 
 #define byteout(addr,val) outb(val,addr)
 #define bytein(addr) inb(addr)
@@ -239,7 +239,7 @@ Start_IPAC:
        return IRQ_HANDLED;
 }
 
-void
+static void
 release_io_asuscom(struct IsdnCardState *cs)
 {
        int bytecnt = 8;
index 6fcb2cf7b0b69f97b1532c9728dc49785401d4cc..625799ab0d14d5292c96d3c41e01c90148e55567 100644 (file)
@@ -172,7 +172,7 @@ struct BCState *Sel_BCS(struct IsdnCardState *cs, int channel)
                return(NULL);
 }
 
-void
+static void
 write_ctrl(struct BCState *bcs, int which) {
 
        if (bcs->cs->debug & L1_DEB_HSCX)
@@ -193,7 +193,7 @@ write_ctrl(struct BCState *bcs, int which) {
        }
 }
 
-void
+static void
 modehdlc(struct BCState *bcs, int mode, int bc)
 {
        struct IsdnCardState *cs = bcs->cs;
@@ -451,7 +451,7 @@ HDLC_irq(struct BCState *bcs, u_int stat) {
        }
 }
 
-inline void
+static inline void
 HDLC_irq_main(struct IsdnCardState *cs)
 {
        u_int stat;
@@ -487,7 +487,7 @@ HDLC_irq_main(struct IsdnCardState *cs)
        }
 }
 
-void
+static void
 hdlc_l2l1(struct PStack *st, int pr, void *arg)
 {
        struct BCState *bcs = st->l1.bcs;
@@ -547,7 +547,7 @@ hdlc_l2l1(struct PStack *st, int pr, void *arg)
        }
 }
 
-void
+static void
 close_hdlcstate(struct BCState *bcs)
 {
        modehdlc(bcs, 0, 0);
@@ -570,7 +570,7 @@ close_hdlcstate(struct BCState *bcs)
        }
 }
 
-int
+static int
 open_hdlcstate(struct IsdnCardState *cs, struct BCState *bcs)
 {
        if (!test_and_set_bit(BC_FLG_INIT, &bcs->Flag)) {
@@ -598,7 +598,7 @@ open_hdlcstate(struct IsdnCardState *cs, struct BCState *bcs)
        return (0);
 }
 
-int
+static int
 setstack_hdlc(struct PStack *st, struct BCState *bcs)
 {
        bcs->channel = st->l1.bc;
@@ -612,6 +612,7 @@ setstack_hdlc(struct PStack *st, struct BCState *bcs)
        return (0);
 }
 
+#if 0
 void __init
 clear_pending_hdlc_ints(struct IsdnCardState *cs)
 {
@@ -641,8 +642,9 @@ clear_pending_hdlc_ints(struct IsdnCardState *cs)
                debugl1(cs, "HDLC 2 VIN %x", val);
        }
 }
+#endif  /*  0  */
 
-void __init
+static void __init
 inithdlc(struct IsdnCardState *cs)
 {
        cs->bcs[0].BC_SetStack = setstack_hdlc;
index f410f628a3e20202b72d942e78e7b8c6093e2669..dcb308aeb50cccdac293e64aae89a7ee7631fd9d 100644 (file)
@@ -23,7 +23,7 @@
 
 extern const char *CardType[];
 
-const char *bkm_a4t_revision = "$Revision: 1.22.2.4 $";
+static const char *bkm_a4t_revision = "$Revision: 1.22.2.4 $";
 
 
 static inline u_char
@@ -167,7 +167,7 @@ bkm_interrupt(int intno, void *dev_id, struct pt_regs *regs)
        }
 }
 
-void
+static void
 release_io_bkm(struct IsdnCardState *cs)
 {
        if (cs->hw.ax.base) {
index 94bb83ce7fd82a28fc9ebb4ad89bf3c2cd20710b..5f21b82c8c8dcba3699b3ee89d112c3439313357 100644 (file)
@@ -27,7 +27,7 @@
 
 extern const char *CardType[];
 
-const char sct_quadro_revision[] = "$Revision: 1.22.2.4 $";
+static const char sct_quadro_revision[] = "$Revision: 1.22.2.4 $";
 
 static const char *sct_quadro_subtypes[] =
 {
@@ -193,7 +193,7 @@ bkm_interrupt_ipac(int intno, void *dev_id, struct pt_regs *regs)
        return IRQ_HANDLED;
 }
 
-void
+static void
 release_io_sct_quadro(struct IsdnCardState *cs)
 {
        release_region(cs->hw.ax.base & 0xffffffc0, 128);
@@ -261,7 +261,7 @@ BKM_card_msg(struct IsdnCardState *cs, int mt, void *arg)
        return (0);
 }
 
-int __init
+static int __init
 sct_alloc_io(u_int adr, u_int len)
 {
        if (!request_region(adr, len, "scitel")) {
index 04065ab2610f9f228754b2837ecc99d8753cdeb9..7c56c44f0fd16955be1e7c488bfc862e709f24a1 100644 (file)
@@ -874,7 +874,7 @@ release_b_st(struct Channel *chanp)
        } 
 }
 
-struct Channel
+static struct Channel
 *selectfreechannel(struct PStack *st, int bch)
 {
        struct IsdnCardState *cs = st->l1.hardware;
@@ -1429,7 +1429,7 @@ capi_debug(struct Channel *chanp, capi_msg *cm)
        HiSax_putstatus(chanp->cs, "Ch", "%d CAPIMSG %s", chanp->chan, tmpbuf);
 }
 
-void
+static void
 lli_got_fac_req(struct Channel *chanp, capi_msg *cm) {
        if ((cm->para[0] != 3) || (cm->para[1] != 0))
                return;
@@ -1454,7 +1454,7 @@ lli_got_fac_req(struct Channel *chanp, capi_msg *cm) {
        }
 }
 
-void
+static void
 lli_got_manufacturer(struct Channel *chanp, struct IsdnCardState *cs, capi_msg *cm) {
        if ((cs->typ == ISDN_CTYPE_ELSA) || (cs->typ == ISDN_CTYPE_ELSA_PNP) ||
                (cs->typ == ISDN_CTYPE_ELSA_PCI)) {
index 1663ee69d41d22a3afc0e2312359a69892855393..c542e6fb2bde736f4c8a1e5efeda10e6c2bb46f0 100644 (file)
@@ -332,7 +332,7 @@ struct IsdnCard cards[HISAX_MAX_CARDS] = {
 #define HISAX_IDSIZE (HISAX_MAX_CARDS*8)
 static char HiSaxID[HISAX_IDSIZE] = { 0, };
 
-char *HiSax_id = HiSaxID;
+static char *HiSax_id = HiSaxID;
 #ifdef MODULE
 /* Variables for insmod */
 static int type[HISAX_MAX_CARDS] = { 0, };
@@ -391,7 +391,7 @@ char *HiSax_getrev(const char *revision)
        return rev;
 }
 
-void __init HiSaxVersion(void)
+static void __init HiSaxVersion(void)
 {
        char tmp[64];
 
@@ -608,6 +608,7 @@ static inline struct IsdnCardState *hisax_findcard(int driverid)
 /*
  * Find card with given card number
  */
+#if 0
 struct IsdnCardState *hisax_get_card(int cardnr)
 {
        if ((cardnr <= nrcards) && (cardnr > 0))
@@ -615,8 +616,9 @@ struct IsdnCardState *hisax_get_card(int cardnr)
                        return cards[cardnr - 1].cs;
        return NULL;
 }
+#endif  /*  0  */
 
-int HiSax_readstatus(u_char __user *buf, int len, int id, int channel)
+static int HiSax_readstatus(u_char __user *buf, int len, int id, int channel)
 {
        int count, cnt;
        u_char __user *p = buf;
@@ -768,7 +770,7 @@ int ll_run(struct IsdnCardState *cs, int addfeatures)
        return 0;
 }
 
-void ll_stop(struct IsdnCardState *cs)
+static void ll_stop(struct IsdnCardState *cs)
 {
        isdn_ctrl ic;
 
@@ -1184,7 +1186,7 @@ static int checkcard(int cardnr, char *id, int *busy_flag, struct module *lockow
        return ret;
 }
 
-void HiSax_shiftcards(int idx)
+static void HiSax_shiftcards(int idx)
 {
        int i;
 
@@ -1192,7 +1194,7 @@ void HiSax_shiftcards(int idx)
                memcpy(&cards[i], &cards[i + 1], sizeof(cards[i]));
 }
 
-int HiSax_inithardware(int *busy_flag)
+static int HiSax_inithardware(int *busy_flag)
 {
        int foundcards = 0;
        int i = 0;
index 394d481e093fde584c61ce5e13545b66bdd8f6a6..b62d6b30b72b861711090ef5d7fd2b591b615828 100644 (file)
@@ -28,7 +28,7 @@
 
 extern const char *CardType[];
 
-const char *Diva_revision = "$Revision: 1.33.2.6 $";
+static const char *Diva_revision = "$Revision: 1.33.2.6 $";
 
 #define byteout(addr,val) outb(val,addr)
 #define bytein(addr) inb(addr)
@@ -706,7 +706,7 @@ diva_irq_ipacx_pci(int intno, void *dev_id, struct pt_regs *regs)
        return IRQ_HANDLED;
 }
 
-void
+static void
 release_io_diva(struct IsdnCardState *cs)
 {
        int bytecnt;
index 4d7a0250d7e20b8c59de10799f9f526e4379f8be..110e9fd669c53a98b36b271a4771d7034a4c8549 100644 (file)
 
 extern const char *CardType[];
 
-const char *Elsa_revision = "$Revision: 2.32.2.4 $";
-const char *Elsa_Types[] =
+static const char *Elsa_revision = "$Revision: 2.32.2.4 $";
+static const char *Elsa_Types[] =
 {"None", "PC", "PCC-8", "PCC-16", "PCF", "PCF-Pro",
  "PCMCIA", "QS 1000", "QS 3000", "Microlink PCI", "QS 3000 PCI", 
  "PCMCIA-IPAC" };
 
-const char *ITACVer[] =
+static const char *ITACVer[] =
 {"?0?", "?1?", "?2?", "?3?", "?4?", "V2.2",
  "B1", "A1"};
 
@@ -425,7 +425,7 @@ Start_IPAC:
        return IRQ_HANDLED;
 }
 
-void
+static void
 release_io_elsa(struct IsdnCardState *cs)
 {
        int bytecnt = 8;
index 689c83395693a9d2ccc3ba124f302a4597244b86..898ec0916195a9b788a4679fad5bbd3b8fe50015 100644 (file)
@@ -237,7 +237,7 @@ static void mshutdown(struct IsdnCardState *cs)
 #endif
 }
 
-inline int
+static inline int
 write_modem(struct BCState *bcs) {
        int ret=0;
        struct IsdnCardState *cs = bcs->cs;
@@ -275,7 +275,7 @@ write_modem(struct BCState *bcs) {
        return(ret);
 }
 
-inline void
+static inline void
 modem_fill(struct BCState *bcs) {
                
        if (bcs->tx_skb) {
@@ -422,7 +422,7 @@ extern int open_hscxstate(struct IsdnCardState *cs, struct BCState *bcs);
 extern void modehscx(struct BCState *bcs, int mode, int bc);
 extern void hscx_l2l1(struct PStack *st, int pr, void *arg);
 
-void
+static void
 close_elsastate(struct BCState *bcs)
 {
        modehscx(bcs, 0, bcs->channel);
@@ -442,7 +442,7 @@ close_elsastate(struct BCState *bcs)
        }
 }
 
-void
+static void
 modem_write_cmd(struct IsdnCardState *cs, u_char *buf, int len) {
        int count, fp;
        u_char *msg = buf;
@@ -472,7 +472,7 @@ modem_write_cmd(struct IsdnCardState *cs, u_char *buf, int len) {
        }
 }
 
-void
+static void
 modem_set_init(struct IsdnCardState *cs) {
        int timeout;
 
@@ -521,7 +521,7 @@ modem_set_init(struct IsdnCardState *cs) {
        udelay(RCV_DELAY);
 }
 
-void
+static void
 modem_set_dial(struct IsdnCardState *cs, int outgoing) {
        int timeout;
 #define RCV_DELAY 20000        
@@ -543,7 +543,7 @@ modem_set_dial(struct IsdnCardState *cs, int outgoing) {
        udelay(RCV_DELAY);
 }
 
-void
+static void
 modem_l2l1(struct PStack *st, int pr, void *arg)
 {
        struct BCState *bcs = st->l1.bcs;
@@ -579,7 +579,7 @@ modem_l2l1(struct PStack *st, int pr, void *arg)
        }
 }
 
-int
+static int
 setstack_elsa(struct PStack *st, struct BCState *bcs)
 {
 
@@ -614,7 +614,7 @@ setstack_elsa(struct PStack *st, struct BCState *bcs)
        return (0);
 }
 
-void
+static void
 init_modem(struct IsdnCardState *cs) {
 
        cs->bcs[0].BC_SetStack = setstack_elsa;
@@ -641,7 +641,7 @@ init_modem(struct IsdnCardState *cs) {
        modem_set_init(cs);
 }
 
-void
+static void
 release_modem(struct IsdnCardState *cs) {
 
        cs->hw.elsa.MFlag = 0;
diff --git a/drivers/isdn/hisax/enternow.h b/drivers/isdn/hisax/enternow.h
deleted file mode 100644 (file)
index ed2eec5..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-/* 2001/10/02
- *
- * enternow.h   Header-file included by
- *              enternow_pci.c
- *
- * Author       Christoph Ersfeld <info@formula-n.de>
- *              Formula-n Europe AG (www.formula-n.com)
- *              previously Gerdes AG
- *
- *
- *              This file is (c) under GNU PUBLIC LICENSE
- */
-
-
-/* ***************************************************************************************** *
- * ****************************** datatypes and macros ************************************* *
- * ***************************************************************************************** */
-
-#define BYTE                                                   unsigned char
-#define WORD                                                   unsigned int
-#define HIBYTE(w)                                              ((unsigned char)((w & 0xff00) / 256))
-#define LOBYTE(w)                                              ((unsigned char)(w & 0x00ff))
-#define InByte(addr)                                           inb(addr)
-#define OutByte(addr,val)                                      outb(val,addr)
-
-
-
-/* ***************************************************************************************** *
- * *********************************** card-specific *************************************** *
- * ***************************************************************************************** */
-
-/* für PowerISDN PCI */
-#define TJ_AMD_IRQ                                             0x20
-#define TJ_LED1                                                0x40
-#define TJ_LED2                                                0x80
-
-
-/* Das Fenster zum AMD...
- * Ab Adresse hw.njet.base + TJ_AMD_PORT werden vom AMD jeweils 8 Bit in
- * den TigerJet i/o-Raum gemappt
- * -> 0x01 des AMD bei hw.njet.base + 0C4 */
-#define TJ_AMD_PORT                                            0xC0
-
-
-
-/* ***************************************************************************************** *
- * *************************************** Prototypen ************************************** *
- * ***************************************************************************************** */
-
-BYTE ReadByteAmd7930(struct IsdnCardState *cs, BYTE offset);
-void WriteByteAmd7930(struct IsdnCardState *cs, BYTE offset, BYTE value);
index 1cc4d11e007a00786d10b4411a6e6622aef425fa..3341cf1555312ee7e7672269373b7bdb42b55531 100644 (file)
@@ -65,7 +65,6 @@
 #include "isac.h"
 #include "isdnl1.h"
 #include "amd7930_fn.h"
-#include "enternow.h"
 #include <linux/interrupt.h>
 #include <linux/ppp_defs.h>
 #include <linux/pci.h>
 
 
 
-const char *enternow_pci_rev = "$Revision: 1.1.4.5 $";
+static const char *enternow_pci_rev = "$Revision: 1.1.4.5 $";
+
+
+/* für PowerISDN PCI */
+#define TJ_AMD_IRQ                                              0x20
+#define TJ_LED1                                                 0x40
+#define TJ_LED2                                                 0x80
+
+
+/* Das Fenster zum AMD...
+ * Ab Adresse hw.njet.base + TJ_AMD_PORT werden vom AMD jeweils 8 Bit in
+ * den TigerJet i/o-Raum gemappt
+ * -> 0x01 des AMD bei hw.njet.base + 0C4 */
+#define TJ_AMD_PORT                                             0xC0
+
 
 
 /* *************************** I/O-Interface functions ************************************* */
 
 
 /* cs->readisac, macro rByteAMD */
-BYTE
-ReadByteAmd7930(struct IsdnCardState *cs, BYTE offset)
+static unsigned char
+ReadByteAmd7930(struct IsdnCardState *cs, unsigned char offset)
 {
        /* direktes Register */
        if(offset < 8)
-               return (InByte(cs->hw.njet.isac + 4*offset));
+               return (inb(cs->hw.njet.isac + 4*offset));
 
        /* indirektes Register */
        else {
-               OutByte(cs->hw.njet.isac + 4*AMD_CR, offset);
-               return(InByte(cs->hw.njet.isac + 4*AMD_DR));
+               outb(offset, cs->hw.njet.isac + 4*AMD_CR);
+               return(inb(cs->hw.njet.isac + 4*AMD_DR));
        }
 }
 
 /* cs->writeisac, macro wByteAMD */
-void
-WriteByteAmd7930(struct IsdnCardState *cs, BYTE offset, BYTE value)
+static void
+WriteByteAmd7930(struct IsdnCardState *cs, unsigned char offset, unsigned char value)
 {
        /* direktes Register */
        if(offset < 8)
-               OutByte(cs->hw.njet.isac + 4*offset, value);
+               outb(value, cs->hw.njet.isac + 4*offset);
 
        /* indirektes Register */
        else {
-               OutByte(cs->hw.njet.isac + 4*AMD_CR, offset);
-               OutByte(cs->hw.njet.isac + 4*AMD_DR, value);
+               outb(offset, cs->hw.njet.isac + 4*AMD_CR);
+               outb(value, cs->hw.njet.isac + 4*AMD_DR);
        }
 }
 
 
-void
-enpci_setIrqMask(struct IsdnCardState *cs, BYTE val) {
+static void
+enpci_setIrqMask(struct IsdnCardState *cs, unsigned char val) {
         if (!val)
-               OutByte(cs->hw.njet.base+NETJET_IRQMASK1, 0x00);
+               outb(0x00, cs->hw.njet.base+NETJET_IRQMASK1);
         else
-               OutByte(cs->hw.njet.base+NETJET_IRQMASK1, TJ_AMD_IRQ);
+               outb(TJ_AMD_IRQ, cs->hw.njet.base+NETJET_IRQMASK1);
 }
 
 
-static BYTE dummyrr(struct IsdnCardState *cs, int chan, BYTE off)
+static unsigned char dummyrr(struct IsdnCardState *cs, int chan, unsigned char off)
 {
         return(5);
 }
 
-static void dummywr(struct IsdnCardState *cs, int chan, BYTE off, BYTE value)
+static void dummywr(struct IsdnCardState *cs, int chan, unsigned char off, unsigned char value)
 {
 
 }
@@ -142,18 +155,18 @@ reset_enpci(struct IsdnCardState *cs)
 
        /* Reset on, (also for AMD) */
        cs->hw.njet.ctrl_reg = 0x07;
-       OutByte(cs->hw.njet.base + NETJET_CTRL, cs->hw.njet.ctrl_reg);
+       outb(cs->hw.njet.ctrl_reg, cs->hw.njet.base + NETJET_CTRL);
        mdelay(20);
        /* Reset off */
        cs->hw.njet.ctrl_reg = 0x30;
-       OutByte(cs->hw.njet.base + NETJET_CTRL, cs->hw.njet.ctrl_reg);
+       outb(cs->hw.njet.ctrl_reg, cs->hw.njet.base + NETJET_CTRL);
        /* 20ms delay */
        mdelay(20);
        cs->hw.njet.auxd = 0;  // LED-status
        cs->hw.njet.dmactrl = 0;
-       OutByte(cs->hw.njet.base + NETJET_AUXCTRL, ~TJ_AMD_IRQ);
-       OutByte(cs->hw.njet.base + NETJET_IRQMASK1, TJ_AMD_IRQ);
-       OutByte(cs->hw.njet.auxa, cs->hw.njet.auxd); // LED off
+       outb(~TJ_AMD_IRQ, cs->hw.njet.base + NETJET_AUXCTRL);
+       outb(TJ_AMD_IRQ, cs->hw.njet.base + NETJET_IRQMASK1);
+       outb(cs->hw.njet.auxd, cs->hw.njet.auxa); // LED off
 }
 
 
@@ -161,7 +174,7 @@ static int
 enpci_card_msg(struct IsdnCardState *cs, int mt, void *arg)
 {
        u_long flags;
-        BYTE *chan;
+        unsigned char *chan;
 
        if (cs->debug & L1_DEB_ISAC)
                debugl1(cs, "enter:now PCI: card_msg: 0x%04X", mt);
@@ -187,16 +200,16 @@ enpci_card_msg(struct IsdnCardState *cs, int mt, void *arg)
                 case MDL_ASSIGN:
                         /* TEI assigned, LED1 on */
                         cs->hw.njet.auxd = TJ_AMD_IRQ << 1;
-                        OutByte(cs->hw.njet.base + NETJET_AUXDATA, cs->hw.njet.auxd);
+                        outb(cs->hw.njet.auxd, cs->hw.njet.base + NETJET_AUXDATA);
                         break;
                 case MDL_REMOVE:
                         /* TEI removed, LEDs off */
                        cs->hw.njet.auxd = 0;
-                        OutByte(cs->hw.njet.base + NETJET_AUXDATA, 0x00);
+                        outb(0x00, cs->hw.njet.base + NETJET_AUXDATA);
                         break;
                 case MDL_BC_ASSIGN:
                         /* activate B-channel */
-                        chan = (BYTE *)arg;
+                        chan = (unsigned char *)arg;
 
                         if (cs->debug & L1_DEB_ISAC)
                                debugl1(cs, "enter:now PCI: assign phys. BC %d in AMD LMR1", *chan);
@@ -204,11 +217,11 @@ enpci_card_msg(struct IsdnCardState *cs, int mt, void *arg)
                         cs->dc.amd7930.ph_command(cs, (cs->dc.amd7930.lmr1 | (*chan + 1)), "MDL_BC_ASSIGN");
                         /* at least one b-channel in use, LED 2 on */
                         cs->hw.njet.auxd |= TJ_AMD_IRQ << 2;
-                        OutByte(cs->hw.njet.base + NETJET_AUXDATA, cs->hw.njet.auxd);
+                        outb(cs->hw.njet.auxd, cs->hw.njet.base + NETJET_AUXDATA);
                         break;
                 case MDL_BC_RELEASE:
                         /* deactivate B-channel */
-                        chan = (BYTE *)arg;
+                        chan = (unsigned char *)arg;
 
                         if (cs->debug & L1_DEB_ISAC)
                                debugl1(cs, "enter:now PCI: release phys. BC %d in Amd LMR1", *chan);
@@ -217,7 +230,7 @@ enpci_card_msg(struct IsdnCardState *cs, int mt, void *arg)
                         /* no b-channel active -> LED2 off */
                         if (!(cs->dc.amd7930.lmr1 & 3)) {
                                 cs->hw.njet.auxd &= ~(TJ_AMD_IRQ << 2);
-                                OutByte(cs->hw.njet.base + NETJET_AUXDATA, cs->hw.njet.auxd);
+                                outb(cs->hw.njet.auxd, cs->hw.njet.base + NETJET_AUXDATA);
                         }
                         break;
                 default:
@@ -231,11 +244,11 @@ static irqreturn_t
 enpci_interrupt(int intno, void *dev_id, struct pt_regs *regs)
 {
        struct IsdnCardState *cs = dev_id;
-       BYTE s0val, s1val, ir;
+       unsigned char s0val, s1val, ir;
        u_long flags;
 
        spin_lock_irqsave(&cs->lock, flags);
-       s1val = InByte(cs->hw.njet.base + NETJET_IRQSTAT1);
+       s1val = inb(cs->hw.njet.base + NETJET_IRQSTAT1);
 
         /* AMD threw an interrupt */
        if (!(s1val & TJ_AMD_IRQ)) {
@@ -245,13 +258,13 @@ enpci_interrupt(int intno, void *dev_id, struct pt_regs *regs)
                s1val = 1;
        } else
                s1val = 0;
-       s0val = InByte(cs->hw.njet.base + NETJET_IRQSTAT0);
+       s0val = inb(cs->hw.njet.base + NETJET_IRQSTAT0);
        if ((s0val | s1val)==0) { // shared IRQ
                spin_unlock_irqrestore(&cs->lock, flags);
                return IRQ_NONE;
        } 
        if (s0val)
-               OutByte(cs->hw.njet.base + NETJET_IRQSTAT0, s0val);
+               outb(s0val, cs->hw.njet.base + NETJET_IRQSTAT0);
 
        /* DMA-Interrupt: B-channel-stuff */
        /* set bits in sval to indicate which page is free */
@@ -342,20 +355,20 @@ setup_enternow_pci(struct IsdnCard *card)
 
                /* Reset an */
                cs->hw.njet.ctrl_reg = 0x07;  // geändert von 0xff
-               OutByte(cs->hw.njet.base + NETJET_CTRL, cs->hw.njet.ctrl_reg);
+               outb(cs->hw.njet.ctrl_reg, cs->hw.njet.base + NETJET_CTRL);
                /* 20 ms Pause */
                mdelay(20);
 
                cs->hw.njet.ctrl_reg = 0x30;  /* Reset Off and status read clear */
-               OutByte(cs->hw.njet.base + NETJET_CTRL, cs->hw.njet.ctrl_reg);
+               outb(cs->hw.njet.ctrl_reg, cs->hw.njet.base + NETJET_CTRL);
                mdelay(10);
 
                cs->hw.njet.auxd = 0x00; // war 0xc0
                cs->hw.njet.dmactrl = 0;
 
-               OutByte(cs->hw.njet.base + NETJET_AUXCTRL, ~TJ_AMD_IRQ);
-               OutByte(cs->hw.njet.base + NETJET_IRQMASK1, TJ_AMD_IRQ);
-               OutByte(cs->hw.njet.auxa, cs->hw.njet.auxd);
+               outb(~TJ_AMD_IRQ, cs->hw.njet.base + NETJET_AUXCTRL);
+               outb(TJ_AMD_IRQ, cs->hw.njet.base + NETJET_IRQMASK1);
+               outb(cs->hw.njet.auxd, cs->hw.njet.auxa);
 
                break;
        }
index 24a05a43f33e35ca78d142cb1ead3bdab60cd8fe..352b45ac5347239c0911c445da6da7f66767b249 100644 (file)
@@ -21,7 +21,7 @@
 #include <linux/pci.h>
 
 extern const char *CardType[];
-const char *gazel_revision = "$Revision: 2.19.2.4 $";
+static const char *gazel_revision = "$Revision: 2.19.2.4 $";
 
 #define R647      1
 #define R685      2
@@ -317,7 +317,8 @@ gazel_interrupt_ipac(int intno, void *dev_id, struct pt_regs *regs)
        spin_unlock_irqrestore(&cs->lock, flags);
        return IRQ_HANDLED;
 }
-void
+
+static void
 release_io_gazel(struct IsdnCardState *cs)
 {
        unsigned int i;
index ba1d028343ecd8e869a39d971d6a5d27e74b94e5..6e7e060716b7b071a478f9f62c3774d767f8778a 100644 (file)
@@ -1358,7 +1358,7 @@ chipreset(hfc4s8s_hw * hw)
 /********************************************/
 /* disable/enable hardware in nt or te mode */
 /********************************************/
-void
+static void
 hfc_hardware_enable(hfc4s8s_hw * hw, int enable, int nt_mode)
 {
        u_long flags;
index ebea3feef003ad0e9f4008573fc67ca6ad6fc1ec..7cf87793e7907d5bdf4d354a1fc4011cce151ad6 100644 (file)
@@ -345,7 +345,7 @@ hfc_send_data(struct BCState *bcs)
                debugl1(cs,"send_data %d blocked", bcs->channel);
 }
 
-void
+static void
 main_rec_2bds0(struct BCState *bcs)
 {
        struct IsdnCardState *cs = bcs->cs;
@@ -399,7 +399,7 @@ main_rec_2bds0(struct BCState *bcs)
        return;
 }
 
-void
+static void
 mode_2bs0(struct BCState *bcs, int mode, int bc)
 {
        struct IsdnCardState *cs = bcs->cs;
@@ -505,7 +505,7 @@ hfc_l2l1(struct PStack *st, int pr, void *arg)
        }
 }
 
-void
+static void
 close_2bs0(struct BCState *bcs)
 {
        mode_2bs0(bcs, 0, bcs->channel);
@@ -534,7 +534,7 @@ open_hfcstate(struct IsdnCardState *cs, struct BCState *bcs)
        return (0);
 }
 
-int
+static int
 setstack_2b(struct PStack *st, struct BCState *bcs)
 {
        bcs->channel = st->l1.bc;
@@ -1004,7 +1004,7 @@ HFCD_l1hw(struct PStack *st, int pr, void *arg)
        }
 }
 
-void
+static void
 setstack_hfcd(struct PStack *st, struct IsdnCardState *cs)
 {
        st->l1.l1hw = HFCD_l1hw;
@@ -1015,7 +1015,7 @@ hfc_dbusy_timer(struct IsdnCardState *cs)
 {
 }
 
-unsigned int __init
+static unsigned int __init
 *init_send_hfcd(int cnt)
 {
        int i, *send;
index bb376f39ac89d9b06e3c0d76828a8c5aa6f1565a..f978a5af866292489ceb58b267219c5a3b86b32e 100644 (file)
@@ -52,7 +52,7 @@ WaitNoBusy(struct IsdnCardState *cs)
                return (to);
 }
 
-int
+static int
 GetFreeFifoBytes(struct BCState *bcs)
 {
        int s;
@@ -66,7 +66,7 @@ GetFreeFifoBytes(struct BCState *bcs)
        return (s);
 }
 
-int
+static int
 ReadZReg(struct BCState *bcs, u_char reg)
 {
        int val;
@@ -394,7 +394,7 @@ main_irq_hfc(struct BCState *bcs)
        return;
 }
 
-void
+static void
 mode_hfc(struct BCState *bcs, int mode, int bc)
 {
        struct IsdnCardState *cs = bcs->cs;
@@ -507,7 +507,7 @@ hfc_l2l1(struct PStack *st, int pr, void *arg)
 }
 
 
-void
+static void
 close_hfcstate(struct BCState *bcs)
 {
        mode_hfc(bcs, 0, bcs->channel);
@@ -537,7 +537,7 @@ open_hfcstate(struct IsdnCardState *cs, struct BCState *bcs)
        return (0);
 }
 
-int
+static int
 setstack_hfc(struct PStack *st, struct BCState *bcs)
 {
        bcs->channel = st->l1.bc;
@@ -551,7 +551,7 @@ setstack_hfc(struct PStack *st, struct BCState *bcs)
        return (0);
 }
 
-void __init
+static void __init
 init_send(struct BCState *bcs)
 {
        int i;
index c2db52696a86bb2350261556116877aa1fe8e06c..8337b0f26cc40183e0846c683bbd43797f4a97bf 100644 (file)
@@ -70,7 +70,7 @@ static const PCI_ENTRY id_list[] =
 /******************************************/
 /* free hardware resources used by driver */
 /******************************************/
-void
+static void
 release_io_hfcpci(struct IsdnCardState *cs)
 {
        printk(KERN_INFO "HiSax: release hfcpci at %p\n",
@@ -394,7 +394,7 @@ receive_dmsg(struct IsdnCardState *cs)
 /*******************************************************************************/
 /* check for transparent receive data and read max one threshold size if avail */
 /*******************************************************************************/
-int
+static int
 hfcpci_empty_fifo_trans(struct BCState *bcs, bzfifo_type * bz, u_char * bdata)
 {
        unsigned short *z1r, *z2r;
@@ -446,7 +446,7 @@ hfcpci_empty_fifo_trans(struct BCState *bcs, bzfifo_type * bz, u_char * bdata)
 /**********************************/
 /* B-channel main receive routine */
 /**********************************/
-void
+static void
 main_rec_hfcpci(struct BCState *bcs)
 {
        struct IsdnCardState *cs = bcs->cs;
@@ -1244,7 +1244,7 @@ HFCPCI_l1hw(struct PStack *st, int pr, void *arg)
 /***********************************************/
 /* called during init setting l1 stack pointer */
 /***********************************************/
-void
+static void
 setstack_hfcpci(struct PStack *st, struct IsdnCardState *cs)
 {
        st->l1.l1hw = HFCPCI_l1hw;
@@ -1268,7 +1268,7 @@ hfcpci_send_data(struct BCState *bcs)
 /***************************************************************/
 /* activate/deactivate hardware for selected channels and mode */
 /***************************************************************/
-void
+static void
 mode_hfcpci(struct BCState *bcs, int mode, int bc)
 {
        struct IsdnCardState *cs = bcs->cs;
@@ -1579,7 +1579,7 @@ hfcpci_bh(struct IsdnCardState *cs)
 /********************************/
 /* called for card init message */
 /********************************/
-void __init
+static void __init
 inithfcpci(struct IsdnCardState *cs)
 {
        cs->bcs[0].BC_SetStack = setstack_2b;
index 4df036ed1af0aa9d5816574d94ef2c0385c429d2..9ef2981e404ed5ba96f87080295eacf3bf46857a 100644 (file)
@@ -232,5 +232,4 @@ typedef union {
 #define Read_hfc(a,b) (*(((u_char *)a->hw.hfcpci.pci_io)+b))
 
 extern void main_irq_hcpci(struct BCState *bcs);
-extern void inithfcpci(struct IsdnCardState *cs);
 extern void releasehfcpci(struct IsdnCardState *cs);
index a307fcb6c6349304dbd163ca300b736bd15ea72c..f27c1608a3a706ba482d4163b0f67c2393e9dedd 100644 (file)
@@ -308,7 +308,7 @@ read_fifo(struct IsdnCardState *cs, u_char fifo, int trans_max)
 /******************************************/
 /* free hardware resources used by driver */
 /******************************************/
-void
+static void
 release_io_hfcsx(struct IsdnCardState *cs)
 {
        cs->hw.hfcsx.int_m2 = 0;        /* interrupt output off ! */
@@ -472,7 +472,7 @@ receive_dmsg(struct IsdnCardState *cs)
 /**********************************/
 /* B-channel main receive routine */
 /**********************************/
-void
+static void
 main_rec_hfcsx(struct BCState *bcs)
 {
        struct IsdnCardState *cs = bcs->cs;
@@ -1003,7 +1003,7 @@ HFCSX_l1hw(struct PStack *st, int pr, void *arg)
 /***********************************************/
 /* called during init setting l1 stack pointer */
 /***********************************************/
-void
+static void
 setstack_hfcsx(struct PStack *st, struct IsdnCardState *cs)
 {
        st->l1.l1hw = HFCSX_l1hw;
@@ -1027,7 +1027,7 @@ hfcsx_send_data(struct BCState *bcs)
 /***************************************************************/
 /* activate/deactivate hardware for selected channels and mode */
 /***************************************************************/
-void
+static void
 mode_hfcsx(struct BCState *bcs, int mode, int bc)
 {
        struct IsdnCardState *cs = bcs->cs;
@@ -1328,7 +1328,7 @@ hfcsx_bh(struct IsdnCardState *cs)
 /********************************/
 /* called for card init message */
 /********************************/
-void __devinit
+static void __devinit
 inithfcsx(struct IsdnCardState *cs)
 {
        cs->setstack_d = setstack_hfcsx;
index 12f54159344aa3ad7970052b89177462250e58f1..6792f13dc22011f3b57a3da96b793f280e8a9bbc 100644 (file)
@@ -193,5 +193,4 @@ struct hfcsx_extra {
 };
 
 extern void main_irq_hfcsx(struct BCState *bcs);
-extern void inithfcsx(struct IsdnCardState *cs);
 extern void releasehfcsx(struct IsdnCardState *cs);
index ffd74b84f502e0f999b2c40725de5aabf8331320..e2c3af49d72b9af938d47fd109924d74e7c84949 100644 (file)
@@ -60,7 +60,7 @@ static const char *hfcusb_revision =
 #include "hisax_debug.h"
 static u_int debug;
 module_param(debug, uint, 0);
-int hfc_debug;
+static int hfc_debug;
 #endif
 
 
@@ -85,7 +85,7 @@ static struct usb_device_id hfc_usb_idtab[] = {
 *   VendorID, ProductID, Devicename, LED_SCHEME,
 *   LED's BitMask in HFCUSB_P_DATA Register : LED_USB, LED_S0, LED_B1, LED_B2
 */
-vendor_data vdata[] = {
+static vendor_data vdata[] = {
        /* CologneChip Eval TA */
        {0x0959, 0x2bd0, "ISDN USB TA (Cologne Chip HFC-S USB based)",
         LED_OFF, {4, 0, 2, 1}
@@ -1137,7 +1137,7 @@ set_hfcmode(hfcusb_data * hfc, int channel, int mode)
        }
 }
 
-void
+static void
 hfc_usb_l2l1(struct hisax_if *my_hisax_if, int pr, void *arg)
 {
        usb_fifo *fifo = my_hisax_if->priv;
index b171600cf641273b039aeefe0d505a15e66039fc..280dd29b30d6fbd0efaaf0f715a15637ab759b49 100644 (file)
@@ -168,7 +168,7 @@ static struct hfcusb_symbolic_list urb_errlist[] = {
 * 3 entries are the configuration number, the minimum interval for
 * Interrupt endpoints & boolean if E-channel logging possible
 */
-int validconf[][19] = {
+static int validconf[][19] = {
        // INT in, ISO out config
        {EP_NUL, EP_INT, EP_NUL, EP_INT, EP_NUL, EP_INT, EP_NOP, EP_INT,
         EP_ISO, EP_NUL, EP_ISO, EP_NUL, EP_ISO, EP_NUL, EP_NUL, EP_NUL,
@@ -187,7 +187,7 @@ int validconf[][19] = {
 };
 
 // string description of chosen config
-char *conf_str[] = {
+static char *conf_str[] = {
        "4 Interrupt IN + 3 Isochron OUT",
        "3 Interrupt IN + 3 Isochron OUT",
        "4 Isochron IN + 3 Isochron OUT",
index 6fc55fea17029bb70428d8231a4e66662b1f931c..86ab1c13f6b15e7ab56f11aed977247809fd2f85 100644 (file)
@@ -52,7 +52,7 @@ hfcs_Timer(struct IsdnCardState *cs)
 */
 }
 
-void
+static void
 release_io_hfcs(struct IsdnCardState *cs)
 {
        release2bds0(cs);
index dc5791728d537f8311b7ba69cffc6bc4934aea6d..17cf7663c58233fda3610b9890d2e663254ba643 100644 (file)
@@ -1271,7 +1271,6 @@ extern void Logl2Frame(struct IsdnCardState *cs, struct sk_buff *skb, char *buf,
 void init_bcstate(struct IsdnCardState *cs, int bc);
 
 void setstack_HiSax(struct PStack *st, struct IsdnCardState *cs);
-unsigned int random_ri(void);
 void HiSax_addlist(struct IsdnCardState *sp, struct PStack *st);
 void HiSax_rmlist(struct IsdnCardState *sp, struct PStack *st);
 
@@ -1315,15 +1314,11 @@ int QuickHex(char *txt, u_char * p, int cnt);
 void LogFrame(struct IsdnCardState *cs, u_char * p, int size);
 void dlogframe(struct IsdnCardState *cs, struct sk_buff *skb, int dir);
 void iecpy(u_char * dest, u_char * iestart, int ieoffset);
-#ifdef ISDN_CHIP_ISAC
-void setstack_isac(struct PStack *st, struct IsdnCardState *cs);
-#endif /* ISDN_CHIP_ISAC */
 #endif /* __KERNEL__ */
 
 #define HZDELAY(jiffs) {int tout = jiffs; while (tout--) udelay(1000000/HZ);}
 
 int ll_run(struct IsdnCardState *cs, int addfeatures);
-void ll_stop(struct IsdnCardState *cs);
 int CallcNew(void);
 void CallcFree(void);
 int CallcNewChan(struct IsdnCardState *cs);
index 5bbbe3e951250708dbf6acd62fe2057101a27434..66dbaee77bfbd005ecd5db41b32e4cd459bec8c3 100644 (file)
@@ -151,7 +151,7 @@ hscx_l2l1(struct PStack *st, int pr, void *arg)
        }
 }
 
-void
+static void
 close_hscxstate(struct BCState *bcs)
 {
        modehscx(bcs, 0, bcs->channel);
@@ -203,7 +203,7 @@ open_hscxstate(struct IsdnCardState *cs, struct BCState *bcs)
        return (0);
 }
 
-int
+static int
 setstack_hscx(struct PStack *st, struct BCState *bcs)
 {
        bcs->channel = st->l1.bc;
index dcf31f83c6000da39c2bd84cd888ad12b6bcb942..b4ca5859b1777cb1e99f88f7fb95714644a845ee 100644 (file)
@@ -108,7 +108,7 @@ icc_bh(struct IsdnCardState *cs)
 #endif
 }
 
-void
+static void
 icc_empty_fifo(struct IsdnCardState *cs, int count)
 {
        u_char *ptr;
@@ -563,13 +563,13 @@ ICC_l1hw(struct PStack *st, int pr, void *arg)
        }
 }
 
-void
+static void
 setstack_icc(struct PStack *st, struct IsdnCardState *cs)
 {
        st->l1.l1hw = ICC_l1hw;
 }
 
-void 
+static void
 DC_Close_icc(struct IsdnCardState *cs) {
        if (cs->dc.icc.mon_rx) {
                kfree(cs->dc.icc.mon_rx);
index 6485e232d86936f728ebb70be5957f929f654cdb..efba2f44801797f726f30c6033b14dfc3d65611a 100644 (file)
@@ -36,8 +36,6 @@ static void ph_command(struct IsdnCardState *cs, unsigned int command);
 static inline void cic_int(struct IsdnCardState *cs);
 static void dch_l2l1(struct PStack *st, int pr, void *arg);
 static void dbusy_timer_handler(struct IsdnCardState *cs);
-static void ipacx_new_ph(struct IsdnCardState *cs);
-static void dch_bh(struct IsdnCardState *cs);
 static void dch_empty_fifo(struct IsdnCardState *cs, int count);
 static void dch_fill_fifo(struct IsdnCardState *cs);
 static inline void dch_int(struct IsdnCardState *cs);
@@ -231,81 +229,6 @@ dbusy_timer_handler(struct IsdnCardState *cs)
        }
 }
 
-//----------------------------------------------------------
-// L1 state machine intermediate layer to isdnl1 module
-//----------------------------------------------------------
-static void
-ipacx_new_ph(struct IsdnCardState *cs)
-{
-       switch (cs->dc.isac.ph_state) {
-               case (IPACX_IND_RES):
-                       ph_command(cs, IPACX_CMD_DI);
-                       l1_msg(cs, HW_RESET | INDICATION, NULL);
-                       break;
-      
-               case (IPACX_IND_DC):
-                       l1_msg(cs, HW_DEACTIVATE | CONFIRM, NULL);
-                       break;
-      
-               case (IPACX_IND_DR):
-                       l1_msg(cs, HW_DEACTIVATE | INDICATION, NULL);
-                       break;
-      
-               case (IPACX_IND_PU):
-                       l1_msg(cs, HW_POWERUP | CONFIRM, NULL);
-                       break;
-
-               case (IPACX_IND_RSY):
-                       l1_msg(cs, HW_RSYNC | INDICATION, NULL);
-                       break;
-
-               case (IPACX_IND_AR):
-                       l1_msg(cs, HW_INFO2 | INDICATION, NULL);
-                       break;
-      
-               case (IPACX_IND_AI8):
-                       l1_msg(cs, HW_INFO4_P8 | INDICATION, NULL);
-                       break;
-      
-               case (IPACX_IND_AI10):
-                       l1_msg(cs, HW_INFO4_P10 | INDICATION, NULL);
-                       break;
-      
-               default:
-                       break;
-       }
-}
-
-//----------------------------------------------------------
-// bottom half handler for D channel
-//----------------------------------------------------------
-static void
-dch_bh(struct IsdnCardState *cs)
-{
-       struct PStack *st;
-       
-       if (!cs) return;
-  
-       if (test_and_clear_bit(D_CLEARBUSY, &cs->event)) {
-               if (cs->debug) debugl1(cs, "D-Channel Busy cleared");
-               for (st = cs->stlist; st; st = st->next) {
-                       st->l1.l1l2(st, PH_PAUSE | CONFIRM, NULL);
-               }
-       }
-  
-       if (test_and_clear_bit(D_RCVBUFREADY, &cs->event)) {
-               DChannel_proc_rcv(cs);
-  }  
-  
-       if (test_and_clear_bit(D_XMTBUFREADY, &cs->event)) {
-               DChannel_proc_xmt(cs);
-  }  
-  
-       if (test_and_clear_bit(D_L1STATECHANGE, &cs->event)) {
-    ipacx_new_ph(cs);
-  }  
-}
-
 //----------------------------------------------------------
 // Fill buffer from receive FIFO
 //----------------------------------------------------------
@@ -991,14 +914,5 @@ init_ipacx(struct IsdnCardState *cs, int part)
        }
 }
 
-
-void __devinit
-setup_ipacx(struct IsdnCardState *cs)
-{
-       INIT_WORK(&cs->tqueue, (void *)(void *) dch_bh, cs);
-       cs->dbusytimer.function = (void *) dbusy_timer_handler;
-       cs->dbusytimer.data = (long) cs;
-       init_timer(&cs->dbusytimer);
-}
 //----------------- end of file -----------------------
 
index 20b9499529528c6d8cfa37ca7c1eda643ab613e0..85e063a08d23e3410215e8c519a729b59a5352de 100644 (file)
@@ -112,7 +112,7 @@ isac_bh(struct IsdnCardState *cs)
 #endif
 }
 
-void
+static void
 isac_empty_fifo(struct IsdnCardState *cs, int count)
 {
        u_char *ptr;
@@ -563,13 +563,13 @@ ISAC_l1hw(struct PStack *st, int pr, void *arg)
        }
 }
 
-void
+static void
 setstack_isac(struct PStack *st, struct IsdnCardState *cs)
 {
        st->l1.l1hw = ISAC_l1hw;
 }
 
-void 
+static void
 DC_Close_isac(struct IsdnCardState *cs) {
        if (cs->dc.isac.mon_rx) {
                kfree(cs->dc.isac.mon_rx);
index ee081321efb25e6e9741ded87490ac0bc6dab641..642a87c51295c70055509678fa71a370a766f9f2 100644 (file)
 #define ETX    0x03
 
 #define FAXMODCNT      13
-const  u_char  faxmodulation[] = {3,24,48,72,73,74,96,97,98,121,122,145,146};
+static const   u_char  faxmodulation[] = {3,24,48,72,73,74,96,97,98,121,122,145,146};
 static u_int   modmask = 0x1fff;
 static int     frm_extra_delay = 2;
 static int     para_TOA = 6;
-const   u_char  *FC1_CMD[] = {"FAE", "FTS", "FRS", "FTM", "FRM", "FTH", "FRH", "CTRL" };
+static const   u_char  *FC1_CMD[] = {"FAE", "FTS", "FRS", "FTM", "FRM", "FTH", "FRH", "CTRL" };
 
-void isar_setup(struct IsdnCardState *cs);
+static void isar_setup(struct IsdnCardState *cs);
 static void isar_pump_cmd(struct BCState *bcs, u_char cmd, u_char para);
 static void ll_deliver_faxstat(struct BCState *bcs, u_char status);
 
@@ -45,7 +45,7 @@ waitforHIA(struct IsdnCardState *cs, int timeout)
 }
 
 
-int
+static int
 sendmsg(struct IsdnCardState *cs, u_char his, u_char creg, u_char len,
        u_char *msg)
 {
@@ -85,7 +85,7 @@ sendmsg(struct IsdnCardState *cs, u_char his, u_char creg, u_char len,
 }
 
 /* Call only with IRQ disabled !!! */
-inline void
+static inline void
 rcv_mbox(struct IsdnCardState *cs, struct isar_reg *ireg, u_char *msg)
 {
        int i;
@@ -114,7 +114,7 @@ rcv_mbox(struct IsdnCardState *cs, struct isar_reg *ireg, u_char *msg)
 }
 
 /* Call only with IRQ disabled !!! */
-inline void
+static inline void
 get_irq_infos(struct IsdnCardState *cs, struct isar_reg *ireg)
 {
        ireg->iis = cs->BC_Read_Reg(cs, 1, ISAR_IIS);
@@ -127,7 +127,7 @@ get_irq_infos(struct IsdnCardState *cs, struct isar_reg *ireg)
 #endif
 }
 
-int
+static int
 waitrecmsg(struct IsdnCardState *cs, u_char *len,
        u_char *msg, int maxdelay)
 {
@@ -185,7 +185,7 @@ ISARVersion(struct IsdnCardState *cs, char *s)
        return(ver);
 }
 
-int
+static int
 isar_load_firmware(struct IsdnCardState *cs, u_char __user *buf)
 {
        int ret, size, cnt, debug;
@@ -739,7 +739,7 @@ isar_fill_fifo(struct BCState *bcs)
        }
 }
 
-inline
+static inline
 struct BCState *sel_bcs_isar(struct IsdnCardState *cs, u_char dpath)
 {
        if ((!dpath) || (dpath == 3))
@@ -751,7 +751,7 @@ struct BCState *sel_bcs_isar(struct IsdnCardState *cs, u_char dpath)
        return(NULL);
 }
 
-void
+static void
 send_frames(struct BCState *bcs)
 {
        if (bcs->tx_skb) {
@@ -806,7 +806,7 @@ send_frames(struct BCState *bcs)
        }
 }
 
-inline void
+static inline void
 check_send(struct IsdnCardState *cs, u_char rdm)
 {
        struct BCState *bcs;
@@ -828,11 +828,13 @@ check_send(struct IsdnCardState *cs, u_char rdm)
        
 }
 
-const char *dmril[] = {"NO SPEED", "1200/75", "NODEF2", "75/1200", "NODEF4",
-                       "300", "600", "1200", "2400", "4800", "7200",
-                       "9600nt", "9600t", "12000", "14400", "WRONG"};
-const char *dmrim[] = {"NO MOD", "NO DEF", "V32/V32b", "V22", "V21",
-                       "Bell103", "V23", "Bell202", "V17", "V29", "V27ter"};
+static const char *dmril[] = {"NO SPEED", "1200/75", "NODEF2", "75/1200",
+                               "NODEF4", "300", "600", "1200", "2400",
+                               "4800", "7200", "9600nt", "9600t", "12000",
+                               "14400", "WRONG"};
+static const char *dmrim[] = {"NO MOD", "NO DEF", "V32/V32b", "V22", "V21",
+                               "Bell103", "V23", "Bell202", "V17", "V29",
+                               "V27ter"};
 
 static void
 isar_pump_status_rsp(struct BCState *bcs, struct isar_reg *ireg) {
@@ -1388,7 +1390,7 @@ setup_iom2(struct BCState *bcs) {
        udelay(1000);
 }
 
-int
+static int
 modeisar(struct BCState *bcs, int mode, int bc)
 {
        struct IsdnCardState *cs = bcs->cs;
@@ -1562,7 +1564,7 @@ isar_pump_cmd(struct BCState *bcs, u_char cmd, u_char para)
                sendmsg(cs, dps | ISAR_HIS_PUMPCTRL, ctrl, nom, &p1);
 }
 
-void
+static void
 isar_setup(struct IsdnCardState *cs)
 {
        u_char msg;
@@ -1582,7 +1584,7 @@ isar_setup(struct IsdnCardState *cs)
        }
 }
 
-void
+static void
 isar_l2l1(struct PStack *st, int pr, void *arg)
 {
        struct BCState *bcs = st->l1.bcs;
@@ -1681,7 +1683,7 @@ isar_l2l1(struct PStack *st, int pr, void *arg)
        }
 }
 
-void
+static void
 close_isarstate(struct BCState *bcs)
 {
        modeisar(bcs, 0, bcs->channel);
@@ -1703,7 +1705,7 @@ close_isarstate(struct BCState *bcs)
        del_timer(&bcs->hw.isar.ftimer);
 }
 
-int
+static int
 open_isarstate(struct IsdnCardState *cs, struct BCState *bcs)
 {
        if (!test_and_set_bit(BC_FLG_INIT, &bcs->Flag)) {
@@ -1725,7 +1727,7 @@ open_isarstate(struct IsdnCardState *cs, struct BCState *bcs)
        return (0);
 }
 
-int
+static int
 setstack_isar(struct PStack *st, struct BCState *bcs)
 {
        bcs->channel = st->l1.bc;
index 4d08d27f14995bf20a0c9da4261d7b479421fcb4..ac899503a74f1ee49b117de3b0d12d670a5a7ab0 100644 (file)
@@ -151,7 +151,7 @@ l1m_debug(struct FsmInst *fi, char *fmt, ...)
        va_end(args);
 }
 
-void
+static void
 L1activated(struct IsdnCardState *cs)
 {
        struct PStack *st;
@@ -166,7 +166,7 @@ L1activated(struct IsdnCardState *cs)
        }
 }
 
-void
+static void
 L1deactivated(struct IsdnCardState *cs)
 {
        struct PStack *st;
@@ -370,7 +370,7 @@ init_bcstate(struct IsdnCardState *cs, int bc)
 
 #ifdef L2FRAME_DEBUG           /* psa */
 
-char *
+static char *
 l2cmd(u_char cmd)
 {
        switch (cmd & ~0x10) {
@@ -404,7 +404,7 @@ l2cmd(u_char cmd)
 
 static char tmpdeb[32];
 
-char *
+static char *
 l2frames(u_char * ptr)
 {
        switch (ptr[2] & ~0x10) {
index d311b5fbf895014f1b529e0f4cb67fc309918609..9022583fd6a06e97b76a6c44dddcc0b7d7eacf8b 100644 (file)
@@ -142,7 +142,7 @@ freewin1(struct Layer2 *l2)
        return cnt;
 }
 
-inline void
+static inline void
 freewin(struct PStack *st)
 {
        freewin1(&st->l2);
@@ -157,7 +157,7 @@ ReleaseWin(struct Layer2 *l2)
                printk(KERN_WARNING "isdl2 freed %d skbuffs in release\n", cnt);
 }
 
-inline unsigned int
+static inline unsigned int
 cansend(struct PStack *st)
 {
        unsigned int p1;
@@ -169,7 +169,7 @@ cansend(struct PStack *st)
        return ((p1 < st->l2.window) && !test_bit(FLG_PEER_BUSY, &st->l2.flag));
 }
 
-inline void
+static inline void
 clear_exception(struct Layer2 *l2)
 {
        test_and_clear_bit(FLG_ACK_PEND, &l2->flag);
@@ -178,7 +178,7 @@ clear_exception(struct Layer2 *l2)
        clear_peer_busy(l2);
 }
 
-inline int
+static inline int
 l2headersize(struct Layer2 *l2, int ui)
 {
        return (((test_bit(FLG_MOD128, &l2->flag) && (!ui)) ? 2 : 1) +
@@ -223,40 +223,31 @@ enqueue_super(struct PStack *st,
 
 #define enqueue_ui(a, b) enqueue_super(a, b)
 
-inline int
+static inline int
 IsUI(u_char * data)
 {
        return ((data[0] & 0xef) == UI);
 }
 
-inline int
+static inline int
 IsUA(u_char * data)
 {
        return ((data[0] & 0xef) == UA);
 }
 
-inline int
+static inline int
 IsDM(u_char * data)
 {
        return ((data[0] & 0xef) == DM);
 }
 
-inline int
+static inline int
 IsDISC(u_char * data)
 {
        return ((data[0] & 0xef) == DISC);
 }
 
-inline int
-IsRR(u_char * data, struct PStack *st)
-{
-       if (test_bit(FLG_MOD128, &st->l2.flag))
-               return (data[0] == RR);
-       else
-               return ((data[0] & 0xf) == 1);
-}
-
-inline int
+static inline int
 IsSFrame(u_char * data, struct PStack *st)
 {
        register u_char d = *data;
@@ -266,7 +257,7 @@ IsSFrame(u_char * data, struct PStack *st)
        return(((d & 0xf3) == 1) && ((d & 0x0c) != 0x0c));
 }
 
-inline int
+static inline int
 IsSABME(u_char * data, struct PStack *st)
 {
        u_char d = data[0] & ~0x10;
@@ -274,25 +265,25 @@ IsSABME(u_char * data, struct PStack *st)
        return (test_bit(FLG_MOD128, &st->l2.flag) ? d == SABME : d == SABM);
 }
 
-inline int
+static inline int
 IsREJ(u_char * data, struct PStack *st)
 {
        return (test_bit(FLG_MOD128, &st->l2.flag) ? data[0] == REJ : (data[0] & 0xf) == REJ);
 }
 
-inline int
+static inline int
 IsFRMR(u_char * data)
 {
        return ((data[0] & 0xef) == FRMR);
 }
 
-inline int
+static inline int
 IsRNR(u_char * data, struct PStack *st)
 {
        return (test_bit(FLG_MOD128, &st->l2.flag) ? data[0] == RNR : (data[0] & 0xf) == RNR);
 }
 
-int
+static int
 iframe_error(struct PStack *st, struct sk_buff *skb)
 {
        int i = l2addrsize(&st->l2) + (test_bit(FLG_MOD128, &st->l2.flag) ? 2 : 1);
@@ -315,7 +306,7 @@ iframe_error(struct PStack *st, struct sk_buff *skb)
        return 0;
 }
 
-int
+static int
 super_error(struct PStack *st, struct sk_buff *skb)
 {
        if (skb->len != l2addrsize(&st->l2) +
@@ -325,7 +316,7 @@ super_error(struct PStack *st, struct sk_buff *skb)
        return 0;
 }
 
-int
+static int
 unnum_error(struct PStack *st, struct sk_buff *skb, int wantrsp)
 {
        int rsp = (*skb->data & 0x2) >> 1;
@@ -341,7 +332,7 @@ unnum_error(struct PStack *st, struct sk_buff *skb, int wantrsp)
        return 0;
 }
 
-int
+static int
 UI_error(struct PStack *st, struct sk_buff *skb)
 {
        int rsp = *skb->data & 0x2;
@@ -357,7 +348,7 @@ UI_error(struct PStack *st, struct sk_buff *skb)
        return 0;
 }
 
-int
+static int
 FRMR_error(struct PStack *st, struct sk_buff *skb)
 {
        int headers = l2addrsize(&st->l2) + 1;
@@ -444,51 +435,44 @@ send_uframe(struct PStack *st, u_char cmd, u_char cr)
        enqueue_super(st, skb);
 }
 
-inline u_char
+static inline u_char
 get_PollFlag(struct PStack * st, struct sk_buff * skb)
 {
        return (skb->data[l2addrsize(&(st->l2))] & 0x10);
 }
 
-inline void
-FreeSkb(struct sk_buff *skb)
-{
-       dev_kfree_skb(skb);
-}
-
-
-inline u_char
+static inline u_char
 get_PollFlagFree(struct PStack *st, struct sk_buff *skb)
 {
        u_char PF;
 
        PF = get_PollFlag(st, skb);
-       FreeSkb(skb);
+       dev_kfree_skb(skb);
        return (PF);
 }
 
-inline void
+static inline void
 start_t200(struct PStack *st, int i)
 {
        FsmAddTimer(&st->l2.t200, st->l2.T200, EV_L2_T200, NULL, i);
        test_and_set_bit(FLG_T200_RUN, &st->l2.flag);
 }
 
-inline void
+static inline void
 restart_t200(struct PStack *st, int i)
 {
        FsmRestartTimer(&st->l2.t200, st->l2.T200, EV_L2_T200, NULL, i);
        test_and_set_bit(FLG_T200_RUN, &st->l2.flag);
 }
 
-inline void
+static inline void
 stop_t200(struct PStack *st, int i)
 {
        if(test_and_clear_bit(FLG_T200_RUN, &st->l2.flag))
                FsmDelTimer(&st->l2.t200, i);
 }
 
-inline void
+static inline void
 st5_dl_release_l2l3(struct PStack *st)
 {
                int pr;
@@ -501,7 +485,7 @@ st5_dl_release_l2l3(struct PStack *st)
                st->l2.l2l3(st, pr, NULL);
 }
 
-inline void
+static inline void
 lapb_dl_release_l2l3(struct PStack *st, int f)
 {
                if (test_bit(FLG_LAPB, &st->l2.flag))
@@ -802,7 +786,7 @@ l2_connected(struct FsmInst *fi, int event, void *arg)
                l2_mdl_error_ua(fi, event, arg);
                return;
        }
-       FreeSkb(skb);
+       dev_kfree_skb(skb);
 
        if (test_and_clear_bit(FLG_PEND_REL, &st->l2.flag))
                l2_disconnect(fi, event, arg);
@@ -840,7 +824,7 @@ l2_released(struct FsmInst *fi, int event, void *arg)
                l2_mdl_error_ua(fi, event, arg);
                return;
        }
-       FreeSkb(skb);
+       dev_kfree_skb(skb);
 
        stop_t200(st, 6);
        lapb_dl_release_l2l3(st, CONFIRM);
@@ -889,7 +873,7 @@ l2_st6_dm_release(struct FsmInst *fi, int event, void *arg)
        }
 }
 
-inline void
+static inline void
 enquiry_cr(struct PStack *st, u_char typ, u_char cr, u_char pf)
 {
        struct sk_buff *skb;
@@ -912,7 +896,7 @@ enquiry_cr(struct PStack *st, u_char typ, u_char cr, u_char pf)
        enqueue_super(st, skb);
 }
 
-inline void
+static inline void
 enquiry_response(struct PStack *st)
 {
        if (test_bit(FLG_OWN_BUSY, &st->l2.flag))
@@ -922,7 +906,7 @@ enquiry_response(struct PStack *st)
        test_and_clear_bit(FLG_ACK_PEND, &st->l2.flag);
 }
 
-inline void
+static inline void
 transmit_enquiry(struct PStack *st)
 {
        if (test_bit(FLG_OWN_BUSY, &st->l2.flag))
@@ -1004,7 +988,7 @@ l2_st7_got_super(struct FsmInst *fi, int event, void *arg)
                PollFlag = (skb->data[0] & 0x10);
                nr = (skb->data[0] >> 5) & 0x7;
        }
-       FreeSkb(skb);
+       dev_kfree_skb(skb);
 
        if (PollFlag) {
                if (rsp)
@@ -1047,7 +1031,7 @@ l2_feed_i_if_reest(struct FsmInst *fi, int event, void *arg)
        if (!test_bit(FLG_L3_INIT, &st->l2.flag))
                skb_queue_tail(&st->l2.i_queue, skb);
        else
-               FreeSkb(skb);
+               dev_kfree_skb(skb);
 }
 
 static void
@@ -1093,7 +1077,7 @@ l2_got_iframe(struct FsmInst *fi, int event, void *arg)
                nr = (skb->data[i] >> 5) & 0x7;
        }
        if (test_bit(FLG_OWN_BUSY, &l2->flag)) {
-               FreeSkb(skb);
+               dev_kfree_skb(skb);
                if(PollFlag) enquiry_response(st);
        } else if (l2->vr == ns) {
                (l2->vr)++;
@@ -1111,7 +1095,7 @@ l2_got_iframe(struct FsmInst *fi, int event, void *arg)
                st->l2.l2l3(st, DL_DATA | INDICATION, skb);
        } else {
                /* n(s)!=v(r) */
-               FreeSkb(skb);
+               dev_kfree_skb(skb);
                if (test_and_set_bit(FLG_REJEXC, &l2->flag)) {
                        if (PollFlag)
                                enquiry_response(st);
@@ -1309,7 +1293,7 @@ l2_pull_iqueue(struct FsmInst *fi, int event, void *arg)
                skb = alloc_skb(oskb->len + i, GFP_ATOMIC);
                memcpy(skb_put(skb, i), header, i);
                memcpy(skb_put(skb, oskb->len), oskb->data, oskb->len);
-               FreeSkb(oskb);
+               dev_kfree_skb(oskb);
        }
        st->l2.l2l1(st, PH_PULL | INDICATION, skb);
        test_and_clear_bit(FLG_ACK_PEND, &st->l2.flag);
@@ -1349,7 +1333,7 @@ l2_st8_got_super(struct FsmInst *fi, int event, void *arg)
                PollFlag = (skb->data[0] & 0x10);
                nr = (skb->data[0] >> 5) & 0x7;
        }
-       FreeSkb(skb);
+       dev_kfree_skb(skb);
 
        if (rsp && PollFlag) {
                if (legalnr(st, nr)) {
@@ -1391,7 +1375,7 @@ l2_got_FRMR(struct FsmInst *fi, int event, void *arg)
                establishlink(fi);
                test_and_clear_bit(FLG_L3_INIT, &st->l2.flag);
        }
-       FreeSkb(skb);
+       dev_kfree_skb(skb);
 }
 
 static void
@@ -1655,7 +1639,7 @@ isdnl2_l1l2(struct PStack *st, int pr, void *arg)
                                datap += len;
                        else {
                                FsmEvent(&st->l2.l2m, EV_L2_FRAME_ERROR, (void *) 'N');
-                               FreeSkb(skb);
+                               dev_kfree_skb(skb);
                                return;
                        }
                        if (!(*datap & 1)) {    /* I-Frame */
@@ -1684,16 +1668,16 @@ isdnl2_l1l2(struct PStack *st, int pr, void *arg)
                                        ret = FsmEvent(&st->l2.l2m, EV_L2_FRMR, skb);
                        } else {
                                FsmEvent(&st->l2.l2m, EV_L2_FRAME_ERROR, (void *) 'L');
-                               FreeSkb(skb);
+                               dev_kfree_skb(skb);
                                ret = 0;
                        }
                        if(c) {
-                               FreeSkb(skb);
+                               dev_kfree_skb(skb);
                                FsmEvent(&st->l2.l2m, EV_L2_FRAME_ERROR, (void *)(long)c);
                                ret = 0;
                        }
                        if (ret)
-                               FreeSkb(skb);
+                               dev_kfree_skb(skb);
                        break;
                case (PH_PULL | CONFIRM):
                        FsmEvent(&st->l2.l2m, EV_L2_ACK_PULL, arg);
index f571b5d18e91f4136c34862bd01fd2608b914274..abcc9530eb347b007b74ea1f5a774c361e2c9902 100644 (file)
@@ -390,7 +390,7 @@ setstack_l3dc(struct PStack *st, struct Channel *chanp)
        }
 }
 
-void
+static void
 isdnl3_trans(struct PStack *st, int pr, void *arg) {
        st->l3.l3l2(st, pr, arg);
 }
index af5171da734572dcc934f391d3de6333f2d4e784..33747afc984db717dbb1601031f06dd1ffc69bae 100644 (file)
@@ -122,7 +122,7 @@ isurf_interrupt(int intno, void *dev_id, struct pt_regs *regs)
        return IRQ_HANDLED;
 }
 
-void
+static void
 release_io_isurf(struct IsdnCardState *cs)
 {
        release_region(cs->hw.isurf.reset, 1);
index b843b7509ae2d4d484158048f084b17aabdc3826..908a7e14442179dba17794a886949edc22ff044a 100644 (file)
@@ -25,7 +25,7 @@
 #include "isdnl1.h"
 
 extern const char *CardType[];
-const char *ix1_revision = "$Revision: 2.12.2.4 $";
+static const char *ix1_revision = "$Revision: 2.12.2.4 $";
 
 #define byteout(addr,val) outb(val,addr)
 #define bytein(addr) inb(addr)
@@ -162,7 +162,7 @@ ix1micro_interrupt(int intno, void *dev_id, struct pt_regs *regs)
        return IRQ_HANDLED;
 }
 
-void
+static void
 release_io_ix1micro(struct IsdnCardState *cs)
 {
        if (cs->hw.ix1.cfg_reg)
index f05d52757557133d9533474abfa10a449c1162d9..363ae3179bbde9a255148c56c5e90a5e6d0eaf81 100644 (file)
@@ -74,7 +74,7 @@ jade_write_indirect(struct IsdnCardState *cs, u_char reg, u_char value)
 
 
 
-void
+static void
 modejade(struct BCState *bcs, int mode, int bc)
 {
     struct IsdnCardState *cs = bcs->cs;
@@ -190,7 +190,7 @@ jade_l2l1(struct PStack *st, int pr, void *arg)
     }
 }
 
-void
+static void
 close_jadestate(struct BCState *bcs)
 {
     modejade(bcs, 0, bcs->channel);
@@ -243,7 +243,7 @@ open_jadestate(struct IsdnCardState *cs, struct BCState *bcs)
 }
 
 
-int
+static int
 setstack_jade(struct PStack *st, struct BCState *bcs)
 {
        bcs->channel = st->l1.bc;
index fa29444859941325f40311ea202c0edb4464e451..29055e1ee38169889731c5097f2fd464c217c9f6 100644 (file)
 #define        jade_TXAUDIOCH2CFG                              0x1A
 
 extern int JadeVersion(struct IsdnCardState *cs, char *s);
-extern void modejade(struct BCState *bcs, int mode, int bc);
 extern void clear_pending_jade_ints(struct IsdnCardState *cs);
 extern void initjade(struct IsdnCardState *cs);
 
index d6c1c8f8329d8672f260945b23033bcabb2997ea..c5c36eeff26111ee962b4e62b4548596b53a9304 100644 (file)
@@ -19,7 +19,7 @@
 #include <linux/ctype.h>
 
 extern char *HiSax_getrev(const char *revision);
-const char *l3_1tr6_revision = "$Revision: 2.15.2.3 $";
+static const char *l3_1tr6_revision = "$Revision: 2.15.2.3 $";
 
 #define MsgHead(ptr, cref, mty, dis) \
        *ptr++ = dis; \
index ec92308c1efc75138b22646be00ea4dc811f948c..a6d2abdb478aeab5c018c0e635d4bc5a5d7c70ee 100644 (file)
@@ -26,7 +26,7 @@
 #include <linux/config.h>
 
 extern char *HiSax_getrev(const char *revision);
-const char *dss1_revision = "$Revision: 2.32.2.3 $";
+static const char *dss1_revision = "$Revision: 2.32.2.3 $";
 
 #define EXT_BEARER_CAPS 1
 
index 3ab3a54daac1b90522d1df55bb4b4a7d5b9b4907..f7041d5ba64e3c08b1ea6ca733b4e22cecdfb66a 100644 (file)
@@ -24,7 +24,7 @@
 #include <linux/ctype.h>
 
 extern char *HiSax_getrev(const char *revision);
-const char *ni1_revision = "$Revision: 2.8.2.3 $";
+static const char *ni1_revision = "$Revision: 2.8.2.3 $";
 
 #define EXT_BEARER_CAPS 1
 
@@ -2665,7 +2665,7 @@ static void l3ni1_spid_send( struct l3_process *pc, u_char pr, void *arg )
        l3ni1_SendSpid( pc, pr, arg, 20 );
 }
 
-void l3ni1_spid_epid( struct l3_process *pc, u_char pr, void *arg )
+static void l3ni1_spid_epid( struct l3_process *pc, u_char pr, void *arg )
 {
        struct sk_buff *skb = arg;
 
index 3ac4484a4886bf1757c51993f843d536f7f898d4..fe11f226b28539b5a0c4c40920ce8ee8f4e98821 100644 (file)
@@ -18,7 +18,7 @@
 
 extern const char *CardType[];
 
-const char *mic_revision = "$Revision: 1.12.2.4 $";
+static const char *mic_revision = "$Revision: 1.12.2.4 $";
 
 #define byteout(addr,val) outb(val,addr)
 #define bytein(addr) inb(addr)
@@ -157,7 +157,7 @@ mic_interrupt(int intno, void *dev_id, struct pt_regs *regs)
        return IRQ_HANDLED;
 }
 
-void
+static void
 release_io_mic(struct IsdnCardState *cs)
 {
        int bytecnt = 8;
index fe61d26365d390ee2e7d6a08982a7272d562f3ca..94da03c30c51507c1af9c74d449e04930a4a3c52 100644 (file)
@@ -25,8 +25,6 @@
 #include <asm/io.h>
 #include "netjet.h"
 
-const char *NETjet_revision = "$Revision: 1.29.2.4 $";
-
 /* Interface functions */
 
 u_char
@@ -66,7 +64,7 @@ NETjet_WriteICfifo(struct IsdnCardState *cs, u_char *data, int size)
        outsb(cs->hw.njet.isac, data, size);
 }
 
-void fill_mem(struct BCState *bcs, u_int *pos, u_int cnt, int chan, u_char fill)
+static void fill_mem(struct BCState *bcs, u_int *pos, u_int cnt, int chan, u_char fill)
 {
        u_int mask=0x000000ff, val = 0, *p=pos;
        u_int i;
@@ -85,7 +83,7 @@ void fill_mem(struct BCState *bcs, u_int *pos, u_int cnt, int chan, u_char fill)
        }
 }
 
-void
+static void
 mode_tiger(struct BCState *bcs, int mode, int bc)
 {
        struct IsdnCardState *cs = bcs->cs;
@@ -852,7 +850,7 @@ tiger_l2l1(struct PStack *st, int pr, void *arg)
 }
 
 
-void
+static void
 close_tigerstate(struct BCState *bcs)
 {
        mode_tiger(bcs, 0, bcs->channel);
@@ -900,7 +898,7 @@ open_tigerstate(struct IsdnCardState *cs, struct BCState *bcs)
        return (0);
 }
 
-int
+static int
 setstack_tiger(struct PStack *st, struct BCState *bcs)
 {
        bcs->channel = st->l1.bc;
@@ -966,7 +964,7 @@ inittiger(struct IsdnCardState *cs)
        cs->bcs[1].BC_Close = close_tigerstate;
 }
 
-void
+static void
 releasetiger(struct IsdnCardState *cs)
 {
        if (cs->bcs[0].hw.tiger.send) {
index cf77d8360975dd07b999375ac0773ab050548ada..68a2159cbd1109ffd9d06d3de6ec83bcc4e53ea9 100644 (file)
@@ -24,7 +24,7 @@
 #include <linux/isapnp.h>
 
 extern const char *CardType[];
-const char *niccy_revision = "$Revision: 1.21.2.4 $";
+static const char *niccy_revision = "$Revision: 1.21.2.4 $";
 
 #define byteout(addr,val) outb(val,addr)
 #define bytein(addr) inb(addr)
@@ -178,7 +178,7 @@ niccy_interrupt(int intno, void *dev_id, struct pt_regs *regs)
        return IRQ_HANDLED;
 }
 
-void
+static void
 release_io_niccy(struct IsdnCardState *cs)
 {
        if (cs->subtyp == NICCY_PCI) {
index fd664697f821bf8d10cbe3948130e04dd3268345..a7d3cd3f36fdabf7b4fb2f6f25366ddb7aa28ba9 100644 (file)
@@ -15,7 +15,7 @@
 #include <linux/ppp_defs.h>
 #include "netjet.h"
 
-const char *NETjet_S_revision = "$Revision: 2.13.2.4 $";
+static const char *NETjet_S_revision = "$Revision: 2.13.2.4 $";
 
 static u_char dummyrr(struct IsdnCardState *cs, int chan, u_char off)
 {
index 3d6441e9633c670dc912d93efda3b4866165a527..1ae7cac98a877724957349f52e9c3d7066e5623b 100644 (file)
@@ -15,7 +15,7 @@
 #include <linux/ppp_defs.h>
 #include "netjet.h"
 
-const char *NETjet_U_revision = "$Revision: 2.14.2.3 $";
+static const char *NETjet_U_revision = "$Revision: 2.14.2.3 $";
 
 static u_char dummyrr(struct IsdnCardState *cs, int chan, u_char off)
 {
index 170fcd4a39845cbc9e4b8fbe9756d07986287fa9..abecabf8c271326d201dc2b3e1c78bcd369af6fd 100644 (file)
@@ -516,7 +516,7 @@ struct MessageType cause_1tr6[] =
        {CAUSE_UserInfoDiscarded, "User Info Discarded"}
 };
 
-int cause_1tr6_len = (sizeof(cause_1tr6) / sizeof(struct MessageType));
+static int cause_1tr6_len = (sizeof(cause_1tr6) / sizeof(struct MessageType));
 
 static int
 prcause_1tr6(char *dest, u_char * p)
@@ -935,7 +935,7 @@ display(char *dest, u_char * p)
        return (dp - dest);
 }
 
-int
+static int
 prfacility(char *dest, u_char * p)
 {
        char *dp = dest;
index f3c481384a4ea8d93d3536c6aca4cd768ac4b649..7b63085ea6e51107c939e8011d86f03607f4f8f9 100644 (file)
@@ -17,7 +17,7 @@
 #include "isdnl1.h"
 
 extern const char *CardType[];
-const char *s0box_revision = "$Revision: 2.6.2.4 $";
+static const char *s0box_revision = "$Revision: 2.6.2.4 $";
 
 static inline void
 writereg(unsigned int padr, signed int addr, u_char off, u_char val) {
@@ -183,7 +183,7 @@ s0box_interrupt(int intno, void *dev_id, struct pt_regs *regs)
        return IRQ_HANDLED;
 }
 
-void
+static void
 release_io_s0box(struct IsdnCardState *cs)
 {
        release_region(cs->hw.teles3.cfg_reg, 8);
index 9e6d3d686cce58937b9f2895686f6af8cc95e8ae..821776e1561acb63ad9b5ad1c062c97bce6298de 100644 (file)
@@ -171,7 +171,7 @@ SaphirWatchDog(struct IsdnCardState *cs)
        mod_timer(&cs->hw.saphir.timer, jiffies+1*HZ);
 }
 
-void
+static void
 release_io_saphir(struct IsdnCardState *cs)
 {
        byteout(cs->hw.saphir.cfg_reg + IRQ_REG, 0xff);
index 8390f16068534e4c2962fbaec73c8921eca85bd7..8c044a6a7fe3b1e6567a5926f99d71932dee4494 100644 (file)
@@ -51,9 +51,9 @@
 
 extern const char *CardType[];
 
-const char *Sedlbauer_revision = "$Revision: 1.34.2.6 $";
+static const char *Sedlbauer_revision = "$Revision: 1.34.2.6 $";
 
-const char *Sedlbauer_Types[] =
+static const char *Sedlbauer_Types[] =
        {"None", "speed card/win", "speed star", "speed fax+",
        "speed win II / ISDN PC/104", "speed star II", "speed pci",
        "speed fax+ pyramid", "speed fax+ pci", "HST Saphir III"};
@@ -394,7 +394,7 @@ sedlbauer_interrupt_isar(int intno, void *dev_id, struct pt_regs *regs)
        return IRQ_HANDLED;
 }
 
-void
+static void
 release_io_sedlbauer(struct IsdnCardState *cs)
 {
        int bytecnt = 8;
index 132840b750cea71c2170bc9bf0a9aef23572b3fb..cdf35dc564c41d90c910abb53a1fa5923b43005c 100644 (file)
@@ -19,7 +19,7 @@
 #include "isdnl1.h"
 
 extern const char *CardType[];
-const char *sportster_revision = "$Revision: 1.16.2.4 $";
+static const char *sportster_revision = "$Revision: 1.16.2.4 $";
 
 #define byteout(addr,val) outb(val,addr)
 #define bytein(addr) inb(addr)
@@ -132,7 +132,7 @@ sportster_interrupt(int intno, void *dev_id, struct pt_regs *regs)
        return IRQ_HANDLED;
 }
 
-void
+static void
 release_io_sportster(struct IsdnCardState *cs)
 {
        int i, adr;
@@ -144,7 +144,7 @@ release_io_sportster(struct IsdnCardState *cs)
        }
 }
 
-void
+static void
 reset_sportster(struct IsdnCardState *cs)
 {
        cs->hw.spt.res_irq |= SPORTSTER_RESET; /* Reset On */
index e8177b017b1d7184f998177efd4706db7d91b6b0..0fda5c89429b4a73180a7c1bfbcfaa79a779e8ee 100644 (file)
@@ -450,12 +450,8 @@ int st5481_setup_isocpipes(struct urb* urb[2], struct usb_device *dev,
                           usb_complete_t complete, void *context);
 void st5481_release_isocpipes(struct urb* urb[2]);
 
-int  st5481_isoc_flatten(struct urb *urb);
 void st5481_usb_pipe_reset(struct st5481_adapter *adapter,
                    u_char pipe, ctrl_complete_t complete, void *context);
-void st5481_usb_ctrl_msg(struct st5481_adapter *adapter,
-                 u8 request, u8 requesttype, u16 value, u16 index,
-                 ctrl_complete_t complete, void *context);
 void st5481_usb_device_ctrl_msg(struct st5481_adapter *adapter,
                         u8 request, u16 value,
                         ctrl_complete_t complete, void *context);
diff --git a/drivers/isdn/hisax/st5481_hdlc.c b/drivers/isdn/hisax/st5481_hdlc.c
deleted file mode 100644 (file)
index 680f42e..0000000
+++ /dev/null
@@ -1,580 +0,0 @@
-/*
- * Driver for ST5481 USB ISDN modem
- *
- * Author       Frode Isaksen
- * Copyright    2001 by Frode Isaksen      <fisaksen@bewan.com>
- *              2001 by Kai Germaschewski  <kai.germaschewski@gmx.de>
- * 
- * This software may be used and distributed according to the terms
- * of the GNU General Public License, incorporated herein by reference.
- *
- */
-
-#include <linux/crc-ccitt.h>
-#include "st5481_hdlc.h"
-
-
-enum {
-       HDLC_FAST_IDLE,HDLC_GET_FLAG_B0,HDLC_GETFLAG_B1A6,HDLC_GETFLAG_B7,
-       HDLC_GET_DATA,HDLC_FAST_FLAG
-};
-
-enum {
-       HDLC_SEND_DATA,HDLC_SEND_CRC1,HDLC_SEND_FAST_FLAG,
-       HDLC_SEND_FIRST_FLAG,HDLC_SEND_CRC2,HDLC_SEND_CLOSING_FLAG,
-       HDLC_SEND_IDLE1,HDLC_SEND_FAST_IDLE,HDLC_SENDFLAG_B0,
-       HDLC_SENDFLAG_B1A6,HDLC_SENDFLAG_B7,STOPPED
-};
-
-void 
-hdlc_rcv_init(struct hdlc_vars *hdlc, int do_adapt56)
-{
-       hdlc->bit_shift = 0;
-       hdlc->hdlc_bits1 = 0;
-       hdlc->data_bits = 0;
-       hdlc->ffbit_shift = 0;
-       hdlc->data_received = 0;
-       hdlc->state = HDLC_GET_DATA;
-       hdlc->do_adapt56 = do_adapt56;
-       hdlc->dchannel = 0;
-       hdlc->crc = 0;
-       hdlc->cbin = 0;
-       hdlc->shift_reg = 0;
-       hdlc->ffvalue = 0;
-       hdlc->dstpos = 0;
-}
-
-void 
-hdlc_out_init(struct hdlc_vars *hdlc, int is_d_channel, int do_adapt56)
-{
-       hdlc->bit_shift = 0;
-       hdlc->hdlc_bits1 = 0;
-       hdlc->data_bits = 0;
-       hdlc->ffbit_shift = 0;
-       hdlc->data_received = 0;
-       hdlc->do_closing = 0;
-       hdlc->ffvalue = 0;
-       if (is_d_channel) {
-               hdlc->dchannel = 1;
-               hdlc->state = HDLC_SEND_FIRST_FLAG;
-       } else {
-               hdlc->dchannel = 0;
-               hdlc->state = HDLC_SEND_FAST_FLAG;
-               hdlc->ffvalue = 0x7e;
-       } 
-       hdlc->cbin = 0x7e;
-       hdlc->bit_shift = 0;
-       if(do_adapt56){
-               hdlc->do_adapt56 = 1;           
-               hdlc->data_bits = 0;
-               hdlc->state = HDLC_SENDFLAG_B0;
-       } else {
-               hdlc->do_adapt56 = 0;           
-               hdlc->data_bits = 8;
-       }
-       hdlc->shift_reg = 0;
-}
-
-/*
-  hdlc_decode - decodes HDLC frames from a transparent bit stream.
-
-  The source buffer is scanned for valid HDLC frames looking for
-  flags (01111110) to indicate the start of a frame. If the start of
-  the frame is found, the bit stuffing is removed (0 after 5 1's).
-  When a new flag is found, the complete frame has been received
-  and the CRC is checked.
-  If a valid frame is found, the function returns the frame length 
-  excluding the CRC with the bit HDLC_END_OF_FRAME set.
-  If the beginning of a valid frame is found, the function returns
-  the length. 
-  If a framing error is found (too many 1s and not a flag) the function 
-  returns the length with the bit HDLC_FRAMING_ERROR set.
-  If a CRC error is found the function returns the length with the
-  bit HDLC_CRC_ERROR set.
-  If the frame length exceeds the destination buffer size, the function
-  returns the length with the bit HDLC_LENGTH_ERROR set.
-
-  src - source buffer
-  slen - source buffer length
-  count - number of bytes removed (decoded) from the source buffer
-  dst _ destination buffer
-  dsize - destination buffer size
-  returns - number of decoded bytes in the destination buffer and status
-  flag.
- */
-int hdlc_decode(struct hdlc_vars *hdlc, const unsigned char *src,
-               int slen, int *count, unsigned char *dst, int dsize)
-{
-       int status=0;
-
-       static const unsigned char fast_flag[]={
-               0x00,0x00,0x00,0x20,0x30,0x38,0x3c,0x3e,0x3f
-       };
-
-       static const unsigned char fast_flag_value[]={
-               0x00,0x7e,0xfc,0xf9,0xf3,0xe7,0xcf,0x9f,0x3f
-       };
-
-       static const unsigned char fast_abort[]={
-               0x00,0x00,0x80,0xc0,0xe0,0xf0,0xf8,0xfc,0xfe,0xff
-       };
-
-       *count = slen;
-
-       while(slen > 0){
-               if(hdlc->bit_shift==0){
-                       hdlc->cbin = *src++;
-                       slen--;
-                       hdlc->bit_shift = 8;
-                       if(hdlc->do_adapt56){
-                               hdlc->bit_shift --;
-                       }
-               }
-
-               switch(hdlc->state){
-               case STOPPED:
-                       return 0;
-               case HDLC_FAST_IDLE:
-                       if(hdlc->cbin == 0xff){
-                               hdlc->bit_shift = 0;
-                               break;
-                       }
-                       hdlc->state = HDLC_GET_FLAG_B0;
-                       hdlc->hdlc_bits1 = 0;
-                       hdlc->bit_shift = 8;
-                       break;
-               case HDLC_GET_FLAG_B0:
-                       if(!(hdlc->cbin & 0x80)) {
-                               hdlc->state = HDLC_GETFLAG_B1A6;
-                               hdlc->hdlc_bits1 = 0;
-                       } else {
-                               if(!hdlc->do_adapt56){
-                                       if(++hdlc->hdlc_bits1 >=8 ) if(hdlc->bit_shift==1)
-                                               hdlc->state = HDLC_FAST_IDLE;
-                               }
-                       }
-                       hdlc->cbin<<=1;
-                       hdlc->bit_shift --;
-                       break;
-               case HDLC_GETFLAG_B1A6:
-                       if(hdlc->cbin & 0x80){
-                               hdlc->hdlc_bits1++;
-                               if(hdlc->hdlc_bits1==6){
-                                       hdlc->state = HDLC_GETFLAG_B7;
-                               }
-                       } else {
-                               hdlc->hdlc_bits1 = 0;
-                       }
-                       hdlc->cbin<<=1;
-                       hdlc->bit_shift --;
-                       break;
-               case HDLC_GETFLAG_B7:
-                       if(hdlc->cbin & 0x80) {
-                               hdlc->state = HDLC_GET_FLAG_B0;
-                       } else {
-                               hdlc->state = HDLC_GET_DATA;
-                               hdlc->crc = 0xffff;
-                               hdlc->shift_reg = 0;
-                               hdlc->hdlc_bits1 = 0;
-                               hdlc->data_bits = 0;
-                               hdlc->data_received = 0;
-                       }
-                       hdlc->cbin<<=1;
-                       hdlc->bit_shift --;
-                       break;
-               case HDLC_GET_DATA:
-                       if(hdlc->cbin & 0x80){
-                               hdlc->hdlc_bits1++;
-                               switch(hdlc->hdlc_bits1){
-                               case 6:
-                                       break;
-                               case 7:
-                                       if(hdlc->data_received) {
-                                               // bad frame
-                                               status = -HDLC_FRAMING_ERROR;
-                                       }
-                                       if(!hdlc->do_adapt56){
-                                               if(hdlc->cbin==fast_abort[hdlc->bit_shift+1]){
-                                                       hdlc->state = HDLC_FAST_IDLE;
-                                                       hdlc->bit_shift=1;
-                                                       break;
-                                               }
-                                       } else {
-                                               hdlc->state = HDLC_GET_FLAG_B0;
-                                       }
-                                       break;
-                               default:
-                                       hdlc->shift_reg>>=1;
-                                       hdlc->shift_reg |= 0x80;
-                                       hdlc->data_bits++;
-                                       break;
-                               }
-                       } else {
-                               switch(hdlc->hdlc_bits1){
-                               case 5:
-                                       break;
-                               case 6:
-                                       if(hdlc->data_received){
-                                               if (hdlc->dstpos < 2) {
-                                                       status = -HDLC_FRAMING_ERROR;
-                                               } else if (hdlc->crc != 0xf0b8){
-                                                       // crc error
-                                                       status = -HDLC_CRC_ERROR;
-                                               } else {
-                                                       // remove CRC
-                                                       hdlc->dstpos -= 2;
-                                                       // good frame
-                                                       status = hdlc->dstpos;
-                                               }
-                                       }
-                                       hdlc->crc = 0xffff;
-                                       hdlc->shift_reg = 0;
-                                       hdlc->data_bits = 0;
-                                       if(!hdlc->do_adapt56){
-                                               if(hdlc->cbin==fast_flag[hdlc->bit_shift]){
-                                                       hdlc->ffvalue = fast_flag_value[hdlc->bit_shift];
-                                                       hdlc->state = HDLC_FAST_FLAG;
-                                                       hdlc->ffbit_shift = hdlc->bit_shift;
-                                                       hdlc->bit_shift = 1;
-                                               } else {
-                                                       hdlc->state = HDLC_GET_DATA;
-                                                       hdlc->data_received = 0;
-                                               }
-                                       } else {
-                                               hdlc->state = HDLC_GET_DATA;
-                                               hdlc->data_received = 0;
-                                       }
-                                       break;
-                               default:
-                                       hdlc->shift_reg>>=1;
-                                       hdlc->data_bits++;
-                                       break;
-                               }
-                               hdlc->hdlc_bits1 = 0;
-                       }
-                       if (status) {
-                               hdlc->dstpos = 0;
-                               *count -= slen;
-                               hdlc->cbin <<= 1;
-                               hdlc->bit_shift--;
-                               return status;
-                       }
-                       if(hdlc->data_bits==8){
-                               hdlc->data_bits = 0;
-                               hdlc->data_received = 1;
-                               hdlc->crc = crc_ccitt_byte(hdlc->crc, hdlc->shift_reg);
-
-                               // good byte received
-                               if (dsize--) {
-                                       dst[hdlc->dstpos++] = hdlc->shift_reg;
-                               } else {
-                                       // frame too long
-                                       status = -HDLC_LENGTH_ERROR;
-                                       hdlc->dstpos = 0;
-                               }
-                       }
-                       hdlc->cbin <<= 1;
-                       hdlc->bit_shift--;
-                       break;
-               case HDLC_FAST_FLAG:
-                       if(hdlc->cbin==hdlc->ffvalue){
-                               hdlc->bit_shift = 0;
-                               break;
-                       } else {
-                               if(hdlc->cbin == 0xff){
-                                       hdlc->state = HDLC_FAST_IDLE;
-                                       hdlc->bit_shift=0;
-                               } else if(hdlc->ffbit_shift==8){
-                                       hdlc->state = HDLC_GETFLAG_B7;
-                                       break;
-                               } else {
-                                       hdlc->shift_reg = fast_abort[hdlc->ffbit_shift-1];
-                                       hdlc->hdlc_bits1 = hdlc->ffbit_shift-2;
-                                       if(hdlc->hdlc_bits1<0)hdlc->hdlc_bits1 = 0;
-                                       hdlc->data_bits = hdlc->ffbit_shift-1;
-                                       hdlc->state = HDLC_GET_DATA;
-                                       hdlc->data_received = 0;
-                               }
-                       }
-                       break;
-               default:
-                       break;
-               }
-       }
-       *count -= slen;
-       return 0;
-}
-
-/*
-  hdlc_encode - encodes HDLC frames to a transparent bit stream.
-
-  The bit stream starts with a beginning flag (01111110). After
-  that each byte is added to the bit stream with bit stuffing added
-  (0 after 5 1's).
-  When the last byte has been removed from the source buffer, the
-  CRC (2 bytes is added) and the frame terminates with the ending flag.
-  For the dchannel, the idle character (all 1's) is also added at the end.
-  If this function is called with empty source buffer (slen=0), flags or
-  idle character will be generated.
-  src - source buffer
-  slen - source buffer length
-  count - number of bytes removed (encoded) from source buffer
-  dst _ destination buffer
-  dsize - destination buffer size
-  returns - number of encoded bytes in the destination buffer
-*/
-int hdlc_encode(struct hdlc_vars *hdlc, const unsigned char *src, 
-               unsigned short slen, int *count,
-               unsigned char *dst, int dsize)
-{
-       static const unsigned char xfast_flag_value[] = {
-               0x7e,0x3f,0x9f,0xcf,0xe7,0xf3,0xf9,0xfc,0x7e
-       };
-
-       int len = 0;
-
-       *count = slen;
-
-       while (dsize > 0) {
-               if(hdlc->bit_shift==0){ 
-                       if(slen && !hdlc->do_closing){
-                               hdlc->shift_reg = *src++;
-                               slen--;
-                               if (slen == 0) 
-                                       hdlc->do_closing = 1;  /* closing sequence, CRC + flag(s) */
-                               hdlc->bit_shift = 8;
-                       } else {
-                               if(hdlc->state == HDLC_SEND_DATA){
-                                       if(hdlc->data_received){
-                                               hdlc->state = HDLC_SEND_CRC1;
-                                               hdlc->crc ^= 0xffff;
-                                               hdlc->bit_shift = 8;
-                                               hdlc->shift_reg = hdlc->crc & 0xff;
-                                       } else if(!hdlc->do_adapt56){
-                                               hdlc->state = HDLC_SEND_FAST_FLAG;
-                                       } else {
-                                               hdlc->state = HDLC_SENDFLAG_B0;
-                                       }
-                               }
-                         
-                       }
-               }
-
-               switch(hdlc->state){
-               case STOPPED:
-                       while (dsize--)
-                               *dst++ = 0xff;
-                 
-                       return dsize;
-               case HDLC_SEND_FAST_FLAG:
-                       hdlc->do_closing = 0;
-                       if(slen == 0){
-                               *dst++ = hdlc->ffvalue;
-                               len++;
-                               dsize--;
-                               break;
-                       }
-                       if(hdlc->bit_shift==8){
-                               hdlc->cbin = hdlc->ffvalue>>(8-hdlc->data_bits);
-                               hdlc->state = HDLC_SEND_DATA;
-                               hdlc->crc = 0xffff;
-                               hdlc->hdlc_bits1 = 0;
-                               hdlc->data_received = 1;
-                       }
-                       break;
-               case HDLC_SENDFLAG_B0:
-                       hdlc->do_closing = 0;
-                       hdlc->cbin <<= 1;
-                       hdlc->data_bits++;
-                       hdlc->hdlc_bits1 = 0;
-                       hdlc->state = HDLC_SENDFLAG_B1A6;
-                       break;
-               case HDLC_SENDFLAG_B1A6:
-                       hdlc->cbin <<= 1;
-                       hdlc->data_bits++;
-                       hdlc->cbin++;
-                       if(++hdlc->hdlc_bits1 == 6)
-                               hdlc->state = HDLC_SENDFLAG_B7;
-                       break;
-               case HDLC_SENDFLAG_B7:
-                       hdlc->cbin <<= 1;
-                       hdlc->data_bits++;
-                       if(slen == 0){
-                               hdlc->state = HDLC_SENDFLAG_B0;
-                               break;
-                       }
-                       if(hdlc->bit_shift==8){
-                               hdlc->state = HDLC_SEND_DATA;
-                               hdlc->crc = 0xffff;
-                               hdlc->hdlc_bits1 = 0;
-                               hdlc->data_received = 1;
-                       }
-                       break;
-               case HDLC_SEND_FIRST_FLAG:
-                       hdlc->data_received = 1;
-                       if(hdlc->data_bits==8){
-                               hdlc->state = HDLC_SEND_DATA;
-                               hdlc->crc = 0xffff;
-                               hdlc->hdlc_bits1 = 0;
-                               break;
-                       }
-                       hdlc->cbin <<= 1;
-                       hdlc->data_bits++;
-                       if(hdlc->shift_reg & 0x01)
-                               hdlc->cbin++;
-                       hdlc->shift_reg >>= 1;
-                       hdlc->bit_shift--;
-                       if(hdlc->bit_shift==0){
-                               hdlc->state = HDLC_SEND_DATA;
-                               hdlc->crc = 0xffff;
-                               hdlc->hdlc_bits1 = 0;
-                       }
-                       break;
-               case HDLC_SEND_DATA:
-                       hdlc->cbin <<= 1;
-                       hdlc->data_bits++;
-                       if(hdlc->hdlc_bits1 == 5){
-                               hdlc->hdlc_bits1 = 0;
-                               break;
-                       }
-                       if(hdlc->bit_shift==8){
-                               hdlc->crc = crc_ccitt_byte(hdlc->crc, hdlc->shift_reg);
-                       }
-                       if(hdlc->shift_reg & 0x01){
-                               hdlc->hdlc_bits1++;
-                               hdlc->cbin++;
-                               hdlc->shift_reg >>= 1;
-                               hdlc->bit_shift--;
-                       } else {
-                               hdlc->hdlc_bits1 = 0;
-                               hdlc->shift_reg >>= 1;
-                               hdlc->bit_shift--;
-                       }
-                       break;
-               case HDLC_SEND_CRC1:
-                       hdlc->cbin <<= 1;
-                       hdlc->data_bits++;
-                       if(hdlc->hdlc_bits1 == 5){
-                               hdlc->hdlc_bits1 = 0;
-                               break;
-                       }
-                       if(hdlc->shift_reg & 0x01){
-                               hdlc->hdlc_bits1++;
-                               hdlc->cbin++;
-                               hdlc->shift_reg >>= 1;
-                               hdlc->bit_shift--;
-                       } else {
-                               hdlc->hdlc_bits1 = 0;
-                               hdlc->shift_reg >>= 1;
-                               hdlc->bit_shift--;
-                       }
-                       if(hdlc->bit_shift==0){
-                               hdlc->shift_reg = (hdlc->crc >> 8);
-                               hdlc->state = HDLC_SEND_CRC2;
-                               hdlc->bit_shift = 8;
-                       }
-                       break;
-               case HDLC_SEND_CRC2:
-                       hdlc->cbin <<= 1;
-                       hdlc->data_bits++;
-                       if(hdlc->hdlc_bits1 == 5){
-                               hdlc->hdlc_bits1 = 0;
-                               break;
-                       }
-                       if(hdlc->shift_reg & 0x01){
-                               hdlc->hdlc_bits1++;
-                               hdlc->cbin++;
-                               hdlc->shift_reg >>= 1;
-                               hdlc->bit_shift--;
-                       } else {
-                               hdlc->hdlc_bits1 = 0;
-                               hdlc->shift_reg >>= 1;
-                               hdlc->bit_shift--;
-                       }
-                       if(hdlc->bit_shift==0){
-                               hdlc->shift_reg = 0x7e;
-                               hdlc->state = HDLC_SEND_CLOSING_FLAG;
-                               hdlc->bit_shift = 8;
-                       }
-                       break;
-               case HDLC_SEND_CLOSING_FLAG:
-                       hdlc->cbin <<= 1;
-                       hdlc->data_bits++;
-                       if(hdlc->hdlc_bits1 == 5){
-                               hdlc->hdlc_bits1 = 0;
-                               break;
-                       }
-                       if(hdlc->shift_reg & 0x01){
-                               hdlc->cbin++;
-                       }
-                       hdlc->shift_reg >>= 1;
-                       hdlc->bit_shift--;
-                       if(hdlc->bit_shift==0){
-                               hdlc->ffvalue = xfast_flag_value[hdlc->data_bits];
-                               if(hdlc->dchannel){
-                                       hdlc->ffvalue = 0x7e;
-                                       hdlc->state = HDLC_SEND_IDLE1;
-                                       hdlc->bit_shift = 8-hdlc->data_bits;
-                                       if(hdlc->bit_shift==0)
-                                               hdlc->state = HDLC_SEND_FAST_IDLE;
-                               } else {
-                                       if(!hdlc->do_adapt56){
-                                               hdlc->state = HDLC_SEND_FAST_FLAG;
-                                               hdlc->data_received = 0;
-                                       } else {
-                                               hdlc->state = HDLC_SENDFLAG_B0;
-                                               hdlc->data_received = 0;
-                                       }
-                                       // Finished with this frame, send flags
-                                       if (dsize > 1) dsize = 1; 
-                               }
-                       }
-                       break;
-               case HDLC_SEND_IDLE1:
-                       hdlc->do_closing = 0;
-                       hdlc->cbin <<= 1;
-                       hdlc->cbin++;
-                       hdlc->data_bits++;
-                       hdlc->bit_shift--;
-                       if(hdlc->bit_shift==0){
-                               hdlc->state = HDLC_SEND_FAST_IDLE;
-                               hdlc->bit_shift = 0;
-                       }
-                       break;
-               case HDLC_SEND_FAST_IDLE:
-                       hdlc->do_closing = 0;
-                       hdlc->cbin = 0xff;
-                       hdlc->data_bits = 8;
-                       if(hdlc->bit_shift == 8){
-                               hdlc->cbin = 0x7e;
-                               hdlc->state = HDLC_SEND_FIRST_FLAG;
-                       } else {
-                               *dst++ = hdlc->cbin;
-                               hdlc->bit_shift = hdlc->data_bits = 0;
-                               len++;
-                               dsize = 0;
-                       }
-                       break;
-               default:
-                       break;
-               }
-               if(hdlc->do_adapt56){
-                       if(hdlc->data_bits==7){
-                               hdlc->cbin <<= 1;
-                               hdlc->cbin++;
-                               hdlc->data_bits++;
-                       }
-               }
-               if(hdlc->data_bits==8){
-                       *dst++ = hdlc->cbin;
-                       hdlc->data_bits = 0;
-                       len++;
-                       dsize--;
-               }
-       }
-       *count -= slen;
-
-       return len;
-}
-
diff --git a/drivers/isdn/hisax/st5481_hdlc.h b/drivers/isdn/hisax/st5481_hdlc.h
deleted file mode 100644 (file)
index 495432f..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Driver for ST5481 USB ISDN modem
- *
- * Author       Frode Isaksen
- * Copyright    2001 by Frode Isaksen      <fisaksen@bewan.com>
- *              2001 by Kai Germaschewski  <kai.germaschewski@gmx.de>
- * 
- * This software may be used and distributed according to the terms
- * of the GNU General Public License, incorporated herein by reference.
- *
- */
-
-#ifndef __ST5481_HDLC_H__
-#define __ST5481_HDLC_H__
-
-struct hdlc_vars {
-       int bit_shift; 
-       int hdlc_bits1;
-       int data_bits;
-       int ffbit_shift; // encoding only
-       int state;
-       int dstpos;
-
-       int data_received:1; // set if transferring data
-       int dchannel:1; // set if D channel (send idle instead of flags)
-       int do_adapt56:1; // set if 56K adaptation
-        int do_closing:1; // set if in closing phase (need to send CRC + flag
-
-       unsigned short crc;
-
-       unsigned char cbin; 
-       unsigned char shift_reg;
-       unsigned char ffvalue;
-       
-};
-
-
-/*
-  The return value from hdlc_decode is
-  the frame length, 0 if no complete frame was decoded,
-  or a negative error number
-*/
-
-#define HDLC_FRAMING_ERROR     1
-#define HDLC_CRC_ERROR         2
-#define HDLC_LENGTH_ERROR      3
-
-void 
-hdlc_rcv_init(struct hdlc_vars *hdlc, int do_adapt56);
-
-int
-hdlc_decode(struct hdlc_vars *hdlc, const unsigned char *src, int slen,int *count, 
-           unsigned char *dst, int dsize);
-
-void 
-hdlc_out_init(struct hdlc_vars *hdlc,int is_d_channel,int do_adapt56);
-
-int 
-hdlc_encode(struct hdlc_vars *hdlc,const unsigned char *src,unsigned short slen,int *count,
-           unsigned char *dst,int dsize);
-
-#endif
index 2369180b1cb1f685a1d732f5ae38ae2d96993b37..ab62223297a56d8cdd2a097341ccd49ade474f42 100644 (file)
@@ -15,6 +15,8 @@
 #include <linux/slab.h>
 #include "st5481.h"
 
+static int st5481_isoc_flatten(struct urb *urb);
+
 /* ======================================================================
  * control pipe
  */
@@ -55,9 +57,9 @@ static void usb_next_ctrl_msg(struct urb *urb,
  * Asynchronous endpoint 0 request (async version of usb_control_msg).
  * The request will be queued up in a FIFO if the endpoint is busy.
  */
-void usb_ctrl_msg(struct st5481_adapter *adapter,
-                 u8 request, u8 requesttype, u16 value, u16 index,
-                 ctrl_complete_t complete, void *context)
+static void usb_ctrl_msg(struct st5481_adapter *adapter,
+                        u8 request, u8 requesttype, u16 value, u16 index,
+                        ctrl_complete_t complete, void *context)
 {
        struct st5481_ctrl *ctrl = &adapter->ctrl;
        int w_index;
@@ -571,7 +573,7 @@ void st5481_release_in(struct st5481_in *in)
  * Make the transfer_buffer contiguous by
  * copying from the iso descriptors if necessary. 
  */
-int st5481_isoc_flatten(struct urb *urb)
+static int st5481_isoc_flatten(struct urb *urb)
 {
        struct usb_iso_packet_descriptor *pipd,*pend;
        unsigned char *src,*dst;
index 082726db39855c7231bf6ec3b7e3dfbbe76b324c..ceb0df92fd3e4e98aa856ac23824f336b715588a 100644 (file)
@@ -74,7 +74,7 @@ static char *strTeiEvent[] =
        "EV_T202",
 };
 
-unsigned int
+static unsigned int
 random_ri(void)
 {
        unsigned int x;
index ef8984c5f1f7aa142553d36480ce6ac0a1e4b77f..a2b1816af37a8b67b4dfb1832a36e4a0a802fc42 100644 (file)
@@ -18,7 +18,7 @@
 
 extern const char *CardType[];
 
-const char *TeleInt_revision = "$Revision: 1.16.2.5 $";
+static const char *TeleInt_revision = "$Revision: 1.16.2.5 $";
 
 #define byteout(addr,val) outb(val,addr)
 #define bytein(addr) inb(addr)
@@ -203,7 +203,7 @@ TeleInt_Timer(struct IsdnCardState *cs)
        add_timer(&cs->hw.hfc.timer);
 }
 
-void
+static void
 release_io_TeleInt(struct IsdnCardState *cs)
 {
        del_timer(&cs->hw.hfc.timer);
index 5ec5ec3e1eabda2189473130f91adca70d3779af..2b7df8f9823327acd590b3fd138ab45daeb507ff 100644 (file)
@@ -23,7 +23,7 @@
 
 extern const char *CardType[];
 
-const char *teles0_revision = "$Revision: 2.15.2.4 $";
+static const char *teles0_revision = "$Revision: 2.15.2.4 $";
 
 #define TELES_IOMEM_SIZE       0x400
 #define byteout(addr,val) outb(val,addr)
@@ -183,7 +183,7 @@ teles0_interrupt(int intno, void *dev_id, struct pt_regs *regs)
        return IRQ_HANDLED;
 }
 
-void
+static void
 release_io_teles0(struct IsdnCardState *cs)
 {
        if (cs->hw.teles0.cfg_reg)
index c5b1f65f7275a87d1cac654a472f232a4b1f6b72..adeaad62d35c3d01353a5706a17b3ecb458daf45 100644 (file)
@@ -21,7 +21,7 @@
 #include "isdnl1.h"
 
 extern const char *CardType[];
-const char *teles3_revision = "$Revision: 2.19.2.4 $";
+static const char *teles3_revision = "$Revision: 2.19.2.4 $";
 
 #define byteout(addr,val) outb(val,addr)
 #define bytein(addr) inb(addr)
@@ -154,7 +154,7 @@ release_ioregs(struct IsdnCardState *cs, int mask)
                release_region(cs->hw.teles3.hscx[1] + 32, 32);
 }
 
-void
+static void
 release_io_teles3(struct IsdnCardState *cs)
 {
        if (cs->typ == ISDN_CTYPE_TELESPCMCIA) {
index 0661c6c31ad0629b3ae07792f05136718ca31f68..e2bb4fd8e25e7602e9c69fd0151edb739a119daa 100644 (file)
@@ -21,7 +21,7 @@
 #include <linux/pci.h>
 
 extern const char *CardType[];
-const char *telespci_revision = "$Revision: 2.23.2.3 $";
+static const char *telespci_revision = "$Revision: 2.23.2.3 $";
 
 #define ZORAN_PO_RQ_PEN        0x02000000
 #define ZORAN_PO_WR    0x00800000
@@ -257,7 +257,7 @@ telespci_interrupt(int intno, void *dev_id, struct pt_regs *regs)
        return IRQ_HANDLED;
 }
 
-void
+static void
 release_io_telespci(struct IsdnCardState *cs)
 {
        iounmap(cs->hw.teles0.membase);
index d2b6b8e72980dcd2172d56313685228748c712b1..7baf8e4884716080266b3eb3df37a7d41152da41 100644 (file)
@@ -41,7 +41,7 @@ static const PCI_ENTRY id_list[] =
 
 extern const char *CardType[];
 
-const char *w6692_revision = "$Revision: 1.18.2.4 $";
+static const char *w6692_revision = "$Revision: 1.18.2.4 $";
 
 #define DBUSY_TIMER_VALUE 80
 
@@ -880,7 +880,7 @@ setstack_w6692(struct PStack *st, struct BCState *bcs)
        return (0);
 }
 
-void resetW6692(struct IsdnCardState *cs)
+static void resetW6692(struct IsdnCardState *cs)
 {
        cs->writeW6692(cs, W_D_CTL, W_D_CTL_SRST);
        mdelay(10);
@@ -902,7 +902,7 @@ void resetW6692(struct IsdnCardState *cs)
        }
 }
 
-void __init initW6692(struct IsdnCardState *cs, int part)
+static void __init initW6692(struct IsdnCardState *cs, int part)
 {
        if (part & 1) {
                cs->setstack_d = setstack_W6692;
index 5350836a4f987ee3fc428800090008032c5bcad9..2cc56d6a9fae76758e5a2e5f71a84bd4a25dffcf 100644 (file)
@@ -391,16 +391,6 @@ isdn_audio_adpcm2xlaw(adpcm_state * s, int fmt, unsigned char *in,
        return olen;
 }
 
-int
-isdn_audio_2adpcm_flush(adpcm_state * s, unsigned char *out)
-{
-       int olen = 0;
-
-       if (s->nleft)
-               isdn_audio_put_bits(0, 8 - s->nleft, s, &out, &olen);
-       return olen;
-}
-
 int
 isdn_audio_xlaw2adpcm(adpcm_state * s, int fmt, unsigned char *in,
                      unsigned char *out, int len)
index 5a977b21dcfa906a2fc8a1825499b9e1e128b3b9..013c3582e0d19f3f813fb8712d3f47d1ef345374 100644 (file)
@@ -35,7 +35,6 @@ extern void isdn_audio_alaw2ulaw(unsigned char *, unsigned long);
 extern adpcm_state *isdn_audio_adpcm_init(adpcm_state *, int);
 extern int isdn_audio_adpcm2xlaw(adpcm_state *, int, unsigned char *, unsigned char *, int);
 extern int isdn_audio_xlaw2adpcm(adpcm_state *, int, unsigned char *, unsigned char *, int);
-extern int isdn_audio_2adpcm_flush(adpcm_state * s, unsigned char *out);
 extern void isdn_audio_calc_dtmf(modem_info *, unsigned char *, int, int);
 extern void isdn_audio_eval_dtmf(modem_info *);
 dtmf_state *isdn_audio_dtmf_init(dtmf_state *);
index c406df6f268a5f630c051bea40c5a45351203de0..eebcb0b97f0e9b6f05d0df1bfa12633285dd9f37 100644 (file)
@@ -67,7 +67,7 @@ static isdn_divert_if *divert_if; /* = NULL */
 static int isdn_writebuf_stub(int, int, const u_char __user *, int);
 static void set_global_features(void);
 static int isdn_wildmat(char *s, char *p);
-
+static int isdn_add_channels(isdn_driver_t *d, int drvidx, int n, int adding);
 
 static inline void
 isdn_lock_driver(isdn_driver_t *drv)
@@ -388,7 +388,7 @@ isdn_all_eaz(int di, int ch)
  */
 #include <linux/isdn/capicmd.h>
 
-int
+static int
 isdn_capi_rec_hl_msg(capi_msg *cm) {
        
        int di;
@@ -1923,7 +1923,7 @@ isdn_writebuf_skb_stub(int drvidx, int chan, int ack, struct sk_buff *skb)
        return ret;
 }
 
-int
+static int
 isdn_add_channels(isdn_driver_t *d, int drvidx, int n, int adding)
 {
        int j, k, m;
index 808135c427ad74737156f516dced2cbce010d84f..e27e9c3a81ed6622641bf853d9e99411c6759183 100644 (file)
@@ -41,7 +41,6 @@ extern int  isdn_get_free_channel(int, int, int, int, int, char *);
 extern int  isdn_writebuf_skb_stub(int, int, int, struct sk_buff *);
 extern int  register_isdn(isdn_if * i);
 extern int  isdn_msncmp( const char *,  const char *);
-extern int  isdn_add_channels(isdn_driver_t *, int, int, int);
 #if defined(ISDN_DEBUG_NET_DUMP) || defined(ISDN_DEBUG_MODEM_DUMP)
 extern void isdn_dumppkt(char *, u_char *, int, int);
 #endif
index 83a4f5382bc2c5b932b65cd9d434417c1e1113b4..0193b6f7c70ca705142fe0d7731dd242b4eacbb6 100644 (file)
@@ -39,7 +39,7 @@
    */
 
 
-int isdn_concap_dl_data_req(struct concap_proto *concap, struct sk_buff *skb)
+static int isdn_concap_dl_data_req(struct concap_proto *concap, struct sk_buff *skb)
 {
        struct net_device *ndev = concap -> net_dev;
        isdn_net_dev *nd = ((isdn_net_local *) ndev->priv)->netdev;
@@ -58,7 +58,7 @@ int isdn_concap_dl_data_req(struct concap_proto *concap, struct sk_buff *skb)
 }
 
 
-int isdn_concap_dl_connect_req(struct concap_proto *concap)
+static int isdn_concap_dl_connect_req(struct concap_proto *concap)
 {
        struct net_device *ndev = concap -> net_dev;
        isdn_net_local *lp = (isdn_net_local *) ndev->priv;
@@ -71,7 +71,7 @@ int isdn_concap_dl_connect_req(struct concap_proto *concap)
        return ret;
 }
 
-int isdn_concap_dl_disconn_req(struct concap_proto *concap)
+static int isdn_concap_dl_disconn_req(struct concap_proto *concap)
 {
        IX25DEBUG( "isdn_concap_dl_disconn_req: %s \n", concap -> net_dev -> name);
 
@@ -85,15 +85,6 @@ struct concap_device_ops isdn_concap_reliable_dl_dops = {
        &isdn_concap_dl_disconn_req
 };
 
-struct concap_device_ops isdn_concap_demand_dial_dops = {
-       NULL, /* set this first entry to something like &isdn_net_start_xmit,
-                but the entry part of the current isdn_net_start_xmit must be
-                separated first. */
-       /* no connection control for demand dial semantics */
-       NULL,
-       NULL,
-};
-
 /* The following should better go into a dedicated source file such that
    this sourcefile does not need to include any protocol specific header
    files. For now:
index 306eb180438ff2af2663b9d1ee01786fe90ddca8..6ac7e0445ea5e594383a4db71a80ed06e1c3551a 100644 (file)
@@ -8,7 +8,6 @@
  */
 
 extern struct concap_device_ops isdn_concap_reliable_dl_dops;
-extern struct concap_device_ops isdn_concap_demand_dial_dops;
 extern struct concap_proto * isdn_concap_new( int );
 
 
index e2b790e34510840b3587b0357d7e1f6cb97bcc89..f30e8e63ae0dedf9802a044d5d3c6eedd3679721 100644 (file)
@@ -176,7 +176,7 @@ static __inline__ void isdn_net_zero_frame_cnt(isdn_net_local *lp)
 
 /* Prototypes */
 
-int isdn_net_force_dial_lp(isdn_net_local *);
+static int isdn_net_force_dial_lp(isdn_net_local *);
 static int isdn_net_start_xmit(struct sk_buff *, struct net_device *);
 
 static void isdn_net_ciscohdlck_connected(isdn_net_local *lp);
@@ -312,7 +312,7 @@ isdn_net_unbind_channel(isdn_net_local * lp)
  * Since this function is called every second, simply reset the
  * byte-counter of the interface after copying it to the cps-variable.
  */
-unsigned long last_jiffies = -HZ;
+static unsigned long last_jiffies = -HZ;
 
 void
 isdn_net_autohup(void)
@@ -1131,7 +1131,7 @@ isdn_net_adjust_hdr(struct sk_buff *skb, struct net_device *dev)
 }
 
 
-void isdn_net_tx_timeout(struct net_device * ndev)
+static void isdn_net_tx_timeout(struct net_device * ndev)
 {
        isdn_net_local *lp = (isdn_net_local *) ndev->priv;
 
@@ -1424,7 +1424,7 @@ isdn_net_ciscohdlck_alloc_skb(isdn_net_local *lp, int len)
 }
 
 /* cisco hdlck device private ioctls */
-int
+static int
 isdn_ciscohdlck_dev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
 {
        isdn_net_local *lp = (isdn_net_local *) dev->priv;
@@ -2461,7 +2461,7 @@ isdn_net_findif(char *name)
  * This is called from the userlevel-routine below or
  * from isdn_net_start_xmit().
  */
-int
+static int
 isdn_net_force_dial_lp(isdn_net_local * lp)
 {
        if ((!(lp->flags & ISDN_NET_CONNECTED)) && !lp->dialstate) {
index e21007eca0f08ff10b996eebd51f7cfce3897d6a..ad5aa38fb5a6eb6001b4b97d1f8154037f3836e3 100644 (file)
@@ -273,7 +273,7 @@ isdn_tty_rcv_skb(int i, int di, int channel, struct sk_buff *skb)
        return 1;
 }
 
-void
+static void
 isdn_tty_cleanup_xmit(modem_info * info)
 {
        skb_queue_purge(&info->xmit_queue);
@@ -560,7 +560,7 @@ isdn_tty_modem_ncarrier(modem_info * info)
 /*
  * return the usage calculated by si and layer 2 protocol
  */
-int
+static int
 isdn_calc_usage(int si, int l2)
 {
        int usg = ISDN_USAGE_MODEM;
index 2423a7ff0cc32ce9541248aff4e93eb2296ff433..9f0fa9501f4d40287fbf980c55a8ec0be9b5926f 100644 (file)
@@ -109,7 +109,6 @@ extern int  isdn_tty_modem_init(void);
 extern void isdn_tty_exit(void);
 extern void isdn_tty_readmodem(void);
 extern int  isdn_tty_find_icall(int, int, setup_parm *);
-extern void isdn_tty_cleanup_xmit(modem_info *);
 extern int  isdn_tty_stat_callback(int, isdn_ctrl *);
 extern int  isdn_tty_rcv_skb(int, int, int, struct sk_buff *);
 extern int  isdn_tty_capi_facility(capi_msg *cm); 
index ce2c3ef92e4661d9050985d442df4cf2017e1cd6..a943d078bacc2991bdd52e8680b4648c3aafb866 100644 (file)
@@ -148,7 +148,7 @@ isdn_tty_fax_modem_result(int code, modem_info * info)
        }
 }
 
-int
+static int
 isdn_tty_fax_command1(modem_info * info, isdn_ctrl * c)
 {
        static char *msg[] =
@@ -316,7 +316,7 @@ isdn_tty_fax_bitorder(modem_info * info, struct sk_buff *skb)
  * Parse AT+F.. FAX class 1 commands
  */
 
-int
+static int
 isdn_tty_cmd_FCLASS1(char **p, modem_info * info)
 {
        static char *cmd[] =
@@ -408,7 +408,7 @@ isdn_tty_cmd_FCLASS1(char **p, modem_info * info)
  * Parse AT+F.. FAX class 2 commands
  */
 
-int
+static int
 isdn_tty_cmd_FCLASS2(char **p, modem_info * info)
 {
        atemu *m = &info->emu;
index 4ab7600cf9c1bb34194580dd05073a4bf9d09424..edf14a2aa3c80a89571770c7ad174572f265b317 100644 (file)
@@ -40,15 +40,15 @@ typedef struct isdn_x25iface_proto_data {
 
 
 /* is now in header file (extern): struct concap_proto * isdn_x25iface_proto_new(void); */
-void isdn_x25iface_proto_del( struct concap_proto * );
-int isdn_x25iface_proto_close( struct concap_proto * );
-int isdn_x25iface_proto_restart( struct concap_proto *,
-                                struct net_device *,
-                                struct concap_device_ops *);
-int isdn_x25iface_xmit( struct concap_proto *, struct sk_buff * );
-int isdn_x25iface_receive( struct concap_proto *, struct sk_buff * );
-int isdn_x25iface_connect_ind( struct concap_proto * );
-int isdn_x25iface_disconn_ind( struct concap_proto * );
+static void isdn_x25iface_proto_del( struct concap_proto * );
+static int isdn_x25iface_proto_close( struct concap_proto * );
+static int isdn_x25iface_proto_restart( struct concap_proto *,
+                                       struct net_device *,
+                                       struct concap_device_ops *);
+static int isdn_x25iface_xmit( struct concap_proto *, struct sk_buff * );
+static int isdn_x25iface_receive( struct concap_proto *, struct sk_buff * );
+static int isdn_x25iface_connect_ind( struct concap_proto * );
+static int isdn_x25iface_disconn_ind( struct concap_proto * );
 
 
 static struct concap_proto_ops ix25_pops = {
@@ -102,7 +102,7 @@ struct concap_proto * isdn_x25iface_proto_new(void)
 
 /* close the x25iface encapsulation protocol 
  */
-int isdn_x25iface_proto_close(struct concap_proto *cprot){
+static int isdn_x25iface_proto_close(struct concap_proto *cprot){
 
        ix25_pdata_t *tmp;
         int ret = 0;
@@ -129,7 +129,7 @@ int isdn_x25iface_proto_close(struct concap_proto *cprot){
 
 /* Delete the x25iface encapsulation protocol instance
  */
-void isdn_x25iface_proto_del(struct concap_proto *cprot){
+static void isdn_x25iface_proto_del(struct concap_proto *cprot){
 
        ix25_pdata_t * tmp;
  
@@ -158,9 +158,9 @@ void isdn_x25iface_proto_del(struct concap_proto *cprot){
 
 /* (re-)initialize the data structures for x25iface encapsulation
  */
-int isdn_x25iface_proto_restart(struct concap_proto *cprot,
-                               struct net_device *ndev, 
-                               struct concap_device_ops *dops)
+static int isdn_x25iface_proto_restart(struct concap_proto *cprot,
+                                       struct net_device *ndev,
+                                       struct concap_device_ops *dops)
 {
        ix25_pdata_t * pda = cprot -> proto_data ;
        ulong flags;
@@ -187,7 +187,7 @@ int isdn_x25iface_proto_restart(struct concap_proto *cprot,
 
 /* deliver a dl_data frame received from i4l HL driver to the network layer 
  */
-int isdn_x25iface_receive(struct concap_proto *cprot, struct sk_buff *skb)
+static int isdn_x25iface_receive(struct concap_proto *cprot, struct sk_buff *skb)
 {
        IX25DEBUG( "isdn_x25iface_receive %s \n", MY_DEVNAME(cprot->net_dev) );
        if ( ( (ix25_pdata_t*) (cprot->proto_data) ) 
@@ -206,7 +206,7 @@ int isdn_x25iface_receive(struct concap_proto *cprot, struct sk_buff *skb)
 
 /* a connection set up is indicated by lower layer 
  */
-int isdn_x25iface_connect_ind(struct concap_proto *cprot)
+static int isdn_x25iface_connect_ind(struct concap_proto *cprot)
 {
        struct sk_buff * skb = dev_alloc_skb(1);
        enum wan_states *state_p 
@@ -235,7 +235,7 @@ int isdn_x25iface_connect_ind(struct concap_proto *cprot)
        
 /* a disconnect is indicated by lower layer 
  */
-int isdn_x25iface_disconn_ind(struct concap_proto *cprot)
+static int isdn_x25iface_disconn_ind(struct concap_proto *cprot)
 {
        struct sk_buff *skb;
        enum wan_states *state_p 
@@ -264,7 +264,7 @@ int isdn_x25iface_disconn_ind(struct concap_proto *cprot)
 /* process a frame handed over to us from linux network layer. First byte
    semantics as defined in Documentation/networking/x25-iface.txt
    */
-int isdn_x25iface_xmit(struct concap_proto *cprot, struct sk_buff *skb)
+static int isdn_x25iface_xmit(struct concap_proto *cprot, struct sk_buff *skb)
 {
        unsigned char firstbyte = skb->data[0];
        enum wan_states *state = &((ix25_pdata_t*)cprot->proto_data)->state;
index 692ec72d1ee8b8626c209b9cabc6f0799c2f55a2..f151f36c8255d4995efccdf53cd2097ddda406e9 100644 (file)
@@ -124,23 +124,6 @@ void cb_out_2(struct pcbit_dev * dev, struct pcbit_chan* chan,
 }
 
 
-/*
- * Disconnect received (actually RELEASE COMPLETE) 
- * This means we were not able to establish connection with remote
- * Inform the big boss above
- */
-void cb_out_3(struct pcbit_dev * dev, struct pcbit_chan* chan,
-             struct callb_data *data) 
-{
-        isdn_ctrl ictl;
-
-        ictl.command = ISDN_STAT_DHUP;
-        ictl.driver=dev->id;
-        ictl.arg=chan->id;
-        dev->dev_if->statcallb(&ictl);
-}
-
-
 /*
  * Incoming call received
  * inform user
index f510dc56b57eadb94f14bd15b9652bcaca205e93..17aa0f54bfc3ce7d8c4c9935ebf2ab0f740f4fdb 100644 (file)
@@ -19,9 +19,6 @@ extern void cb_out_1(struct pcbit_dev * dev, struct pcbit_chan* chan,
 extern void cb_out_2(struct pcbit_dev * dev, struct pcbit_chan* chan, 
                     struct callb_data *data);
 
-extern void cb_out_3(struct pcbit_dev * dev, struct pcbit_chan* chan, 
-                    struct callb_data *data);
-
 extern void cb_in_1(struct pcbit_dev * dev, struct pcbit_chan* chan, 
                    struct callb_data *data);
 extern void cb_in_2(struct pcbit_dev * dev, struct pcbit_chan* chan, 
index 29eb03a8c29d093ab0ec32e0f568317253a7f9f6..bef321d0e51d5a2775ef47fd6ddbcd6b6507bffc 100644 (file)
@@ -627,16 +627,6 @@ int capi_decode_disc_ind(struct pcbit_chan *chan, struct sk_buff *skb)
         return 0;
 }
 
-int capi_decode_disc_conf(struct pcbit_chan *chan, struct sk_buff *skb)
-{
-        ushort errcode;
-
-        errcode = *((ushort*) skb->data);
-        skb_pull(skb, 2);
-
-        return errcode;                
-}
-
 #ifdef DEBUG
 int capi_decode_debug_188(u_char *hdr, ushort hdrlen)
 {
index 18e6aa360a8f9c249576bae3295de938bdd4e462..df8e73c04d7fc2052cc0b86ad6d9eed8a789967a 100644 (file)
@@ -54,7 +54,6 @@ extern int capi_tdata_resp(struct pcbit_chan *chan, struct sk_buff ** skb);
 
 /* Connection Termination */
 extern int capi_disc_req(ushort callref, struct sk_buff **skb, u_char cause);
-extern int capi_decode_disc_conf(struct pcbit_chan *chan, struct sk_buff *skb);
 
 extern int capi_decode_disc_ind(struct pcbit_chan *chan, struct sk_buff *skb);
 extern int capi_disc_resp(struct pcbit_chan *chan, struct sk_buff **skb);
index e98f9c48c18461a9a56cc5bf6395cf4a1f73b357..5de861f4081605ec66d0c375291dda166c8bae80 100644 (file)
@@ -56,10 +56,10 @@ static char* pcbit_devname[MAX_PCBIT_CARDS] = {
  * prototypes
  */
 
-int pcbit_command(isdn_ctrl* ctl);
-int pcbit_stat(u_char __user * buf, int len, int, int);
-int pcbit_xmit(int driver, int chan, int ack, struct sk_buff *skb);
-int pcbit_writecmd(const u_char __user *, int, int, int);
+static int pcbit_command(isdn_ctrl* ctl);
+static int pcbit_stat(u_char __user * buf, int len, int, int);
+static int pcbit_xmit(int driver, int chan, int ack, struct sk_buff *skb);
+static int pcbit_writecmd(const u_char __user *, int, int, int);
 
 static int set_protocol_running(struct pcbit_dev * dev);
 
@@ -238,7 +238,7 @@ void pcbit_terminate(int board)
 }
 #endif
 
-int pcbit_command(isdn_ctrl* ctl)
+static int pcbit_command(isdn_ctrl* ctl)
 {
        struct pcbit_dev  *dev;
        struct pcbit_chan *chan;
@@ -330,7 +330,7 @@ static void pcbit_block_timer(unsigned long data)
 }
 #endif
 
-int pcbit_xmit(int driver, int chnum, int ack, struct sk_buff *skb)
+static int pcbit_xmit(int driver, int chnum, int ack, struct sk_buff *skb)
 {
        ushort hdrlen;
        int refnum, len;
@@ -389,7 +389,7 @@ int pcbit_xmit(int driver, int chnum, int ack, struct sk_buff *skb)
        return len;
 }
 
-int pcbit_writecmd(const u_char __user *buf, int len, int driver, int channel)
+static int pcbit_writecmd(const u_char __user *buf, int len, int driver, int channel)
 {
        struct pcbit_dev * dev;
        int i, j;
@@ -713,7 +713,7 @@ static char statbuf[STATBUF_LEN];
 static int stat_st = 0;
 static int stat_end = 0;
 
-int pcbit_stat(u_char __user *buf, int len, int driver, int channel)
+static int pcbit_stat(u_char __user *buf, int len, int driver, int channel)
 {
        int stat_count;
        stat_count = stat_end - stat_st;
index 9cc474cd0c44c5bc7401a41d78599e6b62c82c49..0f2b7d602ac031ebd6750702648d1e44934014e4 100644 (file)
@@ -6,5 +6,5 @@ obj-$(CONFIG_ISDN_DRV_SC)       += sc.o
 
 # Multipart objects.
 
-sc-y                           := shmem.o init.o debug.o packet.o command.o event.o \
+sc-y                           := shmem.o init.o packet.o command.o event.o \
                                   ioctl.o interrupt.o message.o timer.o        
index b2c4eac7cef536ad42403837aedac5a4d3cd8a74..19f2fcf0ae4a2f579eabac0e9b5720eec8b9f209 100644 (file)
 #include "card.h"
 #include "scioc.h"
 
-int dial(int card, unsigned long channel, setup_parm setup);
-int hangup(int card, unsigned long channel);
-int answer(int card, unsigned long channel);
-int clreaz(int card, unsigned long channel);
-int seteaz(int card, unsigned long channel, char *);
-int setl2(int card, unsigned long arg);
-int setl3(int card, unsigned long arg);
-int acceptb(int card, unsigned long channel);
+static int dial(int card, unsigned long channel, setup_parm setup);
+static int hangup(int card, unsigned long channel);
+static int answer(int card, unsigned long channel);
+static int clreaz(int card, unsigned long channel);
+static int seteaz(int card, unsigned long channel, char *);
+static int setl2(int card, unsigned long arg);
+static int setl3(int card, unsigned long arg);
+static int acceptb(int card, unsigned long channel);
 
 extern int cinst;
 extern board *sc_adapter[];
@@ -147,56 +147,6 @@ int command(isdn_ctrl *cmd)
        return 0;
 }
 
-/*
- * Confirm our ability to communicate with the board.  This test assumes no
- * other message activity is present
- */
-int loopback(int card) 
-{
-
-       int status;
-       static char testmsg[] = "Test Message";
-       RspMessage rspmsg;
-
-       if(!IS_VALID_CARD(card)) {
-               pr_debug("Invalid param: %d is not a valid card id\n", card);
-               return -ENODEV;
-       }
-
-       pr_debug("%s: Sending loopback message\n",
-               sc_adapter[card]->devicename);
-
-       /*
-        * Send the loopback message to confirm that memory transfer is
-        * operational
-        */
-       status = send_and_receive(card, CMPID, cmReqType1,
-                                 cmReqClass0,
-                                 cmReqMsgLpbk,
-                                 0,
-                                 (unsigned char) strlen(testmsg),
-                                 (unsigned char *)testmsg,
-                                 &rspmsg, SAR_TIMEOUT);
-
-
-       if (!status) {
-               pr_debug("%s: Loopback message successfully sent\n",
-                       sc_adapter[card]->devicename);
-               if(strcmp(rspmsg.msg_data.byte_array, testmsg)) {
-                       pr_debug("%s: Loopback return != sent\n",
-                               sc_adapter[card]->devicename);
-                       return -EIO;
-               }
-               return 0;
-       }
-       else {
-               pr_debug("%s: Send loopback message failed\n",
-                       sc_adapter[card]->devicename);
-               return -EIO;
-       }
-
-}
-
 /*
  * start the onboard firmware
  */
@@ -222,16 +172,10 @@ int startproc(int card)
 }
 
 
-int loadproc(int card, char *data) 
-{
-       return -1;
-}
-
-
 /*
  * Dials the number passed in 
  */
-int dial(int card, unsigned long channel, setup_parm setup) 
+static int dial(int card, unsigned long channel, setup_parm setup)
 {
        int status;
        char Phone[48];
@@ -261,7 +205,7 @@ int dial(int card, unsigned long channel, setup_parm setup)
 /*
  * Answer an incoming call 
  */
-int answer(int card, unsigned long channel) 
+static int answer(int card, unsigned long channel)
 {
        if(!IS_VALID_CARD(card)) {
                pr_debug("Invalid param: %d is not a valid card id\n", card);
@@ -282,7 +226,7 @@ int answer(int card, unsigned long channel)
 /*
  * Hangup up the call on specified channel
  */
-int hangup(int card, unsigned long channel) 
+static int hangup(int card, unsigned long channel)
 {
        int status;
 
@@ -305,7 +249,7 @@ int hangup(int card, unsigned long channel)
 /*
  * Set the layer 2 protocol (X.25, HDLC, Raw)
  */
-int setl2(int card, unsigned long arg) 
+static int setl2(int card, unsigned long arg)
 {
        int status =0;
        int protocol,channel;
@@ -340,7 +284,7 @@ int setl2(int card, unsigned long arg)
 /*
  * Set the layer 3 protocol
  */
-int setl3(int card, unsigned long channel) 
+static int setl3(int card, unsigned long channel)
 {
        int protocol = channel >> 8;
 
@@ -355,7 +299,7 @@ int setl3(int card, unsigned long channel)
        return 0;
 }
 
-int acceptb(int card, unsigned long channel)
+static int acceptb(int card, unsigned long channel)
 {
        if(!IS_VALID_CARD(card)) {
                pr_debug("Invalid param: %d is not a valid card id\n", card);
@@ -374,7 +318,7 @@ int acceptb(int card, unsigned long channel)
        return 0;
 }
 
-int clreaz(int card, unsigned long arg)
+static int clreaz(int card, unsigned long arg)
 {
        if(!IS_VALID_CARD(card)) {
                pr_debug("Invalid param: %d is not a valid card id\n", card);
@@ -388,7 +332,7 @@ int clreaz(int card, unsigned long arg)
        return 0;
 }
 
-int seteaz(int card, unsigned long arg, char *num)
+static int seteaz(int card, unsigned long arg, char *num)
 {
        if(!IS_VALID_CARD(card)) {
                pr_debug("Invalid param: %d is not a valid card id\n", card);
diff --git a/drivers/isdn/sc/debug.c b/drivers/isdn/sc/debug.c
deleted file mode 100644 (file)
index 1a992a7..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-/* $Id: debug.c,v 1.5.6.1 2001/09/23 22:24:59 kai Exp $
- *
- * Copyright (C) 1996  SpellCaster Telecommunications Inc.
- *
- * This software may be used and distributed according to the terms
- * of the GNU General Public License, incorporated herein by reference.
- *
- * For more information, please contact gpl-info@spellcast.com or write:
- *
- *     SpellCaster Telecommunications Inc.
- *     5621 Finch Avenue East, Unit #3
- *     Scarborough, Ontario  Canada
- *     M1B 2T9
- *     +1 (416) 297-8565
- *     +1 (416) 297-6433 Facsimile
- */
-
-#include <linux/kernel.h>
-#include <linux/string.h>
-
-int dbg_level = 0;
-static char dbg_funcname[255];
-
-void dbg_endfunc(void)
-{
-       if (dbg_level) {
-               printk("<-- Leaving function %s\n", dbg_funcname);
-               strcpy(dbg_funcname, "");
-       }
-}
-
-void dbg_func(char *func)
-{
-       strcpy(dbg_funcname, func);
-       if(dbg_level)
-               printk("--> Entering function %s\n", dbg_funcname);
-}
-
-inline void pullphone(char *dn, char *str)
-{
-       int i = 0;
-
-       while(dn[i] != ',')
-               str[i] = dn[i], i++;
-       str[i] = 0x0;
-}
index efefedea37b9a8dddf085fcb7c287c9014c3497a..40b0df04ed9f1620e2d36e8336bb243fda21ce88 100644 (file)
@@ -20,9 +20,9 @@ board *sc_adapter[MAX_CARDS];
 int cinst;
 
 static char devname[] = "scX";
-const char version[] = "2.0b1";
+static const char version[] = "2.0b1";
 
-const char *boardname[] = { "DataCommute/BRI", "DataCommute/PRI", "TeleCommute/BRI" };
+static const char *boardname[] = { "DataCommute/BRI", "DataCommute/PRI", "TeleCommute/BRI" };
 
 /* insmod set parameters */
 static unsigned int io[] = {0,0,0,0};
@@ -35,26 +35,13 @@ module_param_array(irq, int, NULL, 0);
 module_param_array(ram, int, NULL, 0);
 module_param(do_reset, bool, 0);
 
-static int sup_irq[] = { 11, 10, 9, 5, 12, 14, 7, 3, 4, 6 };
-#define MAX_IRQS       10
-
 extern irqreturn_t interrupt_handler(int, void *, struct pt_regs *);
 extern int sndpkt(int, int, int, struct sk_buff *);
 extern int command(isdn_ctrl *);
 extern int indicate_status(int, int, ulong, char*);
 extern int reset(int);
 
-int identify_board(unsigned long, unsigned int);
-
-int irq_supported(int irq_x)
-{
-       int i;
-       for(i=0 ; i < MAX_IRQS ; i++) {
-               if(sup_irq[i] == irq_x)
-                       return 1;
-       }
-       return 0;
-}
+static int identify_board(unsigned long, unsigned int);
 
 static int __init sc_init(void)
 {
@@ -454,7 +441,7 @@ static void __exit sc_exit(void)
        pr_info("SpellCaster ISA ISDN Adapter Driver Unloaded.\n");
 }
 
-int identify_board(unsigned long rambase, unsigned int iobase) 
+static int identify_board(unsigned long rambase, unsigned int iobase)
 {
        unsigned int pgport;
        unsigned long sig;
index e5e164aca7faf7d46aa9f05291e715da334adbe6..8631d338d69ab550084ad4e3d0eaaebacd206b6c 100644 (file)
@@ -31,7 +31,7 @@ extern void rcvpkt(int, RspMessage *);
 extern int cinst;
 extern board *sc_adapter[];
 
-int get_card_from_irq(int irq)
+static int get_card_from_irq(int irq)
 {
        int i;
 
index 1371a990416a4fcc8d95f42a947cf74c6e070044..3314a5a19854239f2bf335102c4e6f1c6dabfa97 100644 (file)
@@ -14,7 +14,6 @@
 
 extern int indicate_status(int, int, unsigned long, char *);
 extern int startproc(int);
-extern int loadproc(int, char *record);
 extern int reset(int);
 extern int send_and_receive(int, unsigned int, unsigned char,unsigned char,
                unsigned char,unsigned char, 
@@ -23,7 +22,7 @@ extern int send_and_receive(int, unsigned int, unsigned char,unsigned char,
 extern board *sc_adapter[];
 
 
-int GetStatus(int card, boardInfo *);
+static int GetStatus(int card, boardInfo *);
 
 /*
  * Process private IOCTL messages (typically from scctrl)
@@ -428,7 +427,7 @@ int sc_ioctl(int card, scs_ioctl *data)
        return 0;
 }
 
-int GetStatus(int card, boardInfo *bi)
+static int GetStatus(int card, boardInfo *bi)
 {
        RspMessage rcvmsg;
        int i, status;
index 8e3fac3ba1a19672e65ce3f5e8ccfe6192566458..f50defc38ae5b47baac92c6117b39d9a3bab1b04 100644 (file)
@@ -213,19 +213,3 @@ int setup_buffers(int card, int c)
        return 0;
 }
 
-int print_skb(int card,char *skb_p, int len){
-       int i,data;
-       pr_debug("%s: data at 0x%x len: 0x%x\n", sc_adapter[card]->devicename,
-                       skb_p,len);
-       for(i=1;i<=len;i++,skb_p++){
-               data = (int) (0xff & (*skb_p));
-               pr_debug("%s: data =  0x%x", sc_adapter[card]->devicename,data);
-               if(!(i%4))
-                       pr_debug(" ");
-               if(!(i%32))
-                       pr_debug("\n");
-       }
-       pr_debug("\n");
-       return 0;
-}              
-
index 7bc2dfad0775f2cbdf66fd0bbdeb94eaab079f8b..24854826ca4599842fd7165f4de12f548f1f9b45 100644 (file)
@@ -108,6 +108,7 @@ void memcpy_fromshmem(int card, void *dest, const void *src, size_t n)
                sc_adapter[card]->rambase + ((unsigned long) src %0x4000), (unsigned long) dest); */
 }
 
+#if 0
 void memset_shmem(int card, void *dest, int c, size_t n)
 {
        unsigned long flags;
@@ -141,3 +142,4 @@ void memset_shmem(int card, void *dest, int c, size_t n)
                ((sc_adapter[card]->shmem_magic + ch * SRAM_PAGESIZE)>>14)|0x80);
        spin_unlock_irqrestore(&sc_adapter[card]->lock, flags);
 }
+#endif  /*  0  */
index 710d0f47ca35ccd2bdce256cc806b425bde3e8da..aced19aac5a2e5011d81cb4f03ef6805836e5d62 100644 (file)
@@ -32,7 +32,7 @@ extern int  sendmessage(int, unsigned int, unsigned int, unsigned int,
 /*
  * Write the proper values into the I/O ports following a reset
  */
-void setup_ports(int card)
+static void setup_ports(int card)
 {
 
        outb((sc_adapter[card]->rambase >> 12), sc_adapter[card]->ioport[EXP_BASE]);
@@ -129,19 +129,3 @@ void check_phystat(unsigned long data)
                ceReqPhyStatus,0,0,NULL);
 }
 
-/*
- * When in trace mode, this callback is used to swap the working shared
- * RAM page to the trace page(s) and process all received messages. It
- * must be called often enough to get all of the messages out of RAM before
- * it loops around.
- * Trace messages are \n terminated strings.
- * We output the messages in 64 byte chunks through readstat. Each chunk
- * is scanned for a \n followed by a time stamp. If the timerstamp is older
- * than the current time, scanning stops and the page and offset are recorded
- * as the starting point the next time the trace timer is called. The final
- * step is to restore the working page and reset the timer.
- */
-void trace_timer(unsigned long data)
-{
-       /* not implemented */
-}
index 5ba190ce14a07dbc8a17607d5dce10bc919f8b29..c9ca1118e449207c2dca58a742b0ddd204a556d7 100644 (file)
@@ -328,9 +328,7 @@ static int monitor_task(void *arg)
        struct thermostat* th = arg;
 
        while(!kthread_should_stop()) {
-               if (current->flags & PF_FREEZE)
-                       refrigerator(PF_FREEZE);
-
+               try_to_freeze();
                msleep_interruptible(2000);
 
 #ifndef DEBUG
index af56313ba0af9d6ed7b5ed6a23826d690b44fdbc..0c7bfa74c8efccc36502b1cc99c38a542956f6ba 100644 (file)
@@ -180,7 +180,6 @@ struct mca_device *mca_find_device_by_slot(int slot)
 
        return info.mca_dev;
 }
-EXPORT_SYMBOL(mca_find_device_by_slot);
 
 /**
  *     mca_read_stored_pos - read POS register from boot data
index 0c6b5b6baff60ded7fb24d2f71988711d723c604..3802f7a17f1635c17f2bcd6fe426e994e0871cf4 100644 (file)
@@ -2976,8 +2976,7 @@ static int md_thread(void * arg)
                wait_event_interruptible_timeout(thread->wqueue,
                                                 test_bit(THREAD_WAKEUP, &thread->flags),
                                                 thread->timeout);
-               if (current->flags & PF_FREEZE)
-                       refrigerator(PF_FREEZE);
+               try_to_freeze();
 
                clear_bit(THREAD_WAKEUP, &thread->flags);
 
index d6b7a9de471eebf50fa9c5bb04ec52c63350b535..f11daae91cd4e07ce54bdb375f5f10aed22aa104 100644 (file)
@@ -391,8 +391,7 @@ static int dvb_frontend_thread(void *data)
                        break;
                }
 
-               if (current->flags & PF_FREEZE)
-                       refrigerator(PF_FREEZE);
+               try_to_freeze();
 
                if (down_interruptible(&fepriv->sem))
                        break;
index ac0dc27bb38f7e7dedd7018a76a90d7210597f8a..867e988a5a93cc397685a4095cb861860dbd8e9e 100644 (file)
@@ -435,7 +435,6 @@ struct cx8802_dev {
 /* ----------------------------------------------------------- */
 /* cx88-core.c                                                 */
 
-extern char *cx88_pci_irqs[32];
 extern char *cx88_vid_irqs[32];
 extern char *cx88_mpeg_irqs[32];
 extern void cx88_print_irqbits(char *name, char *tag, char **strings,
index 1b7d38e96f14ca6f7c4505ee3273eabf46364ea5..b4ee9dfe6d4247e1cfcdc47ac8bcdb2082140290 100644 (file)
@@ -750,8 +750,7 @@ static int msp34xx_sleep(struct msp3400c *msp, int timeout)
 #endif
                }
        }
-       if (current->flags & PF_FREEZE)
-               refrigerator(PF_FREEZE);
+       try_to_freeze();
        remove_wait_queue(&msp->wq, &wait);
        return msp->restart;
 }
index 5f870075b55e595df3e8384d0812279092ed3259..15f5bb4869638a78a1dcc94f1196d251d350e361 100644 (file)
@@ -62,8 +62,7 @@ static int videobuf_dvb_thread(void *data)
                        break;
                if (kthread_should_stop())
                        break;
-               if (current->flags & PF_FREEZE)
-                       refrigerator(PF_FREEZE);
+               try_to_freeze();
 
                /* feed buffer data to demux */
                if (buf->state == STATE_DONE)
index 047202c4d9a8b23bd150eae38654c211485f3ccf..5a4a08a7c9518da338ce6f0fcea40bfad4b36d8b 100644 (file)
@@ -1606,7 +1606,7 @@ static int rtl8139_thread (void *data)
                do {
                        timeout = interruptible_sleep_on_timeout (&tp->thr_wait, timeout);
                        /* make swsusp happy with our thread */
-                       try_to_freeze(PF_FREEZE);
+                       try_to_freeze();
                } while (!signal_pending (current) && (timeout > 0));
 
                if (signal_pending (current)) {
index 18cea1099530a1131552879fa42fb304e6264e48..c65054364bca45cb49630df0b13682b90c1b0e6e 100644 (file)
@@ -135,8 +135,7 @@ static int irda_thread(void *startup)
                remove_wait_queue(&irda_rq_queue.kick, &wait);
 
                /* make swsusp happy with our thread */
-               if (current->flags & PF_FREEZE)
-                       refrigerator(PF_FREEZE);
+               try_to_freeze();
 
                run_irda_queue();
        }
index 66f488c13717415b151c1bb1ad5442c09e4486e5..15f207323d97043b124dd6282835447804abf5aa 100644 (file)
@@ -763,7 +763,7 @@ static int stir_transmit_thread(void *arg)
        {
 #ifdef CONFIG_PM
                /* if suspending, then power off and wait */
-               if (unlikely(current->flags & PF_FREEZE)) {
+               if (unlikely(freezing(current))) {
                        if (stir->receiving)
                                receive_stop(stir);
                        else
@@ -771,7 +771,7 @@ static int stir_transmit_thread(void *arg)
 
                        write_reg(stir, REG_CTRL1, CTRL1_TXPWD|CTRL1_RXPWD);
 
-                       refrigerator(PF_FREEZE);
+                       refrigerator();
 
                        if (change_speed(stir, stir->speed))
                                break;
index a0b8848049c9ede346a9160c370d0b1df49c2798..7e371b1209a1a4b3578b80f0d7bb33d2a6d2697c 100644 (file)
@@ -66,8 +66,8 @@
 
 #define DRV_MODULE_NAME                "tg3"
 #define PFX DRV_MODULE_NAME    ": "
-#define DRV_MODULE_VERSION     "3.31"
-#define DRV_MODULE_RELDATE     "June 8, 2005"
+#define DRV_MODULE_VERSION     "3.32"
+#define DRV_MODULE_RELDATE     "June 24, 2005"
 
 #define TG3_DEF_MAC_MODE       0
 #define TG3_DEF_RX_MODE                0
@@ -337,12 +337,10 @@ static struct {
 static void tg3_write_indirect_reg32(struct tg3 *tp, u32 off, u32 val)
 {
        if ((tp->tg3_flags & TG3_FLAG_PCIX_TARGET_HWBUG) != 0) {
-               unsigned long flags;
-
-               spin_lock_irqsave(&tp->indirect_lock, flags);
+               spin_lock_bh(&tp->indirect_lock);
                pci_write_config_dword(tp->pdev, TG3PCI_REG_BASE_ADDR, off);
                pci_write_config_dword(tp->pdev, TG3PCI_REG_DATA, val);
-               spin_unlock_irqrestore(&tp->indirect_lock, flags);
+               spin_unlock_bh(&tp->indirect_lock);
        } else {
                writel(val, tp->regs + off);
                if ((tp->tg3_flags & TG3_FLAG_5701_REG_WRITE_BUG) != 0)
@@ -353,12 +351,10 @@ static void tg3_write_indirect_reg32(struct tg3 *tp, u32 off, u32 val)
 static void _tw32_flush(struct tg3 *tp, u32 off, u32 val)
 {
        if ((tp->tg3_flags & TG3_FLAG_PCIX_TARGET_HWBUG) != 0) {
-               unsigned long flags;
-
-               spin_lock_irqsave(&tp->indirect_lock, flags);
+               spin_lock_bh(&tp->indirect_lock);
                pci_write_config_dword(tp->pdev, TG3PCI_REG_BASE_ADDR, off);
                pci_write_config_dword(tp->pdev, TG3PCI_REG_DATA, val);
-               spin_unlock_irqrestore(&tp->indirect_lock, flags);
+               spin_unlock_bh(&tp->indirect_lock);
        } else {
                void __iomem *dest = tp->regs + off;
                writel(val, dest);
@@ -398,28 +394,24 @@ static inline void _tw32_tx_mbox(struct tg3 *tp, u32 off, u32 val)
 
 static void tg3_write_mem(struct tg3 *tp, u32 off, u32 val)
 {
-       unsigned long flags;
-
-       spin_lock_irqsave(&tp->indirect_lock, flags);
+       spin_lock_bh(&tp->indirect_lock);
        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);
-       spin_unlock_irqrestore(&tp->indirect_lock, flags);
+       spin_unlock_bh(&tp->indirect_lock);
 }
 
 static void tg3_read_mem(struct tg3 *tp, u32 off, u32 *val)
 {
-       unsigned long flags;
-
-       spin_lock_irqsave(&tp->indirect_lock, flags);
+       spin_lock_bh(&tp->indirect_lock);
        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);
-       spin_unlock_irqrestore(&tp->indirect_lock, flags);
+       spin_unlock_bh(&tp->indirect_lock);
 }
 
 static void tg3_disable_ints(struct tg3 *tp)
@@ -438,12 +430,14 @@ static inline void tg3_cond_int(struct tg3 *tp)
 
 static void tg3_enable_ints(struct tg3 *tp)
 {
+       tp->irq_sync = 0;
+       wmb();
+
        tw32(TG3PCI_MISC_HOST_CTRL,
             (tp->misc_host_ctrl & ~MISC_HOST_CTRL_MASK_PCI_INT));
        tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW,
                     (tp->last_tag << 24));
        tr32(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW);
-
        tg3_cond_int(tp);
 }
 
@@ -492,6 +486,7 @@ static void tg3_restart_ints(struct tg3 *tp)
 
 static inline void tg3_netif_stop(struct tg3 *tp)
 {
+       tp->dev->trans_start = jiffies; /* prevent tx timeout */
        netif_poll_disable(tp->dev);
        netif_tx_disable(tp->dev);
 }
@@ -504,7 +499,8 @@ static inline void tg3_netif_start(struct tg3 *tp)
         * (such as after tg3_init_hw)
         */
        netif_poll_enable(tp->dev);
-       tg3_cond_int(tp);
+       tp->hw_status->status |= SD_STATUS_UPDATED;
+       tg3_enable_ints(tp);
 }
 
 static void tg3_switch_clocks(struct tg3 *tp)
@@ -2578,7 +2574,7 @@ static void tg3_tx(struct tg3 *tp)
                        sw_idx = NEXT_TX(sw_idx);
                }
 
-               dev_kfree_skb_irq(skb);
+               dev_kfree_skb(skb);
        }
 
        tp->tx_cons = sw_idx;
@@ -2884,11 +2880,8 @@ static int tg3_poll(struct net_device *netdev, int *budget)
 {
        struct tg3 *tp = netdev_priv(netdev);
        struct tg3_hw_status *sblk = tp->hw_status;
-       unsigned long flags;
        int done;
 
-       spin_lock_irqsave(&tp->lock, flags);
-
        /* handle link change and other phy events */
        if (!(tp->tg3_flags &
              (TG3_FLAG_USE_LINKCHG_REG |
@@ -2896,7 +2889,9 @@ static int tg3_poll(struct net_device *netdev, int *budget)
                if (sblk->status & SD_STATUS_LINK_CHG) {
                        sblk->status = SD_STATUS_UPDATED |
                                (sblk->status & ~SD_STATUS_LINK_CHG);
+                       spin_lock(&tp->lock);
                        tg3_setup_phy(tp, 0);
+                       spin_unlock(&tp->lock);
                }
        }
 
@@ -2907,8 +2902,6 @@ static int tg3_poll(struct net_device *netdev, int *budget)
                spin_unlock(&tp->tx_lock);
        }
 
-       spin_unlock_irqrestore(&tp->lock, flags);
-
        /* run RX thread, within the bounds set by NAPI.
         * All RX "locking" is done by ensuring outside
         * code synchronizes with dev->poll()
@@ -2929,19 +2922,54 @@ static int tg3_poll(struct net_device *netdev, int *budget)
        if (tp->tg3_flags & TG3_FLAG_TAGGED_STATUS)
                tp->last_tag = sblk->status_tag;
        rmb();
+       sblk->status &= ~SD_STATUS_UPDATED;
 
        /* if no more work, tell net stack and NIC we're done */
        done = !tg3_has_work(tp);
        if (done) {
-               spin_lock_irqsave(&tp->lock, flags);
-               __netif_rx_complete(netdev);
+               spin_lock(&tp->lock);
+               netif_rx_complete(netdev);
                tg3_restart_ints(tp);
-               spin_unlock_irqrestore(&tp->lock, flags);
+               spin_unlock(&tp->lock);
        }
 
        return (done ? 0 : 1);
 }
 
+static void tg3_irq_quiesce(struct tg3 *tp)
+{
+       BUG_ON(tp->irq_sync);
+
+       tp->irq_sync = 1;
+       smp_mb();
+
+       synchronize_irq(tp->pdev->irq);
+}
+
+static inline int tg3_irq_sync(struct tg3 *tp)
+{
+       return tp->irq_sync;
+}
+
+/* Fully shutdown all tg3 driver activity elsewhere in the system.
+ * If irq_sync is non-zero, then the IRQ handler must be synchronized
+ * with as well.  Most of the time, this is not necessary except when
+ * shutting down the device.
+ */
+static inline void tg3_full_lock(struct tg3 *tp, int irq_sync)
+{
+       if (irq_sync)
+               tg3_irq_quiesce(tp);
+       spin_lock_bh(&tp->lock);
+       spin_lock(&tp->tx_lock);
+}
+
+static inline void tg3_full_unlock(struct tg3 *tp)
+{
+       spin_unlock(&tp->tx_lock);
+       spin_unlock_bh(&tp->lock);
+}
+
 /* MSI ISR - No need to check for interrupt sharing and no need to
  * flush status block and interrupt mailbox. PCI ordering rules
  * guarantee that MSI will arrive after the status block.
@@ -2951,9 +2979,6 @@ static irqreturn_t tg3_msi(int irq, void *dev_id, struct pt_regs *regs)
        struct net_device *dev = dev_id;
        struct tg3 *tp = netdev_priv(dev);
        struct tg3_hw_status *sblk = tp->hw_status;
-       unsigned long flags;
-
-       spin_lock_irqsave(&tp->lock, flags);
 
        /*
         * Writing any value to intr-mbox-0 clears PCI INTA# and
@@ -2964,6 +2989,9 @@ static irqreturn_t tg3_msi(int irq, void *dev_id, struct pt_regs *regs)
         */
        tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, 0x00000001);
        tp->last_tag = sblk->status_tag;
+       rmb();
+       if (tg3_irq_sync(tp))
+               goto out;
        sblk->status &= ~SD_STATUS_UPDATED;
        if (likely(tg3_has_work(tp)))
                netif_rx_schedule(dev);         /* schedule NAPI poll */
@@ -2972,9 +3000,7 @@ static irqreturn_t tg3_msi(int irq, void *dev_id, struct pt_regs *regs)
                tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW,
                             tp->last_tag << 24);
        }
-
-       spin_unlock_irqrestore(&tp->lock, flags);
-
+out:
        return IRQ_RETVAL(1);
 }
 
@@ -2983,11 +3009,8 @@ static irqreturn_t tg3_interrupt(int irq, void *dev_id, struct pt_regs *regs)
        struct net_device *dev = dev_id;
        struct tg3 *tp = netdev_priv(dev);
        struct tg3_hw_status *sblk = tp->hw_status;
-       unsigned long flags;
        unsigned int handled = 1;
 
-       spin_lock_irqsave(&tp->lock, flags);
-
        /* In INTx mode, it is possible for the interrupt to arrive at
         * the CPU before the status block posted prior to the interrupt.
         * Reading the PCI State register will confirm whether the
@@ -3004,6 +3027,8 @@ static irqreturn_t tg3_interrupt(int irq, void *dev_id, struct pt_regs *regs)
                 */
                tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW,
                             0x00000001);
+               if (tg3_irq_sync(tp))
+                       goto out;
                sblk->status &= ~SD_STATUS_UPDATED;
                if (likely(tg3_has_work(tp)))
                        netif_rx_schedule(dev);         /* schedule NAPI poll */
@@ -3018,9 +3043,7 @@ static irqreturn_t tg3_interrupt(int irq, void *dev_id, struct pt_regs *regs)
        } else {        /* shared interrupt */
                handled = 0;
        }
-
-       spin_unlock_irqrestore(&tp->lock, flags);
-
+out:
        return IRQ_RETVAL(handled);
 }
 
@@ -3029,11 +3052,8 @@ static irqreturn_t tg3_interrupt_tagged(int irq, void *dev_id, struct pt_regs *r
        struct net_device *dev = dev_id;
        struct tg3 *tp = netdev_priv(dev);
        struct tg3_hw_status *sblk = tp->hw_status;
-       unsigned long flags;
        unsigned int handled = 1;
 
-       spin_lock_irqsave(&tp->lock, flags);
-
        /* In INTx mode, it is possible for the interrupt to arrive at
         * the CPU before the status block posted prior to the interrupt.
         * Reading the PCI State register will confirm whether the
@@ -3051,6 +3071,9 @@ static irqreturn_t tg3_interrupt_tagged(int irq, void *dev_id, struct pt_regs *r
                tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW,
                             0x00000001);
                tp->last_tag = sblk->status_tag;
+               rmb();
+               if (tg3_irq_sync(tp))
+                       goto out;
                sblk->status &= ~SD_STATUS_UPDATED;
                if (likely(tg3_has_work(tp)))
                        netif_rx_schedule(dev);         /* schedule NAPI poll */
@@ -3065,9 +3088,7 @@ static irqreturn_t tg3_interrupt_tagged(int irq, void *dev_id, struct pt_regs *r
        } else {        /* shared interrupt */
                handled = 0;
        }
-
-       spin_unlock_irqrestore(&tp->lock, flags);
-
+out:
        return IRQ_RETVAL(handled);
 }
 
@@ -3106,8 +3127,7 @@ static void tg3_reset_task(void *_data)
 
        tg3_netif_stop(tp);
 
-       spin_lock_irq(&tp->lock);
-       spin_lock(&tp->tx_lock);
+       tg3_full_lock(tp, 1);
 
        restart_timer = tp->tg3_flags2 & TG3_FLG2_RESTART_TIMER;
        tp->tg3_flags2 &= ~TG3_FLG2_RESTART_TIMER;
@@ -3117,8 +3137,7 @@ static void tg3_reset_task(void *_data)
 
        tg3_netif_start(tp);
 
-       spin_unlock(&tp->tx_lock);
-       spin_unlock_irq(&tp->lock);
+       tg3_full_unlock(tp);
 
        if (restart_timer)
                mod_timer(&tp->timer, jiffies + 1);
@@ -3224,39 +3243,21 @@ static int tg3_start_xmit(struct sk_buff *skb, struct net_device *dev)
        unsigned int i;
        u32 len, entry, base_flags, mss;
        int would_hit_hwbug;
-       unsigned long flags;
 
        len = skb_headlen(skb);
 
        /* No BH disabling for tx_lock here.  We are running in BH disabled
         * context and TX reclaim runs via tp->poll inside of a software
-        * interrupt.  Rejoice!
-        *
-        * Actually, things are not so simple.  If we are to take a hw
-        * IRQ here, we can deadlock, consider:
-        *
-        *       CPU1           CPU2
-        *   tg3_start_xmit
-        *   take tp->tx_lock
-        *                      tg3_timer
-        *                      take tp->lock
-        *   tg3_interrupt
-        *   spin on tp->lock
-        *                      spin on tp->tx_lock
-        *
-        * So we really do need to disable interrupts when taking
-        * tx_lock here.
+        * interrupt.  Furthermore, IRQ processing runs lockless so we have
+        * no IRQ context deadlocks to worry about either.  Rejoice!
         */
-       local_irq_save(flags);
-       if (!spin_trylock(&tp->tx_lock)) { 
-               local_irq_restore(flags);
+       if (!spin_trylock(&tp->tx_lock))
                return NETDEV_TX_LOCKED; 
-       } 
 
        /* This is a hard error, log it. */
        if (unlikely(TX_BUFFS_AVAIL(tp) <= (skb_shinfo(skb)->nr_frags + 1))) {
                netif_stop_queue(dev);
-               spin_unlock_irqrestore(&tp->tx_lock, flags);
+               spin_unlock(&tp->tx_lock);
                printk(KERN_ERR PFX "%s: BUG! Tx Ring full when queue awake!\n",
                       dev->name);
                return NETDEV_TX_BUSY;
@@ -3421,7 +3422,7 @@ static int tg3_start_xmit(struct sk_buff *skb, struct net_device *dev)
 
 out_unlock:
        mmiowb();
-       spin_unlock_irqrestore(&tp->tx_lock, flags);
+       spin_unlock(&tp->tx_lock);
 
        dev->trans_start = jiffies;
 
@@ -3455,8 +3456,8 @@ static int tg3_change_mtu(struct net_device *dev, int new_mtu)
        }
 
        tg3_netif_stop(tp);
-       spin_lock_irq(&tp->lock);
-       spin_lock(&tp->tx_lock);
+
+       tg3_full_lock(tp, 1);
 
        tg3_halt(tp, RESET_KIND_SHUTDOWN, 1);
 
@@ -3466,8 +3467,7 @@ static int tg3_change_mtu(struct net_device *dev, int new_mtu)
 
        tg3_netif_start(tp);
 
-       spin_unlock(&tp->tx_lock);
-       spin_unlock_irq(&tp->lock);
+       tg3_full_unlock(tp);
 
        return 0;
 }
@@ -5088,9 +5088,9 @@ static int tg3_set_mac_addr(struct net_device *dev, void *p)
 
        memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
 
-       spin_lock_irq(&tp->lock);
+       spin_lock_bh(&tp->lock);
        __tg3_set_mac_addr(tp);
-       spin_unlock_irq(&tp->lock);
+       spin_unlock_bh(&tp->lock);
 
        return 0;
 }
@@ -5727,9 +5727,6 @@ static int tg3_reset_hw(struct tg3 *tp)
 
        tg3_write_sig_post_reset(tp, RESET_KIND_INIT);
 
-       if (tp->tg3_flags & TG3_FLAG_INIT_COMPLETE)
-               tg3_enable_ints(tp);
-
        return 0;
 }
 
@@ -5802,10 +5799,8 @@ static void tg3_periodic_fetch_stats(struct tg3 *tp)
 static void tg3_timer(unsigned long __opaque)
 {
        struct tg3 *tp = (struct tg3 *) __opaque;
-       unsigned long flags;
 
-       spin_lock_irqsave(&tp->lock, flags);
-       spin_lock(&tp->tx_lock);
+       spin_lock(&tp->lock);
 
        if (!(tp->tg3_flags & TG3_FLAG_TAGGED_STATUS)) {
                /* All of this garbage is because when using non-tagged
@@ -5822,8 +5817,7 @@ static void tg3_timer(unsigned long __opaque)
 
                if (!(tr32(WDMAC_MODE) & WDMAC_MODE_ENABLE)) {
                        tp->tg3_flags2 |= TG3_FLG2_RESTART_TIMER;
-                       spin_unlock(&tp->tx_lock);
-                       spin_unlock_irqrestore(&tp->lock, flags);
+                       spin_unlock(&tp->lock);
                        schedule_work(&tp->reset_task);
                        return;
                }
@@ -5891,8 +5885,7 @@ static void tg3_timer(unsigned long __opaque)
                tp->asf_counter = tp->asf_multiplier;
        }
 
-       spin_unlock(&tp->tx_lock);
-       spin_unlock_irqrestore(&tp->lock, flags);
+       spin_unlock(&tp->lock);
 
        tp->timer.expires = jiffies + tp->timer_offset;
        add_timer(&tp->timer);
@@ -6007,14 +6000,12 @@ static int tg3_test_msi(struct tg3 *tp)
        /* Need to reset the chip because the MSI cycle may have terminated
         * with Master Abort.
         */
-       spin_lock_irq(&tp->lock);
-       spin_lock(&tp->tx_lock);
+       tg3_full_lock(tp, 1);
 
        tg3_halt(tp, RESET_KIND_SHUTDOWN, 1);
        err = tg3_init_hw(tp);
 
-       spin_unlock(&tp->tx_lock);
-       spin_unlock_irq(&tp->lock);
+       tg3_full_unlock(tp);
 
        if (err)
                free_irq(tp->pdev->irq, dev);
@@ -6027,14 +6018,12 @@ static int tg3_open(struct net_device *dev)
        struct tg3 *tp = netdev_priv(dev);
        int err;
 
-       spin_lock_irq(&tp->lock);
-       spin_lock(&tp->tx_lock);
+       tg3_full_lock(tp, 0);
 
        tg3_disable_ints(tp);
        tp->tg3_flags &= ~TG3_FLAG_INIT_COMPLETE;
 
-       spin_unlock(&tp->tx_lock);
-       spin_unlock_irq(&tp->lock);
+       tg3_full_unlock(tp);
 
        /* The placement of this call is tied
         * to the setup and use of Host TX descriptors.
@@ -6081,8 +6070,7 @@ static int tg3_open(struct net_device *dev)
                return err;
        }
 
-       spin_lock_irq(&tp->lock);
-       spin_lock(&tp->tx_lock);
+       tg3_full_lock(tp, 0);
 
        err = tg3_init_hw(tp);
        if (err) {
@@ -6106,8 +6094,7 @@ static int tg3_open(struct net_device *dev)
                tp->timer.function = tg3_timer;
        }
 
-       spin_unlock(&tp->tx_lock);
-       spin_unlock_irq(&tp->lock);
+       tg3_full_unlock(tp);
 
        if (err) {
                free_irq(tp->pdev->irq, dev);
@@ -6123,8 +6110,7 @@ static int tg3_open(struct net_device *dev)
                err = tg3_test_msi(tp);
 
                if (err) {
-                       spin_lock_irq(&tp->lock);
-                       spin_lock(&tp->tx_lock);
+                       tg3_full_lock(tp, 0);
 
                        if (tp->tg3_flags2 & TG3_FLG2_USING_MSI) {
                                pci_disable_msi(tp->pdev);
@@ -6134,22 +6120,19 @@ static int tg3_open(struct net_device *dev)
                        tg3_free_rings(tp);
                        tg3_free_consistent(tp);
 
-                       spin_unlock(&tp->tx_lock);
-                       spin_unlock_irq(&tp->lock);
+                       tg3_full_unlock(tp);
 
                        return err;
                }
        }
 
-       spin_lock_irq(&tp->lock);
-       spin_lock(&tp->tx_lock);
+       tg3_full_lock(tp, 0);
 
        add_timer(&tp->timer);
        tp->tg3_flags |= TG3_FLAG_INIT_COMPLETE;
        tg3_enable_ints(tp);
 
-       spin_unlock(&tp->tx_lock);
-       spin_unlock_irq(&tp->lock);
+       tg3_full_unlock(tp);
 
        netif_start_queue(dev);
 
@@ -6395,8 +6378,7 @@ static int tg3_close(struct net_device *dev)
 
        del_timer_sync(&tp->timer);
 
-       spin_lock_irq(&tp->lock);
-       spin_lock(&tp->tx_lock);
+       tg3_full_lock(tp, 1);
 #if 0
        tg3_dump_state(tp);
 #endif
@@ -6410,8 +6392,7 @@ static int tg3_close(struct net_device *dev)
                  TG3_FLAG_GOT_SERDES_FLOWCTL);
        netif_carrier_off(tp->dev);
 
-       spin_unlock(&tp->tx_lock);
-       spin_unlock_irq(&tp->lock);
+       tg3_full_unlock(tp);
 
        free_irq(tp->pdev->irq, dev);
        if (tp->tg3_flags2 & TG3_FLG2_USING_MSI) {
@@ -6448,16 +6429,15 @@ static unsigned long calc_crc_errors(struct tg3 *tp)
        if (!(tp->tg3_flags2 & TG3_FLG2_PHY_SERDES) &&
            (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700 ||
             GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701)) {
-               unsigned long flags;
                u32 val;
 
-               spin_lock_irqsave(&tp->lock, flags);
+               spin_lock_bh(&tp->lock);
                if (!tg3_readphy(tp, 0x1e, &val)) {
                        tg3_writephy(tp, 0x1e, val | 0x8000);
                        tg3_readphy(tp, 0x14, &val);
                } else
                        val = 0;
-               spin_unlock_irqrestore(&tp->lock, flags);
+               spin_unlock_bh(&tp->lock);
 
                tp->phy_crc_errors += val;
 
@@ -6719,11 +6699,9 @@ static void tg3_set_rx_mode(struct net_device *dev)
 {
        struct tg3 *tp = netdev_priv(dev);
 
-       spin_lock_irq(&tp->lock);
-       spin_lock(&tp->tx_lock);
+       tg3_full_lock(tp, 0);
        __tg3_set_rx_mode(dev);
-       spin_unlock(&tp->tx_lock);
-       spin_unlock_irq(&tp->lock);
+       tg3_full_unlock(tp);
 }
 
 #define TG3_REGDUMP_LEN                (32 * 1024)
@@ -6745,8 +6723,7 @@ static void tg3_get_regs(struct net_device *dev,
 
        memset(p, 0, TG3_REGDUMP_LEN);
 
-       spin_lock_irq(&tp->lock);
-       spin_lock(&tp->tx_lock);
+       tg3_full_lock(tp, 0);
 
 #define __GET_REG32(reg)       (*(p)++ = tr32(reg))
 #define GET_REG32_LOOP(base,len)               \
@@ -6796,8 +6773,7 @@ do {      p = (u32 *)(orig_p + (reg));            \
 #undef GET_REG32_LOOP
 #undef GET_REG32_1
 
-       spin_unlock(&tp->tx_lock);
-       spin_unlock_irq(&tp->lock);
+       tg3_full_unlock(tp);
 }
 
 static int tg3_get_eeprom_len(struct net_device *dev)
@@ -6973,8 +6949,7 @@ static int tg3_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
                        return -EINVAL;
        }
 
-       spin_lock_irq(&tp->lock);
-       spin_lock(&tp->tx_lock);
+       tg3_full_lock(tp, 0);
 
        tp->link_config.autoneg = cmd->autoneg;
        if (cmd->autoneg == AUTONEG_ENABLE) {
@@ -6990,8 +6965,7 @@ static int tg3_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
        if (netif_running(dev))
                tg3_setup_phy(tp, 1);
 
-       spin_unlock(&tp->tx_lock);
-       spin_unlock_irq(&tp->lock);
+       tg3_full_unlock(tp);
   
        return 0;
 }
@@ -7027,12 +7001,12 @@ static int tg3_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
            !(tp->tg3_flags & TG3_FLAG_SERDES_WOL_CAP))
                return -EINVAL;
   
-       spin_lock_irq(&tp->lock);
+       spin_lock_bh(&tp->lock);
        if (wol->wolopts & WAKE_MAGIC)
                tp->tg3_flags |= TG3_FLAG_WOL_ENABLE;
        else
                tp->tg3_flags &= ~TG3_FLAG_WOL_ENABLE;
-       spin_unlock_irq(&tp->lock);
+       spin_unlock_bh(&tp->lock);
   
        return 0;
 }
@@ -7072,7 +7046,7 @@ static int tg3_nway_reset(struct net_device *dev)
        if (!netif_running(dev))
                return -EAGAIN;
 
-       spin_lock_irq(&tp->lock);
+       spin_lock_bh(&tp->lock);
        r = -EINVAL;
        tg3_readphy(tp, MII_BMCR, &bmcr);
        if (!tg3_readphy(tp, MII_BMCR, &bmcr) &&
@@ -7080,7 +7054,7 @@ static int tg3_nway_reset(struct net_device *dev)
                tg3_writephy(tp, MII_BMCR, bmcr | BMCR_ANRESTART);
                r = 0;
        }
-       spin_unlock_irq(&tp->lock);
+       spin_unlock_bh(&tp->lock);
   
        return r;
 }
@@ -7102,17 +7076,19 @@ static void tg3_get_ringparam(struct net_device *dev, struct ethtool_ringparam *
 static int tg3_set_ringparam(struct net_device *dev, struct ethtool_ringparam *ering)
 {
        struct tg3 *tp = netdev_priv(dev);
+       int irq_sync = 0;
   
        if ((ering->rx_pending > TG3_RX_RING_SIZE - 1) ||
            (ering->rx_jumbo_pending > TG3_RX_JUMBO_RING_SIZE - 1) ||
            (ering->tx_pending > TG3_TX_RING_SIZE - 1))
                return -EINVAL;
   
-       if (netif_running(dev))
+       if (netif_running(dev)) {
                tg3_netif_stop(tp);
+               irq_sync = 1;
+       }
 
-       spin_lock_irq(&tp->lock);
-       spin_lock(&tp->tx_lock);
+       tg3_full_lock(tp, irq_sync);
   
        tp->rx_pending = ering->rx_pending;
 
@@ -7128,8 +7104,7 @@ static int tg3_set_ringparam(struct net_device *dev, struct ethtool_ringparam *e
                tg3_netif_start(tp);
        }
 
-       spin_unlock(&tp->tx_lock);
-       spin_unlock_irq(&tp->lock);
+       tg3_full_unlock(tp);
   
        return 0;
 }
@@ -7146,12 +7121,15 @@ static void tg3_get_pauseparam(struct net_device *dev, struct ethtool_pauseparam
 static int tg3_set_pauseparam(struct net_device *dev, struct ethtool_pauseparam *epause)
 {
        struct tg3 *tp = netdev_priv(dev);
+       int irq_sync = 0;
   
-       if (netif_running(dev))
+       if (netif_running(dev)) {
                tg3_netif_stop(tp);
+               irq_sync = 1;
+       }
+
+       tg3_full_lock(tp, irq_sync);
 
-       spin_lock_irq(&tp->lock);
-       spin_lock(&tp->tx_lock);
        if (epause->autoneg)
                tp->tg3_flags |= TG3_FLAG_PAUSE_AUTONEG;
        else
@@ -7170,8 +7148,8 @@ static int tg3_set_pauseparam(struct net_device *dev, struct ethtool_pauseparam
                tg3_init_hw(tp);
                tg3_netif_start(tp);
        }
-       spin_unlock(&tp->tx_lock);
-       spin_unlock_irq(&tp->lock);
+
+       tg3_full_unlock(tp);
   
        return 0;
 }
@@ -7192,12 +7170,12 @@ static int tg3_set_rx_csum(struct net_device *dev, u32 data)
                return 0;
        }
   
-       spin_lock_irq(&tp->lock);
+       spin_lock_bh(&tp->lock);
        if (data)
                tp->tg3_flags |= TG3_FLAG_RX_CHECKSUMS;
        else
                tp->tg3_flags &= ~TG3_FLAG_RX_CHECKSUMS;
-       spin_unlock_irq(&tp->lock);
+       spin_unlock_bh(&tp->lock);
   
        return 0;
 }
@@ -7606,8 +7584,6 @@ static int tg3_test_loopback(struct tg3 *tp)
 
        tg3_abort_hw(tp, 1);
 
-       /* Clearing this flag to keep interrupts disabled */
-       tp->tg3_flags &= ~TG3_FLAG_INIT_COMPLETE;
        tg3_reset_hw(tp);
 
        mac_mode = (tp->mac_mode & ~MAC_MODE_PORT_MODE_MASK) |
@@ -7716,11 +7692,14 @@ static void tg3_self_test(struct net_device *dev, struct ethtool_test *etest,
                data[1] = 1;
        }
        if (etest->flags & ETH_TEST_FL_OFFLINE) {
-               if (netif_running(dev))
+               int irq_sync = 0;
+
+               if (netif_running(dev)) {
                        tg3_netif_stop(tp);
+                       irq_sync = 1;
+               }
 
-               spin_lock_irq(&tp->lock);
-               spin_lock(&tp->tx_lock);
+               tg3_full_lock(tp, irq_sync);
 
                tg3_halt(tp, RESET_KIND_SUSPEND, 1);
                tg3_nvram_lock(tp);
@@ -7742,14 +7721,14 @@ static void tg3_self_test(struct net_device *dev, struct ethtool_test *etest,
                        data[4] = 1;
                }
 
-               spin_unlock(&tp->tx_lock);
-               spin_unlock_irq(&tp->lock);
+               tg3_full_unlock(tp);
+
                if (tg3_test_interrupt(tp) != 0) {
                        etest->flags |= ETH_TEST_FL_FAILED;
                        data[5] = 1;
                }
-               spin_lock_irq(&tp->lock);
-               spin_lock(&tp->tx_lock);
+
+               tg3_full_lock(tp, 0);
 
                tg3_halt(tp, RESET_KIND_SHUTDOWN, 1);
                if (netif_running(dev)) {
@@ -7757,8 +7736,8 @@ static void tg3_self_test(struct net_device *dev, struct ethtool_test *etest,
                        tg3_init_hw(tp);
                        tg3_netif_start(tp);
                }
-               spin_unlock(&tp->tx_lock);
-               spin_unlock_irq(&tp->lock);
+
+               tg3_full_unlock(tp);
        }
 }
 
@@ -7779,9 +7758,9 @@ static int tg3_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
                if (tp->tg3_flags2 & TG3_FLG2_PHY_SERDES)
                        break;                  /* We have no PHY */
 
-               spin_lock_irq(&tp->lock);
+               spin_lock_bh(&tp->lock);
                err = tg3_readphy(tp, data->reg_num & 0x1f, &mii_regval);
-               spin_unlock_irq(&tp->lock);
+               spin_unlock_bh(&tp->lock);
 
                data->val_out = mii_regval;
 
@@ -7795,9 +7774,9 @@ static int tg3_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
                if (!capable(CAP_NET_ADMIN))
                        return -EPERM;
 
-               spin_lock_irq(&tp->lock);
+               spin_lock_bh(&tp->lock);
                err = tg3_writephy(tp, data->reg_num & 0x1f, data->val_in);
-               spin_unlock_irq(&tp->lock);
+               spin_unlock_bh(&tp->lock);
 
                return err;
 
@@ -7813,28 +7792,24 @@ static void tg3_vlan_rx_register(struct net_device *dev, struct vlan_group *grp)
 {
        struct tg3 *tp = netdev_priv(dev);
 
-       spin_lock_irq(&tp->lock);
-       spin_lock(&tp->tx_lock);
+       tg3_full_lock(tp, 0);
 
        tp->vlgrp = grp;
 
        /* Update RX_MODE_KEEP_VLAN_TAG bit in RX_MODE register. */
        __tg3_set_rx_mode(dev);
 
-       spin_unlock(&tp->tx_lock);
-       spin_unlock_irq(&tp->lock);
+       tg3_full_unlock(tp);
 }
 
 static void tg3_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid)
 {
        struct tg3 *tp = netdev_priv(dev);
 
-       spin_lock_irq(&tp->lock);
-       spin_lock(&tp->tx_lock);
+       tg3_full_lock(tp, 0);
        if (tp->vlgrp)
                tp->vlgrp->vlan_devices[vid] = NULL;
-       spin_unlock(&tp->tx_lock);
-       spin_unlock_irq(&tp->lock);
+       tg3_full_unlock(tp);
 }
 #endif
 
@@ -10165,24 +10140,19 @@ static int tg3_suspend(struct pci_dev *pdev, pm_message_t state)
 
        del_timer_sync(&tp->timer);
 
-       spin_lock_irq(&tp->lock);
-       spin_lock(&tp->tx_lock);
+       tg3_full_lock(tp, 1);
        tg3_disable_ints(tp);
-       spin_unlock(&tp->tx_lock);
-       spin_unlock_irq(&tp->lock);
+       tg3_full_unlock(tp);
 
        netif_device_detach(dev);
 
-       spin_lock_irq(&tp->lock);
-       spin_lock(&tp->tx_lock);
+       tg3_full_lock(tp, 0);
        tg3_halt(tp, RESET_KIND_SHUTDOWN, 1);
-       spin_unlock(&tp->tx_lock);
-       spin_unlock_irq(&tp->lock);
+       tg3_full_unlock(tp);
 
        err = tg3_set_power_state(tp, pci_choose_state(pdev, state));
        if (err) {
-               spin_lock_irq(&tp->lock);
-               spin_lock(&tp->tx_lock);
+               tg3_full_lock(tp, 0);
 
                tg3_init_hw(tp);
 
@@ -10192,8 +10162,7 @@ static int tg3_suspend(struct pci_dev *pdev, pm_message_t state)
                netif_device_attach(dev);
                tg3_netif_start(tp);
 
-               spin_unlock(&tp->tx_lock);
-               spin_unlock_irq(&tp->lock);
+               tg3_full_unlock(tp);
        }
 
        return err;
@@ -10216,20 +10185,16 @@ static int tg3_resume(struct pci_dev *pdev)
 
        netif_device_attach(dev);
 
-       spin_lock_irq(&tp->lock);
-       spin_lock(&tp->tx_lock);
+       tg3_full_lock(tp, 0);
 
        tg3_init_hw(tp);
 
        tp->timer.expires = jiffies + tp->timer_offset;
        add_timer(&tp->timer);
 
-       tg3_enable_ints(tp);
-
        tg3_netif_start(tp);
 
-       spin_unlock(&tp->tx_lock);
-       spin_unlock_irq(&tp->lock);
+       tg3_full_unlock(tp);
 
        return 0;
 }
index 993f84c93dc41df662f0864e4a6bfb556051512e..99c5f9675a560f06ee89a8f11e1e7cf787cea366 100644 (file)
@@ -2006,17 +2006,31 @@ struct tg3_ethtool_stats {
 struct tg3 {
        /* begin "general, frequently-used members" cacheline section */
 
+       /* If the IRQ handler (which runs lockless) needs to be
+        * quiesced, the following bitmask state is used.  The
+        * SYNC flag is set by non-IRQ context code to initiate
+        * the quiescence.
+        *
+        * When the IRQ handler notices that SYNC is set, it
+        * disables interrupts and returns.
+        *
+        * When all outstanding IRQ handlers have returned after
+        * the SYNC flag has been set, the setter can be assured
+        * that interrupts will no longer get run.
+        *
+        * In this way all SMP driver locks are never acquired
+        * in hw IRQ context, only sw IRQ context or lower.
+        */
+       unsigned int                    irq_sync;
+
        /* SMP locking strategy:
         *
         * lock: Held during all operations except TX packet
         *       processing.
         *
-        * tx_lock: Held during tg3_start_xmit{,_4gbug} and tg3_tx
+        * tx_lock: Held during tg3_start_xmit and tg3_tx
         *
-        * If you want to shut up all asynchronous processing you must
-        * acquire both locks, 'lock' taken before 'tx_lock'.  IRQs must
-        * be disabled to take 'lock' but only softirq disabling is
-        * necessary for acquisition of 'tx_lock'.
+        * Both of these locks are to be held with BH safety.
         */
        spinlock_t                      lock;
        spinlock_t                      indirect_lock;
index 66b94668ddd8a69241d2535ce4726cc74f4d92f2..18c27e1e78840b7832eb4a0d069039843da95be0 100644 (file)
@@ -435,7 +435,7 @@ config VENDOR_SANGOMA
          the driver to support.
 
          If you have one or more of these cards, say M to this option;
-         and read <file:Documentation/networking/wanpipe.txt>.
+         and read <file:Documentation/networking/wan-router.txt>.
 
          To compile this driver as a module, choose M here: the
          module will be called wanpipe.
index fb10a2db63ad018623c2781be4da42db970cf434..d72e0385e4f2690bf90268d080e275b32e56cb50 100644 (file)
@@ -2918,7 +2918,7 @@ static int airo_thread(void *data) {
                        flush_signals(current);
 
                /* make swsusp happy with our thread */
-               try_to_freeze(PF_FREEZE);
+               try_to_freeze();
 
                if (test_bit(JOB_DIE, &ai->flags))
                        break;
index d136b3c8fac99299c9d1b2cf4d7f00dce8d39d16..48e4f04530d886d14d1ad9e3fa0f92a762b40614 100644 (file)
@@ -718,7 +718,7 @@ static int pccardd(void *__skt)
                }
 
                schedule();
-               try_to_freeze(PF_FREEZE);
+               try_to_freeze();
 
                if (!skt->thread)
                        break;
index e939c93a931cf6ea29d3c5be86bf6f81455fb8da..778a324028f4135bdb90bb4e655bac513c17e43d 100644 (file)
@@ -182,7 +182,7 @@ static int pnp_dock_thread(void * unused)
                msleep_interruptible(2000);
 
                if(signal_pending(current)) {
-                       if (try_to_freeze(PF_FREEZE))
+                       if (try_to_freeze())
                                continue;
                        break;
                }
index 96413c2cd1ade4b02137a29f664ac1d82f030914..a86a650f3d6df13684cb07526469d9e8e7d283e3 100644 (file)
@@ -187,6 +187,13 @@ config VMLOGRDR
          *SYMPTOM.
          This driver depends on the IUCV support driver.
 
+config VMCP
+       tristate "Support for the z/VM CP interface (VM only)"
+       help
+         Select this option if you want to be able to interact with the control
+         program on z/VM
+
+
 config MONREADER
        tristate "API for reading z/VM monitor service records"
        depends on IUCV
index ceeb3cf64a16ccc10aa521c550889fc0cad5edcd..6527ff6f470648a3698a774c0222a5c83b6fd1f7 100644 (file)
@@ -176,7 +176,7 @@ dasd_state_known_to_basic(struct dasd_device * device)
                return rc;
 
        /* register 'device' debug area, used for all DBF_DEV_XXX calls */
-       device->debug_area = debug_register(device->cdev->dev.bus_id, 0, 2,
+       device->debug_area = debug_register(device->cdev->dev.bus_id, 1, 2,
                                            8 * sizeof (long));
        debug_register_view(device->debug_area, &debug_sprintf_view);
        debug_set_level(device->debug_area, DBF_EMERG);
@@ -1952,26 +1952,24 @@ dasd_generic_notify(struct ccw_device *cdev, int event)
  * Automatically online either all dasd devices (dasd_autodetect) or
  * all devices specified with dasd= parameters.
  */
+static int
+__dasd_auto_online(struct device *dev, void *data)
+{
+       struct ccw_device *cdev;
+
+       cdev = to_ccwdev(dev);
+       if (dasd_autodetect || dasd_busid_known(cdev->dev.bus_id) == 0)
+               ccw_device_set_online(cdev);
+       return 0;
+}
+
 void
 dasd_generic_auto_online (struct ccw_driver *dasd_discipline_driver)
 {
        struct device_driver *drv;
-       struct device *d, *dev;
-       struct ccw_device *cdev;
 
        drv = get_driver(&dasd_discipline_driver->driver);
-       down_read(&drv->bus->subsys.rwsem);
-       dev = NULL;
-       list_for_each_entry(d, &drv->devices, driver_list) {
-               dev = get_device(d);
-               if (!dev)
-                       continue;
-               cdev = to_ccwdev(dev);
-               if (dasd_autodetect || dasd_busid_known(cdev->dev.bus_id) == 0)
-                       ccw_device_set_online(cdev);
-               put_device(dev);
-       }
-       up_read(&drv->bus->subsys.rwsem);
+       driver_for_each_device(drv, NULL, NULL, __dasd_auto_online);
        put_driver(drv);
 }
 
@@ -1983,7 +1981,7 @@ dasd_init(void)
        init_waitqueue_head(&dasd_init_waitq);
 
        /* register 'common' DASD debug area, used for all DBF_XXX calls */
-       dasd_debug_area = debug_register("dasd", 0, 2, 8 * sizeof (long));
+       dasd_debug_area = debug_register("dasd", 1, 2, 8 * sizeof (long));
        if (dasd_debug_area == NULL) {
                rc = -ENOMEM;
                goto failed;
index d7f19745911f09b4fa391e450a7d18da2d0d60f7..43c34f8c5e685336daeaf87021d4a683720adaa8 100644 (file)
@@ -9,13 +9,14 @@
  *
  * /proc interface for the dasd driver.
  *
- * $Revision: 1.31 $
+ * $Revision: 1.32 $
  */
 
 #include <linux/config.h>
 #include <linux/ctype.h>
 #include <linux/seq_file.h>
 #include <linux/vmalloc.h>
+#include <linux/proc_fs.h>
 
 #include <asm/debug.h>
 #include <asm/uaccess.h>
index 6bc27d52326f11e72e002f364fa53964f318a056..4fde41188996e6ba82231e16592e5f5535e4e3da 100644 (file)
@@ -718,7 +718,7 @@ dcssblk_check_params(void)
                        buf[j-i] = dcssblk_segments[j];
                }
                buf[j-i] = '\0';
-               rc = dcssblk_add_store(dcssblk_root_dev, buf, j-i);
+               rc = dcssblk_add_store(dcssblk_root_dev, NULL, buf, j-i);
                if ((rc >= 0) && (dcssblk_segments[j] == '(')) {
                        for (k = 0; buf[k] != '\0'; k++)
                                buf[k] = toupper(buf[k]);
@@ -728,7 +728,7 @@ dcssblk_check_params(void)
                                up_read(&dcssblk_devices_sem);
                                if (dev_info)
                                        dcssblk_shared_store(&dev_info->dev,
-                                                            "0\n", 2);
+                                                            NULL, "0\n", 2);
                        }
                }
                while ((dcssblk_segments[j] != ',') &&
index 14e8cce9f862a4bc92e53121da52fa7c0b703781..6377a96735df87ccbd5d506b56ee964817940f9c 100644 (file)
@@ -19,6 +19,7 @@ obj-$(CONFIG_SCLP_CPI) += sclp_cpi.o
 
 obj-$(CONFIG_ZVM_WATCHDOG) += vmwatchdog.o
 obj-$(CONFIG_VMLOGRDR) += vmlogrdr.o
+obj-$(CONFIG_VMCP) += vmcp.o
 
 tape-$(CONFIG_S390_TAPE_BLOCK) += tape_block.o
 tape-$(CONFIG_PROC_FS) += tape_proc.o
index 022f17bff7314e2f2ce140ddfcfc709eb248865f..f11a67fda40e55a4a009ff04f16a6217b8fa76c1 100644 (file)
@@ -860,8 +860,8 @@ con3215_init(void)
 
        /* Set the console mode for VM */
        if (MACHINE_IS_VM) {
-               cpcmd("TERM CONMODE 3215", NULL, 0);
-               cpcmd("TERM AUTOCR OFF", NULL, 0);
+               cpcmd("TERM CONMODE 3215", NULL, 0, NULL);
+               cpcmd("TERM AUTOCR OFF", NULL, 0, NULL);
        }
 
        /* allocate 3215 request structures */
index d52fb57a6b197d64efa9c418bc9e863b2b3a36dd..fc7a213e591f5962f78084bbb7416db5a402aee9 100644 (file)
@@ -591,8 +591,8 @@ con3270_init(void)
 
        /* Set the console mode for VM */
        if (MACHINE_IS_VM) {
-               cpcmd("TERM CONMODE 3270", 0, 0);
-               cpcmd("TERM AUTOCR OFF", 0, 0);
+               cpcmd("TERM CONMODE 3270", NULL, 0, NULL);
+               cpcmd("TERM AUTOCR OFF", NULL, 0, NULL);
        }
 
        cdev = ccw_device_probe_console();
index 480ec87976fb0db5a7d1afd472ce5a696d7cb698..20be88e91fa1a7abff383f8e0aac20976f8beac0 100644 (file)
@@ -1351,13 +1351,13 @@ tape_34xx_init (void)
 {
        int rc;
 
-       TAPE_DBF_AREA = debug_register ( "tape_34xx", 1, 2, 4*sizeof(long));
+       TAPE_DBF_AREA = debug_register ( "tape_34xx", 2, 2, 4*sizeof(long));
        debug_register_view(TAPE_DBF_AREA, &debug_sprintf_view);
 #ifdef DBF_LIKE_HELL
        debug_set_level(TAPE_DBF_AREA, 6);
 #endif
 
-       DBF_EVENT(3, "34xx init: $Revision: 1.21 $\n");
+       DBF_EVENT(3, "34xx init: $Revision: 1.23 $\n");
        /* Register driver for 3480/3490 tapes. */
        rc = ccw_driver_register(&tape_34xx_driver);
        if (rc)
@@ -1378,7 +1378,7 @@ tape_34xx_exit(void)
 MODULE_DEVICE_TABLE(ccw, tape_34xx_ids);
 MODULE_AUTHOR("(C) 2001-2002 IBM Deutschland Entwicklung GmbH");
 MODULE_DESCRIPTION("Linux on zSeries channel attached 3480 tape "
-                  "device driver ($Revision: 1.21 $)");
+                  "device driver ($Revision: 1.23 $)");
 MODULE_LICENSE("GPL");
 
 module_init(tape_34xx_init);
index b4df4a515b1256056b5bc7708b12708b177154a4..0597aa0e27ee00c48928256813674c7704df50d1 100644 (file)
@@ -1186,7 +1186,7 @@ tape_mtop(struct tape_device *device, int mt_op, int mt_count)
 static int
 tape_init (void)
 {
-       TAPE_DBF_AREA = debug_register ( "tape", 1, 2, 4*sizeof(long));
+       TAPE_DBF_AREA = debug_register ( "tape", 2, 2, 4*sizeof(long));
        debug_register_view(TAPE_DBF_AREA, &debug_sprintf_view);
 #ifdef DBF_LIKE_HELL
        debug_set_level(TAPE_DBF_AREA, 6);
index 801d17cca34ea06c0e4a3ed9584668002085292c..5fec0a10cc3d089b172da95a59acbe6aaca7e744 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/module.h>
 #include <linux/vmalloc.h>
 #include <linux/seq_file.h>
+#include <linux/proc_fs.h>
 
 #define TAPE_DBF_AREA  tape_core_dbf
 
diff --git a/drivers/s390/char/vmcp.c b/drivers/s390/char/vmcp.c
new file mode 100644 (file)
index 0000000..7f11a60
--- /dev/null
@@ -0,0 +1,219 @@
+/*
+ * Copyright (C) 2004,2005 IBM Corporation
+ * Interface implementation for communication with the v/VM control program
+ * Author(s): Christian Borntraeger <cborntra@de.ibm.com>
+ *
+ *
+ * z/VMs CP offers the possibility to issue commands via the diagnose code 8
+ * this driver implements a character device that issues these commands and
+ * returns the answer of CP.
+
+ * The idea of this driver is based on cpint from Neale Ferguson and #CP in CMS
+ */
+
+#include <linux/fs.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/miscdevice.h>
+#include <linux/module.h>
+#include <asm/cpcmd.h>
+#include <asm/debug.h>
+#include <asm/uaccess.h>
+#include "vmcp.h"
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Christian Borntraeger <cborntra@de.ibm.com>");
+MODULE_DESCRIPTION("z/VM CP interface");
+
+static debug_info_t *vmcp_debug;
+
+static int vmcp_open(struct inode *inode, struct file *file)
+{
+       struct vmcp_session *session;
+
+       if (!capable(CAP_SYS_ADMIN))
+               return -EPERM;
+
+       session = kmalloc(sizeof(*session), GFP_KERNEL);
+       if (!session)
+               return -ENOMEM;
+       session->bufsize = PAGE_SIZE;
+       session->response = NULL;
+       session->resp_size = 0;
+       init_MUTEX(&session->mutex);
+       file->private_data = session;
+       return nonseekable_open(inode, file);
+}
+
+static int vmcp_release(struct inode *inode, struct file *file)
+{
+       struct vmcp_session *session;
+
+       session = (struct vmcp_session *)file->private_data;
+       file->private_data = NULL;
+       free_pages((unsigned long)session->response, get_order(session->bufsize));
+       kfree(session);
+       return 0;
+}
+
+static ssize_t
+vmcp_read(struct file *file, char __user * buff, size_t count, loff_t * ppos)
+{
+       size_t tocopy;
+       struct vmcp_session *session;
+
+       session = (struct vmcp_session *)file->private_data;
+       if (down_interruptible(&session->mutex))
+               return -ERESTARTSYS;
+       if (!session->response) {
+               up(&session->mutex);
+               return 0;
+       }
+       if (*ppos > session->resp_size) {
+               up(&session->mutex);
+               return 0;
+       }
+       tocopy = min(session->resp_size - (size_t) (*ppos), count);
+       tocopy = min(tocopy,session->bufsize - (size_t) (*ppos));
+
+       if (copy_to_user(buff, session->response + (*ppos), tocopy)) {
+               up(&session->mutex);
+               return -EFAULT;
+       }
+       up(&session->mutex);
+       *ppos += tocopy;
+       return tocopy;
+}
+
+static ssize_t
+vmcp_write(struct file *file, const char __user * buff, size_t count,
+          loff_t * ppos)
+{
+       char *cmd;
+       struct vmcp_session *session;
+
+       if (count > 240)
+               return -EINVAL;
+       cmd = kmalloc(count + 1, GFP_KERNEL);
+       if (!cmd)
+               return -ENOMEM;
+       if (copy_from_user(cmd, buff, count)) {
+               kfree(cmd);
+               return -EFAULT;
+       }
+       cmd[count] = '\0';
+       session = (struct vmcp_session *)file->private_data;
+       if (down_interruptible(&session->mutex))
+               return -ERESTARTSYS;
+       if (!session->response)
+               session->response = (char *)__get_free_pages(GFP_KERNEL
+                                               | __GFP_REPEAT  | GFP_DMA,
+                                               get_order(session->bufsize));
+       if (!session->response) {
+               up(&session->mutex);
+               kfree(cmd);
+               return -ENOMEM;
+       }
+       debug_text_event(vmcp_debug, 1, cmd);
+       session->resp_size = cpcmd(cmd, session->response,
+                                  session->bufsize,
+                                  &session->resp_code);
+       up(&session->mutex);
+       kfree(cmd);
+       *ppos = 0;              /* reset the file pointer after a command */
+       return count;
+}
+
+
+/*
+ * These ioctls are available, as the semantics of the diagnose 8 call
+ * does not fit very well into a Linux call. Diagnose X'08' is described in
+ * CP Programming Services SC24-6084-00
+ *
+ * VMCP_GETCODE: gives the CP return code back to user space
+ * VMCP_SETBUF: sets the response buffer for the next write call. diagnose 8
+ * expects adjacent pages in real storage and to make matters worse, we
+ * dont know the size of the response. Therefore we default to PAGESIZE and
+ * let userspace to change the response size, if userspace expects a bigger
+ * response
+ */
+static long vmcp_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+{
+       struct vmcp_session *session;
+       int temp;
+
+       session = (struct vmcp_session *)file->private_data;
+       if (down_interruptible(&session->mutex))
+               return -ERESTARTSYS;
+       switch (cmd) {
+       case VMCP_GETCODE:
+               temp = session->resp_code;
+               up(&session->mutex);
+               return put_user(temp, (int __user *)arg);
+       case VMCP_SETBUF:
+               free_pages((unsigned long)session->response,
+                               get_order(session->bufsize));
+               session->response=NULL;
+               temp = get_user(session->bufsize, (int __user *)arg);
+               if (get_order(session->bufsize) > 8) {
+                       session->bufsize = PAGE_SIZE;
+                       temp = -EINVAL;
+               }
+               up(&session->mutex);
+               return temp;
+       case VMCP_GETSIZE:
+               temp = session->resp_size;
+               up(&session->mutex);
+               return put_user(temp, (int __user *)arg);
+       default:
+               up(&session->mutex);
+               return -ENOIOCTLCMD;
+       }
+}
+
+static struct file_operations vmcp_fops = {
+       .owner          = THIS_MODULE,
+       .open           = &vmcp_open,
+       .release        = &vmcp_release,
+       .read           = &vmcp_read,
+       .llseek         = &no_llseek,
+       .write          = &vmcp_write,
+       .unlocked_ioctl = &vmcp_ioctl,
+       .compat_ioctl   = &vmcp_ioctl
+};
+
+static struct miscdevice vmcp_dev = {
+       .name   = "vmcp",
+       .minor  = MISC_DYNAMIC_MINOR,
+       .fops   = &vmcp_fops,
+};
+
+static int __init vmcp_init(void)
+{
+       int ret;
+
+       if (!MACHINE_IS_VM) {
+               printk(KERN_WARNING
+                      "z/VM CP interface is only available under z/VM\n");
+               return -ENODEV;
+       }
+       ret = misc_register(&vmcp_dev);
+       if (!ret)
+               printk(KERN_INFO "z/VM CP interface loaded\n");
+       else
+               printk(KERN_WARNING
+                      "z/VM CP interface not loaded. Could not register misc device.\n");
+       vmcp_debug = debug_register("vmcp", 1, 1, 240);
+       debug_register_view(vmcp_debug, &debug_hex_ascii_view);
+       return ret;
+}
+
+static void __exit vmcp_exit(void)
+{
+       WARN_ON(misc_deregister(&vmcp_dev) != 0);
+       debug_unregister(vmcp_debug);
+       printk(KERN_INFO "z/VM CP interface unloaded.\n");
+}
+
+module_init(vmcp_init);
+module_exit(vmcp_exit);
diff --git a/drivers/s390/char/vmcp.h b/drivers/s390/char/vmcp.h
new file mode 100644 (file)
index 0000000..87389e7
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2004, 2005 IBM Corporation
+ * Interface implementation for communication with the v/VM control program
+ * Version 1.0
+ * Author(s): Christian Borntraeger <cborntra@de.ibm.com>
+ *
+ *
+ * z/VMs CP offers the possibility to issue commands via the diagnose code 8
+ * this driver implements a character device that issues these commands and
+ * returns the answer of CP.
+ *
+ * The idea of this driver is based on cpint from Neale Ferguson
+ */
+
+#include <asm/semaphore.h>
+#include <linux/ioctl.h>
+
+#define VMCP_GETCODE _IOR(0x10, 1, int)
+#define VMCP_SETBUF _IOW(0x10, 2, int)
+#define VMCP_GETSIZE _IOR(0x10, 3, int)
+
+struct vmcp_session {
+       unsigned int bufsize;
+       char *response;
+       int resp_size;
+       int resp_code;
+       /* As we use copy_from/to_user, which might     *
+        * sleep and cannot use a spinlock              */
+       struct semaphore mutex;
+};
index f7717327d15e1f7a666ac243ae0b04b8d2c63dc1..491f00c032e88dade6b7fa5ac5af0cea9bc1e4d7 100644 (file)
@@ -236,7 +236,7 @@ vmlogrdr_get_recording_class_AB(void) {
        int len,i;
 
        printk (KERN_DEBUG "vmlogrdr: query command: %s\n", cp_command);
-       cpcmd(cp_command, cp_response, sizeof(cp_response));
+       cpcmd(cp_command, cp_response, sizeof(cp_response), NULL);
        printk (KERN_DEBUG "vmlogrdr: response: %s", cp_response);
        len = strnlen(cp_response,sizeof(cp_response));
        // now the parsing
@@ -288,7 +288,7 @@ vmlogrdr_recording(struct vmlogrdr_priv_t * logptr, int action, int purge) {
 
                printk (KERN_DEBUG "vmlogrdr: recording command: %s\n",
                        cp_command);
-               cpcmd(cp_command, cp_response, sizeof(cp_response));
+               cpcmd(cp_command, cp_response, sizeof(cp_response), NULL);
                printk (KERN_DEBUG "vmlogrdr: recording response: %s",
                        cp_response);
        }
@@ -301,7 +301,7 @@ vmlogrdr_recording(struct vmlogrdr_priv_t * logptr, int action, int purge) {
                qid_string);
 
        printk (KERN_DEBUG "vmlogrdr: recording command: %s\n", cp_command);
-       cpcmd(cp_command, cp_response, sizeof(cp_response));
+       cpcmd(cp_command, cp_response, sizeof(cp_response), NULL);
        printk (KERN_DEBUG "vmlogrdr: recording response: %s",
                cp_response);
        /* The recording command will usually answer with 'Command complete'
@@ -607,7 +607,7 @@ vmlogrdr_purge_store(struct device * dev, struct device_attribute *attr, const c
                         priv->recording_name);
 
        printk (KERN_DEBUG "vmlogrdr: recording command: %s\n", cp_command);
-       cpcmd(cp_command, cp_response, sizeof(cp_response));
+       cpcmd(cp_command, cp_response, sizeof(cp_response), NULL);
        printk (KERN_DEBUG "vmlogrdr: recording response: %s",
                cp_response);
 
@@ -682,7 +682,7 @@ vmlogrdr_recording_status_show(struct device_driver *driver, char *buf) {
        char cp_command[] = "QUERY RECORDING ";
        int len;
 
-       cpcmd(cp_command, buf, 4096);
+       cpcmd(cp_command, buf, 4096, NULL);
        len = strlen(buf);
        return len;
 }
index 306525acb9f829d8a51e700e0ac458a4cccaf1a2..91ea8e4777f340b2c47fe76ac5f68cab43e54ffa 100644 (file)
@@ -403,34 +403,22 @@ ccwgroup_driver_register (struct ccwgroup_driver *cdriver)
        return driver_register(&cdriver->driver);
 }
 
-static inline struct device *
-__get_next_ccwgroup_device(struct device_driver *drv)
+static int
+__ccwgroup_driver_unregister_device(struct device *dev, void *data)
 {
-       struct device *dev, *d;
-
-       down_read(&drv->bus->subsys.rwsem);
-       dev = NULL;
-       list_for_each_entry(d, &drv->devices, driver_list) {
-               dev = get_device(d);
-               if (dev)
-                       break;
-       }
-       up_read(&drv->bus->subsys.rwsem);
-       return dev;
+       __ccwgroup_remove_symlinks(to_ccwgroupdev(dev));
+       device_unregister(dev);
+       put_device(dev);
+       return 0;
 }
 
 void
 ccwgroup_driver_unregister (struct ccwgroup_driver *cdriver)
 {
-       struct device *dev;
-
        /* We don't want ccwgroup devices to live longer than their driver. */
        get_driver(&cdriver->driver);
-       while ((dev = __get_next_ccwgroup_device(&cdriver->driver))) {
-               __ccwgroup_remove_symlinks(to_ccwgroupdev(dev));
-               device_unregister(dev);
-               put_device(dev);
-       };
+       driver_for_each_device(&cdriver->driver, NULL, NULL,
+                              __ccwgroup_driver_unregister_device);
        put_driver(&cdriver->driver);
        driver_unregister(&cdriver->driver);
 }
@@ -449,7 +437,7 @@ __ccwgroup_get_gdev_by_cdev(struct ccw_device *cdev)
        if (cdev->dev.driver_data) {
                gdev = (struct ccwgroup_device *)cdev->dev.driver_data;
                if (get_device(&gdev->dev)) {
-                       if (!list_empty(&gdev->dev.node))
+                       if (klist_node_attached(&gdev->dev.knode_bus))
                                return gdev;
                        put_device(&gdev->dev);
                }
index 1d9b3f18d8debddcdd63464295f3fce03ee9c611..ea813bdce1d63a8617ddb2881b98a679bfb17445 100644 (file)
@@ -1,7 +1,7 @@
 /*
  *  drivers/s390/cio/cio.c
  *   S/390 common I/O routines -- low level i/o calls
- *   $Revision: 1.133 $
+ *   $Revision: 1.134 $
  *
  *    Copyright (C) 1999-2002 IBM Deutschland Entwicklung GmbH,
  *                           IBM Corporation
@@ -63,17 +63,17 @@ __setup ("cio_msg=", cio_setup);
 static int __init
 cio_debug_init (void)
 {
-       cio_debug_msg_id = debug_register ("cio_msg", 4, 4, 16*sizeof (long));
+       cio_debug_msg_id = debug_register ("cio_msg", 16, 4, 16*sizeof (long));
        if (!cio_debug_msg_id)
                goto out_unregister;
        debug_register_view (cio_debug_msg_id, &debug_sprintf_view);
        debug_set_level (cio_debug_msg_id, 2);
-       cio_debug_trace_id = debug_register ("cio_trace", 4, 4, 8);
+       cio_debug_trace_id = debug_register ("cio_trace", 16, 4, 8);
        if (!cio_debug_trace_id)
                goto out_unregister;
        debug_register_view (cio_debug_trace_id, &debug_hex_ascii_view);
        debug_set_level (cio_debug_trace_id, 2);
-       cio_debug_crw_id = debug_register ("cio_crw", 2, 4, 16*sizeof (long));
+       cio_debug_crw_id = debug_register ("cio_crw", 4, 4, 16*sizeof (long));
        if (!cio_debug_crw_id)
                goto out_unregister;
        debug_register_view (cio_debug_crw_id, &debug_sprintf_view);
index 87bd70eeabed78f416e36c0a8d13480b8f7f10b9..555119cacc279c07c59372892fba6d4983153a13 100644 (file)
@@ -128,34 +128,28 @@ css_probe_device(int irq)
        return ret;
 }
 
+static int
+check_subchannel(struct device * dev, void * data)
+{
+       struct subchannel *sch;
+       int irq = (unsigned long)data;
+
+       sch = to_subchannel(dev);
+       return (sch->irq == irq);
+}
+
 struct subchannel *
 get_subchannel_by_schid(int irq)
 {
-       struct subchannel *sch;
-       struct list_head *entry;
        struct device *dev;
 
-       if (!get_bus(&css_bus_type))
-               return NULL;
-       down_read(&css_bus_type.subsys.rwsem);
-       sch = NULL;
-       list_for_each(entry, &css_bus_type.devices.list) {
-               dev = get_device(container_of(entry,
-                                             struct device, bus_list));
-               if (!dev)
-                       continue;
-               sch = to_subchannel(dev);
-               if (sch->irq == irq)
-                       break;
-               put_device(dev);
-               sch = NULL;
-       }
-       up_read(&css_bus_type.subsys.rwsem);
-       put_bus(&css_bus_type);
+       dev = bus_find_device(&css_bus_type, NULL,
+                             (void *)(unsigned long)irq, check_subchannel);
 
-       return sch;
+       return dev ? to_subchannel(dev) : NULL;
 }
 
+
 static inline int
 css_get_subchannel_status(struct subchannel *sch, int schid)
 {
index 809e1108a06ef40c00603133d98a38bcc9eaceba..14c76f5e417708ebbd22321ebda46ed9cd5d79b3 100644 (file)
@@ -514,36 +514,39 @@ ccw_device_register(struct ccw_device *cdev)
        return ret;
 }
 
+struct match_data {
+       unsigned int  devno;
+       struct ccw_device * sibling;
+};
+
+static int
+match_devno(struct device * dev, void * data)
+{
+       struct match_data * d = (struct match_data *)data;
+       struct ccw_device * cdev;
+
+       cdev = to_ccwdev(dev);
+       if ((cdev->private->state == DEV_STATE_DISCONNECTED) &&
+           (cdev->private->devno == d->devno) &&
+           (cdev != d->sibling)) {
+               cdev->private->state = DEV_STATE_NOT_OPER;
+               return 1;
+       }
+       return 0;
+}
+
 static struct ccw_device *
 get_disc_ccwdev_by_devno(unsigned int devno, struct ccw_device *sibling)
 {
-       struct ccw_device *cdev;
-       struct list_head *entry;
        struct device *dev;
+       struct match_data data = {
+               .devno  = devno,
+               .sibling = sibling,
+       };
 
-       if (!get_bus(&ccw_bus_type))
-               return NULL;
-       down_read(&ccw_bus_type.subsys.rwsem);
-       cdev = NULL;
-       list_for_each(entry, &ccw_bus_type.devices.list) {
-               dev = get_device(container_of(entry,
-                                             struct device, bus_list));
-               if (!dev)
-                       continue;
-               cdev = to_ccwdev(dev);
-               if ((cdev->private->state == DEV_STATE_DISCONNECTED) &&
-                   (cdev->private->devno == devno) &&
-                   (cdev != sibling)) {
-                       cdev->private->state = DEV_STATE_NOT_OPER;
-                       break;
-               }
-               put_device(dev);
-               cdev = NULL;
-       }
-       up_read(&ccw_bus_type.subsys.rwsem);
-       put_bus(&ccw_bus_type);
+       dev = bus_find_device(&css_bus_type, NULL, &data, match_devno);
 
-       return cdev;
+       return dev ? to_ccwdev(dev) : NULL;
 }
 
 static void
@@ -647,7 +650,7 @@ io_subchannel_register(void *data)
        cdev = (struct ccw_device *) data;
        sch = to_subchannel(cdev->dev.parent);
 
-       if (!list_empty(&sch->dev.children)) {
+       if (klist_node_attached(&cdev->dev.knode_parent)) {
                bus_rescan_devices(&ccw_bus_type);
                goto out;
        }
@@ -1019,30 +1022,29 @@ ccw_device_probe_console(void)
 /*
  * get ccw_device matching the busid, but only if owned by cdrv
  */
+static int
+__ccwdev_check_busid(struct device *dev, void *id)
+{
+       char *bus_id;
+
+       bus_id = (char *)id;
+
+       return (strncmp(bus_id, dev->bus_id, BUS_ID_SIZE) == 0);
+}
+
+
 struct ccw_device *
 get_ccwdev_by_busid(struct ccw_driver *cdrv, const char *bus_id)
 {
-       struct device *d, *dev;
+       struct device *dev;
        struct device_driver *drv;
 
        drv = get_driver(&cdrv->driver);
        if (!drv)
-               return 0;
-
-       down_read(&drv->bus->subsys.rwsem);
-
-       dev = NULL;
-       list_for_each_entry(d, &drv->devices, driver_list) {
-               dev = get_device(d);
+               return NULL;
 
-               if (dev && !strncmp(bus_id, dev->bus_id, BUS_ID_SIZE))
-                       break;
-               else if (dev) {
-                       put_device(dev);
-                       dev = NULL;
-               }
-       }
-       up_read(&drv->bus->subsys.rwsem);
+       dev = driver_find_device(drv, NULL, (void *)bus_id,
+                                __ccwdev_check_busid);
        put_driver(drv);
 
        return dev ? to_ccwdev(dev) : 0;
index bbe9f45d1438e3b7a0c868af5cf76765dcbbb862..82194c4eadfb59844511be40adff6a5f1fed94a6 100644 (file)
@@ -56,7 +56,7 @@
 #include "ioasm.h"
 #include "chsc.h"
 
-#define VERSION_QDIO_C "$Revision: 1.98 $"
+#define VERSION_QDIO_C "$Revision: 1.101 $"
 
 /****************** MODULE PARAMETER VARIABLES ********************/
 MODULE_AUTHOR("Utz Bacher <utz.bacher@de.ibm.com>");
@@ -3342,7 +3342,7 @@ static int
 qdio_register_dbf_views(void)
 {
        qdio_dbf_setup=debug_register(QDIO_DBF_SETUP_NAME,
-                                     QDIO_DBF_SETUP_INDEX,
+                                     QDIO_DBF_SETUP_PAGES,
                                      QDIO_DBF_SETUP_NR_AREAS,
                                      QDIO_DBF_SETUP_LEN);
        if (!qdio_dbf_setup)
@@ -3351,7 +3351,7 @@ qdio_register_dbf_views(void)
        debug_set_level(qdio_dbf_setup,QDIO_DBF_SETUP_LEVEL);
 
        qdio_dbf_sbal=debug_register(QDIO_DBF_SBAL_NAME,
-                                    QDIO_DBF_SBAL_INDEX,
+                                    QDIO_DBF_SBAL_PAGES,
                                     QDIO_DBF_SBAL_NR_AREAS,
                                     QDIO_DBF_SBAL_LEN);
        if (!qdio_dbf_sbal)
@@ -3361,7 +3361,7 @@ qdio_register_dbf_views(void)
        debug_set_level(qdio_dbf_sbal,QDIO_DBF_SBAL_LEVEL);
 
        qdio_dbf_sense=debug_register(QDIO_DBF_SENSE_NAME,
-                                     QDIO_DBF_SENSE_INDEX,
+                                     QDIO_DBF_SENSE_PAGES,
                                      QDIO_DBF_SENSE_NR_AREAS,
                                      QDIO_DBF_SENSE_LEN);
        if (!qdio_dbf_sense)
@@ -3371,7 +3371,7 @@ qdio_register_dbf_views(void)
        debug_set_level(qdio_dbf_sense,QDIO_DBF_SENSE_LEVEL);
 
        qdio_dbf_trace=debug_register(QDIO_DBF_TRACE_NAME,
-                                     QDIO_DBF_TRACE_INDEX,
+                                     QDIO_DBF_TRACE_PAGES,
                                      QDIO_DBF_TRACE_NR_AREAS,
                                      QDIO_DBF_TRACE_LEN);
        if (!qdio_dbf_trace)
@@ -3382,7 +3382,7 @@ qdio_register_dbf_views(void)
 
 #ifdef CONFIG_QDIO_DEBUG
         qdio_dbf_slsb_out=debug_register(QDIO_DBF_SLSB_OUT_NAME,
-                                         QDIO_DBF_SLSB_OUT_INDEX,
+                                         QDIO_DBF_SLSB_OUT_PAGES,
                                          QDIO_DBF_SLSB_OUT_NR_AREAS,
                                          QDIO_DBF_SLSB_OUT_LEN);
         if (!qdio_dbf_slsb_out)
@@ -3391,7 +3391,7 @@ qdio_register_dbf_views(void)
         debug_set_level(qdio_dbf_slsb_out,QDIO_DBF_SLSB_OUT_LEVEL);
 
         qdio_dbf_slsb_in=debug_register(QDIO_DBF_SLSB_IN_NAME,
-                                        QDIO_DBF_SLSB_IN_INDEX,
+                                        QDIO_DBF_SLSB_IN_PAGES,
                                         QDIO_DBF_SLSB_IN_NR_AREAS,
                                         QDIO_DBF_SLSB_IN_LEN);
         if (!qdio_dbf_slsb_in)
index b6daadac4e8b65a0091e3134c33e0029bceba065..6b8aa6a852bedb5230a9964edefca539da3c688a 100644 (file)
@@ -3,7 +3,7 @@
 
 #include <asm/page.h>
 
-#define VERSION_CIO_QDIO_H "$Revision: 1.32 $"
+#define VERSION_CIO_QDIO_H "$Revision: 1.33 $"
 
 #ifdef CONFIG_QDIO_DEBUG
 #define QDIO_VERBOSE_LEVEL 9
@@ -132,7 +132,7 @@ enum qdio_irq_states {
 
 #define QDIO_DBF_SETUP_NAME "qdio_setup"
 #define QDIO_DBF_SETUP_LEN 8
-#define QDIO_DBF_SETUP_INDEX 2
+#define QDIO_DBF_SETUP_PAGES 4
 #define QDIO_DBF_SETUP_NR_AREAS 1
 #ifdef CONFIG_QDIO_DEBUG
 #define QDIO_DBF_SETUP_LEVEL 6
@@ -142,7 +142,7 @@ enum qdio_irq_states {
 
 #define QDIO_DBF_SBAL_NAME "qdio_labs" /* sbal */
 #define QDIO_DBF_SBAL_LEN 256
-#define QDIO_DBF_SBAL_INDEX 2
+#define QDIO_DBF_SBAL_PAGES 4
 #define QDIO_DBF_SBAL_NR_AREAS 2
 #ifdef CONFIG_QDIO_DEBUG
 #define QDIO_DBF_SBAL_LEVEL 6
@@ -154,16 +154,16 @@ enum qdio_irq_states {
 #define QDIO_DBF_TRACE_LEN 8
 #define QDIO_DBF_TRACE_NR_AREAS 2
 #ifdef CONFIG_QDIO_DEBUG
-#define QDIO_DBF_TRACE_INDEX 4
+#define QDIO_DBF_TRACE_PAGES 16
 #define QDIO_DBF_TRACE_LEVEL 4 /* -------- could be even more verbose here */
 #else /* CONFIG_QDIO_DEBUG */
-#define QDIO_DBF_TRACE_INDEX 2
+#define QDIO_DBF_TRACE_PAGES 4
 #define QDIO_DBF_TRACE_LEVEL 2
 #endif /* CONFIG_QDIO_DEBUG */
 
 #define QDIO_DBF_SENSE_NAME "qdio_sense"
 #define QDIO_DBF_SENSE_LEN 64
-#define QDIO_DBF_SENSE_INDEX 1
+#define QDIO_DBF_SENSE_PAGES 2
 #define QDIO_DBF_SENSE_NR_AREAS 1
 #ifdef CONFIG_QDIO_DEBUG
 #define QDIO_DBF_SENSE_LEVEL 6
@@ -176,13 +176,13 @@ enum qdio_irq_states {
 
 #define QDIO_DBF_SLSB_OUT_NAME "qdio_slsb_out"
 #define QDIO_DBF_SLSB_OUT_LEN QDIO_MAX_BUFFERS_PER_Q
-#define QDIO_DBF_SLSB_OUT_INDEX 8
+#define QDIO_DBF_SLSB_OUT_PAGES 256
 #define QDIO_DBF_SLSB_OUT_NR_AREAS 1
 #define QDIO_DBF_SLSB_OUT_LEVEL 6
 
 #define QDIO_DBF_SLSB_IN_NAME "qdio_slsb_in"
 #define QDIO_DBF_SLSB_IN_LEN QDIO_MAX_BUFFERS_PER_Q
-#define QDIO_DBF_SLSB_IN_INDEX 8
+#define QDIO_DBF_SLSB_IN_PAGES 256
 #define QDIO_DBF_SLSB_IN_NR_AREAS 1
 #define QDIO_DBF_SLSB_IN_LEVEL 6
 #endif /* CONFIG_QDIO_DEBUG */
index a99927d54ebb5bb1c40efa9ec20b36169a511d4d..60440dbe3a2764168056bf2b48acbaaf4d64cecb 100644 (file)
@@ -146,8 +146,8 @@ claw_unregister_debug_facility(void)
 static int
 claw_register_debug_facility(void)
 {
-       claw_dbf_setup = debug_register("claw_setup", 1, 1, 8);
-       claw_dbf_trace = debug_register("claw_trace", 1, 2, 8);
+       claw_dbf_setup = debug_register("claw_setup", 2, 1, 8);
+       claw_dbf_trace = debug_register("claw_trace", 2, 2, 8);
        if (claw_dbf_setup == NULL || claw_dbf_trace == NULL) {
                printk(KERN_WARNING "Not enough memory for debug facility.\n");
                claw_unregister_debug_facility();
index 2c86bfa11b2f2bb6b2f2eb4ebddc9c8948406fca..0e2a8bb930322ec9d4f6aacc4c8c5924df8a04ad 100644 (file)
@@ -1,6 +1,6 @@
 /*
  *
- * linux/drivers/s390/net/ctcdbug.c ($Revision: 1.4 $)
+ * linux/drivers/s390/net/ctcdbug.c ($Revision: 1.6 $)
  *
  * CTC / ESCON network driver - s390 dbf exploit.
  *
@@ -9,7 +9,7 @@
  *    Author(s): Original Code written by
  *                       Peter Tiedemann (ptiedem@de.ibm.com)
  *
- *    $Revision: 1.4 $  $Date: 2004/08/04 10:11:59 $
+ *    $Revision: 1.6 $  $Date: 2005/05/11 08:10:17 $
  *
  * 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
@@ -51,15 +51,15 @@ int
 ctc_register_dbf_views(void)
 {
        ctc_dbf_setup = debug_register(CTC_DBF_SETUP_NAME,
-                                       CTC_DBF_SETUP_INDEX,
+                                       CTC_DBF_SETUP_PAGES,
                                        CTC_DBF_SETUP_NR_AREAS,
                                        CTC_DBF_SETUP_LEN);
        ctc_dbf_data = debug_register(CTC_DBF_DATA_NAME,
-                                      CTC_DBF_DATA_INDEX,
+                                      CTC_DBF_DATA_PAGES,
                                       CTC_DBF_DATA_NR_AREAS,
                                       CTC_DBF_DATA_LEN);
        ctc_dbf_trace = debug_register(CTC_DBF_TRACE_NAME,
-                                       CTC_DBF_TRACE_INDEX,
+                                       CTC_DBF_TRACE_PAGES,
                                        CTC_DBF_TRACE_NR_AREAS,
                                        CTC_DBF_TRACE_LEN);
 
index 7fe2ebd1792dc6de5cbe1ee4a30af420fd76d8fb..7d6afa1627c3534cc86f1805f9f4da45c92fa47e 100644 (file)
@@ -1,6 +1,6 @@
 /*
  *
- * linux/drivers/s390/net/ctcdbug.h ($Revision: 1.5 $)
+ * linux/drivers/s390/net/ctcdbug.h ($Revision: 1.6 $)
  *
  * CTC / ESCON network driver - s390 dbf exploit.
  *
@@ -9,7 +9,7 @@
  *    Author(s): Original Code written by
  *                       Peter Tiedemann (ptiedem@de.ibm.com)
  *
- *    $Revision: 1.5 $  $Date: 2005/02/27 19:46:44 $
+ *    $Revision: 1.6 $  $Date: 2005/05/11 08:10:17 $
  *
  * 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
  */
 #define CTC_DBF_SETUP_NAME "ctc_setup"
 #define CTC_DBF_SETUP_LEN 16
-#define CTC_DBF_SETUP_INDEX 3
+#define CTC_DBF_SETUP_PAGES 8
 #define CTC_DBF_SETUP_NR_AREAS 1
 #define CTC_DBF_SETUP_LEVEL 3
 
 #define CTC_DBF_DATA_NAME "ctc_data"
 #define CTC_DBF_DATA_LEN 128
-#define CTC_DBF_DATA_INDEX 3
+#define CTC_DBF_DATA_PAGES 8
 #define CTC_DBF_DATA_NR_AREAS 1
 #define CTC_DBF_DATA_LEVEL 3
 
 #define CTC_DBF_TRACE_NAME "ctc_trace"
 #define CTC_DBF_TRACE_LEN 16
-#define CTC_DBF_TRACE_INDEX 2
+#define CTC_DBF_TRACE_PAGES 4
 #define CTC_DBF_TRACE_NR_AREAS 2
 #define CTC_DBF_TRACE_LEVEL 3
 
index 198330217eff86c04af62dd4f7ee66cb04bf667c..0c4644d3d2f35e76a3529284b9a9b0aeceaf7b06 100644 (file)
  */
 #define IUCV_DBF_SETUP_NAME "iucv_setup"
 #define IUCV_DBF_SETUP_LEN 32
-#define IUCV_DBF_SETUP_INDEX 1
+#define IUCV_DBF_SETUP_PAGES 2
 #define IUCV_DBF_SETUP_NR_AREAS 1
 #define IUCV_DBF_SETUP_LEVEL 3
 
 #define IUCV_DBF_DATA_NAME "iucv_data"
 #define IUCV_DBF_DATA_LEN 128
-#define IUCV_DBF_DATA_INDEX 1
+#define IUCV_DBF_DATA_PAGES 2
 #define IUCV_DBF_DATA_NR_AREAS 1
 #define IUCV_DBF_DATA_LEVEL 2
 
 #define IUCV_DBF_TRACE_NAME "iucv_trace"
 #define IUCV_DBF_TRACE_LEN 16
-#define IUCV_DBF_TRACE_INDEX 2
+#define IUCV_DBF_TRACE_PAGES 4
 #define IUCV_DBF_TRACE_NR_AREAS 1
 #define IUCV_DBF_TRACE_LEVEL 3
 
index ab086242d305a490e80f88f518c156d44ba05b01..46f34ba93ac5c76de5a821a38e6d75eb94fafea6 100644 (file)
@@ -11,7 +11,7 @@
  *                       Frank Pavlic (pavlic@de.ibm.com) and
  *                       Martin Schwidefsky <schwidefsky@de.ibm.com>
  *
- *    $Revision: 1.98 $         $Date: 2005/04/18 13:41:29 $
+ *    $Revision: 1.99 $         $Date: 2005/05/11 08:10:17 $
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -59,7 +59,7 @@
 /**
  * initialization string for output
  */
-#define VERSION_LCS_C  "$Revision: 1.98 $"
+#define VERSION_LCS_C  "$Revision: 1.99 $"
 
 static char version[] __initdata = "LCS driver ("VERSION_LCS_C "/" VERSION_LCS_H ")";
 static char debug_buffer[255];
@@ -93,8 +93,8 @@ lcs_unregister_debug_facility(void)
 static int
 lcs_register_debug_facility(void)
 {
-       lcs_dbf_setup = debug_register("lcs_setup", 1, 1, 8);
-       lcs_dbf_trace = debug_register("lcs_trace", 1, 2, 8);
+       lcs_dbf_setup = debug_register("lcs_setup", 2, 1, 8);
+       lcs_dbf_trace = debug_register("lcs_trace", 2, 2, 8);
        if (lcs_dbf_setup == NULL || lcs_dbf_trace == NULL) {
                PRINT_ERR("Not enough memory for debug facility.\n");
                lcs_unregister_debug_facility();
index 3fd4fb754b2d4736502235012b41d8c54ab7a444..69425a7a6e98a5b71f4fbb6df2826ad61c1bb2a7 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: netiucv.c,v 1.63 2004/07/27 13:36:05 mschwide Exp $
+ * $Id: netiucv.c,v 1.66 2005/05/11 08:10:17 holzheu Exp $
  *
  * IUCV network driver
  *
@@ -30,7 +30,7 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  *
- * RELEASE-TAG: IUCV network driver $Revision: 1.63 $
+ * RELEASE-TAG: IUCV network driver $Revision: 1.66 $
  *
  */
 \f
@@ -391,15 +391,15 @@ static int
 iucv_register_dbf_views(void)
 {
        iucv_dbf_setup = debug_register(IUCV_DBF_SETUP_NAME,
-                                       IUCV_DBF_SETUP_INDEX,
+                                       IUCV_DBF_SETUP_PAGES,
                                        IUCV_DBF_SETUP_NR_AREAS,
                                        IUCV_DBF_SETUP_LEN);
        iucv_dbf_data = debug_register(IUCV_DBF_DATA_NAME,
-                                      IUCV_DBF_DATA_INDEX,
+                                      IUCV_DBF_DATA_PAGES,
                                       IUCV_DBF_DATA_NR_AREAS,
                                       IUCV_DBF_DATA_LEN);
        iucv_dbf_trace = debug_register(IUCV_DBF_TRACE_NAME,
-                                       IUCV_DBF_TRACE_INDEX,
+                                       IUCV_DBF_TRACE_PAGES,
                                        IUCV_DBF_TRACE_NR_AREAS,
                                        IUCV_DBF_TRACE_LEN);
 
@@ -2076,7 +2076,7 @@ DRIVER_ATTR(remove, 0200, NULL, remove_write);
 static void
 netiucv_banner(void)
 {
-       char vbuf[] = "$Revision: 1.63 $";
+       char vbuf[] = "$Revision: 1.66 $";
        char *version = vbuf;
 
        if ((version = strchr(version, ':'))) {
index a755b57db46b359c9cb632919fc71ef7fd9c52fd..008e0a5d2eb38073958aafbe89fffab3c0f77de3 100644 (file)
  */
 #define QETH_DBF_SETUP_NAME "qeth_setup"
 #define QETH_DBF_SETUP_LEN 8
-#define QETH_DBF_SETUP_INDEX 3
+#define QETH_DBF_SETUP_PAGES 8
 #define QETH_DBF_SETUP_NR_AREAS 1
 #define QETH_DBF_SETUP_LEVEL 5
 
 #define QETH_DBF_MISC_NAME "qeth_misc"
 #define QETH_DBF_MISC_LEN 128
-#define QETH_DBF_MISC_INDEX 1
+#define QETH_DBF_MISC_PAGES 2
 #define QETH_DBF_MISC_NR_AREAS 1
 #define QETH_DBF_MISC_LEVEL 2
 
 #define QETH_DBF_DATA_NAME "qeth_data"
 #define QETH_DBF_DATA_LEN 96
-#define QETH_DBF_DATA_INDEX 3
+#define QETH_DBF_DATA_PAGES 8
 #define QETH_DBF_DATA_NR_AREAS 1
 #define QETH_DBF_DATA_LEVEL 2
 
 #define QETH_DBF_CONTROL_NAME "qeth_control"
 #define QETH_DBF_CONTROL_LEN 256
-#define QETH_DBF_CONTROL_INDEX 3
+#define QETH_DBF_CONTROL_PAGES 8
 #define QETH_DBF_CONTROL_NR_AREAS 2
 #define QETH_DBF_CONTROL_LEVEL 5
 
 #define QETH_DBF_TRACE_NAME "qeth_trace"
 #define QETH_DBF_TRACE_LEN 8
-#define QETH_DBF_TRACE_INDEX 2
+#define QETH_DBF_TRACE_PAGES 4
 #define QETH_DBF_TRACE_NR_AREAS 2
 #define QETH_DBF_TRACE_LEVEL 3
 extern debug_info_t *qeth_dbf_trace;
 
 #define QETH_DBF_SENSE_NAME "qeth_sense"
 #define QETH_DBF_SENSE_LEN 64
-#define QETH_DBF_SENSE_INDEX 1
+#define QETH_DBF_SENSE_PAGES 2
 #define QETH_DBF_SENSE_NR_AREAS 1
 #define QETH_DBF_SENSE_LEVEL 2
 
 #define QETH_DBF_QERR_NAME "qeth_qerr"
 #define QETH_DBF_QERR_LEN 8
-#define QETH_DBF_QERR_INDEX 1
+#define QETH_DBF_QERR_PAGES 2
 #define QETH_DBF_QERR_NR_AREAS 2
 #define QETH_DBF_QERR_LEVEL 2
 
index 208127a5033ae707ffdb1168d2c0f7da979cab4d..3cb88c770037fd306490b39e07b06ad38ab1ce09 100644 (file)
@@ -7639,31 +7639,31 @@ static int
 qeth_register_dbf_views(void)
 {
        qeth_dbf_setup = debug_register(QETH_DBF_SETUP_NAME,
-                                       QETH_DBF_SETUP_INDEX,
+                                       QETH_DBF_SETUP_PAGES,
                                        QETH_DBF_SETUP_NR_AREAS,
                                        QETH_DBF_SETUP_LEN);
        qeth_dbf_misc = debug_register(QETH_DBF_MISC_NAME,
-                                      QETH_DBF_MISC_INDEX,
+                                      QETH_DBF_MISC_PAGES,
                                       QETH_DBF_MISC_NR_AREAS,
                                       QETH_DBF_MISC_LEN);
        qeth_dbf_data = debug_register(QETH_DBF_DATA_NAME,
-                                      QETH_DBF_DATA_INDEX,
+                                      QETH_DBF_DATA_PAGES,
                                       QETH_DBF_DATA_NR_AREAS,
                                       QETH_DBF_DATA_LEN);
        qeth_dbf_control = debug_register(QETH_DBF_CONTROL_NAME,
-                                         QETH_DBF_CONTROL_INDEX,
+                                         QETH_DBF_CONTROL_PAGES,
                                          QETH_DBF_CONTROL_NR_AREAS,
                                          QETH_DBF_CONTROL_LEN);
        qeth_dbf_sense = debug_register(QETH_DBF_SENSE_NAME,
-                                       QETH_DBF_SENSE_INDEX,
+                                       QETH_DBF_SENSE_PAGES,
                                        QETH_DBF_SENSE_NR_AREAS,
                                        QETH_DBF_SENSE_LEN);
        qeth_dbf_qerr = debug_register(QETH_DBF_QERR_NAME,
-                                      QETH_DBF_QERR_INDEX,
+                                      QETH_DBF_QERR_PAGES,
                                       QETH_DBF_QERR_NR_AREAS,
                                       QETH_DBF_QERR_LEN);
        qeth_dbf_trace = debug_register(QETH_DBF_TRACE_NAME,
-                                       QETH_DBF_TRACE_INDEX,
+                                       QETH_DBF_TRACE_PAGES,
                                        QETH_DBF_TRACE_NR_AREAS,
                                        QETH_DBF_TRACE_LEN);
 
index 1e3f7f3c662ff53ea09e93d9b14313ba19aed7e8..d6469baa7e16ef1698d7ff9ff27436aca11fc723 100644 (file)
@@ -138,7 +138,7 @@ static void __exit
 smsg_exit(void)
 {
        if (smsg_handle > 0) {
-               cpcmd("SET SMSG OFF", 0, 0);
+               cpcmd("SET SMSG OFF", NULL, 0, NULL);
                iucv_sever(smsg_pathid, 0);
                iucv_unregister_program(smsg_handle);
                driver_unregister(&smsg_driver);
@@ -177,7 +177,7 @@ smsg_init(void)
                smsg_handle = 0;
                return -EIO;
        }
-       cpcmd("SET SMSG IUCV", 0, 0);
+       cpcmd("SET SMSG IUCV", NULL, 0, NULL);
        return 0;
 }
 
index ffa996c8a9082eb1b1e49ed1fd427283e17f255c..5bb255e02acc653f9f93b0ba1e0bcc4392aa83d1 100644 (file)
@@ -31,14 +31,14 @@ extern void css_reiterate_subchannels(void);
 extern struct workqueue_struct *slow_path_wq;
 extern struct work_struct slow_path_work;
 
-static void
+static NORET_TYPE void
 s390_handle_damage(char *msg)
 {
-       printk(KERN_EMERG "%s\n", msg);
 #ifdef CONFIG_SMP
        smp_send_stop();
 #endif
        disabled_wait((unsigned long) __builtin_return_address(0));
+       for(;;);
 }
 
 /*
@@ -122,40 +122,39 @@ repeat:
        return 0;
 }
 
+struct mcck_struct {
+       int kill_task;
+       int channel_report;
+       int warning;
+       unsigned long long mcck_code;
+};
+
+static DEFINE_PER_CPU(struct mcck_struct, cpu_mcck);
+
 /*
- * machine check handler.
+ * Main machine check handler function. Will be called with interrupts enabled
+ * or disabled and machine checks enabled or disabled.
  */
 void
-s390_do_machine_check(void)
+s390_handle_mcck(void)
 {
-       struct mci *mci;
-
-       mci = (struct mci *) &S390_lowcore.mcck_interruption_code;
+       unsigned long flags;
+       struct mcck_struct mcck;
 
-       if (mci->sd)            /* system damage */
-               s390_handle_damage("received system damage machine check\n");
+       /*
+        * Disable machine checks and get the current state of accumulated
+        * machine checks. Afterwards delete the old state and enable machine
+        * checks again.
+        */
+       local_irq_save(flags);
+       local_mcck_disable();
+       mcck = __get_cpu_var(cpu_mcck);
+       memset(&__get_cpu_var(cpu_mcck), 0, sizeof(struct mcck_struct));
+       clear_thread_flag(TIF_MCCK_PENDING);
+       local_mcck_enable();
+       local_irq_restore(flags);
 
-       if (mci->pd)            /* instruction processing damage */
-               s390_handle_damage("received instruction processing "
-                                  "damage machine check\n");
-
-       if (mci->se)            /* storage error uncorrected */
-               s390_handle_damage("received storage error uncorrected "
-                                  "machine check\n");
-
-       if (mci->sc)            /* storage error corrected */
-               printk(KERN_WARNING
-                      "received storage error corrected machine check\n");
-
-       if (mci->ke)            /* storage key-error uncorrected */
-               s390_handle_damage("received storage key-error uncorrected "
-                                  "machine check\n");
-
-       if (mci->ds && mci->fa) /* storage degradation */
-               s390_handle_damage("received storage degradation machine "
-                                  "check\n");
-
-       if (mci->cp)            /* channel report word pending */
+       if (mcck.channel_report)
                up(&m_sem);
 
 #ifdef CONFIG_MACHCHK_WARNING
@@ -168,7 +167,7 @@ s390_do_machine_check(void)
  * On VM we only get one interrupt per virtally presented machinecheck.
  * Though one suffices, we may get one interrupt per (virtual) processor.
  */
-       if (mci->w) {   /* WARNING pending ? */
+       if (mcck.warning) {     /* WARNING pending ? */
                static int mchchk_wng_posted = 0;
                /*
                 * Use single machine clear, as we cannot handle smp right now
@@ -178,6 +177,261 @@ s390_do_machine_check(void)
                        kill_proc(1, SIGPWR, 1);
        }
 #endif
+
+       if (mcck.kill_task) {
+               local_irq_enable();
+               printk(KERN_EMERG "mcck: Terminating task because of machine "
+                      "malfunction (code 0x%016llx).\n", mcck.mcck_code);
+               printk(KERN_EMERG "mcck: task: %s, pid: %d.\n",
+                      current->comm, current->pid);
+               do_exit(SIGSEGV);
+       }
+}
+
+/*
+ * returns 0 if all registers could be validated
+ * returns 1 otherwise
+ */
+static int
+s390_revalidate_registers(struct mci *mci)
+{
+       int kill_task;
+       u64 tmpclock;
+       u64 zero;
+       void *fpt_save_area, *fpt_creg_save_area;
+
+       kill_task = 0;
+       zero = 0;
+       /* General purpose registers */
+       if (!mci->gr)
+               /*
+                * General purpose registers couldn't be restored and have
+                * unknown contents. Process needs to be terminated.
+                */
+               kill_task = 1;
+
+       /* Revalidate floating point registers */
+       if (!mci->fp)
+               /*
+                * Floating point registers can't be restored and
+                * therefore the process needs to be terminated.
+                */
+               kill_task = 1;
+
+#ifndef __s390x__
+       asm volatile("ld 0,0(%0)\n"
+                    "ld 2,8(%0)\n"
+                    "ld 4,16(%0)\n"
+                    "ld 6,24(%0)"
+                    : : "a" (&S390_lowcore.floating_pt_save_area));
+#endif
+
+       if (MACHINE_HAS_IEEE) {
+#ifdef __s390x__
+               fpt_save_area = &S390_lowcore.floating_pt_save_area;
+               fpt_creg_save_area = &S390_lowcore.fpt_creg_save_area;
+#else
+               fpt_save_area = (void *) S390_lowcore.extended_save_area_addr;
+               fpt_creg_save_area = fpt_save_area+128;
+#endif
+               /* Floating point control register */
+               if (!mci->fc) {
+                       /*
+                        * Floating point control register can't be restored.
+                        * Task will be terminated.
+                        */
+                       asm volatile ("lfpc 0(%0)" : : "a" (&zero));
+                       kill_task = 1;
+
+               }
+               else
+                       asm volatile (
+                               "lfpc 0(%0)"
+                               : : "a" (fpt_creg_save_area));
+
+               asm volatile("ld  0,0(%0)\n"
+                            "ld  1,8(%0)\n"
+                            "ld  2,16(%0)\n"
+                            "ld  3,24(%0)\n"
+                            "ld  4,32(%0)\n"
+                            "ld  5,40(%0)\n"
+                            "ld  6,48(%0)\n"
+                            "ld  7,56(%0)\n"
+                            "ld  8,64(%0)\n"
+                            "ld  9,72(%0)\n"
+                            "ld 10,80(%0)\n"
+                            "ld 11,88(%0)\n"
+                            "ld 12,96(%0)\n"
+                            "ld 13,104(%0)\n"
+                            "ld 14,112(%0)\n"
+                            "ld 15,120(%0)\n"
+                            : : "a" (fpt_save_area));
+       }
+
+       /* Revalidate access registers */
+       asm volatile("lam 0,15,0(%0)"
+                    : : "a" (&S390_lowcore.access_regs_save_area));
+       if (!mci->ar)
+               /*
+                * Access registers have unknown contents.
+                * Terminating task.
+                */
+               kill_task = 1;
+
+       /* Revalidate control registers */
+       if (!mci->cr)
+               /*
+                * Control registers have unknown contents.
+                * Can't recover and therefore stopping machine.
+                */
+               s390_handle_damage("invalid control registers.");
+       else
+#ifdef __s390x__
+               asm volatile("lctlg 0,15,0(%0)"
+                            : : "a" (&S390_lowcore.cregs_save_area));
+#else
+               asm volatile("lctl 0,15,0(%0)"
+                            : : "a" (&S390_lowcore.cregs_save_area));
+#endif
+
+       /*
+        * We don't even try to revalidate the TOD register, since we simply
+        * can't write something sensible into that register.
+        */
+
+#ifdef __s390x__
+       /*
+        * See if we can revalidate the TOD programmable register with its
+        * old contents (should be zero) otherwise set it to zero.
+        */
+       if (!mci->pr)
+               asm volatile("sr 0,0\n"
+                            "sckpf"
+                            : : : "0", "cc");
+       else
+               asm volatile(
+                       "l 0,0(%0)\n"
+                       "sckpf"
+                       : : "a" (&S390_lowcore.tod_progreg_save_area) : "0", "cc");
+#endif
+
+       /* Revalidate clock comparator register */
+       asm volatile ("stck 0(%1)\n"
+                     "sckc 0(%1)"
+                     : "=m" (tmpclock) : "a" (&(tmpclock)) : "cc", "memory");
+
+       /* Check if old PSW is valid */
+       if (!mci->wp)
+               /*
+                * Can't tell if we come from user or kernel mode
+                * -> stopping machine.
+                */
+               s390_handle_damage("old psw invalid.");
+
+       if (!mci->ms || !mci->pm || !mci->ia)
+               kill_task = 1;
+
+       return kill_task;
+}
+
+/*
+ * machine check handler.
+ */
+void
+s390_do_machine_check(struct pt_regs *regs)
+{
+       struct mci *mci;
+       struct mcck_struct *mcck;
+       int umode;
+
+       mci = (struct mci *) &S390_lowcore.mcck_interruption_code;
+       mcck = &__get_cpu_var(cpu_mcck);
+       umode = user_mode(regs);
+
+       if (mci->sd)
+               /* System damage -> stopping machine */
+               s390_handle_damage("received system damage machine check.");
+
+       if (mci->pd) {
+               if (mci->b) {
+                       /* Processing backup -> verify if we can survive this */
+                       u64 z_mcic, o_mcic, t_mcic;
+#ifdef __s390x__
+                       z_mcic = (1ULL<<63 | 1ULL<<59 | 1ULL<<29);
+                       o_mcic = (1ULL<<43 | 1ULL<<42 | 1ULL<<41 | 1ULL<<40 |
+                                 1ULL<<36 | 1ULL<<35 | 1ULL<<34 | 1ULL<<32 |
+                                 1ULL<<30 | 1ULL<<21 | 1ULL<<20 | 1ULL<<17 |
+                                 1ULL<<16);
+#else
+                       z_mcic = (1ULL<<63 | 1ULL<<59 | 1ULL<<57 | 1ULL<<50 |
+                                 1ULL<<29);
+                       o_mcic = (1ULL<<43 | 1ULL<<42 | 1ULL<<41 | 1ULL<<40 |
+                                 1ULL<<36 | 1ULL<<35 | 1ULL<<34 | 1ULL<<32 |
+                                 1ULL<<30 | 1ULL<<20 | 1ULL<<17 | 1ULL<<16);
+#endif
+                       t_mcic = *(u64 *)mci;
+
+                       if (((t_mcic & z_mcic) != 0) ||
+                           ((t_mcic & o_mcic) != o_mcic)) {
+                               s390_handle_damage("processing backup machine "
+                                                  "check with damage.");
+                       }
+                       if (!umode)
+                               s390_handle_damage("processing backup machine "
+                                                  "check in kernel mode.");
+                       mcck->kill_task = 1;
+                       mcck->mcck_code = *(unsigned long long *) mci;
+               }
+               else {
+                       /* Processing damage -> stopping machine */
+                       s390_handle_damage("received instruction processing "
+                                          "damage machine check.");
+               }
+       }
+       if (s390_revalidate_registers(mci)) {
+               if (umode) {
+                       /*
+                        * Couldn't restore all register contents while in
+                        * user mode -> mark task for termination.
+                        */
+                       mcck->kill_task = 1;
+                       mcck->mcck_code = *(unsigned long long *) mci;
+                       set_thread_flag(TIF_MCCK_PENDING);
+               }
+               else
+                       /*
+                        * Couldn't restore all register contents while in
+                        * kernel mode -> stopping machine.
+                        */
+                       s390_handle_damage("unable to revalidate registers.");
+       }
+
+       if (mci->se)
+               /* Storage error uncorrected */
+               s390_handle_damage("received storage error uncorrected "
+                                  "machine check.");
+
+       if (mci->ke)
+               /* Storage key-error uncorrected */
+               s390_handle_damage("received storage key-error uncorrected "
+                                  "machine check.");
+
+       if (mci->ds && mci->fa)
+               /* Storage degradation */
+               s390_handle_damage("received storage degradation machine "
+                                  "check.");
+
+       if (mci->cp) {
+               /* Channel report word pending */
+               mcck->channel_report = 1;
+               set_thread_flag(TIF_MCCK_PENDING);
+       }
+
+       if (mci->w) {
+               /* Warning pending */
+               mcck->warning = 1;
+               set_thread_flag(TIF_MCCK_PENDING);
+       }
 }
 
 /*
@@ -189,9 +443,8 @@ static int
 machine_check_init(void)
 {
        init_MUTEX_LOCKED(&m_sem);
-       ctl_clear_bit(14, 25);  /* disable damage MCH */
-       ctl_set_bit(14, 26);    /* enable degradation MCH */
-       ctl_set_bit(14, 27);    /* enable system recovery MCH */
+       ctl_clear_bit(14, 25);  /* disable external damage MCH */
+       ctl_set_bit(14, 27);    /* enable system recovery MCH */
 #ifdef CONFIG_MACHCHK_WARNING
        ctl_set_bit(14, 24);    /* enable warning MCH */
 #endif
index 7e26f0f1b0dcbd2f79d45d954be44953f29507b4..4eaa70179182a62e9b28ef8d4a356f3b3e09096b 100644 (file)
@@ -16,20 +16,45 @@ struct mci {
        __u32   sd              :  1; /* 00 system damage */
        __u32   pd              :  1; /* 01 instruction-processing damage */
        __u32   sr              :  1; /* 02 system recovery */
-       __u32   to_be_defined_1 :  4; /* 03-06 */
+       __u32   to_be_defined_1 :  1; /* 03 */
+       __u32   cd              :  1; /* 04 timing-facility damage */
+       __u32   ed              :  1; /* 05 external damage */
+       __u32   to_be_defined_2 :  1; /* 06 */
        __u32   dg              :  1; /* 07 degradation */
        __u32   w               :  1; /* 08 warning pending */
        __u32   cp              :  1; /* 09 channel-report pending */
-       __u32   to_be_defined_2 :  6; /* 10-15 */
+       __u32   sp              :  1; /* 10 service-processor damage */
+       __u32   ck              :  1; /* 11 channel-subsystem damage */
+       __u32   to_be_defined_3 :  2; /* 12-13 */
+       __u32   b               :  1; /* 14 backed up */
+       __u32   to_be_defined_4 :  1; /* 15 */
        __u32   se              :  1; /* 16 storage error uncorrected */
        __u32   sc              :  1; /* 17 storage error corrected */
        __u32   ke              :  1; /* 18 storage-key error uncorrected */
        __u32   ds              :  1; /* 19 storage degradation */
-       __u32   to_be_defined_3 :  4; /* 20-23 */
+       __u32   wp              :  1; /* 20 psw mwp validity */
+       __u32   ms              :  1; /* 21 psw mask and key validity */
+       __u32   pm              :  1; /* 22 psw program mask and cc validity */
+       __u32   ia              :  1; /* 23 psw instruction address validity */
        __u32   fa              :  1; /* 24 failing storage address validity */
-       __u32   to_be_defined_4 :  7; /* 25-31 */
+       __u32   to_be_defined_5 :  1; /* 25 */
+       __u32   ec              :  1; /* 26 external damage code validity */
+       __u32   fp              :  1; /* 27 floating point register validity */
+       __u32   gr              :  1; /* 28 general register validity */
+       __u32   cr              :  1; /* 29 control register validity */
+       __u32   to_be_defined_6 :  1; /* 30 */
+       __u32   st              :  1; /* 31 storage logical validity */
        __u32   ie              :  1; /* 32 indirect storage error */
-       __u32   to_be_defined_5 : 31; /* 33-63 */
+       __u32   ar              :  1; /* 33 access register validity */
+       __u32   da              :  1; /* 34 delayed access exception */
+       __u32   to_be_defined_7 :  7; /* 35-41 */
+       __u32   pr              :  1; /* 42 tod programmable register validity */
+       __u32   fc              :  1; /* 43 fp control register validity */
+       __u32   ap              :  1; /* 44 ancillary report */
+       __u32   to_be_defined_8 :  1; /* 45 */
+       __u32   ct              :  1; /* 46 cpu timer validity */
+       __u32   cc              :  1; /* 47 clock comparator validity */
+       __u32   to_be_defined_9 : 16; /* 47-63 */
 };
 
 /*
index a699c30b26627937850989f928b41fa0938db391..bbe346bd3cb8f476e8f012abd7e5e6f7a3e2f41f 100644 (file)
@@ -34,7 +34,6 @@
 
 #define ADDR32 (0)
 
-#include <linux/version.h>
 #include <linux/module.h>
 
 MODULE_AUTHOR("Deanna Bonds, with _lots_ of help from Mark Salyzyn");
@@ -1811,9 +1810,9 @@ static int adpt_system_info(void __user *buffer)
        memset(&si, 0, sizeof(si));
 
        si.osType = OS_LINUX;
-       si.osMajorVersion = (u8) (LINUX_VERSION_CODE >> 16);
-       si.osMinorVersion = (u8) (LINUX_VERSION_CODE >> 8 & 0x0ff);
-       si.osRevision =     (u8) (LINUX_VERSION_CODE & 0x0ff);
+       si.osMajorVersion = 0;
+       si.osMinorVersion = 0;
+       si.osRevision = 0;
        si.busType = SI_PCI_BUS;
        si.processorFamily = DPTI_sig.dsProcessorFamily;
 
index 9821783c0164f051bb619cd6b70b8ecb4948f5ff..489194af43d03229c5f15efe42e4a272fc684f16 100644 (file)
 #ifndef _DPT_H
 #define _DPT_H
 
-#ifndef LINUX_VERSION_CODE
-#include <linux/version.h>
-#endif
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,00)
-#define MAX_TO_IOP_MESSAGES   (210)
-#else
 #define MAX_TO_IOP_MESSAGES   (255)
-#endif
 #define MAX_FROM_IOP_MESSAGES (255)
 
 
@@ -321,10 +313,6 @@ static int adpt_close(struct inode *inode, struct file *file);
 static void adpt_delay(int millisec);
 #endif
 
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)
-static struct pci_dev* adpt_pci_find_device(uint vendor, struct pci_dev* from);
-#endif
-
 #if defined __ia64__ 
 static void adpt_ia64_info(sysInfo_S* si);
 #endif
index f7ddc9f1ba41d19628c22c1e5d01627c93adf097..2094d4811d61c859f2dd3399ee01b7710c89909f 100644 (file)
@@ -223,7 +223,7 @@ static void tul_select_atn(HCS * pCurHcb, SCB * pCurScb);
 static void tul_select_atn3(HCS * pCurHcb, SCB * pCurScb);
 static void tul_select_atn_stop(HCS * pCurHcb, SCB * pCurScb);
 static int int_tul_busfree(HCS * pCurHcb);
-int int_tul_scsi_rst(HCS * pCurHcb);
+static int int_tul_scsi_rst(HCS * pCurHcb);
 static int int_tul_bad_seq(HCS * pCurHcb);
 static int int_tul_resel(HCS * pCurHcb);
 static int tul_sync_done(HCS * pCurHcb);
@@ -240,9 +240,8 @@ static int tul_se2_rd_all(WORD CurBase);
 static void tul_se2_update_all(WORD CurBase);  /* setup default pattern */
 static void tul_read_eeprom(WORD CurBase);
 
-                               /* ---- EXTERNAL VARIABLES ---- */
-HCS tul_hcs[MAX_SUPPORTED_ADAPTERS];
                                /* ---- INTERNAL VARIABLES ---- */
+static HCS tul_hcs[MAX_SUPPORTED_ADAPTERS];
 static INI_ADPT_STRUCT i91u_adpt[MAX_SUPPORTED_ADAPTERS];
 
 /*NVRAM nvram, *nvramp = &nvram; */
@@ -381,7 +380,7 @@ void tul_se2_wait(void)
 
 
 ******************************************************************/
-void tul_se2_instr(WORD CurBase, UCHAR instr)
+static void tul_se2_instr(WORD CurBase, UCHAR instr)
 {
        int i;
        UCHAR b;
@@ -437,7 +436,7 @@ void tul_se2_ew_ds(WORD CurBase)
        Input  :address of Serial E2PROM
        Output :value stored in  Serial E2PROM
 *******************************************************************/
-USHORT tul_se2_rd(WORD CurBase, ULONG adr)
+static USHORT tul_se2_rd(WORD CurBase, ULONG adr)
 {
        UCHAR instr, readByte;
        USHORT readWord;
@@ -468,7 +467,7 @@ USHORT tul_se2_rd(WORD CurBase, ULONG adr)
 /******************************************************************
  Input: new value in  Serial E2PROM, address of Serial E2PROM
 *******************************************************************/
-void tul_se2_wr(WORD CurBase, UCHAR adr, USHORT writeWord)
+static void tul_se2_wr(WORD CurBase, UCHAR adr, USHORT writeWord)
 {
        UCHAR readByte;
        UCHAR instr;
@@ -584,8 +583,8 @@ void tul_read_eeprom(WORD CurBase)
        TUL_WR(CurBase + TUL_GCTRL, gctrl & ~TUL_GCTRL_EEPROM_BIT);
 }                              /* read_eeprom */
 
-int Addi91u_into_Adapter_table(WORD wBIOS, WORD wBASE, BYTE bInterrupt,
-                              BYTE bBus, BYTE bDevice)
+static int Addi91u_into_Adapter_table(WORD wBIOS, WORD wBASE, BYTE bInterrupt,
+                                     BYTE bBus, BYTE bDevice)
 {
        int i, j;
 
@@ -616,7 +615,7 @@ int Addi91u_into_Adapter_table(WORD wBIOS, WORD wBASE, BYTE bInterrupt,
        return 1;
 }
 
-void init_i91uAdapter_table(void)
+static void init_i91uAdapter_table(void)
 {
        int i;
 
@@ -630,7 +629,7 @@ void init_i91uAdapter_table(void)
        return;
 }
 
-void tul_stop_bm(HCS * pCurHcb)
+static void tul_stop_bm(HCS * pCurHcb)
 {
 
        if (TUL_RD(pCurHcb->HCS_Base, TUL_XStatus) & XPEND) {   /* if DMA xfer is pending, abort DMA xfer */
@@ -642,7 +641,7 @@ void tul_stop_bm(HCS * pCurHcb)
 }
 
 /***************************************************************************/
-void get_tulipPCIConfig(HCS * pCurHcb, int ch_idx)
+static void get_tulipPCIConfig(HCS * pCurHcb, int ch_idx)
 {
        pCurHcb->HCS_Base = i91u_adpt[ch_idx].ADPT_BASE;        /* Supply base address  */
        pCurHcb->HCS_BIOS = i91u_adpt[ch_idx].ADPT_BIOS;        /* Supply BIOS address  */
@@ -651,7 +650,7 @@ void get_tulipPCIConfig(HCS * pCurHcb, int ch_idx)
 }
 
 /***************************************************************************/
-int tul_reset_scsi(HCS * pCurHcb, int seconds)
+static int tul_reset_scsi(HCS * pCurHcb, int seconds)
 {
        TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl0, TSC_RST_BUS);
 
@@ -670,7 +669,8 @@ int tul_reset_scsi(HCS * pCurHcb, int seconds)
 }
 
 /***************************************************************************/
-int init_tulip(HCS * pCurHcb, SCB * scbp, int tul_num_scb, BYTE * pbBiosAdr, int seconds)
+static int init_tulip(HCS * pCurHcb, SCB * scbp, int tul_num_scb,
+                     BYTE * pbBiosAdr, int seconds)
 {
        int i;
        BYTE *pwFlags;
@@ -788,7 +788,7 @@ int init_tulip(HCS * pCurHcb, SCB * scbp, int tul_num_scb, BYTE * pbBiosAdr, int
 }
 
 /***************************************************************************/
-SCB *tul_alloc_scb(HCS * hcsp)
+static SCB *tul_alloc_scb(HCS * hcsp)
 {
        SCB *pTmpScb;
        ULONG flags;
@@ -807,7 +807,7 @@ SCB *tul_alloc_scb(HCS * hcsp)
 }
 
 /***************************************************************************/
-void tul_release_scb(HCS * hcsp, SCB * scbp)
+static void tul_release_scb(HCS * hcsp, SCB * scbp)
 {
        ULONG flags;
 
@@ -829,7 +829,7 @@ void tul_release_scb(HCS * hcsp, SCB * scbp)
 }
 
 /***************************************************************************/
-void tul_append_pend_scb(HCS * pCurHcb, SCB * scbp)
+static void tul_append_pend_scb(HCS * pCurHcb, SCB * scbp)
 {
 
 #if DEBUG_QUEUE
@@ -847,7 +847,7 @@ void tul_append_pend_scb(HCS * pCurHcb, SCB * scbp)
 }
 
 /***************************************************************************/
-void tul_push_pend_scb(HCS * pCurHcb, SCB * scbp)
+static void tul_push_pend_scb(HCS * pCurHcb, SCB * scbp)
 {
 
 #if DEBUG_QUEUE
@@ -863,7 +863,7 @@ void tul_push_pend_scb(HCS * pCurHcb, SCB * scbp)
 }
 
 /***************************************************************************/
-SCB *tul_find_first_pend_scb(HCS * pCurHcb)
+static SCB *tul_find_first_pend_scb(HCS * pCurHcb)
 {
        SCB *pFirstPend;
 
@@ -894,24 +894,7 @@ SCB *tul_find_first_pend_scb(HCS * pCurHcb)
        return (pFirstPend);
 }
 /***************************************************************************/
-SCB *tul_pop_pend_scb(HCS * pCurHcb)
-{
-       SCB *pTmpScb;
-
-       if ((pTmpScb = pCurHcb->HCS_FirstPend) != NULL) {
-               if ((pCurHcb->HCS_FirstPend = pTmpScb->SCB_NxtScb) == NULL)
-                       pCurHcb->HCS_LastPend = NULL;
-               pTmpScb->SCB_NxtScb = NULL;
-       }
-#if DEBUG_QUEUE
-       printk("Pop pend SCB %lx; ", (ULONG) pTmpScb);
-#endif
-       return (pTmpScb);
-}
-
-
-/***************************************************************************/
-void tul_unlink_pend_scb(HCS * pCurHcb, SCB * pCurScb)
+static void tul_unlink_pend_scb(HCS * pCurHcb, SCB * pCurScb)
 {
        SCB *pTmpScb, *pPrevScb;
 
@@ -939,7 +922,7 @@ void tul_unlink_pend_scb(HCS * pCurHcb, SCB * pCurScb)
        return;
 }
 /***************************************************************************/
-void tul_append_busy_scb(HCS * pCurHcb, SCB * scbp)
+static void tul_append_busy_scb(HCS * pCurHcb, SCB * scbp)
 {
 
 #if DEBUG_QUEUE
@@ -961,7 +944,7 @@ void tul_append_busy_scb(HCS * pCurHcb, SCB * scbp)
 }
 
 /***************************************************************************/
-SCB *tul_pop_busy_scb(HCS * pCurHcb)
+static SCB *tul_pop_busy_scb(HCS * pCurHcb)
 {
        SCB *pTmpScb;
 
@@ -982,7 +965,7 @@ SCB *tul_pop_busy_scb(HCS * pCurHcb)
 }
 
 /***************************************************************************/
-void tul_unlink_busy_scb(HCS * pCurHcb, SCB * pCurScb)
+static void tul_unlink_busy_scb(HCS * pCurHcb, SCB * pCurScb)
 {
        SCB *pTmpScb, *pPrevScb;
 
@@ -1037,7 +1020,7 @@ SCB *tul_find_busy_scb(HCS * pCurHcb, WORD tarlun)
 }
 
 /***************************************************************************/
-void tul_append_done_scb(HCS * pCurHcb, SCB * scbp)
+static void tul_append_done_scb(HCS * pCurHcb, SCB * scbp)
 {
 
 #if DEBUG_QUEUE
@@ -1073,7 +1056,7 @@ SCB *tul_find_done_scb(HCS * pCurHcb)
 }
 
 /***************************************************************************/
-int tul_abort_srb(HCS * pCurHcb, struct scsi_cmnd *srbp)
+static int tul_abort_srb(HCS * pCurHcb, struct scsi_cmnd *srbp)
 {
        ULONG flags;
        SCB *pTmpScb, *pPrevScb;
@@ -1163,7 +1146,7 @@ int tul_abort_srb(HCS * pCurHcb, struct scsi_cmnd *srbp)
 }
 
 /***************************************************************************/
-int tul_bad_seq(HCS * pCurHcb)
+static int tul_bad_seq(HCS * pCurHcb)
 {
        SCB *pCurScb;
 
@@ -1182,9 +1165,11 @@ int tul_bad_seq(HCS * pCurHcb)
        return (tul_post_scsi_rst(pCurHcb));
 }
 
+#if 0
+
 /************************************************************************/
-int tul_device_reset(HCS * pCurHcb, struct scsi_cmnd *pSrb,
-               unsigned int target, unsigned int ResetFlags)
+static int tul_device_reset(HCS * pCurHcb, struct scsi_cmnd *pSrb,
+                           unsigned int target, unsigned int ResetFlags)
 {
        ULONG flags;
        SCB *pScb;
@@ -1255,7 +1240,7 @@ int tul_device_reset(HCS * pCurHcb, struct scsi_cmnd *pSrb,
        return SCSI_RESET_PENDING;
 }
 
-int tul_reset_scsi_bus(HCS * pCurHcb)
+static int tul_reset_scsi_bus(HCS * pCurHcb)
 {
        ULONG flags;
 
@@ -1284,8 +1269,10 @@ int tul_reset_scsi_bus(HCS * pCurHcb)
        return (SCSI_RESET_SUCCESS | SCSI_RESET_HOST_RESET);
 }
 
+#endif  /*  0  */
+
 /************************************************************************/
-void tul_exec_scb(HCS * pCurHcb, SCB * pCurScb)
+static void tul_exec_scb(HCS * pCurHcb, SCB * pCurScb)
 {
        ULONG flags;
 
@@ -1318,7 +1305,7 @@ void tul_exec_scb(HCS * pCurHcb, SCB * pCurScb)
 }
 
 /***************************************************************************/
-int tul_isr(HCS * pCurHcb)
+static int tul_isr(HCS * pCurHcb)
 {
        /* Enter critical section       */
 
@@ -2108,7 +2095,7 @@ int int_tul_busfree(HCS * pCurHcb)
 
 /***************************************************************************/
 /* scsi bus reset */
-int int_tul_scsi_rst(HCS * pCurHcb)
+static int int_tul_scsi_rst(HCS * pCurHcb)
 {
        SCB *pCurScb;
        int i;
@@ -2214,7 +2201,7 @@ int int_tul_resel(HCS * pCurHcb)
 
 
 /***************************************************************************/
-int int_tul_bad_seq(HCS * pCurHcb)
+static int int_tul_bad_seq(HCS * pCurHcb)
 {                              /* target wrong phase           */
        SCB *pCurScb;
        int i;
index df3ed7c1cee364c0645cd2dbaaf263662c67315d..3efb1184fc39ea66230eea7bd5c08530dc31f9d2 100644 (file)
@@ -719,21 +719,3 @@ typedef struct _HCSinfo {
 #define SCSI_RESET_HOST_RESET 0x200
 #define SCSI_RESET_ACTION   0xff
 
-extern void init_i91uAdapter_table(void);
-extern int Addi91u_into_Adapter_table(WORD, WORD, BYTE, BYTE, BYTE);
-extern int tul_ReturnNumberOfAdapters(void);
-extern void get_tulipPCIConfig(HCS * pHCB, int iChannel_index);
-extern int init_tulip(HCS * pHCB, SCB * pSCB, int tul_num_scb, BYTE * pbBiosAdr, int reset_time);
-extern SCB *tul_alloc_scb(HCS * pHCB);
-extern int tul_abort_srb(HCS * pHCB, struct scsi_cmnd * pSRB);
-extern void tul_exec_scb(HCS * pHCB, SCB * pSCB);
-extern void tul_release_scb(HCS * pHCB, SCB * pSCB);
-extern void tul_stop_bm(HCS * pHCB);
-extern int tul_reset_scsi(HCS * pCurHcb, int seconds);
-extern int tul_isr(HCS * pHCB);
-extern int tul_reset(HCS * pHCB, struct scsi_cmnd * pSRB, unsigned char target);
-extern int tul_reset_scsi_bus(HCS * pCurHcb);
-extern int tul_device_reset(HCS * pCurHcb, struct scsi_cmnd *pSrb,
-               unsigned int target, unsigned int ResetFlags);
-                               /* ---- EXTERNAL VARIABLES ---- */
-extern HCS tul_hcs[];
index db92a0ceda79fa4b71444dcea16b0b06a1406ea8..feb8e73fc1c959b1bb5b3da435ff183524d4e54d 100644 (file)
@@ -992,18 +992,17 @@ static int get_lsr_info(struct m68k_serial * info, unsigned int *value)
 /*
  * This routine sends a break character out the serial port.
  */
-static void send_break(        struct m68k_serial * info, int duration)
+static void send_break(struct m68k_serial * info, unsigned int duration)
 {
        m68328_uart *uart = &uart_addr[info->line];
         unsigned long flags;
         if (!info->port)
                 return;
-        set_current_state(TASK_INTERRUPTIBLE);
         save_flags(flags);
         cli();
 #ifdef USE_INTS        
        uart->utx.w |= UTX_SEND_BREAK;
-        schedule_timeout(duration);
+       msleep_interruptible(duration);
        uart->utx.w &= ~UTX_SEND_BREAK;
 #endif         
         restore_flags(flags);
@@ -1033,14 +1032,14 @@ static int rs_ioctl(struct tty_struct *tty, struct file * file,
                                return retval;
                        tty_wait_until_sent(tty, 0);
                        if (!arg)
-                               send_break(info, HZ/4); /* 1/4 second */
+                               send_break(info, 250);  /* 1/4 second */
                        return 0;
                case TCSBRKP:   /* support for POSIX tcsendbreak() */
                        retval = tty_check_change(tty);
                        if (retval)
                                return retval;
                        tty_wait_until_sent(tty, 0);
-                       send_break(info, arg ? arg*(HZ/10) : HZ/4);
+                       send_break(info, arg ? arg*(100) : 250);
                        return 0;
                case TIOCGSOFTCAR:
                        error = put_user(C_CLOCAL(tty) ? 1 : 0,
index f148022b6b4e739e729fbe52f24bada0acd4646a..b116122e569ab3592b5e3abaa23f24d83c39e9d5 100644 (file)
@@ -1394,14 +1394,13 @@ static void end_break(ser_info_t *info)
 /*
  * This routine sends a break character out the serial port.
  */
-static void send_break(ser_info_t *info, int duration)
+static void send_break(ser_info_t *info, unsigned int duration)
 {
-       set_current_state(TASK_INTERRUPTIBLE);
 #ifdef SERIAL_DEBUG_SEND_BREAK
        printk("rs_send_break(%d) jiff=%lu...", duration, jiffies);
 #endif
        begin_break(info);
-       schedule_timeout(duration);
+       msleep_interruptible(duration);
        end_break(info);
 #ifdef SERIAL_DEBUG_SEND_BREAK
        printk("done jiffies=%lu\n", jiffies);
@@ -1436,7 +1435,7 @@ static int rs_360_ioctl(struct tty_struct *tty, struct file * file,
                        if (signal_pending(current))
                                return -EINTR;
                        if (!arg) {
-                               send_break(info, HZ/4); /* 1/4 second */
+                               send_break(info, 250);  /* 1/4 second */
                                if (signal_pending(current))
                                        return -EINTR;
                        }
@@ -1448,7 +1447,7 @@ static int rs_360_ioctl(struct tty_struct *tty, struct file * file,
                        tty_wait_until_sent(tty, 0);
                        if (signal_pending(current))
                                return -EINTR;
-                       send_break(info, arg ? arg*(HZ/10) : HZ/4);
+                       send_break(info, arg ? arg*100 : 250);
                        if (signal_pending(current))
                                return -EINTR;
                        return 0;
index 23dc0f7ddf8bb6712613ba0274374f609e1c4412..798f1ef237128e8e5d3a672247c8b53faab67bcd 100644 (file)
@@ -286,5 +286,3 @@ struct lookup_int_table {
        u32     __iomem *global_int_mask;
        unsigned long   processor_id;
 };
-
-#define MSECS_TO_JIFFIES(ms) (((ms)*HZ+999)/1000)
index a8314aee2ab8b7a32e8e67f2f6e0c2e82c8f39b4..a2a643318002892201db6c0e2b478401e4d93cdc 100644 (file)
 
 static struct mpsc_port_info mpsc_ports[MPSC_NUM_CTLRS];
 static struct mpsc_shared_regs mpsc_shared_regs;
+static struct uart_driver mpsc_reg;
 
+static void mpsc_start_rx(struct mpsc_port_info *pi);
+static void mpsc_free_ring_mem(struct mpsc_port_info *pi);
+static void mpsc_release_port(struct uart_port *port);
 /*
  ******************************************************************************
  *
@@ -546,7 +550,6 @@ static int
 mpsc_alloc_ring_mem(struct mpsc_port_info *pi)
 {
        int rc = 0;
-       static void mpsc_free_ring_mem(struct mpsc_port_info *pi);
 
        pr_debug("mpsc_alloc_ring_mem[%d]: Allocating ring mem\n",
                pi->port.line);
@@ -745,7 +748,6 @@ mpsc_rx_intr(struct mpsc_port_info *pi, struct pt_regs *regs)
        int     rc = 0;
        u8      *bp;
        char    flag = TTY_NORMAL;
-       static void mpsc_start_rx(struct mpsc_port_info *pi);
 
        pr_debug("mpsc_rx_intr[%d]: Handling Rx intr\n", pi->port.line);
 
@@ -1178,7 +1180,6 @@ static void
 mpsc_shutdown(struct uart_port *port)
 {
        struct mpsc_port_info *pi = (struct mpsc_port_info *)port;
-       static void mpsc_release_port(struct uart_port *port);
 
        pr_debug("mpsc_shutdown[%d]: Shutting down MPSC\n", port->line);
 
@@ -1448,7 +1449,6 @@ mpsc_console_setup(struct console *co, char *options)
        return uart_set_options(&pi->port, co, baud, parity, bits, flow);
 }
 
-extern struct uart_driver mpsc_reg;
 static struct console mpsc_console = {
        .name   = MPSC_DEV_NAME,
        .write  = mpsc_console_write,
index 5c4231ae295b05cf7750a4ba3bd7533f154532f3..8e65206d3d760c0542f8ee6bceb60bc235004f22 100644 (file)
@@ -1071,7 +1071,7 @@ static void __init sunzilog_alloc_tables(void)
  */
 static struct zilog_layout __iomem * __init get_zs_sun4u(int chip, int zsnode)
 {
-       unsigned long mapped_addr;
+       void __iomem *mapped_addr;
        unsigned int sun4u_ino;
        struct sbus_bus *sbus = NULL;
        struct sbus_dev *sdev = NULL;
@@ -1111,9 +1111,9 @@ static struct zilog_layout __iomem * __init get_zs_sun4u(int chip, int zsnode)
                apply_fhc_ranges(central_bus->child,
                                 &zsregs[0], 1);
                apply_central_ranges(central_bus, &zsregs[0], 1);
-               mapped_addr =
-                       (((u64)zsregs[0].which_io)<<32UL) |
-                       ((u64)zsregs[0].phys_addr);
+               mapped_addr = (void __iomem *)
+                       ((((u64)zsregs[0].which_io)<<32UL) |
+                       ((u64)zsregs[0].phys_addr));
        }
 
        if (zilog_irq == -1) {
index d5863b8b56eeaf00745a03f3d3a76c11c12a512f..f2c9fa423d402d1262b6af64e3d3180c567f39cf 100644 (file)
@@ -329,10 +329,8 @@ static IXJ *ixj_alloc()
 
 static void ixj_fsk_free(IXJ *j)
 {
-       if(j->fskdata != NULL) {
-               kfree(j->fskdata);
-               j->fskdata = NULL;
-       }
+       kfree(j->fskdata);
+       j->fskdata = NULL;
 }
 
 static void ixj_fsk_alloc(IXJ *j)
@@ -3867,13 +3865,11 @@ static int set_rec_codec(IXJ *j, int rate)
                j->rec_mode = 7;
                break;
        default:
+               kfree(j->read_buffer);
                j->rec_frame_size = 0;
                j->rec_mode = -1;
-               if (j->read_buffer) {
-                       kfree(j->read_buffer);
-                       j->read_buffer = NULL;
-                       j->read_buffer_size = 0;
-               }
+               j->read_buffer = NULL;
+               j->read_buffer_size = 0;
                retval = 1;
                break;
        }
@@ -3991,14 +3987,12 @@ static int ixj_record_start(IXJ *j)
 
 static void ixj_record_stop(IXJ *j)
 {
-       if(ixjdebug & 0x0002)
+       if (ixjdebug & 0x0002)
                printk("IXJ %d Stopping Record Codec %d at %ld\n", j->board, j->rec_codec, jiffies);
 
-       if (j->read_buffer) {
-               kfree(j->read_buffer);
-               j->read_buffer = NULL;
-               j->read_buffer_size = 0;
-       }
+       kfree(j->read_buffer);
+       j->read_buffer = NULL;
+       j->read_buffer_size = 0;
        if (j->rec_mode > -1) {
                ixj_WriteDSPCommand(0x5120, j);
                j->rec_mode = -1;
@@ -4449,13 +4443,11 @@ static int set_play_codec(IXJ *j, int rate)
                j->play_mode = 5;
                break;
        default:
+               kfree(j->write_buffer);
                j->play_frame_size = 0;
                j->play_mode = -1;
-               if (j->write_buffer) {
-                       kfree(j->write_buffer);
-                       j->write_buffer = NULL;
-                       j->write_buffer_size = 0;
-               }
+               j->write_buffer = NULL;
+               j->write_buffer_size = 0;
                retval = 1;
                break;
        }
@@ -4578,14 +4570,12 @@ static int ixj_play_start(IXJ *j)
 
 static void ixj_play_stop(IXJ *j)
 {
-       if(ixjdebug & 0x0002)
+       if (ixjdebug & 0x0002)
                printk("IXJ %d Stopping Play Codec %d at %ld\n", j->board, j->play_codec, jiffies);
 
-       if (j->write_buffer) {
-               kfree(j->write_buffer);
-               j->write_buffer = NULL;
-               j->write_buffer_size = 0;
-       }
+       kfree(j->write_buffer);
+       j->write_buffer = NULL;
+       j->write_buffer_size = 0;
        if (j->play_mode > -1) {
                ixj_WriteDSPCommand(0x5221, j); /* Stop playback and flush buffers.  8022 reference page 9-40 */
 
@@ -5810,9 +5800,7 @@ static void ixj_cpt_stop(IXJ *j)
                ixj_play_tone(j, 0);
                j->tone_state = j->tone_cadence_state = 0;
                if (j->cadence_t) {
-                       if (j->cadence_t->ce) {
-                               kfree(j->cadence_t->ce);
-                       }
+                       kfree(j->cadence_t->ce);
                        kfree(j->cadence_t);
                        j->cadence_t = NULL;
                }
@@ -7497,10 +7485,8 @@ static void cleanup(void)
                                        printk(KERN_INFO "IXJ: Releasing XILINX address for /dev/phone%d\n", cnt);
                                release_region(j->XILINXbase, 4);
                        }
-                       if (j->read_buffer)
-                               kfree(j->read_buffer);
-                       if (j->write_buffer)
-                               kfree(j->write_buffer);
+                       kfree(j->read_buffer);
+                       kfree(j->write_buffer);
                        if (j->dev)
                                pnp_device_detach(j->dev);
                        if (ixjdebug & 0x0002)
index d2d648ee864009cc028d2ce539ffede88f9bf17f..a8d879a85d04a26d6d6b50d03cbbd47445ad9c8a 100644 (file)
@@ -2808,7 +2808,7 @@ static int hub_thread(void *__unused)
        do {
                hub_events();
                wait_event_interruptible(khubd_wait, !list_empty(&hub_event_list)); 
-               try_to_freeze(PF_FREEZE);
+               try_to_freeze();
        } while (!signal_pending(current));
 
        pr_debug ("%s: khubd exiting\n", usbcore_name);
index 037a7f163822d6c74c4a671d0a904b5e02a577e8..a9be85103d2342a920c892f3a3952ef663e37ecd 100644 (file)
@@ -1554,8 +1554,7 @@ static int sleep_thread(struct fsg_dev *fsg)
        rc = wait_event_interruptible(fsg->thread_wqh,
                        fsg->thread_wakeup_needed);
        fsg->thread_wakeup_needed = 0;
-       if (current->flags & PF_FREEZE)
-               refrigerator(PF_FREEZE);
+       try_to_freeze();
        return (rc ? -EINTR : 0);
 }
 
index 35c1ca6b5a8eb828613fe87fbfac1dfeaaa918fe..77e7fc258aa2a7c104da2ba0a74a203525849d4d 100644 (file)
@@ -847,10 +847,8 @@ retry:
                wait_event_interruptible_timeout(us->delay_wait,
                                test_bit(US_FLIDX_DISCONNECTING, &us->flags),
                                delay_use * HZ);
-               if (current->flags & PF_FREEZE) {
-                       refrigerator(PF_FREEZE);
+               if (try_to_freeze())
                        goto retry;
-               }
        }
 
        /* If the device is still connected, perform the scanning */
index cacd88cc84ab6e56c680ae8b543e06e7a6e89034..b6fe30c3ad6253691417d61552643805ac31d57b 100644 (file)
@@ -111,15 +111,15 @@ static int au1100fb_ioctl(struct inode *inode, struct file *file, u_int cmd,
 void au1100_nocursor(struct display *p, int mode, int xx, int yy){};
 
 static struct fb_ops au1100fb_ops = {
-       owner:          THIS_MODULE,
-       fb_get_fix:     fbgen_get_fix,
-       fb_get_var:     fbgen_get_var,
-       fb_set_var:     fbgen_set_var,
-       fb_get_cmap:    fbgen_get_cmap,
-       fb_set_cmap:    fbgen_set_cmap,
-       fb_pan_display: fbgen_pan_display,
-        fb_ioctl:       au1100fb_ioctl,
-       fb_mmap:        au1100fb_mmap,
+       .owner          = THIS_MODULE,
+       .fb_get_fix     = fbgen_get_fix,
+       .fb_get_var     = fbgen_get_var,
+       .fb_set_var     = fbgen_set_var,
+       .fb_get_cmap    = fbgen_get_cmap,
+       .fb_set_cmap    = fbgen_set_cmap,
+       .fb_pan_display = fbgen_pan_display,
+        .fb_ioctl      = au1100fb_ioctl,
+       .fb_mmap        = au1100fb_mmap,
 };
 
 static void au1100_detect(void)
index e4b91a4b936c9c9125d42eb799973fab6b7aec83..cbff98337aa6b37069e62bd03d4fc67c7e5eb15a 100644 (file)
@@ -156,7 +156,6 @@ config FONT_6x11
 config FONT_7x14
        bool "console 7x14 font (not supported by all drivers)" if FONTS
        depends on FRAMEBUFFER_CONSOLE
-       default y if !SPARC32 && !SPARC64 && !FONTS
        help
          Console font with characters just a bit smaller than the default.
          If the standard 8x16 font is a little too big for you, say Y.
@@ -197,8 +196,8 @@ config FONT_SUN12x22
          standard font is unreadable for you, say Y, otherwise say N.
 
 config FONT_10x18
-       bool "console 10x18 font (not supported by all drivers)"
-       depends on FONTS
+       bool "console 10x18 font (not supported by all drivers)" if FONTS
+       depends on FRAMEBUFFER_CONSOLE
        help
          This is a high resolution console font for machines with very
          big letters. It fits between the sun 12x22 and the normal 8x16 font.
index 277d733c6d00a4150436c42b234aec4edc572b15..7dfbf39b4ed3c9c59ea502bd9a507d1a7a224c75 100644 (file)
@@ -228,8 +228,6 @@ static ssize_t store_virtual(struct class_device *class_device,
        if (last - buf >= count)
                return -EINVAL;
        var.yres_virtual = simple_strtoul(last, &last, 0);
-       printk(KERN_ERR "fb: xres %d yres %d\n", var.xres_virtual,
-              var.yres_virtual);
 
        if ((err = activate(fb_info, &var)))
                return err;
index 76fd3a519b8af1d1d637a308c6d1e969bf99b37c..a18dd024fc86a9384b67c49391c1685ca75e95f3 100644 (file)
@@ -197,10 +197,7 @@ int matroxfb_vgaHWinit(WPMINFO struct my_timming* m) {
        DBG(__FUNCTION__)
 
        hw->SEQ[0] = 0x00;
-       if (fwidth == 9)
-               hw->SEQ[1] = 0x00;
-       else
-               hw->SEQ[1] = 0x01;      /* or 0x09 */
+       hw->SEQ[1] = 0x01;      /* or 0x09 */
        hw->SEQ[2] = 0x0F;      /* bitplanes */
        hw->SEQ[3] = 0x00;
        hw->SEQ[4] = 0x0E;
index f3069b01e248efa1eaf86e00fec16ff6047fc048..9ed1a931dd315c8008d7d6b952f1a34900c2222f 100644 (file)
@@ -389,10 +389,11 @@ static int __init vesafb_probe(struct device *device)
                unsigned int temp_size = size_total;
                /* Find the largest power-of-two */
                while (temp_size & (temp_size - 1))
-                       temp_size &= (temp_size - 1);
-                        
-                /* Try and find a power of two to add */
-               while (temp_size && mtrr_add(vesafb_fix.smem_start, temp_size, MTRR_TYPE_WRCOMB, 1)==-EINVAL) {
+                       temp_size &= (temp_size - 1);
+
+               /* Try and find a power of two to add */
+               while (temp_size > PAGE_SIZE &&
+                       mtrr_add(vesafb_fix.smem_start, temp_size, MTRR_TYPE_WRCOMB, 1)==-EINVAL) {
                        temp_size >>= 1;
                }
        }
index b460927ec32ad78432660372a7fa20ab49dedfef..312cf3220f12dfa9f81f1515cb793efa3fa7db32 100644 (file)
@@ -646,7 +646,7 @@ static int w1_control(void *data)
        while (!control_needs_exit || have_to_wait) {
                have_to_wait = 0;
 
-               try_to_freeze(PF_FREEZE);
+               try_to_freeze();
                msleep_interruptible(w1_timeout * 1000);
 
                if (signal_pending(current))
@@ -725,7 +725,7 @@ int w1_process(void *data)
        allow_signal(SIGTERM);
 
        while (!test_bit(W1_MASTER_NEED_EXIT, &dev->flags)) {
-               try_to_freeze(PF_FREEZE);
+               try_to_freeze();
                msleep_interruptible(w1_timeout * 1000);
 
                if (signal_pending(current))
index 8157f2e2d515fb37ff1ad81dde3e22cd22905254..062177956239b1c25c6199579e9f72faecc21212 100644 (file)
@@ -734,6 +734,12 @@ config PROC_KCORE
        bool "/proc/kcore support" if !ARM
        depends on PROC_FS && MMU
 
+config PROC_VMCORE
+        bool "/proc/vmcore support (EXPERIMENTAL)"
+        depends on PROC_FS && EMBEDDED && EXPERIMENTAL && CRASH_DUMP
+        help
+        Exports the dump image of crashed kernel in ELF format.
+
 config SYSFS
        bool "sysfs file system support" if EMBEDDED
        default y
index 6fc88ae8ad9477fd3e12d5d151ef7a142266dfee..7ac07d0d47b91b90e4c40dc16216e50b5876d0af 100644 (file)
@@ -116,7 +116,7 @@ static int kafsasyncd(void *arg)
                remove_wait_queue(&kafsasyncd_sleepq, &myself);
                set_current_state(TASK_RUNNING);
 
-               try_to_freeze(PF_FREEZE);
+               try_to_freeze();
 
                /* discard pending signals */
                afs_discard_my_signals();
index 86e710dd057e766ed89a59c83c8d4ea3c02ff5e0..65bc05ab81826b417513f203a5b7e930d7b9fed7 100644 (file)
@@ -91,7 +91,7 @@ static int kafstimod(void *arg)
                        complete_and_exit(&kafstimod_dead, 0);
                }
 
-               try_to_freeze(PF_FREEZE);
+               try_to_freeze();
 
                /* discard pending signals */
                afs_discard_my_signals();
index 37212b039a4ab834770bfd663f503dcaa669a37a..b9732335bcdcd6006733a9561e9ef8ceb8769117 100644 (file)
@@ -409,13 +409,10 @@ out_dqlock:
  * for this sb+type at all. */
 static void invalidate_dquots(struct super_block *sb, int type)
 {
-       struct dquot *dquot;
-       struct list_head *head;
+       struct dquot *dquot, *tmp;
 
        spin_lock(&dq_list_lock);
-       for (head = inuse_list.next; head != &inuse_list;) {
-               dquot = list_entry(head, struct dquot, dq_inuse);
-               head = head->next;
+       list_for_each_entry_safe(dquot, tmp, &inuse_list, dq_inuse) {
                if (dquot->dq_sb != sb)
                        continue;
                if (dquot->dq_type != type)
index 1e6f2e2ad4a33d48b6ed38d8e21f0ed68f865b88..5e7b439495171c9d0fcfa7f28b2fa51aab489823 100644 (file)
@@ -167,7 +167,7 @@ loop:
        }
 
        wake_up(&journal->j_wait_done_commit);
-       if (current->flags & PF_FREEZE) {
+       if (freezing(current)) {
                /*
                 * The simpler the better. Flushing journal isn't a
                 * good idea, because that depends on threads that may
@@ -175,7 +175,7 @@ loop:
                 */
                jbd_debug(1, "Now suspending kjournald\n");
                spin_unlock(&journal->j_state_lock);
-               refrigerator(PF_FREEZE);
+               refrigerator();
                spin_lock(&journal->j_state_lock);
        } else {
                /*
index 8cc6893fc56cd61a44015313e3cc5a907dff1115..fc589ddd0762d6491a3ab7d151c760a36e6d08d1 100644 (file)
@@ -175,8 +175,64 @@ jffs_hexdump(struct mtd_info *mtd, loff_t pos, int size)
        }
 }
 
+/* Print the contents of a node.  */
+static void
+jffs_print_node(struct jffs_node *n)
+{
+       D(printk("jffs_node: 0x%p\n", n));
+       D(printk("{\n"));
+       D(printk("        0x%08x, /* version  */\n", n->version));
+       D(printk("        0x%08x, /* data_offset  */\n", n->data_offset));
+       D(printk("        0x%08x, /* data_size  */\n", n->data_size));
+       D(printk("        0x%08x, /* removed_size  */\n", n->removed_size));
+       D(printk("        0x%08x, /* fm_offset  */\n", n->fm_offset));
+       D(printk("        0x%02x,       /* name_size  */\n", n->name_size));
+       D(printk("        0x%p, /* fm,  fm->offset: %u  */\n",
+                n->fm, (n->fm ? n->fm->offset : 0)));
+       D(printk("        0x%p, /* version_prev  */\n", n->version_prev));
+       D(printk("        0x%p, /* version_next  */\n", n->version_next));
+       D(printk("        0x%p, /* range_prev  */\n", n->range_prev));
+       D(printk("        0x%p, /* range_next  */\n", n->range_next));
+       D(printk("}\n"));
+}
+
 #endif
 
+/* Print the contents of a raw inode.  */
+static void
+jffs_print_raw_inode(struct jffs_raw_inode *raw_inode)
+{
+       D(printk("jffs_raw_inode: inode number: %u\n", raw_inode->ino));
+       D(printk("{\n"));
+       D(printk("        0x%08x, /* magic  */\n", raw_inode->magic));
+       D(printk("        0x%08x, /* ino  */\n", raw_inode->ino));
+       D(printk("        0x%08x, /* pino  */\n", raw_inode->pino));
+       D(printk("        0x%08x, /* version  */\n", raw_inode->version));
+       D(printk("        0x%08x, /* mode  */\n", raw_inode->mode));
+       D(printk("        0x%04x,     /* uid  */\n", raw_inode->uid));
+       D(printk("        0x%04x,     /* gid  */\n", raw_inode->gid));
+       D(printk("        0x%08x, /* atime  */\n", raw_inode->atime));
+       D(printk("        0x%08x, /* mtime  */\n", raw_inode->mtime));
+       D(printk("        0x%08x, /* ctime  */\n", raw_inode->ctime));
+       D(printk("        0x%08x, /* offset  */\n", raw_inode->offset));
+       D(printk("        0x%08x, /* dsize  */\n", raw_inode->dsize));
+       D(printk("        0x%08x, /* rsize  */\n", raw_inode->rsize));
+       D(printk("        0x%02x,       /* nsize  */\n", raw_inode->nsize));
+       D(printk("        0x%02x,       /* nlink  */\n", raw_inode->nlink));
+       D(printk("        0x%02x,       /* spare  */\n",
+                raw_inode->spare));
+       D(printk("        %u,          /* rename  */\n",
+                raw_inode->rename));
+       D(printk("        %u,          /* deleted  */\n",
+                raw_inode->deleted));
+       D(printk("        0x%02x,       /* accurate  */\n",
+                raw_inode->accurate));
+       D(printk("        0x%08x, /* dchksum  */\n", raw_inode->dchksum));
+       D(printk("        0x%04x,     /* nchksum  */\n", raw_inode->nchksum));
+       D(printk("        0x%04x,     /* chksum  */\n", raw_inode->chksum));
+       D(printk("}\n"));
+}
+
 #define flash_safe_acquire(arg)
 #define flash_safe_release(arg)
 
@@ -2507,64 +2563,6 @@ jffs_update_file(struct jffs_file *f, struct jffs_node *node)
        return 0;
 }
 
-/* Print the contents of a node.  */
-void
-jffs_print_node(struct jffs_node *n)
-{
-       D(printk("jffs_node: 0x%p\n", n));
-       D(printk("{\n"));
-       D(printk("        0x%08x, /* version  */\n", n->version));
-       D(printk("        0x%08x, /* data_offset  */\n", n->data_offset));
-       D(printk("        0x%08x, /* data_size  */\n", n->data_size));
-       D(printk("        0x%08x, /* removed_size  */\n", n->removed_size));
-       D(printk("        0x%08x, /* fm_offset  */\n", n->fm_offset));
-       D(printk("        0x%02x,       /* name_size  */\n", n->name_size));
-       D(printk("        0x%p, /* fm,  fm->offset: %u  */\n",
-                n->fm, (n->fm ? n->fm->offset : 0)));
-       D(printk("        0x%p, /* version_prev  */\n", n->version_prev));
-       D(printk("        0x%p, /* version_next  */\n", n->version_next));
-       D(printk("        0x%p, /* range_prev  */\n", n->range_prev));
-       D(printk("        0x%p, /* range_next  */\n", n->range_next));
-       D(printk("}\n"));
-}
-
-
-/* Print the contents of a raw inode.  */
-void
-jffs_print_raw_inode(struct jffs_raw_inode *raw_inode)
-{
-       D(printk("jffs_raw_inode: inode number: %u\n", raw_inode->ino));
-       D(printk("{\n"));
-       D(printk("        0x%08x, /* magic  */\n", raw_inode->magic));
-       D(printk("        0x%08x, /* ino  */\n", raw_inode->ino));
-       D(printk("        0x%08x, /* pino  */\n", raw_inode->pino));
-       D(printk("        0x%08x, /* version  */\n", raw_inode->version));
-       D(printk("        0x%08x, /* mode  */\n", raw_inode->mode));
-       D(printk("        0x%04x,     /* uid  */\n", raw_inode->uid));
-       D(printk("        0x%04x,     /* gid  */\n", raw_inode->gid));
-       D(printk("        0x%08x, /* atime  */\n", raw_inode->atime));
-       D(printk("        0x%08x, /* mtime  */\n", raw_inode->mtime));
-       D(printk("        0x%08x, /* ctime  */\n", raw_inode->ctime));
-       D(printk("        0x%08x, /* offset  */\n", raw_inode->offset));
-       D(printk("        0x%08x, /* dsize  */\n", raw_inode->dsize));
-       D(printk("        0x%08x, /* rsize  */\n", raw_inode->rsize));
-       D(printk("        0x%02x,       /* nsize  */\n", raw_inode->nsize));
-       D(printk("        0x%02x,       /* nlink  */\n", raw_inode->nlink));
-       D(printk("        0x%02x,       /* spare  */\n",
-                raw_inode->spare));
-       D(printk("        %u,          /* rename  */\n",
-                raw_inode->rename));
-       D(printk("        %u,          /* deleted  */\n",
-                raw_inode->deleted));
-       D(printk("        0x%02x,       /* accurate  */\n",
-                raw_inode->accurate));
-       D(printk("        0x%08x, /* dchksum  */\n", raw_inode->dchksum));
-       D(printk("        0x%04x,     /* nchksum  */\n", raw_inode->nchksum));
-       D(printk("        0x%04x,     /* chksum  */\n", raw_inode->chksum));
-       D(printk("}\n"));
-}
-
-
 /* Print the contents of a file.  */
 #if 0
 int
index 4ae97b17911c581908cb8324455aa176c72428ad..5c7abe0e26953555549a3361109d5110da7a106f 100644 (file)
@@ -49,8 +49,6 @@ int jffs_garbage_collect_thread(void *c);
 void jffs_garbage_collect_trigger(struct jffs_control *c);
 
 /* For debugging purposes.  */
-void jffs_print_node(struct jffs_node *n);
-void jffs_print_raw_inode(struct jffs_raw_inode *raw_inode);
 #if 0
 int jffs_print_file(struct jffs_file *f);
 #endif  /*  0  */
index 0cab8da49d3c445fb6ed0d7dda4f9ebbb613f510..053e3a98a276ec1f63d0a7035355d06b94474cdd 100644 (file)
@@ -31,6 +31,60 @@ static void jffs_free_fm(struct jffs_fm *n);
 extern kmem_cache_t     *fm_cache;
 extern kmem_cache_t     *node_cache;
 
+#if CONFIG_JFFS_FS_VERBOSE > 0
+void
+jffs_print_fmcontrol(struct jffs_fmcontrol *fmc)
+{
+       D(printk("struct jffs_fmcontrol: 0x%p\n", fmc));
+       D(printk("{\n"));
+       D(printk("        %u, /* flash_size  */\n", fmc->flash_size));
+       D(printk("        %u, /* used_size  */\n", fmc->used_size));
+       D(printk("        %u, /* dirty_size  */\n", fmc->dirty_size));
+       D(printk("        %u, /* free_size  */\n", fmc->free_size));
+       D(printk("        %u, /* sector_size  */\n", fmc->sector_size));
+       D(printk("        %u, /* min_free_size  */\n", fmc->min_free_size));
+       D(printk("        %u, /* max_chunk_size  */\n", fmc->max_chunk_size));
+       D(printk("        0x%p, /* mtd  */\n", fmc->mtd));
+       D(printk("        0x%p, /* head  */    "
+                "(head->offset = 0x%08x)\n",
+                fmc->head, (fmc->head ? fmc->head->offset : 0)));
+       D(printk("        0x%p, /* tail  */    "
+                "(tail->offset + tail->size = 0x%08x)\n",
+                fmc->tail,
+                (fmc->tail ? fmc->tail->offset + fmc->tail->size : 0)));
+       D(printk("        0x%p, /* head_extra  */\n", fmc->head_extra));
+       D(printk("        0x%p, /* tail_extra  */\n", fmc->tail_extra));
+       D(printk("}\n"));
+}
+#endif  /*  CONFIG_JFFS_FS_VERBOSE > 0  */
+
+#if CONFIG_JFFS_FS_VERBOSE > 2
+static void
+jffs_print_fm(struct jffs_fm *fm)
+{
+       D(printk("struct jffs_fm: 0x%p\n", fm));
+       D(printk("{\n"));
+       D(printk("       0x%08x, /* offset  */\n", fm->offset));
+       D(printk("       %u, /* size  */\n", fm->size));
+       D(printk("       0x%p, /* prev  */\n", fm->prev));
+       D(printk("       0x%p, /* next  */\n", fm->next));
+       D(printk("       0x%p, /* nodes  */\n", fm->nodes));
+       D(printk("}\n"));
+}
+#endif  /*  CONFIG_JFFS_FS_VERBOSE > 2  */
+
+#if 0
+void
+jffs_print_node_ref(struct jffs_node_ref *ref)
+{
+       D(printk("struct jffs_node_ref: 0x%p\n", ref));
+       D(printk("{\n"));
+       D(printk("       0x%p, /* node  */\n", ref->node));
+       D(printk("       0x%p, /* next  */\n", ref->next));
+       D(printk("}\n"));
+}
+#endif  /*  0  */
+
 /* This function creates a new shiny flash memory control structure.  */
 struct jffs_fmcontrol *
 jffs_build_begin(struct jffs_control *c, int unit)
@@ -742,54 +796,3 @@ int jffs_get_node_inuse(void)
 {
        return no_jffs_node;
 }
-
-void
-jffs_print_fmcontrol(struct jffs_fmcontrol *fmc)
-{
-       D(printk("struct jffs_fmcontrol: 0x%p\n", fmc));
-       D(printk("{\n"));
-       D(printk("        %u, /* flash_size  */\n", fmc->flash_size));
-       D(printk("        %u, /* used_size  */\n", fmc->used_size));
-       D(printk("        %u, /* dirty_size  */\n", fmc->dirty_size));
-       D(printk("        %u, /* free_size  */\n", fmc->free_size));
-       D(printk("        %u, /* sector_size  */\n", fmc->sector_size));
-       D(printk("        %u, /* min_free_size  */\n", fmc->min_free_size));
-       D(printk("        %u, /* max_chunk_size  */\n", fmc->max_chunk_size));
-       D(printk("        0x%p, /* mtd  */\n", fmc->mtd));
-       D(printk("        0x%p, /* head  */    "
-                "(head->offset = 0x%08x)\n",
-                fmc->head, (fmc->head ? fmc->head->offset : 0)));
-       D(printk("        0x%p, /* tail  */    "
-                "(tail->offset + tail->size = 0x%08x)\n",
-                fmc->tail,
-                (fmc->tail ? fmc->tail->offset + fmc->tail->size : 0)));
-       D(printk("        0x%p, /* head_extra  */\n", fmc->head_extra));
-       D(printk("        0x%p, /* tail_extra  */\n", fmc->tail_extra));
-       D(printk("}\n"));
-}
-
-void
-jffs_print_fm(struct jffs_fm *fm)
-{
-       D(printk("struct jffs_fm: 0x%p\n", fm));
-       D(printk("{\n"));
-       D(printk("       0x%08x, /* offset  */\n", fm->offset));
-       D(printk("       %u, /* size  */\n", fm->size));
-       D(printk("       0x%p, /* prev  */\n", fm->prev));
-       D(printk("       0x%p, /* next  */\n", fm->next));
-       D(printk("       0x%p, /* nodes  */\n", fm->nodes));
-       D(printk("}\n"));
-}
-
-#if 0
-void
-jffs_print_node_ref(struct jffs_node_ref *ref)
-{
-       D(printk("struct jffs_node_ref: 0x%p\n", ref));
-       D(printk("{\n"));
-       D(printk("       0x%p, /* node  */\n", ref->node));
-       D(printk("       0x%p, /* next  */\n", ref->next));
-       D(printk("}\n"));
-}
-#endif  /*  0  */
-
index bc291c4318225496cf6ce47bf877db524046d7fd..f64151e741225141f632400ddfded9788c6bb794 100644 (file)
@@ -139,8 +139,9 @@ int jffs_add_node(struct jffs_node *node);
 void jffs_fmfree_partly(struct jffs_fmcontrol *fmc, struct jffs_fm *fm,
                        __u32 size);
 
+#if CONFIG_JFFS_FS_VERBOSE > 0
 void jffs_print_fmcontrol(struct jffs_fmcontrol *fmc);
-void jffs_print_fm(struct jffs_fm *fm);
+#endif
 #if 0
 void jffs_print_node_ref(struct jffs_node_ref *ref);
 #endif  /*  0  */
index 1be6de27dd81142842be0acc56e1a94533580d54..638836b277d444d36c07acc8284a0824e99769f2 100644 (file)
@@ -92,7 +92,7 @@ static int jffs2_garbage_collect_thread(void *_c)
                        schedule();
                }
 
-               if (try_to_freeze(0))
+               if (try_to_freeze())
                        continue;
 
                cond_resched();
index 7c8387ed4192be68cd090956e430cf12eb5ac936..79d07624bfe1787fff2b5ee3b3c8e1479b34ffe3 100644 (file)
@@ -2359,9 +2359,9 @@ int jfsIOWait(void *arg)
                        lbmStartIO(bp);
                        spin_lock_irq(&log_redrive_lock);
                }
-               if (current->flags & PF_FREEZE) {
+               if (freezing(current)) {
                        spin_unlock_irq(&log_redrive_lock);
-                       refrigerator(PF_FREEZE);
+                       refrigerator();
                } else {
                        add_wait_queue(&jfs_IO_thread_wait, &wq);
                        set_current_state(TASK_INTERRUPTIBLE);
index 8cbaaff1d5fa05628f18b0e8213e0ce66dfe3839..121c981ff45363bef9af40c859132ba3e03007f0 100644 (file)
@@ -2788,9 +2788,9 @@ int jfs_lazycommit(void *arg)
                /* In case a wakeup came while all threads were active */
                jfs_commit_thread_waking = 0;
 
-               if (current->flags & PF_FREEZE) {
+               if (freezing(current)) {
                        LAZY_UNLOCK(flags);
-                       refrigerator(PF_FREEZE);
+                       refrigerator();
                } else {
                        DECLARE_WAITQUEUE(wq, current);
 
@@ -2987,9 +2987,9 @@ int jfs_sync(void *arg)
                /* Add anon_list2 back to anon_list */
                list_splice_init(&TxAnchor.anon_list2, &TxAnchor.anon_list);
 
-               if (current->flags & PF_FREEZE) {
+               if (freezing(current)) {
                        TXN_UNLOCK();
-                       refrigerator(PF_FREEZE);
+                       refrigerator();
                } else {
                        DECLARE_WAITQUEUE(wq, current);
 
index 5025563e7379675b7df2834427aabb0800f4b740..58101dff2c66de94fc4fa82bf13696e9d9b8d665 100644 (file)
@@ -183,6 +183,7 @@ struct file_operations simple_dir_operations = {
        .llseek         = dcache_dir_lseek,
        .read           = generic_read_dir,
        .readdir        = dcache_readdir,
+       .fsync          = simple_sync_file,
 };
 
 struct inode_operations simple_dir_inode_operations = {
index fd77ed1d710de4f198c275960f1bb4898f19ef3e..14b3ce87fa29cd96162678fb754936e22c99caec 100644 (file)
@@ -313,7 +313,7 @@ static int nlm_wait_on_grace(wait_queue_head_t *queue)
        prepare_to_wait(queue, &wait, TASK_INTERRUPTIBLE);
        if (!signalled ()) {
                schedule_timeout(NLMCLNT_GRACE_WAIT);
-               try_to_freeze(PF_FREEZE);
+               try_to_freeze();
                if (!signalled ())
                        status = 0;
        }
index 2dc2d8693968e7d223e96cfc8c4aa4aac27d20d6..a9f7a8ab1d595d30fcb656eea4a1349a7f324d43 100644 (file)
@@ -705,18 +705,6 @@ ncp_do_readdir(struct file *filp, void *dirent, filldir_t filldir,
                DPRINTK("ncp_do_readdir: init failed, err=%d\n", err);
                return;
        }
-#ifdef USE_OLD_SLOW_DIRECTORY_LISTING
-       for (;;) {
-               err = ncp_search_for_file_or_subdir(server, &seq, &entry.i);
-               if (err) {
-                       DPRINTK("ncp_do_readdir: search failed, err=%d\n", err);
-                       break;
-               }
-               entry.volume = entry.i.volNumber;
-               if (!ncp_fill_cache(filp, dirent, filldir, ctl, &entry))
-                       break;
-       }
-#else
        /* We MUST NOT use server->buffer_size handshaked with server if we are
           using UDP, as for UDP server uses max. buffer size determined by
           MTU, and for TCP server uses hardwired value 65KB (== 66560 bytes). 
@@ -754,7 +742,6 @@ ncp_do_readdir(struct file *filp, void *dirent, filldir_t filldir,
                }
        } while (more);
        vfree(buf);
-#endif
        return;
 }
 
index e4eb5ed4bee45636c6a2abd4307dbfd804bc15c1..c755e1848a42366d0a08d4e379680b3fc2665a86 100644 (file)
@@ -845,46 +845,6 @@ out:
        return result;
 }
 
-/* Search for everything */
-int ncp_search_for_file_or_subdir(struct ncp_server *server,
-                                 struct nw_search_sequence *seq,
-                                 struct nw_info_struct *target)
-{
-       int result;
-
-       ncp_init_request(server);
-       ncp_add_byte(server, 3);        /* subfunction */
-       ncp_add_byte(server, server->name_space[seq->volNumber]);
-       ncp_add_byte(server, 0);        /* data stream (???) */
-       ncp_add_word(server, cpu_to_le16(0x8006));      /* Search attribs */
-       ncp_add_dword(server, RIM_ALL);         /* return info mask */
-       ncp_add_mem(server, seq, 9);
-#ifdef CONFIG_NCPFS_NFS_NS
-       if (server->name_space[seq->volNumber] == NW_NS_NFS) {
-               ncp_add_byte(server, 0);        /* 0 byte pattern */
-       } else 
-#endif
-       {
-               ncp_add_byte(server, 2);        /* 2 byte pattern */
-               ncp_add_byte(server, 0xff);     /* following is a wildcard */
-               ncp_add_byte(server, '*');
-       }
-       
-       if ((result = ncp_request(server, 87)) != 0)
-               goto out;
-       memcpy(seq, ncp_reply_data(server, 0), sizeof(*seq));
-       ncp_extract_file_info(ncp_reply_data(server, 10), target);
-
-       ncp_unlock_server(server);
-       
-       result = ncp_obtain_nfs_info(server, target);
-       return result;
-
-out:
-       ncp_unlock_server(server);
-       return result;
-}
-
 int ncp_search_for_fileset(struct ncp_server *server,
                           struct nw_search_sequence *seq,
                           int* more,
index 05ec2e9d90c626e5d61e1d39f81f04f37677f196..9e4dc30c2435c207ddce4d2c67311db24429d457 100644 (file)
@@ -87,9 +87,6 @@ int ncp_open_create_file_or_subdir(struct ncp_server *, struct inode *, char *,
 
 int ncp_initialize_search(struct ncp_server *, struct inode *,
                      struct nw_search_sequence *target);
-int ncp_search_for_file_or_subdir(struct ncp_server *server,
-                             struct nw_search_sequence *seq,
-                             struct nw_info_struct *target);
 int ncp_search_for_fileset(struct ncp_server *server,
                           struct nw_search_sequence *seq,
                           int* more, int* cnt,
index 4c83c17969e12505248dc0767985af06b568062e..66d5cc26fafbf65bfcdf4b18a0ee49c5e48ebbc7 100644 (file)
@@ -17,4 +17,3 @@ obj-$(CONFIG_SUN_PARTITION) += sun.o
 obj-$(CONFIG_ULTRIX_PARTITION) += ultrix.o
 obj-$(CONFIG_IBM_PARTITION) += ibm.o
 obj-$(CONFIG_EFI_PARTITION) += efi.o
-obj-$(CONFIG_NEC98_PARTITION) += nec98.o msdos.o
index 2cab98a9a621ce12a2f402688acb976b6a5ef9e8..77e178f13162abef0305852554dbfa73d2a99ff0 100644 (file)
@@ -79,9 +79,6 @@ static int (*check_part[])(struct parsed_partitions *, struct block_device *) =
 #ifdef CONFIG_LDM_PARTITION
        ldm_partition,          /* this must come before msdos */
 #endif
-#ifdef CONFIG_NEC98_PARTITION
-       nec98_partition,        /* must be come before `msdos_partition' */
-#endif
 #ifdef CONFIG_MSDOS_PARTITION
        msdos_partition,
 #endif
index 43adcc68e47197c8bcc86dca3ae7327e2c5c43e9..17ae8ecd9e8b60afae6a8538d850ed7032477a4f 100644 (file)
@@ -30,7 +30,3 @@ put_partition(struct parsed_partitions *p, int n, sector_t from, sector_t size)
 
 extern int warn_no_part;
 
-extern void parse_bsd(struct parsed_partitions *state,
-                       struct block_device *bdev, u32 offset, u32 size,
-                       int origin, char *flavour, int max_partitions);
-
index 584a27b2bbd5a5cfc4317356a28efb3b42ef427f..9935d254186ef10276781815193995895b3dab8b 100644 (file)
@@ -202,12 +202,12 @@ parse_solaris_x86(struct parsed_partitions *state, struct block_device *bdev,
 #endif
 }
 
-#if defined(CONFIG_BSD_DISKLABEL) || defined(CONFIG_NEC98_PARTITION)
+#if defined(CONFIG_BSD_DISKLABEL)
 /* 
  * Create devices for BSD partitions listed in a disklabel, under a
  * dos-like partition. See parse_extended() for more information.
  */
-void
+static void
 parse_bsd(struct parsed_partitions *state, struct block_device *bdev,
                u32 offset, u32 size, int origin, char *flavour,
                int max_partitions)
index 738b9b602932b9b61eb0ced4841a4cbc1f88b312..7431d7ba2d097981e1e87a191dc0ab81a2684537 100644 (file)
@@ -11,4 +11,5 @@ proc-y       += inode.o root.o base.o generic.o array.o \
                kmsg.o proc_tty.o proc_misc.o
 
 proc-$(CONFIG_PROC_KCORE)      += kcore.o
+proc-$(CONFIG_PROC_VMCORE)     += vmcore.o
 proc-$(CONFIG_PROC_DEVICETREE) += proc_devtree.o
index 94b570ad037d7e76cd00ebbb5999d42f2df8a0b4..a3453555a94e76ca4e84952a993049faa257f2b4 100644 (file)
@@ -44,6 +44,7 @@
 #include <linux/jiffies.h>
 #include <linux/sysrq.h>
 #include <linux/vmalloc.h>
+#include <linux/crash_dump.h>
 #include <asm/uaccess.h>
 #include <asm/pgtable.h>
 #include <asm/io.h>
@@ -618,6 +619,11 @@ void __init proc_misc_init(void)
                                (size_t)high_memory - PAGE_OFFSET + PAGE_SIZE;
        }
 #endif
+#ifdef CONFIG_PROC_VMCORE
+       proc_vmcore = create_proc_entry("vmcore", S_IRUSR, NULL);
+       if (proc_vmcore)
+               proc_vmcore->proc_fops = &proc_vmcore_operations;
+#endif
 #ifdef CONFIG_MAGIC_SYSRQ
        entry = create_proc_entry("sysrq-trigger", S_IWUSR, NULL);
        if (entry)
diff --git a/fs/proc/vmcore.c b/fs/proc/vmcore.c
new file mode 100644 (file)
index 0000000..3b2e7b6
--- /dev/null
@@ -0,0 +1,669 @@
+/*
+ *     fs/proc/vmcore.c Interface for accessing the crash
+ *                              dump from the system's previous life.
+ *     Heavily borrowed from fs/proc/kcore.c
+ *     Created by: Hariprasad Nellitheertha (hari@in.ibm.com)
+ *     Copyright (C) IBM Corporation, 2004. All rights reserved
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/mm.h>
+#include <linux/proc_fs.h>
+#include <linux/user.h>
+#include <linux/a.out.h>
+#include <linux/elf.h>
+#include <linux/elfcore.h>
+#include <linux/proc_fs.h>
+#include <linux/highmem.h>
+#include <linux/bootmem.h>
+#include <linux/init.h>
+#include <linux/crash_dump.h>
+#include <linux/list.h>
+#include <asm/uaccess.h>
+#include <asm/io.h>
+
+/* List representing chunks of contiguous memory areas and their offsets in
+ * vmcore file.
+ */
+static LIST_HEAD(vmcore_list);
+
+/* Stores the pointer to the buffer containing kernel elf core headers. */
+static char *elfcorebuf;
+static size_t elfcorebuf_sz;
+
+/* Total size of vmcore file. */
+static u64 vmcore_size;
+
+struct proc_dir_entry *proc_vmcore = NULL;
+
+/* Reads a page from the oldmem device from given offset. */
+static ssize_t read_from_oldmem(char *buf, size_t count,
+                            loff_t *ppos, int userbuf)
+{
+       unsigned long pfn, offset;
+       size_t nr_bytes;
+       ssize_t read = 0, tmp;
+
+       if (!count)
+               return 0;
+
+       offset = (unsigned long)(*ppos % PAGE_SIZE);
+       pfn = (unsigned long)(*ppos / PAGE_SIZE);
+       if (pfn > saved_max_pfn)
+               return -EINVAL;
+
+       do {
+               if (count > (PAGE_SIZE - offset))
+                       nr_bytes = PAGE_SIZE - offset;
+               else
+                       nr_bytes = count;
+
+               tmp = copy_oldmem_page(pfn, buf, nr_bytes, offset, userbuf);
+               if (tmp < 0)
+                       return tmp;
+               *ppos += nr_bytes;
+               count -= nr_bytes;
+               buf += nr_bytes;
+               read += nr_bytes;
+               ++pfn;
+               offset = 0;
+       } while (count);
+
+       return read;
+}
+
+/* Maps vmcore file offset to respective physical address in memroy. */
+static u64 map_offset_to_paddr(loff_t offset, struct list_head *vc_list,
+                                       struct vmcore **m_ptr)
+{
+       struct vmcore *m;
+       u64 paddr;
+
+       list_for_each_entry(m, vc_list, list) {
+               u64 start, end;
+               start = m->offset;
+               end = m->offset + m->size - 1;
+               if (offset >= start && offset <= end) {
+                       paddr = m->paddr + offset - start;
+                       *m_ptr = m;
+                       return paddr;
+               }
+       }
+       *m_ptr = NULL;
+       return 0;
+}
+
+/* Read from the ELF header and then the crash dump. On error, negative value is
+ * returned otherwise number of bytes read are returned.
+ */
+static ssize_t read_vmcore(struct file *file, char __user *buffer,
+                               size_t buflen, loff_t *fpos)
+{
+       ssize_t acc = 0, tmp;
+       size_t tsz, nr_bytes;
+       u64 start;
+       struct vmcore *curr_m = NULL;
+
+       if (buflen == 0 || *fpos >= vmcore_size)
+               return 0;
+
+       /* trim buflen to not go beyond EOF */
+       if (buflen > vmcore_size - *fpos)
+               buflen = vmcore_size - *fpos;
+
+       /* Read ELF core header */
+       if (*fpos < elfcorebuf_sz) {
+               tsz = elfcorebuf_sz - *fpos;
+               if (buflen < tsz)
+                       tsz = buflen;
+               if (copy_to_user(buffer, elfcorebuf + *fpos, tsz))
+                       return -EFAULT;
+               buflen -= tsz;
+               *fpos += tsz;
+               buffer += tsz;
+               acc += tsz;
+
+               /* leave now if filled buffer already */
+               if (buflen == 0)
+                       return acc;
+       }
+
+       start = map_offset_to_paddr(*fpos, &vmcore_list, &curr_m);
+       if (!curr_m)
+               return -EINVAL;
+       if ((tsz = (PAGE_SIZE - (start & ~PAGE_MASK))) > buflen)
+               tsz = buflen;
+
+       /* Calculate left bytes in current memory segment. */
+       nr_bytes = (curr_m->size - (start - curr_m->paddr));
+       if (tsz > nr_bytes)
+               tsz = nr_bytes;
+
+       while (buflen) {
+               tmp = read_from_oldmem(buffer, tsz, &start, 1);
+               if (tmp < 0)
+                       return tmp;
+               buflen -= tsz;
+               *fpos += tsz;
+               buffer += tsz;
+               acc += tsz;
+               if (start >= (curr_m->paddr + curr_m->size)) {
+                       if (curr_m->list.next == &vmcore_list)
+                               return acc;     /*EOF*/
+                       curr_m = list_entry(curr_m->list.next,
+                                               struct vmcore, list);
+                       start = curr_m->paddr;
+               }
+               if ((tsz = (PAGE_SIZE - (start & ~PAGE_MASK))) > buflen)
+                       tsz = buflen;
+               /* Calculate left bytes in current memory segment. */
+               nr_bytes = (curr_m->size - (start - curr_m->paddr));
+               if (tsz > nr_bytes)
+                       tsz = nr_bytes;
+       }
+       return acc;
+}
+
+static int open_vmcore(struct inode *inode, struct file *filp)
+{
+       return 0;
+}
+
+struct file_operations proc_vmcore_operations = {
+       .read           = read_vmcore,
+       .open           = open_vmcore,
+};
+
+static struct vmcore* __init get_new_element(void)
+{
+       struct vmcore *p;
+
+       p = kmalloc(sizeof(*p), GFP_KERNEL);
+       if (p)
+               memset(p, 0, sizeof(*p));
+       return p;
+}
+
+static u64 __init get_vmcore_size_elf64(char *elfptr)
+{
+       int i;
+       u64 size;
+       Elf64_Ehdr *ehdr_ptr;
+       Elf64_Phdr *phdr_ptr;
+
+       ehdr_ptr = (Elf64_Ehdr *)elfptr;
+       phdr_ptr = (Elf64_Phdr*)(elfptr + sizeof(Elf64_Ehdr));
+       size = sizeof(Elf64_Ehdr) + ((ehdr_ptr->e_phnum) * sizeof(Elf64_Phdr));
+       for (i = 0; i < ehdr_ptr->e_phnum; i++) {
+               size += phdr_ptr->p_memsz;
+               phdr_ptr++;
+       }
+       return size;
+}
+
+static u64 __init get_vmcore_size_elf32(char *elfptr)
+{
+       int i;
+       u64 size;
+       Elf32_Ehdr *ehdr_ptr;
+       Elf32_Phdr *phdr_ptr;
+
+       ehdr_ptr = (Elf32_Ehdr *)elfptr;
+       phdr_ptr = (Elf32_Phdr*)(elfptr + sizeof(Elf32_Ehdr));
+       size = sizeof(Elf32_Ehdr) + ((ehdr_ptr->e_phnum) * sizeof(Elf32_Phdr));
+       for (i = 0; i < ehdr_ptr->e_phnum; i++) {
+               size += phdr_ptr->p_memsz;
+               phdr_ptr++;
+       }
+       return size;
+}
+
+/* Merges all the PT_NOTE headers into one. */
+static int __init merge_note_headers_elf64(char *elfptr, size_t *elfsz,
+                                               struct list_head *vc_list)
+{
+       int i, nr_ptnote=0, rc=0;
+       char *tmp;
+       Elf64_Ehdr *ehdr_ptr;
+       Elf64_Phdr phdr, *phdr_ptr;
+       Elf64_Nhdr *nhdr_ptr;
+       u64 phdr_sz = 0, note_off;
+
+       ehdr_ptr = (Elf64_Ehdr *)elfptr;
+       phdr_ptr = (Elf64_Phdr*)(elfptr + sizeof(Elf64_Ehdr));
+       for (i = 0; i < ehdr_ptr->e_phnum; i++, phdr_ptr++) {
+               int j;
+               void *notes_section;
+               struct vmcore *new;
+               u64 offset, max_sz, sz, real_sz = 0;
+               if (phdr_ptr->p_type != PT_NOTE)
+                       continue;
+               nr_ptnote++;
+               max_sz = phdr_ptr->p_memsz;
+               offset = phdr_ptr->p_offset;
+               notes_section = kmalloc(max_sz, GFP_KERNEL);
+               if (!notes_section)
+                       return -ENOMEM;
+               rc = read_from_oldmem(notes_section, max_sz, &offset, 0);
+               if (rc < 0) {
+                       kfree(notes_section);
+                       return rc;
+               }
+               nhdr_ptr = notes_section;
+               for (j = 0; j < max_sz; j += sz) {
+                       if (nhdr_ptr->n_namesz == 0)
+                               break;
+                       sz = sizeof(Elf64_Nhdr) +
+                               ((nhdr_ptr->n_namesz + 3) & ~3) +
+                               ((nhdr_ptr->n_descsz + 3) & ~3);
+                       real_sz += sz;
+                       nhdr_ptr = (Elf64_Nhdr*)((char*)nhdr_ptr + sz);
+               }
+
+               /* Add this contiguous chunk of notes section to vmcore list.*/
+               new = get_new_element();
+               if (!new) {
+                       kfree(notes_section);
+                       return -ENOMEM;
+               }
+               new->paddr = phdr_ptr->p_offset;
+               new->size = real_sz;
+               list_add_tail(&new->list, vc_list);
+               phdr_sz += real_sz;
+               kfree(notes_section);
+       }
+
+       /* Prepare merged PT_NOTE program header. */
+       phdr.p_type    = PT_NOTE;
+       phdr.p_flags   = 0;
+       note_off = sizeof(Elf64_Ehdr) +
+                       (ehdr_ptr->e_phnum - nr_ptnote +1) * sizeof(Elf64_Phdr);
+       phdr.p_offset  = note_off;
+       phdr.p_vaddr   = phdr.p_paddr = 0;
+       phdr.p_filesz  = phdr.p_memsz = phdr_sz;
+       phdr.p_align   = 0;
+
+       /* Add merged PT_NOTE program header*/
+       tmp = elfptr + sizeof(Elf64_Ehdr);
+       memcpy(tmp, &phdr, sizeof(phdr));
+       tmp += sizeof(phdr);
+
+       /* Remove unwanted PT_NOTE program headers. */
+       i = (nr_ptnote - 1) * sizeof(Elf64_Phdr);
+       *elfsz = *elfsz - i;
+       memmove(tmp, tmp+i, ((*elfsz)-sizeof(Elf64_Ehdr)-sizeof(Elf64_Phdr)));
+
+       /* Modify e_phnum to reflect merged headers. */
+       ehdr_ptr->e_phnum = ehdr_ptr->e_phnum - nr_ptnote + 1;
+
+       return 0;
+}
+
+/* Merges all the PT_NOTE headers into one. */
+static int __init merge_note_headers_elf32(char *elfptr, size_t *elfsz,
+                                               struct list_head *vc_list)
+{
+       int i, nr_ptnote=0, rc=0;
+       char *tmp;
+       Elf32_Ehdr *ehdr_ptr;
+       Elf32_Phdr phdr, *phdr_ptr;
+       Elf32_Nhdr *nhdr_ptr;
+       u64 phdr_sz = 0, note_off;
+
+       ehdr_ptr = (Elf32_Ehdr *)elfptr;
+       phdr_ptr = (Elf32_Phdr*)(elfptr + sizeof(Elf32_Ehdr));
+       for (i = 0; i < ehdr_ptr->e_phnum; i++, phdr_ptr++) {
+               int j;
+               void *notes_section;
+               struct vmcore *new;
+               u64 offset, max_sz, sz, real_sz = 0;
+               if (phdr_ptr->p_type != PT_NOTE)
+                       continue;
+               nr_ptnote++;
+               max_sz = phdr_ptr->p_memsz;
+               offset = phdr_ptr->p_offset;
+               notes_section = kmalloc(max_sz, GFP_KERNEL);
+               if (!notes_section)
+                       return -ENOMEM;
+               rc = read_from_oldmem(notes_section, max_sz, &offset, 0);
+               if (rc < 0) {
+                       kfree(notes_section);
+                       return rc;
+               }
+               nhdr_ptr = notes_section;
+               for (j = 0; j < max_sz; j += sz) {
+                       if (nhdr_ptr->n_namesz == 0)
+                               break;
+                       sz = sizeof(Elf32_Nhdr) +
+                               ((nhdr_ptr->n_namesz + 3) & ~3) +
+                               ((nhdr_ptr->n_descsz + 3) & ~3);
+                       real_sz += sz;
+                       nhdr_ptr = (Elf32_Nhdr*)((char*)nhdr_ptr + sz);
+               }
+
+               /* Add this contiguous chunk of notes section to vmcore list.*/
+               new = get_new_element();
+               if (!new) {
+                       kfree(notes_section);
+                       return -ENOMEM;
+               }
+               new->paddr = phdr_ptr->p_offset;
+               new->size = real_sz;
+               list_add_tail(&new->list, vc_list);
+               phdr_sz += real_sz;
+               kfree(notes_section);
+       }
+
+       /* Prepare merged PT_NOTE program header. */
+       phdr.p_type    = PT_NOTE;
+       phdr.p_flags   = 0;
+       note_off = sizeof(Elf32_Ehdr) +
+                       (ehdr_ptr->e_phnum - nr_ptnote +1) * sizeof(Elf32_Phdr);
+       phdr.p_offset  = note_off;
+       phdr.p_vaddr   = phdr.p_paddr = 0;
+       phdr.p_filesz  = phdr.p_memsz = phdr_sz;
+       phdr.p_align   = 0;
+
+       /* Add merged PT_NOTE program header*/
+       tmp = elfptr + sizeof(Elf32_Ehdr);
+       memcpy(tmp, &phdr, sizeof(phdr));
+       tmp += sizeof(phdr);
+
+       /* Remove unwanted PT_NOTE program headers. */
+       i = (nr_ptnote - 1) * sizeof(Elf32_Phdr);
+       *elfsz = *elfsz - i;
+       memmove(tmp, tmp+i, ((*elfsz)-sizeof(Elf32_Ehdr)-sizeof(Elf32_Phdr)));
+
+       /* Modify e_phnum to reflect merged headers. */
+       ehdr_ptr->e_phnum = ehdr_ptr->e_phnum - nr_ptnote + 1;
+
+       return 0;
+}
+
+/* Add memory chunks represented by program headers to vmcore list. Also update
+ * the new offset fields of exported program headers. */
+static int __init process_ptload_program_headers_elf64(char *elfptr,
+                                               size_t elfsz,
+                                               struct list_head *vc_list)
+{
+       int i;
+       Elf64_Ehdr *ehdr_ptr;
+       Elf64_Phdr *phdr_ptr;
+       loff_t vmcore_off;
+       struct vmcore *new;
+
+       ehdr_ptr = (Elf64_Ehdr *)elfptr;
+       phdr_ptr = (Elf64_Phdr*)(elfptr + sizeof(Elf64_Ehdr)); /* PT_NOTE hdr */
+
+       /* First program header is PT_NOTE header. */
+       vmcore_off = sizeof(Elf64_Ehdr) +
+                       (ehdr_ptr->e_phnum) * sizeof(Elf64_Phdr) +
+                       phdr_ptr->p_memsz; /* Note sections */
+
+       for (i = 0; i < ehdr_ptr->e_phnum; i++, phdr_ptr++) {
+               if (phdr_ptr->p_type != PT_LOAD)
+                       continue;
+
+               /* Add this contiguous chunk of memory to vmcore list.*/
+               new = get_new_element();
+               if (!new)
+                       return -ENOMEM;
+               new->paddr = phdr_ptr->p_offset;
+               new->size = phdr_ptr->p_memsz;
+               list_add_tail(&new->list, vc_list);
+
+               /* Update the program header offset. */
+               phdr_ptr->p_offset = vmcore_off;
+               vmcore_off = vmcore_off + phdr_ptr->p_memsz;
+       }
+       return 0;
+}
+
+static int __init process_ptload_program_headers_elf32(char *elfptr,
+                                               size_t elfsz,
+                                               struct list_head *vc_list)
+{
+       int i;
+       Elf32_Ehdr *ehdr_ptr;
+       Elf32_Phdr *phdr_ptr;
+       loff_t vmcore_off;
+       struct vmcore *new;
+
+       ehdr_ptr = (Elf32_Ehdr *)elfptr;
+       phdr_ptr = (Elf32_Phdr*)(elfptr + sizeof(Elf32_Ehdr)); /* PT_NOTE hdr */
+
+       /* First program header is PT_NOTE header. */
+       vmcore_off = sizeof(Elf32_Ehdr) +
+                       (ehdr_ptr->e_phnum) * sizeof(Elf32_Phdr) +
+                       phdr_ptr->p_memsz; /* Note sections */
+
+       for (i = 0; i < ehdr_ptr->e_phnum; i++, phdr_ptr++) {
+               if (phdr_ptr->p_type != PT_LOAD)
+                       continue;
+
+               /* Add this contiguous chunk of memory to vmcore list.*/
+               new = get_new_element();
+               if (!new)
+                       return -ENOMEM;
+               new->paddr = phdr_ptr->p_offset;
+               new->size = phdr_ptr->p_memsz;
+               list_add_tail(&new->list, vc_list);
+
+               /* Update the program header offset */
+               phdr_ptr->p_offset = vmcore_off;
+               vmcore_off = vmcore_off + phdr_ptr->p_memsz;
+       }
+       return 0;
+}
+
+/* Sets offset fields of vmcore elements. */
+static void __init set_vmcore_list_offsets_elf64(char *elfptr,
+                                               struct list_head *vc_list)
+{
+       loff_t vmcore_off;
+       Elf64_Ehdr *ehdr_ptr;
+       struct vmcore *m;
+
+       ehdr_ptr = (Elf64_Ehdr *)elfptr;
+
+       /* Skip Elf header and program headers. */
+       vmcore_off = sizeof(Elf64_Ehdr) +
+                       (ehdr_ptr->e_phnum) * sizeof(Elf64_Phdr);
+
+       list_for_each_entry(m, vc_list, list) {
+               m->offset = vmcore_off;
+               vmcore_off += m->size;
+       }
+}
+
+/* Sets offset fields of vmcore elements. */
+static void __init set_vmcore_list_offsets_elf32(char *elfptr,
+                                               struct list_head *vc_list)
+{
+       loff_t vmcore_off;
+       Elf32_Ehdr *ehdr_ptr;
+       struct vmcore *m;
+
+       ehdr_ptr = (Elf32_Ehdr *)elfptr;
+
+       /* Skip Elf header and program headers. */
+       vmcore_off = sizeof(Elf32_Ehdr) +
+                       (ehdr_ptr->e_phnum) * sizeof(Elf32_Phdr);
+
+       list_for_each_entry(m, vc_list, list) {
+               m->offset = vmcore_off;
+               vmcore_off += m->size;
+       }
+}
+
+static int __init parse_crash_elf64_headers(void)
+{
+       int rc=0;
+       Elf64_Ehdr ehdr;
+       u64 addr;
+
+       addr = elfcorehdr_addr;
+
+       /* Read Elf header */
+       rc = read_from_oldmem((char*)&ehdr, sizeof(Elf64_Ehdr), &addr, 0);
+       if (rc < 0)
+               return rc;
+
+       /* Do some basic Verification. */
+       if (memcmp(ehdr.e_ident, ELFMAG, SELFMAG) != 0 ||
+               (ehdr.e_type != ET_CORE) ||
+               !elf_check_arch(&ehdr) ||
+               ehdr.e_ident[EI_CLASS] != ELFCLASS64 ||
+               ehdr.e_ident[EI_VERSION] != EV_CURRENT ||
+               ehdr.e_version != EV_CURRENT ||
+               ehdr.e_ehsize != sizeof(Elf64_Ehdr) ||
+               ehdr.e_phentsize != sizeof(Elf64_Phdr) ||
+               ehdr.e_phnum == 0) {
+               printk(KERN_WARNING "Warning: Core image elf header is not"
+                                       "sane\n");
+               return -EINVAL;
+       }
+
+       /* Read in all elf headers. */
+       elfcorebuf_sz = sizeof(Elf64_Ehdr) + ehdr.e_phnum * sizeof(Elf64_Phdr);
+       elfcorebuf = kmalloc(elfcorebuf_sz, GFP_KERNEL);
+       if (!elfcorebuf)
+               return -ENOMEM;
+       addr = elfcorehdr_addr;
+       rc = read_from_oldmem(elfcorebuf, elfcorebuf_sz, &addr, 0);
+       if (rc < 0) {
+               kfree(elfcorebuf);
+               return rc;
+       }
+
+       /* Merge all PT_NOTE headers into one. */
+       rc = merge_note_headers_elf64(elfcorebuf, &elfcorebuf_sz, &vmcore_list);
+       if (rc) {
+               kfree(elfcorebuf);
+               return rc;
+       }
+       rc = process_ptload_program_headers_elf64(elfcorebuf, elfcorebuf_sz,
+                                                       &vmcore_list);
+       if (rc) {
+               kfree(elfcorebuf);
+               return rc;
+       }
+       set_vmcore_list_offsets_elf64(elfcorebuf, &vmcore_list);
+       return 0;
+}
+
+static int __init parse_crash_elf32_headers(void)
+{
+       int rc=0;
+       Elf32_Ehdr ehdr;
+       u64 addr;
+
+       addr = elfcorehdr_addr;
+
+       /* Read Elf header */
+       rc = read_from_oldmem((char*)&ehdr, sizeof(Elf32_Ehdr), &addr, 0);
+       if (rc < 0)
+               return rc;
+
+       /* Do some basic Verification. */
+       if (memcmp(ehdr.e_ident, ELFMAG, SELFMAG) != 0 ||
+               (ehdr.e_type != ET_CORE) ||
+               !elf_check_arch(&ehdr) ||
+               ehdr.e_ident[EI_CLASS] != ELFCLASS32||
+               ehdr.e_ident[EI_VERSION] != EV_CURRENT ||
+               ehdr.e_version != EV_CURRENT ||
+               ehdr.e_ehsize != sizeof(Elf32_Ehdr) ||
+               ehdr.e_phentsize != sizeof(Elf32_Phdr) ||
+               ehdr.e_phnum == 0) {
+               printk(KERN_WARNING "Warning: Core image elf header is not"
+                                       "sane\n");
+               return -EINVAL;
+       }
+
+       /* Read in all elf headers. */
+       elfcorebuf_sz = sizeof(Elf32_Ehdr) + ehdr.e_phnum * sizeof(Elf32_Phdr);
+       elfcorebuf = kmalloc(elfcorebuf_sz, GFP_KERNEL);
+       if (!elfcorebuf)
+               return -ENOMEM;
+       addr = elfcorehdr_addr;
+       rc = read_from_oldmem(elfcorebuf, elfcorebuf_sz, &addr, 0);
+       if (rc < 0) {
+               kfree(elfcorebuf);
+               return rc;
+       }
+
+       /* Merge all PT_NOTE headers into one. */
+       rc = merge_note_headers_elf32(elfcorebuf, &elfcorebuf_sz, &vmcore_list);
+       if (rc) {
+               kfree(elfcorebuf);
+               return rc;
+       }
+       rc = process_ptload_program_headers_elf32(elfcorebuf, elfcorebuf_sz,
+                                                               &vmcore_list);
+       if (rc) {
+               kfree(elfcorebuf);
+               return rc;
+       }
+       set_vmcore_list_offsets_elf32(elfcorebuf, &vmcore_list);
+       return 0;
+}
+
+static int __init parse_crash_elf_headers(void)
+{
+       unsigned char e_ident[EI_NIDENT];
+       u64 addr;
+       int rc=0;
+
+       addr = elfcorehdr_addr;
+       rc = read_from_oldmem(e_ident, EI_NIDENT, &addr, 0);
+       if (rc < 0)
+               return rc;
+       if (memcmp(e_ident, ELFMAG, SELFMAG) != 0) {
+               printk(KERN_WARNING "Warning: Core image elf header"
+                                       " not found\n");
+               return -EINVAL;
+       }
+
+       if (e_ident[EI_CLASS] == ELFCLASS64) {
+               rc = parse_crash_elf64_headers();
+               if (rc)
+                       return rc;
+
+               /* Determine vmcore size. */
+               vmcore_size = get_vmcore_size_elf64(elfcorebuf);
+       } else if (e_ident[EI_CLASS] == ELFCLASS32) {
+               rc = parse_crash_elf32_headers();
+               if (rc)
+                       return rc;
+
+               /* Determine vmcore size. */
+               vmcore_size = get_vmcore_size_elf32(elfcorebuf);
+       } else {
+               printk(KERN_WARNING "Warning: Core image elf header is not"
+                                       " sane\n");
+               return -EINVAL;
+       }
+       return 0;
+}
+
+/* Init function for vmcore module. */
+static int __init vmcore_init(void)
+{
+       int rc = 0;
+
+       /* If elfcorehdr= has been passed in cmdline, then capture the dump.*/
+       if (!(elfcorehdr_addr < ELFCORE_ADDR_MAX))
+               return rc;
+       rc = parse_crash_elf_headers();
+       if (rc) {
+               printk(KERN_WARNING "Kdump: vmcore not initialized\n");
+               return rc;
+       }
+
+       /* Initialize /proc/vmcore size if proc is already up. */
+       if (proc_vmcore)
+               proc_vmcore->size = vmcore_size;
+       return 0;
+}
+module_init(vmcore_init)
index 0d5817f8197201c77163f480815215dedf11af6e..289d864fe73189947416e1f6bc965da948554000 100644 (file)
@@ -254,6 +254,7 @@ static int _get_block_create_0 (struct inode * inode, long block,
     char * p = NULL;
     int chars;
     int ret ;
+    int result ;
     int done = 0 ;
     unsigned long offset ;
 
@@ -262,10 +263,13 @@ static int _get_block_create_0 (struct inode * inode, long block,
                  (loff_t)block * inode->i_sb->s_blocksize + 1, TYPE_ANY, 3);
 
 research:
-    if (search_for_position_by_key (inode->i_sb, &key, &path) != POSITION_FOUND) {
+    result = search_for_position_by_key (inode->i_sb, &key, &path) ;
+    if (result != POSITION_FOUND) {
        pathrelse (&path);
         if (p)
             kunmap(bh_result->b_page) ;
+       if (result == IO_ERROR)
+           return -EIO;
        // We do not return -ENOENT if there is a hole but page is uptodate, because it means
        // That there is some MMAPED data associated with it that is yet to be written to disk.
        if ((args & GET_BLOCK_NO_HOLE) && !PageUptodate(bh_result->b_page) ) {
@@ -382,8 +386,9 @@ research:
 
        // update key to look for the next piece
        set_cpu_key_k_offset (&key, cpu_key_k_offset (&key) + chars);
-       if (search_for_position_by_key (inode->i_sb, &key, &path) != POSITION_FOUND)
-           // we read something from tail, even if now we got IO_ERROR
+       result = search_for_position_by_key (inode->i_sb, &key, &path);
+       if (result != POSITION_FOUND)
+           // i/o error most likely
            break;
        bh = get_last_bh (&path);
        ih = get_ih (&path);
@@ -394,6 +399,10 @@ research:
 
 finished:
     pathrelse (&path);
+
+    if (result == IO_ERROR)
+       return -EIO;
+
     /* this buffer has valid data, but isn't valid for io.  mapping it to
      * block #0 tells the rest of reiserfs it just has a tail in it
      */
index c60e69431e11d746abc9b41d3c525c0ac65116d7..df0cba239dd589b2ac7b9fbb90aa0909190a5ac3 100644 (file)
@@ -1771,9 +1771,9 @@ xfsbufd(
 
        INIT_LIST_HEAD(&tmp);
        do {
-               if (unlikely(current->flags & PF_FREEZE)) {
+               if (unlikely(freezing(current))) {
                        xfsbufd_force_sleep = 1;
-                       refrigerator(PF_FREEZE);
+                       refrigerator();
                } else {
                        xfsbufd_force_sleep = 0;
                }
index 5fe9af38aa2063ac56c23ef7faa39a539b4161d1..f6dd7de2592748c95dee026e0f865ec37d5ca89b 100644 (file)
@@ -483,7 +483,7 @@ xfssyncd(
                set_current_state(TASK_INTERRUPTIBLE);
                timeleft = schedule_timeout(timeleft);
                /* swsusp */
-               try_to_freeze(PF_FREEZE);
+               try_to_freeze();
                if (vfsp->vfs_flag & VFS_UMOUNT)
                        break;
 
index 5e56b47446e0c4a2ba6e8fe9ea1d7a5dd3ed9e02..3241cd6f0778e0384e188a945a8747f705f68750 100644 (file)
 
 #define IO_SPACE_LIMIT         0xffffffff
 #define __mem_pci(a)           (a)
-#define ___io(p)               ((void __iomem *)((p)+IXP2000_PCI_IO_VIRT_BASE))
 
 /*
- * The IXP2400 before revision B0 asserts byte lanes for PCI I/O
+ * The A? revisions of the IXP2000s assert byte lanes for PCI I/O
  * transactions the other way round (MEM transactions don't have this
- * issue), so we need to override the standard functions.  B0 and later
- * have a bit that can be set to 1 to get the 'proper' behavior, but
- * since that isn't available on the A? revisions we just keep doing
- * things manually.
+ * issue), so if we want to support those models, we need to override
+ * the standard I/O functions.
+ *
+ * B0 and later have a bit that can be set to 1 to get the proper
+ * behavior for I/O transactions, which then allows us to use the
+ * standard I/O functions.  This is what we do if the user does not
+ * explicitly ask for support for pre-B0.
  */
+#ifdef CONFIG_IXP2000_SUPPORT_BROKEN_PCI_IO
+#define ___io(p)               ((void __iomem *)((p)+IXP2000_PCI_IO_VIRT_BASE))
+
 #define alignb(addr)           (void __iomem *)((unsigned long)(addr) ^ 3)
 #define alignw(addr)           (void __iomem *)((unsigned long)(addr) ^ 2)
 
 #define ioport_map(port, nr)   ___io(port)
 
 #define ioport_unmap(addr)
+#else
+#define __io(p)                        ((void __iomem *)((p)+IXP2000_PCI_IO_VIRT_BASE))
+#endif
 
 
 #ifdef CONFIG_ARCH_IXDP2X01
index a1d9e181b10f1c1d579cf4b3fa4d30db1a39b9a5..5eb47d4bfbf63e2ca1e555e75603d97fc8b634d6 100644 (file)
 #define PCI_CONTROL_BE_DEI             (1 << 21)       /* Big Endian Data Enable In  */
 #define PCI_CONTROL_BE_BEO             (1 << 20)       /* Big Endian Byte Enable Out */
 #define PCI_CONTROL_BE_BEI             (1 << 19)       /* Big Endian Byte Enable In  */
-#define PCI_CONTROL_PNR                        (1 << 17)       /* PCI Not Reset bit */
+#define PCI_CONTROL_IEE                        (1 << 17)       /* I/O cycle Endian swap Enable */
 
 #define IXP2000_PCI_RST_REL            (1 << 2)
 #define CFG_RST_DIR                    (*IXP2000_PCI_CONTROL & IXP2000_PCICNTL_PCF)
index 5cf4fd659fd54d4b64e2c4dbd9faa1690da22f72..047980ad18d119aeb2e6136bba3221294fb75883 100644 (file)
@@ -39,8 +39,29 @@ struct sys_timer {
        void                    (*suspend)(void);
        void                    (*resume)(void);
        unsigned long           (*offset)(void);
+
+#ifdef CONFIG_NO_IDLE_HZ
+       struct dyn_tick_timer   *dyn_tick;
+#endif
+};
+
+#ifdef CONFIG_NO_IDLE_HZ
+
+#define DYN_TICK_SKIPPING      (1 << 2)
+#define DYN_TICK_ENABLED       (1 << 1)
+#define DYN_TICK_SUITABLE      (1 << 0)
+
+struct dyn_tick_timer {
+       unsigned int    state;                  /* Current state */
+       int             (*enable)(void);        /* Enables dynamic tick */
+       int             (*disable)(void);       /* Disables dynamic tick */
+       void            (*reprogram)(unsigned long); /* Reprograms the timer */
+       int             (*handler)(int, void *, struct pt_regs *);
 };
 
+void timer_dyn_reprogram(void);
+#endif
+
 extern struct sys_timer *system_timer;
 extern void timer_tick(struct pt_regs *);
 
index 46e69ae395af53a9d2c7db10be7479ec12836678..760f6e65af05583c2faea5b1997989d8435c5c3b 100644 (file)
@@ -114,6 +114,7 @@ typedef unsigned long sigset_t;
 #define SIGSTKSZ       8192
 
 #ifdef __KERNEL__
+#define SA_TIMER               0x40000000
 #define SA_IRQNOMASK           0x08000000
 #endif
 
index 39dd7008013c839a102bc49f53ba4ba5691ab864..3d0d2860b6db103c3969f60d4cf06975304032d8 100644 (file)
@@ -145,34 +145,12 @@ extern unsigned int user_debug;
 #define set_wmb(var, value) do { var = value; wmb(); } while (0)
 #define nop() __asm__ __volatile__("mov\tr0,r0\t@ nop\n\t");
 
-#ifdef CONFIG_SMP
 /*
- * Define our own context switch locking.  This allows us to enable
- * interrupts over the context switch, otherwise we end up with high
- * interrupt latency.  The real problem area is switch_mm() which may
- * do a full cache flush.
+ * switch_mm() may do a full cache flush over the context switch,
+ * so enable interrupts over the context switch to avoid high
+ * latency.
  */
-#define prepare_arch_switch(rq,next)                                   \
-do {                                                                   \
-       spin_lock(&(next)->switch_lock);                                \
-       spin_unlock_irq(&(rq)->lock);                                   \
-} while (0)
-
-#define finish_arch_switch(rq,prev)                                    \
-       spin_unlock(&(prev)->switch_lock)
-
-#define task_running(rq,p)                                             \
-       ((rq)->curr == (p) || spin_is_locked(&(p)->switch_lock))
-#else
-/*
- * Our UP-case is more simple, but we assume knowledge of how
- * spin_unlock_irq() and friends are implemented.  This avoids
- * us needlessly decrementing and incrementing the preempt count.
- */
-#define prepare_arch_switch(rq,next)   local_irq_enable()
-#define finish_arch_switch(rq,prev)    spin_unlock(&(rq)->lock)
-#define task_running(rq,p)             ((rq)->curr == (p))
-#endif
+#define __ARCH_WANT_INTERRUPTS_ON_CTXSW
 
 /*
  * switch_to(prev, next) should switch from task `prev' to `next'
index 99cef06a364a6cdc3a3fc4756cb29646cbeb7925..b3bb326ae5b618a74cc3ca79d158f6d8b92c5743 100644 (file)
@@ -73,7 +73,7 @@
        }
 
 #define SECURITY_INIT                                                  \
-       .security_initcall.init : {                                     \
+       .security_initcall.init : AT(ADDR(.security_initcall.init) - LOAD_OFFSET) { \
                VMLINUX_SYMBOL(__security_initcall_start) = .;          \
                *(.security_initcall.init)                              \
                VMLINUX_SYMBOL(__security_initcall_end) = .;            \
index a5810cf7b5783b9c156a33af77b1d1f0e960246e..6a1b1882285c004a1c5f80b109c046fe483c8bee 100644 (file)
@@ -5,6 +5,7 @@
 #include <linux/pm.h>
 #include <asm/fixmap.h>
 #include <asm/apicdef.h>
+#include <asm/processor.h>
 #include <asm/system.h>
 
 #define Dprintk(x...)
 #define APIC_VERBOSE 1
 #define APIC_DEBUG   2
 
+extern int enable_local_apic;
 extern int apic_verbosity;
 
+static inline void lapic_disable(void)
+{
+       enable_local_apic = -1;
+       clear_bit(X86_FEATURE_APIC, boot_cpu_data.x86_capability);
+}
+
+static inline void lapic_enable(void)
+{
+       enable_local_apic = 1;
+}
+
 /*
  * Define the default level of output to be very little
  * This can be turned up by using apic=verbose for more
@@ -87,7 +100,7 @@ extern void (*wait_timer_tick)(void);
 extern int get_maxlvt(void);
 extern void clear_local_APIC(void);
 extern void connect_bsp_APIC (void);
-extern void disconnect_bsp_APIC (void);
+extern void disconnect_bsp_APIC (int virt_wire_setup);
 extern void disable_local_APIC (void);
 extern void lapic_shutdown (void);
 extern int verify_local_APIC (void);
index c689554ad5b98a9db353e427ed58018c1b09b767..0fed5e3c699c738009d3113edcc2c7436433f6c0 100644 (file)
 #define                        APIC_LVT_REMOTE_IRR             (1<<14)
 #define                        APIC_INPUT_POLARITY             (1<<13)
 #define                        APIC_SEND_PENDING               (1<<12)
+#define                        APIC_MODE_MASK                  0x700
 #define                        GET_APIC_DELIVERY_MODE(x)       (((x)>>8)&0x7)
 #define                        SET_APIC_DELIVERY_MODE(x,y)     (((x)&~0x700)|((y)<<8))
 #define                                APIC_MODE_FIXED         0x0
 #define                                APIC_MODE_NMI           0x4
-#define                                APIC_MODE_EXINT         0x7
+#define                                APIC_MODE_EXTINT        0x7
 #define        APIC_LVT1       0x360
 #define                APIC_LVTERR     0x370
 #define                APIC_TMICT      0x380
index 002740b2195113799e2c7fe592f3f46e1b8e2a71..e7252c216ca81cc8d6543f51b51fa1f8a216d194 100644 (file)
@@ -5,6 +5,7 @@
 #include <linux/cpu.h>
 #include <linux/topology.h>
 #include <linux/nodemask.h>
+#include <linux/percpu.h>
 
 #include <asm/node.h>
 
@@ -16,4 +17,5 @@ extern int arch_register_cpu(int num);
 extern void arch_unregister_cpu(int);
 #endif
 
+DECLARE_PER_CPU(int, cpu_state);
 #endif /* _ASM_I386_CPU_H_ */
index 1df42bf347df6783e5d1d8bd7c6849505f7537d3..0fd331306b60115f9b889fe74313722ae28141ac 100644 (file)
@@ -70,6 +70,7 @@ void *kmap(struct page *page);
 void kunmap(struct page *page);
 void *kmap_atomic(struct page *page, enum km_type type);
 void kunmap_atomic(void *kvaddr, enum km_type type);
+void *kmap_atomic_pfn(unsigned long pfn, enum km_type type);
 struct page *kmap_atomic_to_page(void *ptr);
 
 #define flush_cache_kmaps()    do { } while (0)
index 05b9e61b0a7252c51ab218735160da67e39b0afc..270f1986b19f781ff7788a126d2d1486b5e5bfbc 100644 (file)
@@ -29,13 +29,19 @@ extern void release_vm86_irqs(struct task_struct *);
 
 #ifdef CONFIG_4KSTACKS
   extern void irq_ctx_init(int cpu);
+  extern void irq_ctx_exit(int cpu);
 # define __ARCH_HAS_DO_SOFTIRQ
 #else
 # define irq_ctx_init(cpu) do { } while (0)
+# define irq_ctx_exit(cpu) do { } while (0)
 #endif
 
 #ifdef CONFIG_IRQBALANCE
 extern int irqbalance_disable(char *str);
 #endif
 
+#ifdef CONFIG_HOTPLUG_CPU
+extern void fixup_irqs(cpumask_t map);
+#endif
+
 #endif /* _ASM_IRQ_H */
index de6498b0d49381e0d37cb0318ab245d6c28acdd4..b3f8d5f59d5d8fc02cc1c5f88bce01921c641496 100644 (file)
@@ -18,7 +18,7 @@ struct die_args {
 };
 
 /* Note - you should never unregister because that can race with NMIs.
-   If you really want to do it first unregister - then synchronize_kernel - then free.
+   If you really want to do it first unregister - then synchronize_sched - then free.
   */
 int register_die_notifier(struct notifier_block *nb);
 extern struct notifier_block *i386die_chain;
diff --git a/include/asm-i386/kexec.h b/include/asm-i386/kexec.h
new file mode 100644 (file)
index 0000000..6ed2a03
--- /dev/null
@@ -0,0 +1,33 @@
+#ifndef _I386_KEXEC_H
+#define _I386_KEXEC_H
+
+#include <asm/fixmap.h>
+
+/*
+ * KEXEC_SOURCE_MEMORY_LIMIT maximum page get_free_page can return.
+ * I.e. Maximum page that is mapped directly into kernel memory,
+ * and kmap is not required.
+ *
+ * Someone correct me if FIXADDR_START - PAGEOFFSET is not the correct
+ * calculation for the amount of memory directly mappable into the
+ * kernel memory space.
+ */
+
+/* Maximum physical address we can use pages from */
+#define KEXEC_SOURCE_MEMORY_LIMIT (-1UL)
+/* Maximum address we can reach in physical address mode */
+#define KEXEC_DESTINATION_MEMORY_LIMIT (-1UL)
+/* Maximum address we can use for the control code buffer */
+#define KEXEC_CONTROL_MEMORY_LIMIT TASK_SIZE
+
+#define KEXEC_CONTROL_CODE_SIZE        4096
+
+/* The native architecture */
+#define KEXEC_ARCH KEXEC_ARCH_386
+
+#define MAX_NOTE_BYTES 1024
+typedef u32 note_buf_t[MAX_NOTE_BYTES/4];
+
+extern note_buf_t crash_notes[];
+
+#endif /* _I386_KEXEC_H */
index 6f2b17a2008995d4939313982b165a8937ea6214..cc756a67cd63fee819143ff9994acf675de2de75 100644 (file)
@@ -4,11 +4,34 @@
 void send_IPI_mask_bitmask(cpumask_t mask, int vector);
 void __send_IPI_shortcut(unsigned int shortcut, int vector);
 
+extern int no_broadcast;
+
 static inline void send_IPI_mask(cpumask_t mask, int vector)
 {
        send_IPI_mask_bitmask(mask, vector);
 }
 
+static inline void __local_send_IPI_allbutself(int vector)
+{
+       if (no_broadcast) {
+               cpumask_t mask = cpu_online_map;
+               int this_cpu = get_cpu();
+
+               cpu_clear(this_cpu, mask);
+               send_IPI_mask(mask, vector);
+               put_cpu();
+       } else
+               __send_IPI_shortcut(APIC_DEST_ALLBUT, vector);
+}
+
+static inline void __local_send_IPI_all(int vector)
+{
+       if (no_broadcast)
+               send_IPI_mask(cpu_online_map, vector);
+       else
+               __send_IPI_shortcut(APIC_DEST_ALLINC, vector);
+}
+
 static inline void send_IPI_allbutself(int vector)
 {
        /*
@@ -18,13 +41,13 @@ static inline void send_IPI_allbutself(int vector)
        if (!(num_online_cpus() > 1))
                return;
 
-       __send_IPI_shortcut(APIC_DEST_ALLBUT, vector);
+       __local_send_IPI_allbutself(vector);
        return;
 }
 
 static inline void send_IPI_all(int vector)
 {
-       __send_IPI_shortcut(APIC_DEST_ALLINC, vector);
+       __local_send_IPI_all(vector);
 }
 
 #endif /* __ASM_MACH_IPI_H */
index dea8f8e6d86ed60dc5bcfdafd324fd16f9c421ef..8d93f732d72d0586dc1598542ffa354893351808 100644 (file)
@@ -126,9 +126,12 @@ extern int page_is_ram(unsigned long pagenr);
 
 #ifdef __ASSEMBLY__
 #define __PAGE_OFFSET          (0xC0000000)
+#define __PHYSICAL_START       CONFIG_PHYSICAL_START
 #else
 #define __PAGE_OFFSET          (0xC0000000UL)
+#define __PHYSICAL_START       ((unsigned long)CONFIG_PHYSICAL_START)
 #endif
+#define __KERNEL_START         (__PAGE_OFFSET + __PHYSICAL_START)
 
 
 #define PAGE_OFFSET            ((unsigned long)__PAGE_OFFSET)
index c76c50e9622533caaeaf44f5e9ba35b9ff972a19..6f0f93d0d41741ea7f094a3975f7cae5843aa44f 100644 (file)
@@ -691,5 +691,7 @@ extern void select_idle_routine(const struct cpuinfo_x86 *c);
 #define cache_line_size() (boot_cpu_data.x86_cache_alignment)
 
 extern unsigned long boot_option_idle_override;
+extern void enable_sep_cpu(void);
+extern int sysenter_setup(void);
 
 #endif /* __ASM_I386_PROCESSOR_H */
index 55ef31f66bbec2c7771a7571658dad9451dd4823..edad9b4712fafe5ffbc9fed0cd1d075bf6cc1a79 100644 (file)
@@ -42,10 +42,17 @@ extern void smp_message_irq(int cpl, void *dev_id, struct pt_regs *regs);
 extern void smp_invalidate_rcv(void);          /* Process an NMI */
 extern void (*mtrr_hook) (void);
 extern void zap_low_mappings (void);
+extern void lock_ipi_call_lock(void);
+extern void unlock_ipi_call_lock(void);
 
 #define MAX_APICID 256
 extern u8 x86_cpu_to_apicid[];
 
+#ifdef CONFIG_HOTPLUG_CPU
+extern void cpu_exit_clear(void);
+extern void cpu_uninit(void);
+#endif
+
 /*
  * This function is needed by all SMP systems. It must _always_ be valid
  * from the initial startup. We map APIC_BASE very early in page_setup(),
@@ -83,6 +90,9 @@ static __inline int logical_smp_processor_id(void)
 }
 
 #endif
+
+extern int __cpu_disable(void);
+extern void __cpu_die(unsigned int cpu);
 #endif /* !__ASSEMBLY__ */
 
 #define NO_PROC_ID             0xFF            /* No processor magic marker */
index 6d0f67507b2101dcca96f484def09841fc82aa9c..2461b731781ebc182fd7b70c534b6dd87bb15e76 100644 (file)
@@ -74,11 +74,14 @@ static inline int node_to_first_cpu(int node)
        .imbalance_pct          = 125,                  \
        .cache_hot_time         = (10*1000000),         \
        .cache_nice_tries       = 1,                    \
+       .busy_idx               = 3,                    \
+       .idle_idx               = 1,                    \
+       .newidle_idx            = 2,                    \
+       .wake_idx               = 1,                    \
        .per_cpu_gain           = 100,                  \
        .flags                  = SD_LOAD_BALANCE       \
                                | SD_BALANCE_EXEC       \
-                               | SD_BALANCE_NEWIDLE    \
-                               | SD_WAKE_IDLE          \
+                               | SD_BALANCE_FORK       \
                                | SD_WAKE_BALANCE,      \
        .last_balance           = jiffies,              \
        .balance_interval       = 1,                    \
index 6f516e76d1f0cf0947d99fa6d429f01657343791..cd2cf76b2db1d77cb22a69f928f96c4a74d1c59c 100644 (file)
@@ -183,8 +183,6 @@ do {                                                                \
 
 #ifdef __KERNEL__
 
-#define prepare_to_switch()    do { } while(0)
-
 #ifdef CONFIG_IA32_SUPPORT
 # define IS_IA32_PROCESS(regs) (ia64_psr(regs)->is != 0)
 #else
@@ -274,13 +272,7 @@ extern void ia64_load_extra (struct task_struct *task);
  * of that CPU which will not be released, because there we wait for the
  * tasklist_lock to become available.
  */
-#define prepare_arch_switch(rq, next)          \
-do {                                           \
-       spin_lock(&(next)->switch_lock);        \
-       spin_unlock(&(rq)->lock);               \
-} while (0)
-#define finish_arch_switch(rq, prev)   spin_unlock_irq(&(prev)->switch_lock)
-#define task_running(rq, p)            ((rq)->curr == (p) || spin_is_locked(&(p)->switch_lock))
+#define __ARCH_WANT_UNLOCKED_CTXSW
 
 #define ia64_platform_is(x) (strcmp(x, platform_name) == 0)
 
index 21cf351fd05cce785e81aa3243c68b4848c804ff..4e64c2a6b36913a5f2a0da25c9c7195ff39d747f 100644 (file)
 
 void build_cpu_to_node_map(void);
 
+#define SD_CPU_INIT (struct sched_domain) {            \
+       .span                   = CPU_MASK_NONE,        \
+       .parent                 = NULL,                 \
+       .groups                 = NULL,                 \
+       .min_interval           = 1,                    \
+       .max_interval           = 4,                    \
+       .busy_factor            = 64,                   \
+       .imbalance_pct          = 125,                  \
+       .cache_hot_time         = (10*1000000),         \
+       .per_cpu_gain           = 100,                  \
+       .cache_nice_tries       = 2,                    \
+       .busy_idx               = 2,                    \
+       .idle_idx               = 1,                    \
+       .newidle_idx            = 2,                    \
+       .wake_idx               = 1,                    \
+       .forkexec_idx           = 1,                    \
+       .flags                  = SD_LOAD_BALANCE       \
+                               | SD_BALANCE_NEWIDLE    \
+                               | SD_BALANCE_EXEC       \
+                               | SD_WAKE_AFFINE,       \
+       .last_balance           = jiffies,              \
+       .balance_interval       = 1,                    \
+       .nr_balance_failed      = 0,                    \
+}
+
 /* sched_domains SD_NODE_INIT for IA64 NUMA machines */
 #define SD_NODE_INIT (struct sched_domain) {           \
        .span                   = CPU_MASK_NONE,        \
        .parent                 = NULL,                 \
        .groups                 = NULL,                 \
-       .min_interval           = 80,                   \
-       .max_interval           = 320,                  \
-       .busy_factor            = 320,                  \
+       .min_interval           = 8                   \
+       .max_interval           = 8*(min(num_online_cpus(), 32)), \
+       .busy_factor            = 64,                   \
        .imbalance_pct          = 125,                  \
        .cache_hot_time         = (10*1000000),         \
-       .cache_nice_tries       = 1,                    \
+       .cache_nice_tries       = 2,                    \
+       .busy_idx               = 3,                    \
+       .idle_idx               = 2,                    \
+       .newidle_idx            = 0, /* unused */       \
+       .wake_idx               = 1,                    \
+       .forkexec_idx           = 1,                    \
        .per_cpu_gain           = 100,                  \
        .flags                  = SD_LOAD_BALANCE       \
                                | SD_BALANCE_EXEC       \
-                               | SD_BALANCE_NEWIDLE    \
-                               | SD_WAKE_IDLE          \
+                               | SD_BALANCE_FORK       \
                                | SD_WAKE_BALANCE,      \
        .last_balance           = jiffies,              \
-       .balance_interval       = 1,                    \
+       .balance_interval       = 64,                   \
        .nr_balance_failed      = 0,                    \
 }
 
@@ -69,17 +98,21 @@ void build_cpu_to_node_map(void);
        .span                   = CPU_MASK_NONE,        \
        .parent                 = NULL,                 \
        .groups                 = NULL,                 \
-       .min_interval           = 80,                   \
-       .max_interval           = 320,                  \
-       .busy_factor            = 320,                  \
-       .imbalance_pct          = 125,                  \
+       .min_interval           = 64,                   \
+       .max_interval           = 64*num_online_cpus(), \
+       .busy_factor            = 128,                  \
+       .imbalance_pct          = 133,                  \
        .cache_hot_time         = (10*1000000),         \
        .cache_nice_tries       = 1,                    \
+       .busy_idx               = 3,                    \
+       .idle_idx               = 3,                    \
+       .newidle_idx            = 0, /* unused */       \
+       .wake_idx               = 0, /* unused */       \
+       .forkexec_idx           = 0, /* unused */       \
        .per_cpu_gain           = 100,                  \
-       .flags                  = SD_LOAD_BALANCE       \
-                               | SD_BALANCE_EXEC,      \
+       .flags                  = SD_LOAD_BALANCE,      \
        .last_balance           = jiffies,              \
-       .balance_interval       = 100*(63+num_online_cpus())/64,   \
+       .balance_interval       = 64,                   \
        .nr_balance_failed      = 0,                    \
 }
 
index 29ee13be0b2ad28687ae2eb57edc546f5ca9fdf0..d721143dbd47596f4387c8ba72f9baa1153c4ef1 100644 (file)
@@ -8,6 +8,8 @@
 #include <asm/page.h>
 #include <mmzone.h>
 
+#ifdef CONFIG_DISCONTIGMEM
+
 #define kvaddr_to_nid(kvaddr)  pa_to_nid(__pa(kvaddr))
 #define pfn_to_nid(pfn)                pa_to_nid((pfn) << PAGE_SHIFT)
 
@@ -36,4 +38,6 @@
 /* XXX: FIXME -- wli */
 #define kern_addr_valid(addr)  (0)
 
+#endif /* CONFIG_DISCONTIGMEM */
+
 #endif /* _ASM_MMZONE_H_ */
index d1bf8240e73b258ff411918683ae7045cdf5493c..5cae35cd9ba923f76e49754d5a81757fdd2f83ad 100644 (file)
@@ -127,7 +127,7 @@ static __inline__ int get_order(unsigned long size)
 
 #define pfn_to_kaddr(pfn)      __va((pfn) << PAGE_SHIFT)
 
-#ifndef CONFIG_DISCONTIGMEM
+#ifndef CONFIG_NEED_MULTIPLE_NODES
 #define pfn_to_page(pfn)       (mem_map + (pfn))
 #define page_to_pfn(page)      ((unsigned long)((page) - mem_map))
 #define pfn_valid(pfn)         ((pfn) < max_mapnr)
index 878843203d67aca6580f2aa2d997d39a6685b56e..e76ccd6e3a5dcc8ef9760d7a48bc62b2414af3d8 100644 (file)
@@ -350,7 +350,7 @@ static inline void update_mmu_cache(struct vm_area_struct *vma,
        __update_cache(vma, address, pte);
 }
 
-#ifndef CONFIG_DISCONTIGMEM
+#ifndef CONFIG_NEED_MULTIPLE_NODES
 #define kern_addr_valid(addr)  (1)
 #endif
 
index 888fd8908467210cc9344e3ce3050eabd28ee2de..169f3d4265b14fdeec80c30982572938bab81fc1 100644 (file)
@@ -422,16 +422,10 @@ extern void __die_if_kernel(const char *, struct pt_regs *, const char *file,
 extern int stop_a_enabled;
 
 /*
- * Taken from include/asm-ia64/system.h; prevents deadlock on SMP
+ * See include/asm-ia64/system.h; prevents deadlock on SMP
  * systems.
  */
-#define prepare_arch_switch(rq, next)          \
-do {                                           \
-       spin_lock(&(next)->switch_lock);        \
-       spin_unlock(&(rq)->lock);               \
-} while (0)
-#define finish_arch_switch(rq, prev)   spin_unlock_irq(&(prev)->switch_lock)
-#define task_running(rq, p)            ((rq)->curr == (p) || spin_is_locked(&(p)->switch_lock))
+#define __ARCH_WANT_UNLOCKED_CTXSW
 
 #define arch_align_stack(x) (x)
 
diff --git a/include/asm-ppc/fsl_ocp.h b/include/asm-ppc/fsl_ocp.h
deleted file mode 100644 (file)
index 050fbba..0000000
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * include/asm-ppc/fsl_ocp.h
- *
- * Definitions for the on-chip peripherals on Freescale PPC processors
- *
- * Maintainer: Kumar Gala (kumar.gala@freescale.com)
- *
- * Copyright 2004 Freescale Semiconductor, Inc
- *
- * This program is free software; you can redistribute  it and/or modify it
- * under  the terms of  the GNU General  Public License as published by the
- * Free Software Foundation;  either version 2 of the  License, or (at your
- * option) any later version.
- */
-
-#ifdef __KERNEL__
-#ifndef __ASM_FS_OCP_H__
-#define __ASM_FS_OCP_H__
-
-/* A table of information for supporting the Gianfar Ethernet Controller
- * This helps identify which enet controller we are dealing with,
- * and what type of enet controller it is
- */
-struct ocp_gfar_data {
-       uint interruptTransmit;
-       uint interruptError;
-       uint interruptReceive;
-       uint interruptPHY;
-       uint flags;
-       uint phyid;
-       uint phyregidx;
-       unsigned char mac_addr[6];
-};
-
-/* Flags in the flags field */
-#define GFAR_HAS_COALESCE              0x20
-#define GFAR_HAS_RMON                  0x10
-#define GFAR_HAS_MULTI_INTR            0x08
-#define GFAR_FIRM_SET_MACADDR          0x04
-#define GFAR_HAS_PHY_INTR              0x02    /* if not set use a timer */
-#define GFAR_HAS_GIGABIT               0x01
-
-/* Data structure for I2C support.  Just contains a couple flags
- * to distinguish various I2C implementations*/
-struct ocp_fs_i2c_data {
-       uint flags;
-};
-
-/* Flags for I2C */
-#define FS_I2C_SEPARATE_DFSRR  0x02
-#define FS_I2C_CLOCK_5200      0x01
-
-#endif /* __ASM_FS_OCP_H__ */
-#endif /* __KERNEL__ */
diff --git a/include/asm-ppc/kexec.h b/include/asm-ppc/kexec.h
new file mode 100644 (file)
index 0000000..7319131
--- /dev/null
@@ -0,0 +1,38 @@
+#ifndef _PPC_KEXEC_H
+#define _PPC_KEXEC_H
+
+#ifdef CONFIG_KEXEC
+
+/*
+ * KEXEC_SOURCE_MEMORY_LIMIT maximum page get_free_page can return.
+ * I.e. Maximum page that is mapped directly into kernel memory,
+ * and kmap is not required.
+ *
+ * Someone correct me if FIXADDR_START - PAGEOFFSET is not the correct
+ * calculation for the amount of memory directly mappable into the
+ * kernel memory space.
+ */
+
+/* Maximum physical address we can use pages from */
+#define KEXEC_SOURCE_MEMORY_LIMIT (-1UL)
+/* Maximum address we can reach in physical address mode */
+#define KEXEC_DESTINATION_MEMORY_LIMIT (-1UL)
+/* Maximum address we can use for the control code buffer */
+#define KEXEC_CONTROL_MEMORY_LIMIT TASK_SIZE
+
+#define KEXEC_CONTROL_CODE_SIZE        4096
+
+/* The native architecture */
+#define KEXEC_ARCH KEXEC_ARCH_PPC
+
+#ifndef __ASSEMBLY__
+
+struct kimage;
+
+extern void machine_kexec_simple(struct kimage *image);
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* CONFIG_KEXEC */
+
+#endif /* _PPC_KEXEC_H */
index b78d40870c951ac1a41c7133ac3edcc0acad1532..1d4ab70a56f353eed0e22d06d3241983d9559d42 100644 (file)
@@ -4,6 +4,7 @@
 
 #include <linux/config.h>
 #include <linux/init.h>
+#include <linux/kexec.h>
 
 #include <asm/setup.h>
 #include <asm/page.h>
@@ -114,6 +115,36 @@ struct machdep_calls {
        /* functions for dealing with other cpus */
        struct smp_ops_t *smp_ops;
 #endif /* CONFIG_SMP */
+
+#ifdef CONFIG_KEXEC
+       /* Called to shutdown machine specific hardware not already controlled
+        * by other drivers.
+        * XXX Should we move this one out of kexec scope?
+        */
+       void (*machine_shutdown)(void);
+
+       /* Called to do the minimal shutdown needed to run a kexec'd kernel
+        * to run successfully.
+        * XXX Should we move this one out of kexec scope?
+        */
+       void (*machine_crash_shutdown)(void);
+
+       /* Called to do what every setup is needed on image and the
+        * reboot code buffer. Returns 0 on success.
+        * Provide your own (maybe dummy) implementation if your platform
+        * claims to support kexec.
+        */
+       int (*machine_kexec_prepare)(struct kimage *image);
+
+       /* Called to handle any machine specific cleanup on image */
+       void (*machine_kexec_cleanup)(struct kimage *image);
+
+       /* Called to perform the _real_ kexec.
+        * Do NOT allocate memory or fail here. We are past the point of
+        * no return.
+        */
+       void (*machine_kexec)(struct kimage *image);
+#endif /* CONFIG_KEXEC */
 };
 
 extern struct machdep_calls ppc_md;
index d465aee1c82ea6c554b986c9058e71e2af75b01c..9205db404c7a27fb9d8b7be620a083323a928588 100644 (file)
@@ -405,7 +405,7 @@ typedef struct _P601_BAT {
 
 #define MAS0_TLBSEL(x) ((x << 28) & 0x30000000)
 #define MAS0_ESEL(x)   ((x << 16) & 0x0FFF0000)
-#define MAS0_NV                0x00000FFF
+#define MAS0_NV(x)     ((x) & 0x00000FFF)
 
 #define MAS1_VALID     0x80000000
 #define MAS1_IPROT     0x40000000
index 9222fa6ca172337970970985870ceca2d9dabe84..ccabbce39d8538702683e0fd51e30680018607f7 100644 (file)
@@ -63,7 +63,7 @@ static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk)
 #define LAST_CONTEXT           255
 #define FIRST_CONTEXT          1
 
-#elif defined(CONFIG_E500)
+#elif defined(CONFIG_E200) || defined(CONFIG_E500)
 #define NO_CONTEXT             256
 #define LAST_CONTEXT           255
 #define FIRST_CONTEXT          1
index c726f18451906536ea29f337251d633035b2f98e..983116f59d909f0e802c6f19c30a5d5a9a974e82 100644 (file)
@@ -202,10 +202,6 @@ static DEVICE_ATTR(name##_##field, S_IRUGO, show_##name##_##field, NULL);
 #include <asm/ibm_ocp.h>
 #endif
 
-#ifdef CONFIG_FSL_OCP
-#include <asm/fsl_ocp.h>
-#endif
-
 #endif                         /* CONFIG_PPC_OCP */
 #endif                         /* __OCP_H__ */
 #endif                         /* __KERNEL__ */
index 13fa8e7483c1c39319be4598ee67fc64e4345f72..f76221def484d3f8bffa45b0f9a71f9ee88a9cd4 100644 (file)
@@ -174,6 +174,8 @@ END_FTR_SECTION_IFCLR(CPU_FTR_601)
 #define CLR_TOP32(r)
 #endif /* CONFIG_PPC64BRIDGE */
 
+#define RFCI           .long 0x4c000066        /* rfci instruction */
+#define RFDI           .long 0x4c00004e        /* rfdi instruction */
 #define RFMCI          .long 0x4c00004c        /* rfmci instruction */
 
 #ifdef CONFIG_IBM405_ERR77
index c418aab7cd346a7967581c150789cbb0480c2363..88b4222154d48517cb8ba5e7014a69d306929ccb 100644 (file)
 #define HID0_ICFI      (1<<11)         /* Instr. Cache Flash Invalidate */
 #define HID0_DCI       (1<<10)         /* Data Cache Invalidate */
 #define HID0_SPD       (1<<9)          /* Speculative disable */
+#define HID0_DAPUEN    (1<<8)          /* Debug APU enable */
 #define HID0_SGE       (1<<7)          /* Store Gathering Enable */
 #define HID0_SIED      (1<<7)          /* Serial Instr. Execution [Disable] */
 #define HID0_DFCA      (1<<6)          /* Data Cache Flush Assist */
index 45c5e6f2b7abfc41c22dedf2d4eec2ae8b95c47a..00ad9c754c789b580a05f07110f7f4fccae9202c 100644 (file)
@@ -165,6 +165,8 @@ do {                                                \
 #define SPRN_MCSRR1    0x23B   /* Machine Check Save and Restore Register 1 */
 #define SPRN_MCSR      0x23C   /* Machine Check Status Register */
 #define SPRN_MCAR      0x23D   /* Machine Check Address Register */
+#define SPRN_DSRR0     0x23E   /* Debug Save and Restore Register 0 */
+#define SPRN_DSRR1     0x23F   /* Debug Save and Restore Register 1 */
 #define SPRN_MAS0      0x270   /* MMU Assist Register 0 */
 #define SPRN_MAS1      0x271   /* MMU Assist Register 1 */
 #define SPRN_MAS2      0x272   /* MMU Assist Register 2 */
@@ -264,6 +266,17 @@ do {                                               \
 #define MCSR_BUS_IPERR         0x00000002UL /* Instruction parity Error */
 #define MCSR_BUS_RPERR         0x00000001UL /* Read parity Error */
 #endif
+#ifdef CONFIG_E200
+#define MCSR_MCP       0x80000000UL /* Machine Check Input Pin */
+#define MCSR_CP_PERR   0x20000000UL /* Cache Push Parity Error */
+#define MCSR_CPERR     0x10000000UL /* Cache Parity Error */
+#define MCSR_EXCP_ERR  0x08000000UL /* ISI, ITLB, or Bus Error on 1st insn
+                                       fetch for an exception handler */
+#define MCSR_BUS_IRERR         0x00000010UL /* Read Bus Error on instruction fetch*/
+#define MCSR_BUS_DRERR         0x00000008UL /* Read Bus Error on data load */
+#define MCSR_BUS_WRERR         0x00000004UL /* Write Bus Error on buffered
+                                       store or cache line push */
+#endif
 
 /* Bit definitions for the DBSR. */
 /*
@@ -311,6 +324,7 @@ do {                                                \
 #define ESR_ST         0x00800000      /* Store Operation */
 #define ESR_DLK                0x00200000      /* Data Cache Locking */
 #define ESR_ILK                0x00100000      /* Instr. Cache Locking */
+#define ESR_PUO                0x00040000      /* Unimplemented Operation exception */
 #define ESR_BO         0x00020000      /* Byte Ordering */
 
 /* Bit definitions related to the DBCR0. */
@@ -387,10 +401,12 @@ do {                                              \
 #define ICCR_CACHE     1               /* Cacheable */
 
 /* Bit definitions for L1CSR0. */
+#define L1CSR0_CLFC    0x00000100      /* Cache Lock Bits Flash Clear */
 #define L1CSR0_DCFI    0x00000002      /* Data Cache Flash Invalidate */
+#define L1CSR0_CFI     0x00000002      /* Cache Flash Invalidate */
 #define L1CSR0_DCE     0x00000001      /* Data Cache Enable */
 
-/* Bit definitions for L1CSR0. */
+/* Bit definitions for L1CSR1. */
 #define L1CSR1_ICLFR   0x00000100      /* Instr Cache Lock Bits Flash Reset */
 #define L1CSR1_ICFI    0x00000002      /* Instr Cache Flash Invalidate */
 #define L1CSR1_ICE     0x00000001      /* Instr Cache Enable */
index 488634258a722ee7da2319b61caae04ff877f1e4..d383d161cf8d9b24e28b1f230ae7dedec81cbfdd 100644 (file)
@@ -17,7 +17,7 @@ struct die_args {
 
 /*
    Note - you should never unregister because that can race with NMIs.
-   If you really want to do it first unregister - then synchronize_kernel -
+   If you really want to do it first unregister - then synchronize_sched -
    then free.
  */
 int register_die_notifier(struct notifier_block *nb);
diff --git a/include/asm-ppc64/kexec.h b/include/asm-ppc64/kexec.h
new file mode 100644 (file)
index 0000000..511908a
--- /dev/null
@@ -0,0 +1,41 @@
+#ifndef _PPC64_KEXEC_H
+#define _PPC64_KEXEC_H
+
+/*
+ * KEXEC_SOURCE_MEMORY_LIMIT maximum page get_free_page can return.
+ * I.e. Maximum page that is mapped directly into kernel memory,
+ * and kmap is not required.
+ */
+
+/* Maximum physical address we can use pages from */
+/* XXX: since we copy virt we can use any page we allocate */
+#define KEXEC_SOURCE_MEMORY_LIMIT (-1UL)
+
+/* Maximum address we can reach in physical address mode */
+/* XXX: I want to allow initrd in highmem.  otherwise set to rmo on lpar */
+#define KEXEC_DESTINATION_MEMORY_LIMIT (-1UL)
+
+/* Maximum address we can use for the control code buffer */
+/* XXX: unused today, ppc32 uses TASK_SIZE, probably left over from use_mm  */
+#define KEXEC_CONTROL_MEMORY_LIMIT (-1UL)
+
+/* XXX: today we don't use this at all, althogh we have a static stack */
+#define KEXEC_CONTROL_CODE_SIZE 4096
+
+/* The native architecture */
+#define KEXEC_ARCH KEXEC_ARCH_PPC64
+
+#define MAX_NOTE_BYTES 1024
+
+#ifndef __ASSEMBLY__
+
+typedef u32 note_buf_t[MAX_NOTE_BYTES/4];
+
+extern note_buf_t crash_notes[];
+
+extern void kexec_smp_wait(void);      /* get and clear naca physid, wait for
+                                         master to copy new code to 0 */
+
+#endif /* __ASSEMBLY__ */
+#endif /* _PPC_KEXEC_H */
+
index 553b2ea23bedfb324b56dc76347917794f1872b2..9cdad3ed1526c2a6a74dff7f9c7d0d2ca8ec85b4 100644 (file)
@@ -86,6 +86,7 @@ struct machdep_calls {
 
        void            (*init_IRQ)(void);
        int             (*get_irq)(struct pt_regs *);
+       void            (*cpu_irq_down)(void);
 
        /* PCI stuff */
        void            (*pcibios_fixup)(void);
index 9d03a98a4fa3009ea04496d117649a0203a68a16..f373de5e3dd900964fbf2ac5f3b52e751eeab3a3 100644 (file)
@@ -181,6 +181,28 @@ static inline void tlbiel(unsigned long va)
        asm volatile("ptesync": : :"memory");
 }
 
+static inline unsigned long slot2va(unsigned long avpn, unsigned long large,
+               unsigned long secondary, unsigned long slot)
+{
+       unsigned long va;
+
+       va = avpn << 23;
+
+       if (!large) {
+               unsigned long vpi, pteg;
+
+               pteg = slot / HPTES_PER_GROUP;
+               if (secondary)
+                       pteg = ~pteg;
+
+               vpi = ((va >> 28) ^ pteg) & htab_hash_mask;
+
+               va |= vpi << PAGE_SHIFT;
+       }
+
+       return va;
+}
+
 /*
  * Handle a fault by adding an HPTE. If the address can't be determined
  * to be valid via Linux page tables, return 1. If handled return 0
index fdec5e7a7af6cd177e324648bbeeb29da3fb8c4a..0c45e14e26ca66d219035da90519703b7dbdac09 100644 (file)
@@ -17,6 +17,7 @@
 void xics_init_IRQ(void);
 int xics_get_irq(struct pt_regs *);
 void xics_setup_cpu(void);
+void xics_teardown_cpu(void);
 void xics_cause_IPI(int cpu);
 void xics_request_IPIs(void);
 void xics_migrate_irqs_away(void);
index 1d33c5da083edaa5f933598498978e1985efc171..1fcf65be7a230cbc91caa153cb97dfe900ac1b82 100644 (file)
 #define __CPCMD__
 
 /*
+ * the lowlevel function for cpcmd
  * the caller of __cpcmd has to ensure that the response buffer is below 2 GB
  */
-extern void __cpcmd(char *cmd, char *response, int rlen);
+extern int __cpcmd(const char *cmd, char *response, int rlen, int *response_code);
 
 #ifndef __s390x__
 #define cpcmd __cpcmd
 #else
-extern void cpcmd(char *cmd, char *response, int rlen);
+/*
+ * cpcmd is the in-kernel interface for issuing CP commands
+ *
+ * cmd:                null-terminated command string, max 240 characters
+ * response:   response buffer for VM's textual response
+ * rlen:       size of the response buffer, cpcmd will not exceed this size
+ *             but will cap the output, if its too large. Everything that
+ *             did not fit into the buffer will be silently dropped
+ * response_code: return pointer for VM's error code
+ * return value: the size of the response. The caller can check if the buffer
+ *             was large enough by comparing the return value and rlen
+ * NOTE: If the response buffer is not below 2 GB, cpcmd can sleep
+ */
+extern int cpcmd(const char *cmd, char *response, int rlen, int *response_code);
 #endif /*__s390x__*/
 
 #endif
index 6bbcdea42a86079a25d981f40c80097773c8bd08..92360d90144bc698618f1dbf09da1dae22a202d7 100644 (file)
@@ -9,6 +9,8 @@
 #ifndef DEBUG_H
 #define DEBUG_H
 
+#include <linux/config.h>
+#include <linux/fs.h>
 #include <linux/string.h>
 
 /* Note:
@@ -31,19 +33,18 @@ struct __debug_entry{
 } __attribute__((packed));
 
 
-#define __DEBUG_FEATURE_VERSION      1  /* version of debug feature */
+#define __DEBUG_FEATURE_VERSION      2  /* version of debug feature */
 
 #ifdef __KERNEL__
 #include <linux/spinlock.h>
 #include <linux/kernel.h>
 #include <linux/time.h>
-#include <linux/proc_fs.h>
 
 #define DEBUG_MAX_LEVEL            6  /* debug levels range from 0 to 6 */
 #define DEBUG_OFF_LEVEL            -1 /* level where debug is switched off */
 #define DEBUG_FLUSH_ALL            -1 /* parameter to flush all areas */
 #define DEBUG_MAX_VIEWS            10 /* max number of views in proc fs */
-#define DEBUG_MAX_PROCF_LEN        64 /* max length for a proc file name */
+#define DEBUG_MAX_NAME_LEN         64 /* max length for a debugfs file name */
 #define DEBUG_DEFAULT_LEVEL        3  /* initial debug level */
 
 #define DEBUG_DIR_ROOT "s390dbf" /* name of debug root directory in proc fs */
@@ -64,16 +65,17 @@ typedef struct debug_info {
        spinlock_t lock;                        
        int level;
        int nr_areas;
-       int page_order;
+       int pages_per_area;
        int buf_size;
        int entry_size; 
-       debug_entry_t** areas;
+       debug_entry_t*** areas;
        int active_area;
-       int *active_entry;
-       struct proc_dir_entry* proc_root_entry;
-       struct proc_dir_entry* proc_entries[DEBUG_MAX_VIEWS];
+       int *active_pages;
+       int *active_entries;
+       struct dentry* debugfs_root_entry;
+       struct dentry* debugfs_entries[DEBUG_MAX_VIEWS];
        struct debug_view* views[DEBUG_MAX_VIEWS];      
-       char name[DEBUG_MAX_PROCF_LEN];
+       char name[DEBUG_MAX_NAME_LEN];
 } debug_info_t;
 
 typedef int (debug_header_proc_t) (debug_info_t* id,
@@ -98,7 +100,7 @@ int debug_dflt_header_fn(debug_info_t* id, struct debug_view* view,
                         int area, debug_entry_t* entry, char* out_buf);                                                
                                
 struct debug_view {
-       char name[DEBUG_MAX_PROCF_LEN];
+       char name[DEBUG_MAX_NAME_LEN];
        debug_prolog_proc_t* prolog_proc;
        debug_header_proc_t* header_proc;
        debug_format_proc_t* format_proc;
@@ -120,7 +122,7 @@ debug_entry_t* debug_exception_common(debug_info_t* id, int level,
 
 /* Debug Feature API: */
 
-debug_info_t* debug_register(char* name, int pages_index, int nr_areas,
+debug_info_t* debug_register(char* name, int pages, int nr_areas,
                              int buf_size);
 
 void debug_unregister(debug_info_t* id);
@@ -132,7 +134,8 @@ void debug_stop_all(void);
 extern inline debug_entry_t* 
 debug_event(debug_info_t* id, int level, void* data, int length)
 {
-       if ((!id) || (level > id->level)) return NULL;
+       if ((!id) || (level > id->level) || (id->pages_per_area == 0))
+               return NULL;
         return debug_event_common(id,level,data,length);
 }
 
@@ -140,7 +143,8 @@ extern inline debug_entry_t*
 debug_int_event(debug_info_t* id, int level, unsigned int tag)
 {
         unsigned int t=tag;
-       if ((!id) || (level > id->level)) return NULL;
+       if ((!id) || (level > id->level) || (id->pages_per_area == 0))
+               return NULL;
         return debug_event_common(id,level,&t,sizeof(unsigned int));
 }
 
@@ -148,14 +152,16 @@ extern inline debug_entry_t *
 debug_long_event (debug_info_t* id, int level, unsigned long tag)
 {
         unsigned long t=tag;
-       if ((!id) || (level > id->level)) return NULL;
+       if ((!id) || (level > id->level) || (id->pages_per_area == 0))
+               return NULL;
         return debug_event_common(id,level,&t,sizeof(unsigned long));
 }
 
 extern inline debug_entry_t* 
 debug_text_event(debug_info_t* id, int level, const char* txt)
 {
-       if ((!id) || (level > id->level)) return NULL;
+       if ((!id) || (level > id->level) || (id->pages_per_area == 0))
+               return NULL;
         return debug_event_common(id,level,txt,strlen(txt));
 }
 
@@ -167,7 +173,8 @@ debug_sprintf_event(debug_info_t* id,int level,char *string,...)
 extern inline debug_entry_t* 
 debug_exception(debug_info_t* id, int level, void* data, int length)
 {
-       if ((!id) || (level > id->level)) return NULL;
+       if ((!id) || (level > id->level) || (id->pages_per_area == 0))
+               return NULL;
         return debug_exception_common(id,level,data,length);
 }
 
@@ -175,7 +182,8 @@ extern inline debug_entry_t*
 debug_int_exception(debug_info_t* id, int level, unsigned int tag)
 {
         unsigned int t=tag;
-       if ((!id) || (level > id->level)) return NULL;
+       if ((!id) || (level > id->level) || (id->pages_per_area == 0))
+               return NULL;
         return debug_exception_common(id,level,&t,sizeof(unsigned int));
 }
 
@@ -183,14 +191,16 @@ extern inline debug_entry_t *
 debug_long_exception (debug_info_t* id, int level, unsigned long tag)
 {
         unsigned long t=tag;
-       if ((!id) || (level > id->level)) return NULL;
+       if ((!id) || (level > id->level) || (id->pages_per_area == 0))
+               return NULL;
         return debug_exception_common(id,level,&t,sizeof(unsigned long));
 }
 
 extern inline debug_entry_t* 
 debug_text_exception(debug_info_t* id, int level, const char* txt)
 {
-       if ((!id) || (level > id->level)) return NULL;
+       if ((!id) || (level > id->level) || (id->pages_per_area == 0))
+               return NULL;
         return debug_exception_common(id,level,txt,strlen(txt));
 }
 
diff --git a/include/asm-s390/kexec.h b/include/asm-s390/kexec.h
new file mode 100644 (file)
index 0000000..54cf7d9
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * include/asm-s390/kexec.h
+ *
+ * (C) Copyright IBM Corp. 2005
+ *
+ * Author(s): Rolf Adelsberger <adelsberger@de.ibm.com>
+ *
+ */
+
+#ifndef _S390_KEXEC_H
+#define _S390_KEXEC_H
+
+#include <asm/page.h>
+#include <asm/processor.h>
+/*
+ * KEXEC_SOURCE_MEMORY_LIMIT maximum page get_free_page can return.
+ * I.e. Maximum page that is mapped directly into kernel memory,
+ * and kmap is not required.
+ */
+
+/* Maximum physical address we can use pages from */
+#define KEXEC_SOURCE_MEMORY_LIMIT (-1UL)
+
+/* Maximum address we can reach in physical address mode */
+#define KEXEC_DESTINATION_MEMORY_LIMIT (-1UL)
+
+/* Maximum address we can use for the control pages */
+/* Not more than 2GB */
+#define KEXEC_CONTROL_MEMORY_LIMIT (1<<31)
+
+/* Allocate one page for the pdp and the second for the code */
+#define KEXEC_CONTROL_CODE_SIZE 4096
+
+/* The native architecture */
+#define KEXEC_ARCH KEXEC_ARCH_S390
+
+#define MAX_NOTE_BYTES 1024
+typedef u32 note_buf_t[MAX_NOTE_BYTES/4];
+
+extern note_buf_t crash_notes[];
+
+#endif /*_S390_KEXEC_H */
index df5172fc589dc5c4debd62a924047c21bcf5be47..76b5b19c0ae2c1f4c7160d08337c92b4e93444ce 100644 (file)
 
 #ifndef __s390x__
 #define __LC_PFAULT_INTPARM             0x080
+#define __LC_CPU_TIMER_SAVE_AREA        0x0D8
 #define __LC_AREGS_SAVE_AREA            0x120
+#define __LC_GPREGS_SAVE_AREA           0x180
 #define __LC_CREGS_SAVE_AREA            0x1C0
 #else /* __s390x__ */
 #define __LC_PFAULT_INTPARM             0x11B8
+#define __LC_GPREGS_SAVE_AREA           0x1280
+#define __LC_CPU_TIMER_SAVE_AREA        0x1328
 #define __LC_AREGS_SAVE_AREA            0x1340
 #define __LC_CREGS_SAVE_AREA            0x1380
 #endif /* __s390x__ */
@@ -167,7 +171,8 @@ struct _lowcore
        __u16        subchannel_nr;            /* 0x0ba */
        __u32        io_int_parm;              /* 0x0bc */
        __u32        io_int_word;              /* 0x0c0 */
-        __u8         pad3[0xD8-0xC4];          /* 0x0c4 */
+        __u8         pad3[0xD4-0xC4];          /* 0x0c4 */
+       __u32        extended_save_area_addr;  /* 0x0d4 */
        __u32        cpu_timer_save_area[2];   /* 0x0d8 */
        __u32        clock_comp_save_area[2];  /* 0x0e0 */
        __u32        mcck_interruption_code[2]; /* 0x0e8 */
index fb46e9090b500bc2405ca4660dbfb6040188dceb..8bd14de69e35bf5cbbe5c1dcc5ab4a5cffc1b4a1 100644 (file)
@@ -206,6 +206,18 @@ unsigned long get_wchan(struct task_struct *p);
        asm volatile ("ex 0,%0" : : "i" (__LC_DIAG44_OPCODE) : "memory")
 #endif /* __s390x__ */
 
+/*
+ * Set PSW to specified value.
+ */
+static inline void __load_psw(psw_t psw)
+{
+#ifndef __s390x__
+       asm volatile ("lpsw  0(%0)" : : "a" (&psw), "m" (psw) : "cc" );
+#else
+       asm volatile ("lpswe 0(%0)" : : "a" (&psw), "m" (psw) : "cc" );
+#endif
+}
+
 /*
  * Set PSW mask to specified value, while leaving the
  * PSW addr pointing to the next instruction.
@@ -214,8 +226,8 @@ unsigned long get_wchan(struct task_struct *p);
 static inline void __load_psw_mask (unsigned long mask)
 {
        unsigned long addr;
-
        psw_t psw;
+
        psw.mask = mask;
 
 #ifndef __s390x__
@@ -241,30 +253,8 @@ static inline void __load_psw_mask (unsigned long mask)
  */
 static inline void enabled_wait(void)
 {
-       unsigned long reg;
-       psw_t wait_psw;
-
-       wait_psw.mask = PSW_BASE_BITS | PSW_MASK_IO | PSW_MASK_EXT |
-               PSW_MASK_MCHECK | PSW_MASK_WAIT | PSW_DEFAULT_KEY;
-#ifndef __s390x__
-       asm volatile (
-               "    basr %0,0\n"
-               "0:  la   %0,1f-0b(%0)\n"
-               "    st   %0,4(%1)\n"
-               "    oi   4(%1),0x80\n"
-               "    lpsw 0(%1)\n"
-               "1:"
-               : "=&a" (reg) : "a" (&wait_psw), "m" (wait_psw)
-               : "memory", "cc" );
-#else /* __s390x__ */
-       asm volatile (
-               "    larl  %0,0f\n"
-               "    stg   %0,8(%1)\n"
-               "    lpswe 0(%1)\n"
-               "0:"
-               : "=&a" (reg) : "a" (&wait_psw), "m" (wait_psw)
-               : "memory", "cc" );
-#endif /* __s390x__ */
+       __load_psw_mask(PSW_BASE_BITS | PSW_MASK_IO | PSW_MASK_EXT |
+                       PSW_MASK_MCHECK | PSW_MASK_WAIT | PSW_DEFAULT_KEY);
 }
 
 /*
@@ -273,13 +263,11 @@ static inline void enabled_wait(void)
 
 static inline void disabled_wait(unsigned long code)
 {
-        char psw_buffer[2*sizeof(psw_t)];
         unsigned long ctl_buf;
-        psw_t *dw_psw = (psw_t *)(((unsigned long) &psw_buffer+sizeof(psw_t)-1)
-                                  & -sizeof(psw_t));
+        psw_t dw_psw;
 
-        dw_psw->mask = PSW_BASE_BITS | PSW_MASK_WAIT;
-        dw_psw->addr = code;
+        dw_psw.mask = PSW_BASE_BITS | PSW_MASK_WAIT;
+        dw_psw.addr = code;
         /* 
          * Store status and then load disabled wait psw,
          * the processor is dead afterwards
@@ -301,7 +289,7 @@ static inline void disabled_wait(unsigned long code)
                       "    oi    0x1c0,0x10\n" /* fake protection bit */
                       "    lpsw 0(%1)"
                       : "=m" (ctl_buf)
-                     : "a" (dw_psw), "a" (&ctl_buf), "m" (dw_psw) : "cc" );
+                     : "a" (&dw_psw), "a" (&ctl_buf), "m" (dw_psw) : "cc" );
 #else /* __s390x__ */
         asm volatile ("    stctg 0,0,0(%2)\n"
                       "    ni    4(%2),0xef\n" /* switch off protection */
@@ -333,7 +321,7 @@ static inline void disabled_wait(unsigned long code)
                       "    oi    0x384(1),0x10\n" /* fake protection bit */
                       "    lpswe 0(%1)"
                       : "=m" (ctl_buf)
-                     : "a" (dw_psw), "a" (&ctl_buf),
+                     : "a" (&dw_psw), "a" (&ctl_buf),
                        "m" (dw_psw) : "cc", "0", "1");
 #endif /* __s390x__ */
 }
index 4eff8f2e3bf1d636e78ccb9842bc519722387c7d..fc7c96edc697c5922f0377811b3531cc0d161cdb 100644 (file)
@@ -276,7 +276,7 @@ typedef struct
 #endif /* __s390x__ */
 
 #define PSW_KERNEL_BITS        (PSW_BASE_BITS | PSW_MASK_DAT | PSW_ASC_PRIMARY | \
-                        PSW_DEFAULT_KEY)
+                        PSW_MASK_MCHECK | PSW_DEFAULT_KEY)
 #define PSW_USER_BITS  (PSW_BASE_BITS | PSW_MASK_DAT | PSW_ASC_HOME | \
                         PSW_MASK_IO | PSW_MASK_EXT | PSW_MASK_MCHECK | \
                         PSW_MASK_PSTATE | PSW_DEFAULT_KEY)
index 81514d76edcf3d1d498cfc5e53dfa14803c24fd3..b4a9f05a93d6d74317aa1a3446e67088b2c2609f 100644 (file)
@@ -16,6 +16,7 @@
 #include <asm/types.h>
 #include <asm/ptrace.h>
 #include <asm/setup.h>
+#include <asm/processor.h>
 
 #ifdef __KERNEL__
 
@@ -103,29 +104,18 @@ static inline void restore_access_regs(unsigned int *acrs)
        prev = __switch_to(prev,next);                                       \
 } while (0)
 
-#define prepare_arch_switch(rq, next)  do { } while(0)
-#define task_running(rq, p)            ((rq)->curr == (p))
-
 #ifdef CONFIG_VIRT_CPU_ACCOUNTING
 extern void account_user_vtime(struct task_struct *);
 extern void account_system_vtime(struct task_struct *);
-
-#define finish_arch_switch(rq, prev) do {                                   \
-       set_fs(current->thread.mm_segment);                                  \
-       spin_unlock(&(rq)->lock);                                            \
-       account_system_vtime(prev);                                          \
-       local_irq_enable();                                                  \
-} while (0)
-
 #else
+#define account_system_vtime(prev) do { } while (0)
+#endif
 
 #define finish_arch_switch(rq, prev) do {                                   \
        set_fs(current->thread.mm_segment);                                  \
-       spin_unlock_irq(&(rq)->lock);                                        \
+       account_system_vtime(prev);                                          \
 } while (0)
 
-#endif
-
 #define nop() __asm__ __volatile__ ("nop")
 
 #define xchg(ptr,x) \
@@ -331,9 +321,6 @@ __cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, int size)
 
 #ifdef __s390x__
 
-#define __load_psw(psw) \
-        __asm__ __volatile__("lpswe 0(%0)" : : "a" (&psw), "m" (psw) : "cc" );
-
 #define __ctl_load(array, low, high) ({ \
        typedef struct { char _[sizeof(array)]; } addrtype; \
        __asm__ __volatile__ ( \
@@ -390,9 +377,6 @@ __cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, int size)
 
 #else /* __s390x__ */
 
-#define __load_psw(psw) \
-       __asm__ __volatile__("lpsw 0(%0)" : : "a" (&psw) : "cc" );
-
 #define __ctl_load(array, low, high) ({ \
        typedef struct { char _[sizeof(array)]; } addrtype; \
        __asm__ __volatile__ ( \
@@ -451,6 +435,20 @@ __cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, int size)
 /* For spinlocks etc */
 #define local_irq_save(x)      ((x) = local_irq_disable())
 
+/*
+ * Use to set psw mask except for the first byte which
+ * won't be changed by this function.
+ */
+static inline void
+__set_psw_mask(unsigned long mask)
+{
+       local_save_flags(mask);
+       __load_psw_mask(mask);
+}
+
+#define local_mcck_enable()  __set_psw_mask(PSW_KERNEL_BITS)
+#define local_mcck_disable() __set_psw_mask(PSW_KERNEL_BITS & ~PSW_MASK_MCHECK)
+
 #ifdef CONFIG_SMP
 
 extern void smp_ctl_set_bit(int cr, int bit);
index fe101d41e849bfe9c35c08aa624e6e7cdb1fdc93..6c18a3f24316ad69defc3f680edefe695702fca7 100644 (file)
@@ -96,6 +96,7 @@ static inline struct thread_info *current_thread_info(void)
 #define TIF_RESTART_SVC                4       /* restart svc with new svc number */
 #define TIF_SYSCALL_AUDIT      5       /* syscall auditing active */
 #define TIF_SINGLE_STEP                6       /* deliver sigtrap on return to user */
+#define TIF_MCCK_PENDING       7       /* machine check handling is pending */
 #define TIF_USEDFPU            16      /* FPU was used by this task this quantum (SMP) */
 #define TIF_POLLING_NRFLAG     17      /* true if poll_idle() is polling 
                                           TIF_NEED_RESCHED */
@@ -109,6 +110,7 @@ static inline struct thread_info *current_thread_info(void)
 #define _TIF_RESTART_SVC       (1<<TIF_RESTART_SVC)
 #define _TIF_SYSCALL_AUDIT     (1<<TIF_SYSCALL_AUDIT)
 #define _TIF_SINGLE_STEP       (1<<TIF_SINGLE_STEP)
+#define _TIF_MCCK_PENDING      (1<<TIF_MCCK_PENDING)
 #define _TIF_USEDFPU           (1<<TIF_USEDFPU)
 #define _TIF_POLLING_NRFLAG    (1<<TIF_POLLING_NRFLAG)
 #define _TIF_31BIT             (1<<TIF_31BIT)
index f1a204f7c0f0b2559636a815d813766f89d71d1f..363db45f8d074314ed9603bc8c26466aeb270134 100644 (file)
 #define __NR_mq_timedreceive   274
 #define __NR_mq_notify         275
 #define __NR_mq_getsetattr     276
-/* Number 277 is reserved for new sys_kexec_load */
+#define __NR_kexec_load                277
 #define __NR_add_key           278
 #define __NR_request_key       279
 #define __NR_keyctl            280
index 80cf20cfaee1cdf1d6213fbd5b9a516a73c9a9ff..898562ebe94c6d8e7abfbc75d8d9f22e0ffd8dc1 100644 (file)
@@ -101,7 +101,7 @@ extern void fpsave(unsigned long *fpregs, unsigned long *fsr,
  * SWITCH_ENTER and SWITH_DO_LAZY_FPU do not work yet (e.g. SMP does not work)
  * XXX WTF is the above comment? Found in late teen 2.4.x.
  */
-#define prepare_arch_switch(rq, next) do { \
+#define prepare_arch_switch(next) do { \
        __asm__ __volatile__( \
        ".globl\tflush_patch_switch\nflush_patch_switch:\n\t" \
        "save %sp, -0x40, %sp; save %sp, -0x40, %sp; save %sp, -0x40, %sp\n\t" \
@@ -109,8 +109,6 @@ extern void fpsave(unsigned long *fpregs, unsigned long *fsr,
        "save %sp, -0x40, %sp\n\t" \
        "restore; restore; restore; restore; restore; restore; restore"); \
 } while(0)
-#define finish_arch_switch(rq, next)   spin_unlock_irq(&(rq)->lock)
-#define task_running(rq, p)            ((rq)->curr == (p))
 
        /* Much care has gone into this code, do not touch it.
         *
index f70d3dad01f9398166409397efbf2f5013959654..6321f5a0198d4811c3a7ed4a8bbf2efed4b86a37 100644 (file)
@@ -16,7 +16,7 @@ struct die_args {
 };
 
 /* Note - you should never unregister because that can race with NMIs.
- * If you really want to do it first unregister - then synchronize_kernel
+ * If you really want to do it first unregister - then synchronize_sched
  * - then free.
  */
 int register_die_notifier(struct notifier_block *nb);
index fd12ca386f486047b141926aa41890f2d129d095..f9be2c5b4dc97360013fb5ddfe2d54c23aeaad90 100644 (file)
@@ -139,19 +139,13 @@ extern void __flushw_user(void);
 #define flush_user_windows flushw_user
 #define flush_register_windows flushw_all
 
-#define prepare_arch_switch(rq, next)          \
-do {   spin_lock(&(next)->switch_lock);        \
-       spin_unlock(&(rq)->lock);               \
+/* Don't hold the runqueue lock over context switch */
+#define __ARCH_WANT_UNLOCKED_CTXSW
+#define prepare_arch_switch(next)              \
+do {                                           \
        flushw_all();                           \
 } while (0)
 
-#define finish_arch_switch(rq, prev)           \
-do {   spin_unlock_irq(&(prev)->switch_lock);  \
-} while (0)
-
-#define task_running(rq, p) \
-       ((rq)->curr == (p) || spin_is_locked(&(p)->switch_lock))
-
        /* See what happens when you design the chip correctly?
         *
         * We tell gcc we clobber all non-fixed-usage registers except
index 8effce0da0878f054ec6b3514a3f34b00a385fa5..9777a9cca88aa900a68545fccb1e7939bcf51a81 100644 (file)
@@ -100,16 +100,17 @@ struct winsize {
 #define user_termio_to_kernel_termios(termios, termio) \
 ({ \
        unsigned short tmp; \
-       get_user(tmp, &(termio)->c_iflag); \
+       int err; \
+       err = get_user(tmp, &(termio)->c_iflag); \
        (termios)->c_iflag = (0xffff0000 & ((termios)->c_iflag)) | tmp; \
-       get_user(tmp, &(termio)->c_oflag); \
+       err |= get_user(tmp, &(termio)->c_oflag); \
        (termios)->c_oflag = (0xffff0000 & ((termios)->c_oflag)) | tmp; \
-       get_user(tmp, &(termio)->c_cflag); \
+       err |= get_user(tmp, &(termio)->c_cflag); \
        (termios)->c_cflag = (0xffff0000 & ((termios)->c_cflag)) | tmp; \
-       get_user(tmp, &(termio)->c_lflag); \
+       err |= get_user(tmp, &(termio)->c_lflag); \
        (termios)->c_lflag = (0xffff0000 & ((termios)->c_lflag)) | tmp; \
-       copy_from_user((termios)->c_cc, (termio)->c_cc, NCC); \
-       0; \
+       err |= copy_from_user((termios)->c_cc, (termio)->c_cc, NCC); \
+       err; \
 })
 
 /*
@@ -119,53 +120,56 @@ struct winsize {
  */
 #define kernel_termios_to_user_termio(termio, termios) \
 ({ \
-       put_user((termios)->c_iflag, &(termio)->c_iflag); \
-       put_user((termios)->c_oflag, &(termio)->c_oflag); \
-       put_user((termios)->c_cflag, &(termio)->c_cflag); \
-       put_user((termios)->c_lflag, &(termio)->c_lflag); \
-       put_user((termios)->c_line,  &(termio)->c_line); \
-       copy_to_user((termio)->c_cc, (termios)->c_cc, NCC); \
+       int err; \
+       err  = put_user((termios)->c_iflag, &(termio)->c_iflag); \
+       err |= put_user((termios)->c_oflag, &(termio)->c_oflag); \
+       err |= put_user((termios)->c_cflag, &(termio)->c_cflag); \
+       err |= put_user((termios)->c_lflag, &(termio)->c_lflag); \
+       err |= put_user((termios)->c_line,  &(termio)->c_line); \
+       err |= copy_to_user((termio)->c_cc, (termios)->c_cc, NCC); \
        if (!((termios)->c_lflag & ICANON)) { \
-               put_user((termios)->c_cc[VMIN], &(termio)->c_cc[_VMIN]); \
-               put_user((termios)->c_cc[VTIME], &(termio)->c_cc[_VTIME]); \
+               err |= put_user((termios)->c_cc[VMIN], &(termio)->c_cc[_VMIN]); \
+               err |= put_user((termios)->c_cc[VTIME], &(termio)->c_cc[_VTIME]); \
        } \
-       0; \
+       err; \
 })
 
 #define user_termios_to_kernel_termios(k, u) \
 ({ \
-       get_user((k)->c_iflag, &(u)->c_iflag); \
-       get_user((k)->c_oflag, &(u)->c_oflag); \
-       get_user((k)->c_cflag, &(u)->c_cflag); \
-       get_user((k)->c_lflag, &(u)->c_lflag); \
-       get_user((k)->c_line,  &(u)->c_line); \
-       copy_from_user((k)->c_cc, (u)->c_cc, NCCS); \
+       int err; \
+       err  = get_user((k)->c_iflag, &(u)->c_iflag); \
+       err |= get_user((k)->c_oflag, &(u)->c_oflag); \
+       err |= get_user((k)->c_cflag, &(u)->c_cflag); \
+       err |= get_user((k)->c_lflag, &(u)->c_lflag); \
+       err |= get_user((k)->c_line,  &(u)->c_line); \
+       err |= copy_from_user((k)->c_cc, (u)->c_cc, NCCS); \
        if((k)->c_lflag & ICANON) { \
-               get_user((k)->c_cc[VEOF], &(u)->c_cc[VEOF]); \
-               get_user((k)->c_cc[VEOL], &(u)->c_cc[VEOL]); \
+               err |= get_user((k)->c_cc[VEOF], &(u)->c_cc[VEOF]); \
+               err |= get_user((k)->c_cc[VEOL], &(u)->c_cc[VEOL]); \
        } else { \
-               get_user((k)->c_cc[VMIN],  &(u)->c_cc[_VMIN]); \
-               get_user((k)->c_cc[VTIME], &(u)->c_cc[_VTIME]); \
+               err |= get_user((k)->c_cc[VMIN],  &(u)->c_cc[_VMIN]); \
+               err |= get_user((k)->c_cc[VTIME], &(u)->c_cc[_VTIME]); \
        } \
-       0; \
+       err; \
 })
 
 #define kernel_termios_to_user_termios(u, k) \
 ({ \
-       put_user((k)->c_iflag, &(u)->c_iflag); \
-       put_user((k)->c_oflag, &(u)->c_oflag); \
-       put_user((k)->c_cflag, &(u)->c_cflag); \
-       put_user((k)->c_lflag, &(u)->c_lflag); \
-       put_user((k)->c_line, &(u)->c_line); \
-       copy_to_user((u)->c_cc, (k)->c_cc, NCCS); \
+       int err; \
+       err  = put_user((k)->c_iflag, &(u)->c_iflag); \
+       err |= put_user((k)->c_oflag, &(u)->c_oflag); \
+       err |= put_user((k)->c_cflag, &(u)->c_cflag); \
+       err |= put_user((k)->c_lflag, &(u)->c_lflag); \
+       err |= put_user((k)->c_line, &(u)->c_line); \
+       err |= copy_to_user((u)->c_cc, (k)->c_cc, NCCS); \
        if(!((k)->c_lflag & ICANON)) { \
-               put_user((k)->c_cc[VMIN],  &(u)->c_cc[_VMIN]); \
-               put_user((k)->c_cc[VTIME], &(u)->c_cc[_VTIME]); \
+               err |= put_user((k)->c_cc[VMIN],  &(u)->c_cc[_VMIN]); \
+               err |= put_user((k)->c_cc[VTIME], &(u)->c_cc[_VTIME]); \
        } else { \
-               put_user((k)->c_cc[VEOF], &(u)->c_cc[VEOF]); \
-               put_user((k)->c_cc[VEOL], &(u)->c_cc[VEOL]); \
+               err |= put_user((k)->c_cc[VEOF], &(u)->c_cc[VEOF]); \
+               err |= put_user((k)->c_cc[VEOL], &(u)->c_cc[VEOL]); \
        } \
-       0; \
+       err; \
 })
 
 #endif /* __KERNEL__ */
index 04222f35c43e2cd0a64b9b28e390be9953104ee6..fe882b9d917eb3d42d4fb73151a833271ef1c8e3 100644 (file)
 #define PT_REGS_SYSCALL_RET(r) PT_REGS_EAX(r)
 #define PT_FIX_EXEC_STACK(sp) do ; while(0)
 
+/* Cope with a conditional i386 definition. */
+#undef profile_pc
+#define profile_pc(regs) PT_REGS_IP(regs)
+
 #define user_mode(r) UPT_IS_USER(&(r)->regs)
 
 #endif
index e4b1017b8b2b1cbb7208abcd123b38e49d0d3e46..16ec82e16b21aa18e400e269f386b3d52b3d9ee0 100644 (file)
@@ -77,7 +77,7 @@ static inline void ack_APIC_irq(void)
 extern int get_maxlvt (void);
 extern void clear_local_APIC (void);
 extern void connect_bsp_APIC (void);
-extern void disconnect_bsp_APIC (void);
+extern void disconnect_bsp_APIC (int virt_wire_setup);
 extern void disable_local_APIC (void);
 extern int verify_local_APIC (void);
 extern void cache_APIC_registers (void);
index bfebdb6906547182cb1c328d208518a300f1eabf..9388062c4f6e52fd409ef099395ca55be862c21d 100644 (file)
@@ -94,7 +94,7 @@
 #define                        SET_APIC_DELIVERY_MODE(x,y)     (((x)&~0x700)|((y)<<8))
 #define                                APIC_MODE_FIXED         0x0
 #define                                APIC_MODE_NMI           0x4
-#define                                APIC_MODE_EXINT         0x7
+#define                                APIC_MODE_EXTINT        0x7
 #define        APIC_LVT1       0x360
 #define                APIC_LVTERR     0x370
 #define                APIC_TMICT      0x380
index 3af50b3c3b05130a3044c37cb46bb89f2843a3d4..eb3b7aa9eb9f2c4ea0bc34b6a72522a36a8a1041 100644 (file)
@@ -52,4 +52,9 @@ struct irqaction;
 struct pt_regs;
 int handle_IRQ_event(unsigned int, struct pt_regs *, struct irqaction *);
 
+#ifdef CONFIG_HOTPLUG_CPU
+#include <linux/cpumask.h>
+extern void fixup_irqs(cpumask_t map);
+#endif
+
 #endif /* _ASM_IRQ_H */
index 6277f75cbb4b3f1a25330cf80280e9118f63f8a3..b90341994d80f6e78d18f685cca99e15baea8e37 100644 (file)
@@ -14,7 +14,7 @@ struct die_args {
 }; 
 
 /* Note - you should never unregister because that can race with NMIs.
-   If you really want to do it first unregister - then synchronize_kernel - then free. 
+   If you really want to do it first unregister - then synchronize_sched - then free.
   */
 int register_die_notifier(struct notifier_block *nb);
 extern struct notifier_block *die_chain;
diff --git a/include/asm-x86_64/kexec.h b/include/asm-x86_64/kexec.h
new file mode 100644 (file)
index 0000000..42d2ff1
--- /dev/null
@@ -0,0 +1,33 @@
+#ifndef _X86_64_KEXEC_H
+#define _X86_64_KEXEC_H
+
+#include <asm/page.h>
+#include <asm/proto.h>
+
+/*
+ * KEXEC_SOURCE_MEMORY_LIMIT maximum page get_free_page can return.
+ * I.e. Maximum page that is mapped directly into kernel memory,
+ * and kmap is not required.
+ *
+ * So far x86_64 is limited to 40 physical address bits.
+ */
+
+/* Maximum physical address we can use pages from */
+#define KEXEC_SOURCE_MEMORY_LIMIT      (0xFFFFFFFFFFUL)
+/* Maximum address we can reach in physical address mode */
+#define KEXEC_DESTINATION_MEMORY_LIMIT (0xFFFFFFFFFFUL)
+/* Maximum address we can use for the control pages */
+#define KEXEC_CONTROL_MEMORY_LIMIT     (0xFFFFFFFFFFUL)
+
+/* Allocate one page for the pdp and the second for the code */
+#define KEXEC_CONTROL_CODE_SIZE  (4096UL + 4096UL)
+
+/* The native architecture */
+#define KEXEC_ARCH KEXEC_ARCH_X86_64
+
+#define MAX_NOTE_BYTES 1024
+typedef u32 note_buf_t[MAX_NOTE_BYTES/4];
+
+extern note_buf_t crash_notes[];
+
+#endif /* _X86_64_KEXEC_H */
index 60130f4ca986b7855119ec0486c45a94e881191f..431318764af60da58dae27c150deed7379676198 100644 (file)
@@ -64,12 +64,14 @@ typedef struct { unsigned long pgprot; } pgprot_t;
 #define __pgd(x) ((pgd_t) { (x) } )
 #define __pgprot(x)    ((pgprot_t) { (x) } )
 
-#define __START_KERNEL         0xffffffff80100000UL
+#define __PHYSICAL_START       ((unsigned long)CONFIG_PHYSICAL_START)
+#define __START_KERNEL         (__START_KERNEL_map + __PHYSICAL_START)
 #define __START_KERNEL_map     0xffffffff80000000UL
 #define __PAGE_OFFSET           0xffff810000000000UL
 
 #else
-#define __START_KERNEL         0xffffffff80100000
+#define __PHYSICAL_START       CONFIG_PHYSICAL_START
+#define __START_KERNEL         (__START_KERNEL_map + __PHYSICAL_START)
 #define __START_KERNEL_map     0xffffffff80000000
 #define __PAGE_OFFSET           0xffff810000000000
 #endif /* !__ASSEMBLY__ */
index a7425aa5a3b72d369ef676c5f1fda8c5dec049b3..aeb1b73e21e117eb24a5ea341bdc2e1f80eb3774 100644 (file)
@@ -43,6 +43,8 @@ extern cpumask_t cpu_callout_map;
 extern void smp_alloc_memory(void);
 extern volatile unsigned long smp_invalidate_needed;
 extern int pic_mode;
+extern void lock_ipi_call_lock(void);
+extern void unlock_ipi_call_lock(void);
 extern int smp_num_siblings;
 extern void smp_flush_tlb(void);
 extern void smp_message_irq(int cpl, void *dev_id, struct pt_regs *regs);
@@ -77,6 +79,8 @@ extern __inline int hard_smp_processor_id(void)
 }
 
 extern int safe_smp_processor_id(void);
+extern int __cpu_disable(void);
+extern void __cpu_die(unsigned int cpu);
 
 #endif /* !ASSEMBLY */
 
index ec745807feae4892ec7d560e9fc930ca04591acb..bb9f40597d097dacf7e08ae8de2cc23dfbb2adab 100644 (file)
@@ -16,7 +16,7 @@ arch_prepare_suspend(void)
 struct saved_context {
        u16 ds, es, fs, gs, ss;
        unsigned long gs_base, gs_kernel_base, fs_base;
-       unsigned long cr0, cr2, cr3, cr4;
+       unsigned long cr0, cr2, cr3, cr4, cr8;
        u16 gdt_pad;
        u16 gdt_limit;
        unsigned long gdt_base;
index 8f77e9f6bc23c4ac810c304cc859316843e5faf4..c1bc3fad482ed4a4388412ff300a0395f86178a1 100644 (file)
@@ -39,12 +39,16 @@ extern int __node_distance(int, int);
        .busy_factor            = 32,                   \
        .imbalance_pct          = 125,                  \
        .cache_hot_time         = (10*1000000),         \
-       .cache_nice_tries       = 1,                    \
+       .cache_nice_tries       = 2,                    \
+       .busy_idx               = 3,                    \
+       .idle_idx               = 2,                    \
+       .newidle_idx            = 0,                    \
+       .wake_idx               = 1,                    \
+       .forkexec_idx           = 1,                    \
        .per_cpu_gain           = 100,                  \
        .flags                  = SD_LOAD_BALANCE       \
-                               | SD_BALANCE_NEWIDLE    \
+                               | SD_BALANCE_FORK       \
                                | SD_BALANCE_EXEC       \
-                               | SD_WAKE_IDLE          \
                                | SD_WAKE_BALANCE,      \
        .last_balance           = jiffies,              \
        .balance_interval       = 1,                    \
index 3c9af6fd433216fdfd26b60619dc6d3b9ce903b8..d767adcbf0ffa3cadd3830fec9202ae82a79fd54 100644 (file)
@@ -552,7 +552,7 @@ __SYSCALL(__NR_mq_notify, sys_mq_notify)
 #define __NR_mq_getsetattr     245
 __SYSCALL(__NR_mq_getsetattr, sys_mq_getsetattr)
 #define __NR_kexec_load        246
-__SYSCALL(__NR_kexec_load, sys_ni_syscall)
+__SYSCALL(__NR_kexec_load, sys_kexec_load)
 #define __NR_waitid            247
 __SYSCALL(__NR_waitid, sys_waitid)
 #define __NR_add_key           248
index af8a1dfa5c329dd2dcdbbefc11238e413c3c08a8..f913cc3e1b0da141d273522c751e4003cfc7ec18 100644 (file)
@@ -138,7 +138,7 @@ enum machine_type {
 #endif
 #endif
 
-#define _N_SEGMENT_ROUND(x) (((x) + SEGMENT_SIZE - 1) & ~(SEGMENT_SIZE - 1))
+#define _N_SEGMENT_ROUND(x) ALIGN(x, SEGMENT_SIZE)
 
 #define _N_TXTENDADDR(x) (N_TXTADDR(x)+(x).a_text)
 
index 60272141ff1976c57c3f4f58daf514d2f79d0e52..b54a0348a8905c78a570272b6b8c9a4c953b3d0b 100644 (file)
@@ -539,15 +539,12 @@ extern void generic_make_request(struct bio *bio);
 extern void blk_put_request(struct request *);
 extern void blk_end_sync_rq(struct request *rq);
 extern void blk_attempt_remerge(request_queue_t *, struct request *);
-extern void __blk_attempt_remerge(request_queue_t *, struct request *);
 extern struct request *blk_get_request(request_queue_t *, int, int);
 extern void blk_insert_request(request_queue_t *, struct request *, int, void *);
 extern void blk_requeue_request(request_queue_t *, struct request *);
 extern void blk_plug_device(request_queue_t *);
 extern int blk_remove_plug(request_queue_t *);
 extern void blk_recount_segments(request_queue_t *, struct bio *);
-extern int blk_phys_contig_segment(request_queue_t *q, struct bio *, struct bio *);
-extern int blk_hw_contig_segment(request_queue_t *q, struct bio *, struct bio *);
 extern int scsi_cmd_ioctl(struct file *, struct gendisk *, unsigned int, void __user *);
 extern void blk_start_queue(request_queue_t *q);
 extern void blk_stop_queue(request_queue_t *q);
@@ -631,7 +628,6 @@ extern void blk_queue_dma_alignment(request_queue_t *, int);
 extern struct backing_dev_info *blk_get_backing_dev_info(struct block_device *bdev);
 extern void blk_queue_ordered(request_queue_t *, int);
 extern void blk_queue_issue_flush_fn(request_queue_t *, issue_flush_fn *);
-extern int blkdev_scsi_issue_flush_fn(request_queue_t *, struct gendisk *, sector_t *);
 extern struct request *blk_start_pre_flush(request_queue_t *,struct request *);
 extern int blk_complete_barrier_rq(request_queue_t *, struct request *, int);
 extern int blk_complete_barrier_rq_locked(request_queue_t *, struct request *, int);
@@ -675,8 +671,6 @@ extern int blkdev_issue_flush(struct block_device *, sector_t *);
 
 #define blkdev_entry_to_request(entry) list_entry((entry), struct request, queuelist)
 
-extern void drive_stat_acct(struct request *, int, int);
-
 static inline int queue_hardsect_size(request_queue_t *q)
 {
        int retval = 512;
index 500f451ce0c0012dfe533ddd4f05b2a28db5b78f..82bd8842d11cfe3a01e704aaec3aab947b917c08 100644 (file)
@@ -22,6 +22,10 @@ extern unsigned long min_low_pfn;
  */
 extern unsigned long max_pfn;
 
+#ifdef CONFIG_CRASH_DUMP
+extern unsigned long saved_max_pfn;
+#endif
+
 /*
  * node_bootmem_map is a map pointer - the bits represent all physical 
  * memory pages (including holes) on the node.
index fe0298e5dae1563b165f60aac60164cf13766121..e8904c0da686e0f347c5fe35a8603fa6e581de31 100644 (file)
@@ -69,6 +69,7 @@ extern struct semaphore cpucontrol;
        register_cpu_notifier(&fn##_nb);                        \
 }
 int cpu_down(unsigned int cpu);
+extern int __attribute__((weak)) smp_prepare_cpu(int cpu);
 #define cpu_is_offline(cpu) unlikely(!cpu_online(cpu))
 #else
 #define lock_cpu_hotplug()     do { } while (0)
diff --git a/include/linux/crash_dump.h b/include/linux/crash_dump.h
new file mode 100644 (file)
index 0000000..534d750
--- /dev/null
@@ -0,0 +1,18 @@
+#ifndef LINUX_CRASH_DUMP_H
+#define LINUX_CRASH_DUMP_H
+
+#ifdef CONFIG_CRASH_DUMP
+#include <linux/kexec.h>
+#include <linux/smp_lock.h>
+#include <linux/device.h>
+#include <linux/proc_fs.h>
+
+#define ELFCORE_ADDR_MAX       (-1ULL)
+extern unsigned long long elfcorehdr_addr;
+extern ssize_t copy_oldmem_page(unsigned long, char *, size_t,
+                                               unsigned long, int);
+extern struct file_operations proc_vmcore_operations;
+extern struct proc_dir_entry *proc_vmcore;
+
+#endif /* CONFIG_CRASH_DUMP */
+#endif /* LINUX_CRASHDUMP_H */
index d2bcf556088b99a58ead0a44c883a5c88df19c84..5e93e6dce9a4751b7107d24e4e241a1eb1989651 100644 (file)
@@ -9,6 +9,7 @@ enum dmi_field {
        DMI_SYS_VENDOR,
        DMI_PRODUCT_NAME,
        DMI_PRODUCT_VERSION,
+       DMI_PRODUCT_SERIAL,
        DMI_BOARD_VENDOR,
        DMI_BOARD_NAME,
        DMI_BOARD_VERSION,
index 2a7e6c65c882f6b17b1d4037ed1c8a25637d7455..6bece9280eb779cf673e9f700ccc64ccc28d543a 100644 (file)
@@ -28,6 +28,7 @@ static inline void *kmap(struct page *page)
 
 #define kmap_atomic(page, idx)         page_address(page)
 #define kunmap_atomic(addr, idx)       do { } while (0)
+#define kmap_atomic_pfn(pfn, idx)      page_address(pfn_to_page(pfn))
 #define kmap_atomic_to_page(ptr)       virt_to_page(ptr)
 
 #endif /* CONFIG_HIGHMEM */
index 05c83e0521ca6290638a22a6d22cd68c90a3d6ef..59008c3826cf790806f1f68bd007fa172e89fc5f 100644 (file)
@@ -229,6 +229,18 @@ void __init parse_early_param(void);
 #define __devexitdata __exitdata
 #endif
 
+#ifdef CONFIG_HOTPLUG_CPU
+#define __cpuinit
+#define __cpuinitdata
+#define __cpuexit
+#define __cpuexitdata
+#else
+#define __cpuinit      __init
+#define __cpuinitdata __initdata
+#define __cpuexit __exit
+#define __cpuexitdata  __exitdata
+#endif
+
 /* Functions marked as __devexit may be discarded at kernel link time, depending
    on config options.  Newer versions of binutils detect references from
    retained sections to discarded sections and flag an error.  Pointers to
index a6a8c1a38d5e4278a8472132d70b44a6589ae654..03206a425d7a3c2a187f702de734c98fe66df8b5 100644 (file)
@@ -108,7 +108,6 @@ extern struct group_info init_groups;
        .blocked        = {{0}},                                        \
        .alloc_lock     = SPIN_LOCK_UNLOCKED,                           \
        .proc_lock      = SPIN_LOCK_UNLOCKED,                           \
-       .switch_lock    = SPIN_LOCK_UNLOCKED,                           \
        .journal_info   = NULL,                                         \
        .cpu_timers     = INIT_CPU_TIMERS(tsk.cpu_timers),              \
 }
index e25b97062ce1ac942d14301335584bd66e3d331d..687ba8c9973de2d30d97e234817a52e6b2d2f993 100644 (file)
@@ -58,15 +58,23 @@ struct completion;
  * be biten later when the calling function happens to sleep when it is not
  * supposed to.
  */
+#ifdef CONFIG_PREEMPT_VOLUNTARY
+extern int cond_resched(void);
+# define might_resched() cond_resched()
+#else
+# define might_resched() do { } while (0)
+#endif
+
 #ifdef CONFIG_DEBUG_SPINLOCK_SLEEP
-#define might_sleep() __might_sleep(__FILE__, __LINE__)
-#define might_sleep_if(cond) do { if (unlikely(cond)) might_sleep(); } while (0)
-void __might_sleep(char *file, int line);
+  void __might_sleep(char *file, int line);
+# define might_sleep() \
+       do { __might_sleep(__FILE__, __LINE__); might_resched(); } while (0)
 #else
-#define might_sleep() do {} while(0)
-#define might_sleep_if(cond) do {} while (0)
+# define might_sleep() do { might_resched(); } while (0)
 #endif
 
+#define might_sleep_if(cond) do { if (unlikely(cond)) might_sleep(); } while (0)
+
 #define abs(x) ({                              \
                int __x = (x);                  \
                (__x < 0) ? -__x : __x;         \
diff --git a/include/linux/kexec.h b/include/linux/kexec.h
new file mode 100644 (file)
index 0000000..c846847
--- /dev/null
@@ -0,0 +1,135 @@
+#ifndef LINUX_KEXEC_H
+#define LINUX_KEXEC_H
+
+#ifdef CONFIG_KEXEC
+#include <linux/types.h>
+#include <linux/list.h>
+#include <linux/linkage.h>
+#include <linux/compat.h>
+#include <asm/kexec.h>
+
+/* Verify architecture specific macros are defined */
+
+#ifndef KEXEC_SOURCE_MEMORY_LIMIT
+#error KEXEC_SOURCE_MEMORY_LIMIT not defined
+#endif
+
+#ifndef KEXEC_DESTINATION_MEMORY_LIMIT
+#error KEXEC_DESTINATION_MEMORY_LIMIT not defined
+#endif
+
+#ifndef KEXEC_CONTROL_MEMORY_LIMIT
+#error KEXEC_CONTROL_MEMORY_LIMIT not defined
+#endif
+
+#ifndef KEXEC_CONTROL_CODE_SIZE
+#error KEXEC_CONTROL_CODE_SIZE not defined
+#endif
+
+#ifndef KEXEC_ARCH
+#error KEXEC_ARCH not defined
+#endif
+
+/*
+ * This structure is used to hold the arguments that are used when loading
+ * kernel binaries.
+ */
+
+typedef unsigned long kimage_entry_t;
+#define IND_DESTINATION  0x1
+#define IND_INDIRECTION  0x2
+#define IND_DONE         0x4
+#define IND_SOURCE       0x8
+
+#define KEXEC_SEGMENT_MAX 8
+struct kexec_segment {
+       void __user *buf;
+       size_t bufsz;
+       unsigned long mem;      /* User space sees this as a (void *) ... */
+       size_t memsz;
+};
+
+#ifdef CONFIG_COMPAT
+struct compat_kexec_segment {
+       compat_uptr_t buf;
+       compat_size_t bufsz;
+       compat_ulong_t mem;     /* User space sees this as a (void *) ... */
+       compat_size_t memsz;
+};
+#endif
+
+struct kimage {
+       kimage_entry_t head;
+       kimage_entry_t *entry;
+       kimage_entry_t *last_entry;
+
+       unsigned long destination;
+
+       unsigned long start;
+       struct page *control_code_page;
+
+       unsigned long nr_segments;
+       struct kexec_segment segment[KEXEC_SEGMENT_MAX];
+
+       struct list_head control_pages;
+       struct list_head dest_pages;
+       struct list_head unuseable_pages;
+
+       /* Address of next control page to allocate for crash kernels. */
+       unsigned long control_page;
+
+       /* Flags to indicate special processing */
+       unsigned int type : 1;
+#define KEXEC_TYPE_DEFAULT 0
+#define KEXEC_TYPE_CRASH   1
+};
+
+
+
+/* kexec interface functions */
+extern NORET_TYPE void machine_kexec(struct kimage *image) ATTRIB_NORET;
+extern int machine_kexec_prepare(struct kimage *image);
+extern void machine_kexec_cleanup(struct kimage *image);
+extern asmlinkage long sys_kexec_load(unsigned long entry,
+                                       unsigned long nr_segments,
+                                       struct kexec_segment __user *segments,
+                                       unsigned long flags);
+#ifdef CONFIG_COMPAT
+extern asmlinkage long compat_sys_kexec_load(unsigned long entry,
+                               unsigned long nr_segments,
+                               struct compat_kexec_segment __user *segments,
+                               unsigned long flags);
+#endif
+extern struct page *kimage_alloc_control_pages(struct kimage *image,
+                                               unsigned int order);
+extern void crash_kexec(struct pt_regs *);
+int kexec_should_crash(struct task_struct *);
+extern struct kimage *kexec_image;
+
+#define KEXEC_ON_CRASH  0x00000001
+#define KEXEC_ARCH_MASK 0xffff0000
+
+/* These values match the ELF architecture values.
+ * Unless there is a good reason that should continue to be the case.
+ */
+#define KEXEC_ARCH_DEFAULT ( 0 << 16)
+#define KEXEC_ARCH_386     ( 3 << 16)
+#define KEXEC_ARCH_X86_64  (62 << 16)
+#define KEXEC_ARCH_PPC     (20 << 16)
+#define KEXEC_ARCH_PPC64   (21 << 16)
+#define KEXEC_ARCH_IA_64   (50 << 16)
+#define KEXEC_ARCH_S390    (22 << 16)
+
+#define KEXEC_FLAGS    (KEXEC_ON_CRASH)  /* List of defined/legal kexec flags */
+
+/* Location of a reserved region to hold the crash kernel.
+ */
+extern struct resource crashk_res;
+
+#else /* !CONFIG_KEXEC */
+struct pt_regs;
+struct task_struct;
+static inline void crash_kexec(struct pt_regs *regs) { }
+static inline int kexec_should_crash(struct task_struct *p) { return 0; }
+#endif /* CONFIG_KEXEC */
+#endif /* LINUX_KEXEC_H */
index 399b51d1721880e6eac3d8b293a140938bf7eb17..aab2db21b013e438c672dbfe4fcceb065bf578d3 100644 (file)
@@ -185,7 +185,7 @@ static inline void list_del(struct list_head *entry)
  * list_for_each_entry_rcu().
  *
  * Note that the caller is not permitted to immediately free
- * the newly deleted entry.  Instead, either synchronize_kernel()
+ * the newly deleted entry.  Instead, either synchronize_rcu()
  * or call_rcu() must be used to defer freeing until an RCU
  * grace period has elapsed.
  */
index b031e41b5e0d106d620e7184f5fafd4773ab5a06..9189829c131c3051a0b3087b1d1596dcfa292954 100644 (file)
@@ -20,8 +20,6 @@ extern void __nvram_write_byte(unsigned char c, int i);
 extern void nvram_write_byte(unsigned char c, int i);
 extern int __nvram_check_checksum(void);
 extern int nvram_check_checksum(void);
-extern void __nvram_set_checksum(void);
-extern void nvram_set_checksum(void);
 #endif
 
 #endif  /* _LINUX_NVRAM_H */
index ed2b76e75199256e0ad037a5db8ff10966eaa67f..14479325e3f38d35a8e4ca36835254bbcb376114 100644 (file)
@@ -103,7 +103,8 @@ extern int pm_active;
 /*
  * Register a device with power management
  */
-struct pm_dev __deprecated *pm_register(pm_dev_t type, unsigned long id, pm_callback callback);
+struct pm_dev __deprecated *
+pm_register(pm_dev_t type, unsigned long id, pm_callback callback);
 
 /*
  * Unregister a device with power management
@@ -190,17 +191,18 @@ typedef u32 __bitwise pm_message_t;
 /*
  * There are 4 important states driver can be in:
  * ON     -- driver is working
- * FREEZE -- stop operations and apply whatever policy is applicable to a suspended driver
- *           of that class, freeze queues for block like IDE does, drop packets for
- *           ethernet, etc... stop DMA engine too etc... so a consistent image can be
- *           saved; but do not power any hardware down.
- * SUSPEND - like FREEZE, but hardware is doing as much powersaving as possible. Roughly
- *           pci D3.
+ * FREEZE -- stop operations and apply whatever policy is applicable to a
+ *           suspended driver of that class, freeze queues for block like IDE
+ *           does, drop packets for ethernet, etc... stop DMA engine too etc...
+ *           so a consistent image can be saved; but do not power any hardware
+ *           down.
+ * SUSPEND - like FREEZE, but hardware is doing as much powersaving as
+ *           possible. Roughly pci D3.
  *
- * Unfortunately, current drivers only recognize numeric values 0 (ON) and 3 (SUSPEND).
- * We'll need to fix the drivers. So yes, putting 3 to all diferent defines is intentional,
- * and will go away as soon as drivers are fixed. Also note that typedef is neccessary,
- * we'll probably want to switch to
+ * Unfortunately, current drivers only recognize numeric values 0 (ON) and 3
+ * (SUSPEND).  We'll need to fix the drivers. So yes, putting 3 to all different
+ * defines is intentional, and will go away as soon as drivers are fixed.  Also
+ * note that typedef is neccessary, we'll probably want to switch to
  *   typedef struct pm_message_t { int event; int flags; } pm_message_t
  * or something similar soon.
  */
@@ -222,11 +224,18 @@ struct dev_pm_info {
 
 extern void device_pm_set_parent(struct device * dev, struct device * parent);
 
-extern int device_suspend(pm_message_t state);
 extern int device_power_down(pm_message_t state);
 extern void device_power_up(void);
 extern void device_resume(void);
 
+#ifdef CONFIG_PM
+extern int device_suspend(pm_message_t state);
+#else
+static inline int device_suspend(pm_message_t state)
+{
+       return 0;
+}
+#endif
 
 #endif /* __KERNEL__ */
 
index 59e505261fd677deb989ada1ca68b5f57af71319..0563581e3a0289b7c4ff9ce2868609cf2d39dda4 100644 (file)
@@ -74,6 +74,13 @@ struct kcore_list {
        size_t size;
 };
 
+struct vmcore {
+       struct list_head list;
+       unsigned long long paddr;
+       unsigned long size;
+       loff_t offset;
+};
+
 #ifdef CONFIG_PROC_FS
 
 extern struct proc_dir_entry proc_root;
index d60fafc8bdc584e73662a1e51f2876b09b13c9f1..2d4dd23168dd2dac2470f3d169742cd297975bc2 100644 (file)
@@ -51,6 +51,10 @@ extern void machine_restart(char *cmd);
 extern void machine_halt(void);
 extern void machine_power_off(void);
 
+extern void machine_shutdown(void);
+struct pt_regs;
+extern void machine_crash_shutdown(struct pt_regs *);
+
 #endif
 
 #endif /* _LINUX_REBOOT_H */
index 2c69682b0444623ab7fea6d6ace03174b8ce79c0..9530b19031609cb3136c40795461f10a7d87f897 100644 (file)
@@ -368,6 +368,11 @@ struct signal_struct {
 #endif
 };
 
+/* Context switch must be unlocked if interrupts are to be enabled */
+#ifdef __ARCH_WANT_INTERRUPTS_ON_CTXSW
+# define __ARCH_WANT_UNLOCKED_CTXSW
+#endif
+
 /*
  * Bits in flags field of signal_struct.
  */
@@ -460,10 +465,11 @@ enum idle_type
 #define SD_LOAD_BALANCE                1       /* Do load balancing on this domain. */
 #define SD_BALANCE_NEWIDLE     2       /* Balance when about to become idle */
 #define SD_BALANCE_EXEC                4       /* Balance on exec */
-#define SD_WAKE_IDLE           8       /* Wake to idle CPU on task wakeup */
-#define SD_WAKE_AFFINE         16      /* Wake task to waking CPU */
-#define SD_WAKE_BALANCE                32      /* Perform balancing at task wakeup */
-#define SD_SHARE_CPUPOWER      64      /* Domain members share cpu power */
+#define SD_BALANCE_FORK                8       /* Balance on fork, clone */
+#define SD_WAKE_IDLE           16      /* Wake to idle CPU on task wakeup */
+#define SD_WAKE_AFFINE         32      /* Wake task to waking CPU */
+#define SD_WAKE_BALANCE                64      /* Perform balancing at task wakeup */
+#define SD_SHARE_CPUPOWER      128     /* Domain members share cpu power */
 
 struct sched_group {
        struct sched_group *next;       /* Must be a circular list */
@@ -488,6 +494,11 @@ struct sched_domain {
        unsigned long long cache_hot_time; /* Task considered cache hot (ns) */
        unsigned int cache_nice_tries;  /* Leave cache hot tasks for # tries */
        unsigned int per_cpu_gain;      /* CPU % gained by adding domain cpus */
+       unsigned int busy_idx;
+       unsigned int idle_idx;
+       unsigned int newidle_idx;
+       unsigned int wake_idx;
+       unsigned int forkexec_idx;
        int flags;                      /* See SD_* */
 
        /* Runtime fields. */
@@ -511,10 +522,16 @@ struct sched_domain {
        unsigned long alb_failed;
        unsigned long alb_pushed;
 
-       /* sched_balance_exec() stats */
-       unsigned long sbe_attempts;
+       /* SD_BALANCE_EXEC stats */
+       unsigned long sbe_cnt;
+       unsigned long sbe_balanced;
        unsigned long sbe_pushed;
 
+       /* SD_BALANCE_FORK stats */
+       unsigned long sbf_cnt;
+       unsigned long sbf_balanced;
+       unsigned long sbf_pushed;
+
        /* try_to_wake_up() stats */
        unsigned long ttwu_wake_remote;
        unsigned long ttwu_move_affine;
@@ -522,6 +539,8 @@ struct sched_domain {
 #endif
 };
 
+extern void partition_sched_domains(cpumask_t *partition1,
+                                   cpumask_t *partition2);
 #ifdef ARCH_HAS_SCHED_DOMAIN
 /* Useful helpers that arch setup code may use. Defined in kernel/sched.c */
 extern cpumask_t cpu_isolated_map;
@@ -582,6 +601,9 @@ struct task_struct {
 
        int lock_depth;         /* BKL lock depth */
 
+#if defined(CONFIG_SMP) && defined(__ARCH_WANT_UNLOCKED_CTXSW)
+       int oncpu;
+#endif
        int prio, static_prio;
        struct list_head run_list;
        prio_array_t *array;
@@ -704,8 +726,6 @@ struct task_struct {
        spinlock_t alloc_lock;
 /* Protection of proc_dentry: nesting proc_lock, dcache_lock, write_lock_irq(&tasklist_lock); */
        spinlock_t proc_lock;
-/* context-switch lock */
-       spinlock_t switch_lock;
 
 /* journalling filesystem info */
        void *journal_info;
@@ -912,7 +932,7 @@ extern void FASTCALL(wake_up_new_task(struct task_struct * tsk,
 #else
  static inline void kick_process(struct task_struct *tsk) { }
 #endif
-extern void FASTCALL(sched_fork(task_t * p));
+extern void FASTCALL(sched_fork(task_t * p, int clone_flags));
 extern void FASTCALL(sched_exit(task_t * p));
 
 extern int in_group_p(gid_t);
@@ -1245,33 +1265,78 @@ extern void normalize_rt_tasks(void);
 
 #endif
 
-/* try_to_freeze
- *
- * Checks whether we need to enter the refrigerator
- * and returns 1 if we did so.
- */
 #ifdef CONFIG_PM
-extern void refrigerator(unsigned long);
+/*
+ * Check if a process has been frozen
+ */
+static inline int frozen(struct task_struct *p)
+{
+       return p->flags & PF_FROZEN;
+}
+
+/*
+ * Check if there is a request to freeze a process
+ */
+static inline int freezing(struct task_struct *p)
+{
+       return p->flags & PF_FREEZE;
+}
+
+/*
+ * Request that a process be frozen
+ * FIXME: SMP problem. We may not modify other process' flags!
+ */
+static inline void freeze(struct task_struct *p)
+{
+       p->flags |= PF_FREEZE;
+}
+
+/*
+ * Wake up a frozen process
+ */
+static inline int thaw_process(struct task_struct *p)
+{
+       if (frozen(p)) {
+               p->flags &= ~PF_FROZEN;
+               wake_up_process(p);
+               return 1;
+       }
+       return 0;
+}
+
+/*
+ * freezing is complete, mark process as frozen
+ */
+static inline void frozen_process(struct task_struct *p)
+{
+       p->flags = (p->flags & ~PF_FREEZE) | PF_FROZEN;
+}
+
+extern void refrigerator(void);
 extern int freeze_processes(void);
 extern void thaw_processes(void);
 
-static inline int try_to_freeze(unsigned long refrigerator_flags)
+static inline int try_to_freeze(void)
 {
-       if (unlikely(current->flags & PF_FREEZE)) {
-               refrigerator(refrigerator_flags);
+       if (freezing(current)) {
+               refrigerator();
                return 1;
        } else
                return 0;
 }
 #else
-static inline void refrigerator(unsigned long flag) {}
+static inline int frozen(struct task_struct *p) { return 0; }
+static inline int freezing(struct task_struct *p) { return 0; }
+static inline void freeze(struct task_struct *p) { BUG(); }
+static inline int thaw_process(struct task_struct *p) { return 1; }
+static inline void frozen_process(struct task_struct *p) { BUG(); }
+
+static inline void refrigerator(void) {}
 static inline int freeze_processes(void) { BUG(); return 0; }
 static inline void thaw_processes(void) {}
 
-static inline int try_to_freeze(unsigned long refrigerator_flags)
-{
-       return 0;
-}
+static inline int try_to_freeze(void) { return 0; }
+
 #endif /* CONFIG_PM */
 #endif /* __KERNEL__ */
 
index 2bf0d5fabcdb9592adfa3f182ba5a90ad5aa5782..f2e96fdfaae01604e207fc9362f55d9286b1b95c 100644 (file)
@@ -58,7 +58,7 @@ static inline int software_suspend(void)
 }
 #endif
 
-#ifdef CONFIG_SMP
+#ifdef CONFIG_SUSPEND_SMP
 extern void disable_nonboot_cpus(void);
 extern void enable_nonboot_cpus(void);
 #else
index c39f6f72cbbc3f0a53ae8e8a31b0749e2c8ea747..52830b6d94e5c8fc926f291452b29bef4dcee91e 100644 (file)
@@ -159,8 +159,9 @@ asmlinkage long sys_shutdown(int, int);
 asmlinkage long sys_reboot(int magic1, int magic2, unsigned int cmd,
                                void __user *arg);
 asmlinkage long sys_restart_syscall(void);
-asmlinkage long sys_kexec_load(void *entry, unsigned long nr_segments,
-                       struct kexec_segment *segments, unsigned long flags);
+asmlinkage long sys_kexec_load(unsigned long entry, unsigned long nr_segments,
+                               struct kexec_segment __user *segments,
+                               unsigned long flags);
 
 asmlinkage long sys_exit(int error_code);
 asmlinkage void sys_exit_group(int error_code);
index d70e8972c67f5c3857b9e8df7ecfb99fd74ed9fd..0320225e96da5b6b24bc5e3d5107fc55527e6aab 100644 (file)
        .cache_hot_time         = 0,                    \
        .cache_nice_tries       = 0,                    \
        .per_cpu_gain           = 25,                   \
+       .busy_idx               = 0,                    \
+       .idle_idx               = 0,                    \
+       .newidle_idx            = 1,                    \
+       .wake_idx               = 0,                    \
+       .forkexec_idx           = 0,                    \
        .flags                  = SD_LOAD_BALANCE       \
                                | SD_BALANCE_NEWIDLE    \
                                | SD_BALANCE_EXEC       \
        .cache_hot_time         = (5*1000000/2),        \
        .cache_nice_tries       = 1,                    \
        .per_cpu_gain           = 100,                  \
+       .busy_idx               = 2,                    \
+       .idle_idx               = 1,                    \
+       .newidle_idx            = 2,                    \
+       .wake_idx               = 1,                    \
+       .forkexec_idx           = 1,                    \
        .flags                  = SD_LOAD_BALANCE       \
                                | SD_BALANCE_NEWIDLE    \
                                | SD_BALANCE_EXEC       \
-                               | SD_WAKE_AFFINE        \
-                               | SD_WAKE_IDLE          \
-                               | SD_WAKE_BALANCE,      \
+                               | SD_WAKE_AFFINE,       \
        .last_balance           = jiffies,              \
        .balance_interval       = 1,                    \
        .nr_balance_failed      = 0,                    \
index 07e7d31f2d0b09000e7bb9dcce72541d9e89d85d..4def882d0b317f8fa59188875c3efa0c18875c2f 100644 (file)
@@ -41,7 +41,7 @@ static int __init do_linuxrc(void * shell)
 static void __init handle_initrd(void)
 {
        int error;
-       int i, pid;
+       int pid;
 
        real_root_dev = new_encode_dev(ROOT_DEV);
        create_dev("/dev/root.old", Root_RAM0, NULL);
@@ -58,7 +58,7 @@ static void __init handle_initrd(void)
 
        pid = kernel_thread(do_linuxrc, "/linuxrc", SIGCHLD);
        if (pid > 0) {
-               while (pid != sys_wait4(-1, &i, 0, NULL))
+               while (pid != sys_wait4(-1, NULL, 0, NULL))
                        yield();
        }
 
diff --git a/kernel/Kconfig.preempt b/kernel/Kconfig.preempt
new file mode 100644 (file)
index 0000000..0b46a5d
--- /dev/null
@@ -0,0 +1,65 @@
+
+choice
+       prompt "Preemption Model"
+       default PREEMPT_NONE
+
+config PREEMPT_NONE
+       bool "No Forced Preemption (Server)"
+       help
+         This is the traditional Linux preemption model, geared towards
+         throughput. It will still provide good latencies most of the
+         time, but there are no guarantees and occasional longer delays
+         are possible.
+
+         Select this option if you are building a kernel for a server or
+         scientific/computation system, or if you want to maximize the
+         raw processing power of the kernel, irrespective of scheduling
+         latencies.
+
+config PREEMPT_VOLUNTARY
+       bool "Voluntary Kernel Preemption (Desktop)"
+       help
+         This option reduces the latency of the kernel by adding more
+         "explicit preemption points" to the kernel code. These new
+         preemption points have been selected to reduce the maximum
+         latency of rescheduling, providing faster application reactions,
+         at the cost of slighly lower throughput.
+
+         This allows reaction to interactive events by allowing a
+         low priority process to voluntarily preempt itself even if it
+         is in kernel mode executing a system call. This allows
+         applications to run more 'smoothly' even when the system is
+         under load.
+
+         Select this if you are building a kernel for a desktop system.
+
+config PREEMPT
+       bool "Preemptible Kernel (Low-Latency Desktop)"
+       help
+         This option reduces the latency of the kernel by making
+         all kernel code (that is not executing in a critical section)
+         preemptible.  This allows reaction to interactive events by
+         permitting a low priority process to be preempted involuntarily
+         even if it is in kernel mode executing a system call and would
+         otherwise not be about to reach a natural preemption point.
+         This allows applications to run more 'smoothly' even when the
+         system is under load, at the cost of slighly lower throughput
+         and a slight runtime overhead to kernel code.
+
+         Select this if you are building a kernel for a desktop or
+         embedded system with latency requirements in the milliseconds
+         range.
+
+endchoice
+
+config PREEMPT_BKL
+       bool "Preempt The Big Kernel Lock"
+       depends on SMP || PREEMPT
+       default y
+       help
+         This option reduces the latency of the kernel by making the
+         big kernel lock preemptible.
+
+         Say Y here if you are building a kernel for a desktop system.
+         Say N if you are unsure.
+
index b01d26fe8db71abdd0397bcb25eb4e47d3f8c45e..cb05cd05d2374b1ae316adb437ec14da370bd8a5 100644 (file)
@@ -17,6 +17,7 @@ obj-$(CONFIG_MODULES) += module.o
 obj-$(CONFIG_KALLSYMS) += kallsyms.o
 obj-$(CONFIG_PM) += power/
 obj-$(CONFIG_BSD_PROCESS_ACCT) += acct.o
+obj-$(CONFIG_KEXEC) += kexec.o
 obj-$(CONFIG_COMPAT) += compat.o
 obj-$(CONFIG_CPUSETS) += cpuset.o
 obj-$(CONFIG_IKCONFIG) += configs.o
@@ -27,6 +28,7 @@ obj-$(CONFIG_AUDITSYSCALL) += auditsc.o
 obj-$(CONFIG_KPROBES) += kprobes.o
 obj-$(CONFIG_SYSFS) += ksysfs.o
 obj-$(CONFIG_GENERIC_HARDIRQS) += irq/
+obj-$(CONFIG_CRASH_DUMP) += crash_dump.o
 obj-$(CONFIG_SECCOMP) += seccomp.o
 
 ifneq ($(CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER),y)
index 628f4ccda12790da9663a4bde4ac897607a8ebd2..53d8263ae12ebc00483a3ad999177799003467e2 100644 (file)
@@ -63,19 +63,15 @@ static int take_cpu_down(void *unused)
 {
        int err;
 
-       /* Take offline: makes arch_cpu_down somewhat easier. */
-       cpu_clear(smp_processor_id(), cpu_online_map);
-
        /* Ensure this CPU doesn't handle any more interrupts. */
        err = __cpu_disable();
        if (err < 0)
-               cpu_set(smp_processor_id(), cpu_online_map);
-       else
-               /* Force idle task to run as soon as we yield: it should
-                  immediately notice cpu is offline and die quickly. */
-               sched_idle_next();
+               return err;
 
-       return err;
+       /* Force idle task to run as soon as we yield: it should
+          immediately notice cpu is offline and die quickly. */
+       sched_idle_next();
+       return 0;
 }
 
 int cpu_down(unsigned int cpu)
index 79dd929f4084395ff82dd6fa8f8065dcc111b16f..984c0bf3807fcc7e56bf339c0620205f79e0205b 100644 (file)
@@ -595,10 +595,62 @@ static int validate_change(const struct cpuset *cur, const struct cpuset *trial)
        return 0;
 }
 
+/*
+ * For a given cpuset cur, partition the system as follows
+ * a. All cpus in the parent cpuset's cpus_allowed that are not part of any
+ *    exclusive child cpusets
+ * b. All cpus in the current cpuset's cpus_allowed that are not part of any
+ *    exclusive child cpusets
+ * Build these two partitions by calling partition_sched_domains
+ *
+ * Call with cpuset_sem held.  May nest a call to the
+ * lock_cpu_hotplug()/unlock_cpu_hotplug() pair.
+ */
+static void update_cpu_domains(struct cpuset *cur)
+{
+       struct cpuset *c, *par = cur->parent;
+       cpumask_t pspan, cspan;
+
+       if (par == NULL || cpus_empty(cur->cpus_allowed))
+               return;
+
+       /*
+        * Get all cpus from parent's cpus_allowed not part of exclusive
+        * children
+        */
+       pspan = par->cpus_allowed;
+       list_for_each_entry(c, &par->children, sibling) {
+               if (is_cpu_exclusive(c))
+                       cpus_andnot(pspan, pspan, c->cpus_allowed);
+       }
+       if (is_removed(cur) || !is_cpu_exclusive(cur)) {
+               cpus_or(pspan, pspan, cur->cpus_allowed);
+               if (cpus_equal(pspan, cur->cpus_allowed))
+                       return;
+               cspan = CPU_MASK_NONE;
+       } else {
+               if (cpus_empty(pspan))
+                       return;
+               cspan = cur->cpus_allowed;
+               /*
+                * Get all cpus from current cpuset's cpus_allowed not part
+                * of exclusive children
+                */
+               list_for_each_entry(c, &cur->children, sibling) {
+                       if (is_cpu_exclusive(c))
+                               cpus_andnot(cspan, cspan, c->cpus_allowed);
+               }
+       }
+
+       lock_cpu_hotplug();
+       partition_sched_domains(&pspan, &cspan);
+       unlock_cpu_hotplug();
+}
+
 static int update_cpumask(struct cpuset *cs, char *buf)
 {
        struct cpuset trialcs;
-       int retval;
+       int retval, cpus_unchanged;
 
        trialcs = *cs;
        retval = cpulist_parse(buf, trialcs.cpus_allowed);
@@ -608,9 +660,13 @@ static int update_cpumask(struct cpuset *cs, char *buf)
        if (cpus_empty(trialcs.cpus_allowed))
                return -ENOSPC;
        retval = validate_change(cs, &trialcs);
-       if (retval == 0)
-               cs->cpus_allowed = trialcs.cpus_allowed;
-       return retval;
+       if (retval < 0)
+               return retval;
+       cpus_unchanged = cpus_equal(cs->cpus_allowed, trialcs.cpus_allowed);
+       cs->cpus_allowed = trialcs.cpus_allowed;
+       if (is_cpu_exclusive(cs) && !cpus_unchanged)
+               update_cpu_domains(cs);
+       return 0;
 }
 
 static int update_nodemask(struct cpuset *cs, char *buf)
@@ -646,7 +702,7 @@ static int update_flag(cpuset_flagbits_t bit, struct cpuset *cs, char *buf)
 {
        int turning_on;
        struct cpuset trialcs;
-       int err;
+       int err, cpu_exclusive_changed;
 
        turning_on = (simple_strtoul(buf, NULL, 10) != 0);
 
@@ -657,13 +713,18 @@ static int update_flag(cpuset_flagbits_t bit, struct cpuset *cs, char *buf)
                clear_bit(bit, &trialcs.flags);
 
        err = validate_change(cs, &trialcs);
-       if (err == 0) {
-               if (turning_on)
-                       set_bit(bit, &cs->flags);
-               else
-                       clear_bit(bit, &cs->flags);
-       }
-       return err;
+       if (err < 0)
+               return err;
+       cpu_exclusive_changed =
+               (is_cpu_exclusive(cs) != is_cpu_exclusive(&trialcs));
+       if (turning_on)
+               set_bit(bit, &cs->flags);
+       else
+               clear_bit(bit, &cs->flags);
+
+       if (cpu_exclusive_changed)
+                update_cpu_domains(cs);
+       return 0;
 }
 
 static int attach_task(struct cpuset *cs, char *buf)
@@ -1309,12 +1370,14 @@ static int cpuset_rmdir(struct inode *unused_dir, struct dentry *dentry)
                up(&cpuset_sem);
                return -EBUSY;
        }
-       spin_lock(&cs->dentry->d_lock);
        parent = cs->parent;
        set_bit(CS_REMOVED, &cs->flags);
+       if (is_cpu_exclusive(cs))
+               update_cpu_domains(cs);
        list_del(&cs->sibling); /* delete my sibling from parent->children */
        if (list_empty(&parent->children))
                check_for_release(parent);
+       spin_lock(&cs->dentry->d_lock);
        d = dget(cs->dentry);
        cs->dentry = NULL;
        spin_unlock(&d->d_lock);
diff --git a/kernel/crash_dump.c b/kernel/crash_dump.c
new file mode 100644 (file)
index 0000000..459ba49
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ *     kernel/crash_dump.c - Memory preserving reboot related code.
+ *
+ *     Created by: Hariprasad Nellitheertha (hari@in.ibm.com)
+ *     Copyright (C) IBM Corporation, 2004. All rights reserved
+ */
+
+#include <linux/smp_lock.h>
+#include <linux/errno.h>
+#include <linux/proc_fs.h>
+#include <linux/bootmem.h>
+#include <linux/highmem.h>
+#include <linux/crash_dump.h>
+
+#include <asm/io.h>
+#include <asm/uaccess.h>
+
+/* Stores the physical address of elf header of crash image. */
+unsigned long long elfcorehdr_addr = ELFCORE_ADDR_MAX;
+
+/*
+ * Copy a page from "oldmem". For this page, there is no pte mapped
+ * in the current kernel. We stitch up a pte, similar to kmap_atomic.
+ */
+ssize_t copy_oldmem_page(unsigned long pfn, char *buf,
+                               size_t csize, unsigned long offset, int userbuf)
+{
+       void *page, *vaddr;
+
+       if (!csize)
+               return 0;
+
+       page = kmalloc(PAGE_SIZE, GFP_KERNEL);
+       if (!page)
+               return -ENOMEM;
+
+       vaddr = kmap_atomic_pfn(pfn, KM_PTE0);
+       copy_page(page, vaddr);
+       kunmap_atomic(vaddr, KM_PTE0);
+
+       if (userbuf) {
+               if (copy_to_user(buf, (page + offset), csize)) {
+                       kfree(page);
+                       return -EFAULT;
+               }
+       } else {
+               memcpy(buf, (page + offset), csize);
+       }
+
+       kfree(page);
+       return csize;
+}
index a28d11e10877d07ebdd1ccde6006493122873b28..2c7806873bfd1b656b5dc033a6abaf4ff535531f 100644 (file)
@@ -1003,9 +1003,6 @@ static task_t *copy_process(unsigned long clone_flags,
        p->pdeath_signal = 0;
        p->exit_state = 0;
 
-       /* Perform scheduler related setup */
-       sched_fork(p);
-
        /*
         * Ok, make it visible to the rest of the system.
         * We dont wake it up yet.
@@ -1014,18 +1011,24 @@ static task_t *copy_process(unsigned long clone_flags,
        INIT_LIST_HEAD(&p->ptrace_children);
        INIT_LIST_HEAD(&p->ptrace_list);
 
+       /* Perform scheduler related setup. Assign this task to a CPU. */
+       sched_fork(p, clone_flags);
+
        /* Need tasklist lock for parent etc handling! */
        write_lock_irq(&tasklist_lock);
 
        /*
-        * The task hasn't been attached yet, so cpus_allowed mask cannot
-        * have changed. The cpus_allowed mask of the parent may have
-        * changed after it was copied first time, and it may then move to
-        * another CPU - so we re-copy it here and set the child's CPU to
-        * the parent's CPU. This avoids alot of nasty races.
+        * The task hasn't been attached yet, so its cpus_allowed mask will
+        * not be changed, nor will its assigned CPU.
+        *
+        * The cpus_allowed mask of the parent may have changed after it was
+        * copied first time - so re-copy it here, then check the child's CPU
+        * to ensure it is on a valid CPU (and if not, just force it back to
+        * parent's CPU). This avoids alot of nasty races.
         */
        p->cpus_allowed = current->cpus_allowed;
-       set_task_cpu(p, smp_processor_id());
+       if (unlikely(!cpu_isset(task_cpu(p), p->cpus_allowed)))
+               set_task_cpu(p, smp_processor_id());
 
        /*
         * Check for pending SIGKILL! The new thread should not be allowed
diff --git a/kernel/kexec.c b/kernel/kexec.c
new file mode 100644 (file)
index 0000000..7843548
--- /dev/null
@@ -0,0 +1,1063 @@
+/*
+ * kexec.c - kexec system call
+ * Copyright (C) 2002-2004 Eric Biederman  <ebiederm@xmission.com>
+ *
+ * This source code is licensed under the GNU General Public License,
+ * Version 2.  See the file COPYING for more details.
+ */
+
+#include <linux/mm.h>
+#include <linux/file.h>
+#include <linux/slab.h>
+#include <linux/fs.h>
+#include <linux/kexec.h>
+#include <linux/spinlock.h>
+#include <linux/list.h>
+#include <linux/highmem.h>
+#include <linux/syscalls.h>
+#include <linux/reboot.h>
+#include <linux/syscalls.h>
+#include <linux/ioport.h>
+#include <linux/hardirq.h>
+
+#include <asm/page.h>
+#include <asm/uaccess.h>
+#include <asm/io.h>
+#include <asm/system.h>
+#include <asm/semaphore.h>
+
+/* Location of the reserved area for the crash kernel */
+struct resource crashk_res = {
+       .name  = "Crash kernel",
+       .start = 0,
+       .end   = 0,
+       .flags = IORESOURCE_BUSY | IORESOURCE_MEM
+};
+
+int kexec_should_crash(struct task_struct *p)
+{
+       if (in_interrupt() || !p->pid || p->pid == 1 || panic_on_oops)
+               return 1;
+       return 0;
+}
+
+/*
+ * When kexec transitions to the new kernel there is a one-to-one
+ * mapping between physical and virtual addresses.  On processors
+ * where you can disable the MMU this is trivial, and easy.  For
+ * others it is still a simple predictable page table to setup.
+ *
+ * In that environment kexec copies the new kernel to its final
+ * resting place.  This means I can only support memory whose
+ * physical address can fit in an unsigned long.  In particular
+ * addresses where (pfn << PAGE_SHIFT) > ULONG_MAX cannot be handled.
+ * If the assembly stub has more restrictive requirements
+ * KEXEC_SOURCE_MEMORY_LIMIT and KEXEC_DEST_MEMORY_LIMIT can be
+ * defined more restrictively in <asm/kexec.h>.
+ *
+ * The code for the transition from the current kernel to the
+ * the new kernel is placed in the control_code_buffer, whose size
+ * is given by KEXEC_CONTROL_CODE_SIZE.  In the best case only a single
+ * page of memory is necessary, but some architectures require more.
+ * Because this memory must be identity mapped in the transition from
+ * virtual to physical addresses it must live in the range
+ * 0 - TASK_SIZE, as only the user space mappings are arbitrarily
+ * modifiable.
+ *
+ * The assembly stub in the control code buffer is passed a linked list
+ * of descriptor pages detailing the source pages of the new kernel,
+ * and the destination addresses of those source pages.  As this data
+ * structure is not used in the context of the current OS, it must
+ * be self-contained.
+ *
+ * The code has been made to work with highmem pages and will use a
+ * destination page in its final resting place (if it happens
+ * to allocate it).  The end product of this is that most of the
+ * physical address space, and most of RAM can be used.
+ *
+ * Future directions include:
+ *  - allocating a page table with the control code buffer identity
+ *    mapped, to simplify machine_kexec and make kexec_on_panic more
+ *    reliable.
+ */
+
+/*
+ * KIMAGE_NO_DEST is an impossible destination address..., for
+ * allocating pages whose destination address we do not care about.
+ */
+#define KIMAGE_NO_DEST (-1UL)
+
+static int kimage_is_destination_range(struct kimage *image,
+                                      unsigned long start, unsigned long end);
+static struct page *kimage_alloc_page(struct kimage *image,
+                                      unsigned int gfp_mask,
+                                      unsigned long dest);
+
+static int do_kimage_alloc(struct kimage **rimage, unsigned long entry,
+                           unsigned long nr_segments,
+                            struct kexec_segment __user *segments)
+{
+       size_t segment_bytes;
+       struct kimage *image;
+       unsigned long i;
+       int result;
+
+       /* Allocate a controlling structure */
+       result = -ENOMEM;
+       image = kmalloc(sizeof(*image), GFP_KERNEL);
+       if (!image)
+               goto out;
+
+       memset(image, 0, sizeof(*image));
+       image->head = 0;
+       image->entry = &image->head;
+       image->last_entry = &image->head;
+       image->control_page = ~0; /* By default this does not apply */
+       image->start = entry;
+       image->type = KEXEC_TYPE_DEFAULT;
+
+       /* Initialize the list of control pages */
+       INIT_LIST_HEAD(&image->control_pages);
+
+       /* Initialize the list of destination pages */
+       INIT_LIST_HEAD(&image->dest_pages);
+
+       /* Initialize the list of unuseable pages */
+       INIT_LIST_HEAD(&image->unuseable_pages);
+
+       /* Read in the segments */
+       image->nr_segments = nr_segments;
+       segment_bytes = nr_segments * sizeof(*segments);
+       result = copy_from_user(image->segment, segments, segment_bytes);
+       if (result)
+               goto out;
+
+       /*
+        * Verify we have good destination addresses.  The caller is
+        * responsible for making certain we don't attempt to load
+        * the new image into invalid or reserved areas of RAM.  This
+        * just verifies it is an address we can use.
+        *
+        * Since the kernel does everything in page size chunks ensure
+        * the destination addreses are page aligned.  Too many
+        * special cases crop of when we don't do this.  The most
+        * insidious is getting overlapping destination addresses
+        * simply because addresses are changed to page size
+        * granularity.
+        */
+       result = -EADDRNOTAVAIL;
+       for (i = 0; i < nr_segments; i++) {
+               unsigned long mstart, mend;
+
+               mstart = image->segment[i].mem;
+               mend   = mstart + image->segment[i].memsz;
+               if ((mstart & ~PAGE_MASK) || (mend & ~PAGE_MASK))
+                       goto out;
+               if (mend >= KEXEC_DESTINATION_MEMORY_LIMIT)
+                       goto out;
+       }
+
+       /* Verify our destination addresses do not overlap.
+        * If we alloed overlapping destination addresses
+        * through very weird things can happen with no
+        * easy explanation as one segment stops on another.
+        */
+       result = -EINVAL;
+       for (i = 0; i < nr_segments; i++) {
+               unsigned long mstart, mend;
+               unsigned long j;
+
+               mstart = image->segment[i].mem;
+               mend   = mstart + image->segment[i].memsz;
+               for (j = 0; j < i; j++) {
+                       unsigned long pstart, pend;
+                       pstart = image->segment[j].mem;
+                       pend   = pstart + image->segment[j].memsz;
+                       /* Do the segments overlap ? */
+                       if ((mend > pstart) && (mstart < pend))
+                               goto out;
+               }
+       }
+
+       /* Ensure our buffer sizes are strictly less than
+        * our memory sizes.  This should always be the case,
+        * and it is easier to check up front than to be surprised
+        * later on.
+        */
+       result = -EINVAL;
+       for (i = 0; i < nr_segments; i++) {
+               if (image->segment[i].bufsz > image->segment[i].memsz)
+                       goto out;
+       }
+
+       result = 0;
+out:
+       if (result == 0)
+               *rimage = image;
+       else
+               kfree(image);
+
+       return result;
+
+}
+
+static int kimage_normal_alloc(struct kimage **rimage, unsigned long entry,
+                               unsigned long nr_segments,
+                               struct kexec_segment __user *segments)
+{
+       int result;
+       struct kimage *image;
+
+       /* Allocate and initialize a controlling structure */
+       image = NULL;
+       result = do_kimage_alloc(&image, entry, nr_segments, segments);
+       if (result)
+               goto out;
+
+       *rimage = image;
+
+       /*
+        * Find a location for the control code buffer, and add it
+        * the vector of segments so that it's pages will also be
+        * counted as destination pages.
+        */
+       result = -ENOMEM;
+       image->control_code_page = kimage_alloc_control_pages(image,
+                                          get_order(KEXEC_CONTROL_CODE_SIZE));
+       if (!image->control_code_page) {
+               printk(KERN_ERR "Could not allocate control_code_buffer\n");
+               goto out;
+       }
+
+       result = 0;
+ out:
+       if (result == 0)
+               *rimage = image;
+       else
+               kfree(image);
+
+       return result;
+}
+
+static int kimage_crash_alloc(struct kimage **rimage, unsigned long entry,
+                               unsigned long nr_segments,
+                               struct kexec_segment *segments)
+{
+       int result;
+       struct kimage *image;
+       unsigned long i;
+
+       image = NULL;
+       /* Verify we have a valid entry point */
+       if ((entry < crashk_res.start) || (entry > crashk_res.end)) {
+               result = -EADDRNOTAVAIL;
+               goto out;
+       }
+
+       /* Allocate and initialize a controlling structure */
+       result = do_kimage_alloc(&image, entry, nr_segments, segments);
+       if (result)
+               goto out;
+
+       /* Enable the special crash kernel control page
+        * allocation policy.
+        */
+       image->control_page = crashk_res.start;
+       image->type = KEXEC_TYPE_CRASH;
+
+       /*
+        * Verify we have good destination addresses.  Normally
+        * the caller is responsible for making certain we don't
+        * attempt to load the new image into invalid or reserved
+        * areas of RAM.  But crash kernels are preloaded into a
+        * reserved area of ram.  We must ensure the addresses
+        * are in the reserved area otherwise preloading the
+        * kernel could corrupt things.
+        */
+       result = -EADDRNOTAVAIL;
+       for (i = 0; i < nr_segments; i++) {
+               unsigned long mstart, mend;
+
+               mstart = image->segment[i].mem;
+               mend = mstart + image->segment[i].memsz - 1;
+               /* Ensure we are within the crash kernel limits */
+               if ((mstart < crashk_res.start) || (mend > crashk_res.end))
+                       goto out;
+       }
+
+       /*
+        * Find a location for the control code buffer, and add
+        * the vector of segments so that it's pages will also be
+        * counted as destination pages.
+        */
+       result = -ENOMEM;
+       image->control_code_page = kimage_alloc_control_pages(image,
+                                          get_order(KEXEC_CONTROL_CODE_SIZE));
+       if (!image->control_code_page) {
+               printk(KERN_ERR "Could not allocate control_code_buffer\n");
+               goto out;
+       }
+
+       result = 0;
+out:
+       if (result == 0)
+               *rimage = image;
+       else
+               kfree(image);
+
+       return result;
+}
+
+static int kimage_is_destination_range(struct kimage *image,
+                                       unsigned long start,
+                                       unsigned long end)
+{
+       unsigned long i;
+
+       for (i = 0; i < image->nr_segments; i++) {
+               unsigned long mstart, mend;
+
+               mstart = image->segment[i].mem;
+               mend = mstart + image->segment[i].memsz;
+               if ((end > mstart) && (start < mend))
+                       return 1;
+       }
+
+       return 0;
+}
+
+static struct page *kimage_alloc_pages(unsigned int gfp_mask,
+                                       unsigned int order)
+{
+       struct page *pages;
+
+       pages = alloc_pages(gfp_mask, order);
+       if (pages) {
+               unsigned int count, i;
+               pages->mapping = NULL;
+               pages->private = order;
+               count = 1 << order;
+               for (i = 0; i < count; i++)
+                       SetPageReserved(pages + i);
+       }
+
+       return pages;
+}
+
+static void kimage_free_pages(struct page *page)
+{
+       unsigned int order, count, i;
+
+       order = page->private;
+       count = 1 << order;
+       for (i = 0; i < count; i++)
+               ClearPageReserved(page + i);
+       __free_pages(page, order);
+}
+
+static void kimage_free_page_list(struct list_head *list)
+{
+       struct list_head *pos, *next;
+
+       list_for_each_safe(pos, next, list) {
+               struct page *page;
+
+               page = list_entry(pos, struct page, lru);
+               list_del(&page->lru);
+               kimage_free_pages(page);
+       }
+}
+
+static struct page *kimage_alloc_normal_control_pages(struct kimage *image,
+                                                       unsigned int order)
+{
+       /* Control pages are special, they are the intermediaries
+        * that are needed while we copy the rest of the pages
+        * to their final resting place.  As such they must
+        * not conflict with either the destination addresses
+        * or memory the kernel is already using.
+        *
+        * The only case where we really need more than one of
+        * these are for architectures where we cannot disable
+        * the MMU and must instead generate an identity mapped
+        * page table for all of the memory.
+        *
+        * At worst this runs in O(N) of the image size.
+        */
+       struct list_head extra_pages;
+       struct page *pages;
+       unsigned int count;
+
+       count = 1 << order;
+       INIT_LIST_HEAD(&extra_pages);
+
+       /* Loop while I can allocate a page and the page allocated
+        * is a destination page.
+        */
+       do {
+               unsigned long pfn, epfn, addr, eaddr;
+
+               pages = kimage_alloc_pages(GFP_KERNEL, order);
+               if (!pages)
+                       break;
+               pfn   = page_to_pfn(pages);
+               epfn  = pfn + count;
+               addr  = pfn << PAGE_SHIFT;
+               eaddr = epfn << PAGE_SHIFT;
+               if ((epfn >= (KEXEC_CONTROL_MEMORY_LIMIT >> PAGE_SHIFT)) ||
+                             kimage_is_destination_range(image, addr, eaddr)) {
+                       list_add(&pages->lru, &extra_pages);
+                       pages = NULL;
+               }
+       } while (!pages);
+
+       if (pages) {
+               /* Remember the allocated page... */
+               list_add(&pages->lru, &image->control_pages);
+
+               /* Because the page is already in it's destination
+                * location we will never allocate another page at
+                * that address.  Therefore kimage_alloc_pages
+                * will not return it (again) and we don't need
+                * to give it an entry in image->segment[].
+                */
+       }
+       /* Deal with the destination pages I have inadvertently allocated.
+        *
+        * Ideally I would convert multi-page allocations into single
+        * page allocations, and add everyting to image->dest_pages.
+        *
+        * For now it is simpler to just free the pages.
+        */
+       kimage_free_page_list(&extra_pages);
+
+       return pages;
+}
+
+static struct page *kimage_alloc_crash_control_pages(struct kimage *image,
+                                                     unsigned int order)
+{
+       /* Control pages are special, they are the intermediaries
+        * that are needed while we copy the rest of the pages
+        * to their final resting place.  As such they must
+        * not conflict with either the destination addresses
+        * or memory the kernel is already using.
+        *
+        * Control pages are also the only pags we must allocate
+        * when loading a crash kernel.  All of the other pages
+        * are specified by the segments and we just memcpy
+        * into them directly.
+        *
+        * The only case where we really need more than one of
+        * these are for architectures where we cannot disable
+        * the MMU and must instead generate an identity mapped
+        * page table for all of the memory.
+        *
+        * Given the low demand this implements a very simple
+        * allocator that finds the first hole of the appropriate
+        * size in the reserved memory region, and allocates all
+        * of the memory up to and including the hole.
+        */
+       unsigned long hole_start, hole_end, size;
+       struct page *pages;
+
+       pages = NULL;
+       size = (1 << order) << PAGE_SHIFT;
+       hole_start = (image->control_page + (size - 1)) & ~(size - 1);
+       hole_end   = hole_start + size - 1;
+       while (hole_end <= crashk_res.end) {
+               unsigned long i;
+
+               if (hole_end > KEXEC_CONTROL_MEMORY_LIMIT)
+                       break;
+               if (hole_end > crashk_res.end)
+                       break;
+               /* See if I overlap any of the segments */
+               for (i = 0; i < image->nr_segments; i++) {
+                       unsigned long mstart, mend;
+
+                       mstart = image->segment[i].mem;
+                       mend   = mstart + image->segment[i].memsz - 1;
+                       if ((hole_end >= mstart) && (hole_start <= mend)) {
+                               /* Advance the hole to the end of the segment */
+                               hole_start = (mend + (size - 1)) & ~(size - 1);
+                               hole_end   = hole_start + size - 1;
+                               break;
+                       }
+               }
+               /* If I don't overlap any segments I have found my hole! */
+               if (i == image->nr_segments) {
+                       pages = pfn_to_page(hole_start >> PAGE_SHIFT);
+                       break;
+               }
+       }
+       if (pages)
+               image->control_page = hole_end;
+
+       return pages;
+}
+
+
+struct page *kimage_alloc_control_pages(struct kimage *image,
+                                        unsigned int order)
+{
+       struct page *pages = NULL;
+
+       switch (image->type) {
+       case KEXEC_TYPE_DEFAULT:
+               pages = kimage_alloc_normal_control_pages(image, order);
+               break;
+       case KEXEC_TYPE_CRASH:
+               pages = kimage_alloc_crash_control_pages(image, order);
+               break;
+       }
+
+       return pages;
+}
+
+static int kimage_add_entry(struct kimage *image, kimage_entry_t entry)
+{
+       if (*image->entry != 0)
+               image->entry++;
+
+       if (image->entry == image->last_entry) {
+               kimage_entry_t *ind_page;
+               struct page *page;
+
+               page = kimage_alloc_page(image, GFP_KERNEL, KIMAGE_NO_DEST);
+               if (!page)
+                       return -ENOMEM;
+
+               ind_page = page_address(page);
+               *image->entry = virt_to_phys(ind_page) | IND_INDIRECTION;
+               image->entry = ind_page;
+               image->last_entry = ind_page +
+                                     ((PAGE_SIZE/sizeof(kimage_entry_t)) - 1);
+       }
+       *image->entry = entry;
+       image->entry++;
+       *image->entry = 0;
+
+       return 0;
+}
+
+static int kimage_set_destination(struct kimage *image,
+                                  unsigned long destination)
+{
+       int result;
+
+       destination &= PAGE_MASK;
+       result = kimage_add_entry(image, destination | IND_DESTINATION);
+       if (result == 0)
+               image->destination = destination;
+
+       return result;
+}
+
+
+static int kimage_add_page(struct kimage *image, unsigned long page)
+{
+       int result;
+
+       page &= PAGE_MASK;
+       result = kimage_add_entry(image, page | IND_SOURCE);
+       if (result == 0)
+               image->destination += PAGE_SIZE;
+
+       return result;
+}
+
+
+static void kimage_free_extra_pages(struct kimage *image)
+{
+       /* Walk through and free any extra destination pages I may have */
+       kimage_free_page_list(&image->dest_pages);
+
+       /* Walk through and free any unuseable pages I have cached */
+       kimage_free_page_list(&image->unuseable_pages);
+
+}
+static int kimage_terminate(struct kimage *image)
+{
+       if (*image->entry != 0)
+               image->entry++;
+
+       *image->entry = IND_DONE;
+
+       return 0;
+}
+
+#define for_each_kimage_entry(image, ptr, entry) \
+       for (ptr = &image->head; (entry = *ptr) && !(entry & IND_DONE); \
+               ptr = (entry & IND_INDIRECTION)? \
+                       phys_to_virt((entry & PAGE_MASK)): ptr +1)
+
+static void kimage_free_entry(kimage_entry_t entry)
+{
+       struct page *page;
+
+       page = pfn_to_page(entry >> PAGE_SHIFT);
+       kimage_free_pages(page);
+}
+
+static void kimage_free(struct kimage *image)
+{
+       kimage_entry_t *ptr, entry;
+       kimage_entry_t ind = 0;
+
+       if (!image)
+               return;
+
+       kimage_free_extra_pages(image);
+       for_each_kimage_entry(image, ptr, entry) {
+               if (entry & IND_INDIRECTION) {
+                       /* Free the previous indirection page */
+                       if (ind & IND_INDIRECTION)
+                               kimage_free_entry(ind);
+                       /* Save this indirection page until we are
+                        * done with it.
+                        */
+                       ind = entry;
+               }
+               else if (entry & IND_SOURCE)
+                       kimage_free_entry(entry);
+       }
+       /* Free the final indirection page */
+       if (ind & IND_INDIRECTION)
+               kimage_free_entry(ind);
+
+       /* Handle any machine specific cleanup */
+       machine_kexec_cleanup(image);
+
+       /* Free the kexec control pages... */
+       kimage_free_page_list(&image->control_pages);
+       kfree(image);
+}
+
+static kimage_entry_t *kimage_dst_used(struct kimage *image,
+                                       unsigned long page)
+{
+       kimage_entry_t *ptr, entry;
+       unsigned long destination = 0;
+
+       for_each_kimage_entry(image, ptr, entry) {
+               if (entry & IND_DESTINATION)
+                       destination = entry & PAGE_MASK;
+               else if (entry & IND_SOURCE) {
+                       if (page == destination)
+                               return ptr;
+                       destination += PAGE_SIZE;
+               }
+       }
+
+       return 0;
+}
+
+static struct page *kimage_alloc_page(struct kimage *image,
+                                       unsigned int gfp_mask,
+                                       unsigned long destination)
+{
+       /*
+        * Here we implement safeguards to ensure that a source page
+        * is not copied to its destination page before the data on
+        * the destination page is no longer useful.
+        *
+        * To do this we maintain the invariant that a source page is
+        * either its own destination page, or it is not a
+        * destination page at all.
+        *
+        * That is slightly stronger than required, but the proof
+        * that no problems will not occur is trivial, and the
+        * implementation is simply to verify.
+        *
+        * When allocating all pages normally this algorithm will run
+        * in O(N) time, but in the worst case it will run in O(N^2)
+        * time.   If the runtime is a problem the data structures can
+        * be fixed.
+        */
+       struct page *page;
+       unsigned long addr;
+
+       /*
+        * Walk through the list of destination pages, and see if I
+        * have a match.
+        */
+       list_for_each_entry(page, &image->dest_pages, lru) {
+               addr = page_to_pfn(page) << PAGE_SHIFT;
+               if (addr == destination) {
+                       list_del(&page->lru);
+                       return page;
+               }
+       }
+       page = NULL;
+       while (1) {
+               kimage_entry_t *old;
+
+               /* Allocate a page, if we run out of memory give up */
+               page = kimage_alloc_pages(gfp_mask, 0);
+               if (!page)
+                       return 0;
+               /* If the page cannot be used file it away */
+               if (page_to_pfn(page) >
+                               (KEXEC_SOURCE_MEMORY_LIMIT >> PAGE_SHIFT)) {
+                       list_add(&page->lru, &image->unuseable_pages);
+                       continue;
+               }
+               addr = page_to_pfn(page) << PAGE_SHIFT;
+
+               /* If it is the destination page we want use it */
+               if (addr == destination)
+                       break;
+
+               /* If the page is not a destination page use it */
+               if (!kimage_is_destination_range(image, addr,
+                                                 addr + PAGE_SIZE))
+                       break;
+
+               /*
+                * I know that the page is someones destination page.
+                * See if there is already a source page for this
+                * destination page.  And if so swap the source pages.
+                */
+               old = kimage_dst_used(image, addr);
+               if (old) {
+                       /* If so move it */
+                       unsigned long old_addr;
+                       struct page *old_page;
+
+                       old_addr = *old & PAGE_MASK;
+                       old_page = pfn_to_page(old_addr >> PAGE_SHIFT);
+                       copy_highpage(page, old_page);
+                       *old = addr | (*old & ~PAGE_MASK);
+
+                       /* The old page I have found cannot be a
+                        * destination page, so return it.
+                        */
+                       addr = old_addr;
+                       page = old_page;
+                       break;
+               }
+               else {
+                       /* Place the page on the destination list I
+                        * will use it later.
+                        */
+                       list_add(&page->lru, &image->dest_pages);
+               }
+       }
+
+       return page;
+}
+
+static int kimage_load_normal_segment(struct kimage *image,
+                                        struct kexec_segment *segment)
+{
+       unsigned long maddr;
+       unsigned long ubytes, mbytes;
+       int result;
+       unsigned char *buf;
+
+       result = 0;
+       buf = segment->buf;
+       ubytes = segment->bufsz;
+       mbytes = segment->memsz;
+       maddr = segment->mem;
+
+       result = kimage_set_destination(image, maddr);
+       if (result < 0)
+               goto out;
+
+       while (mbytes) {
+               struct page *page;
+               char *ptr;
+               size_t uchunk, mchunk;
+
+               page = kimage_alloc_page(image, GFP_HIGHUSER, maddr);
+               if (page == 0) {
+                       result  = -ENOMEM;
+                       goto out;
+               }
+               result = kimage_add_page(image, page_to_pfn(page)
+                                                               << PAGE_SHIFT);
+               if (result < 0)
+                       goto out;
+
+               ptr = kmap(page);
+               /* Start with a clear page */
+               memset(ptr, 0, PAGE_SIZE);
+               ptr += maddr & ~PAGE_MASK;
+               mchunk = PAGE_SIZE - (maddr & ~PAGE_MASK);
+               if (mchunk > mbytes)
+                       mchunk = mbytes;
+
+               uchunk = mchunk;
+               if (uchunk > ubytes)
+                       uchunk = ubytes;
+
+               result = copy_from_user(ptr, buf, uchunk);
+               kunmap(page);
+               if (result) {
+                       result = (result < 0) ? result : -EIO;
+                       goto out;
+               }
+               ubytes -= uchunk;
+               maddr  += mchunk;
+               buf    += mchunk;
+               mbytes -= mchunk;
+       }
+out:
+       return result;
+}
+
+static int kimage_load_crash_segment(struct kimage *image,
+                                       struct kexec_segment *segment)
+{
+       /* For crash dumps kernels we simply copy the data from
+        * user space to it's destination.
+        * We do things a page at a time for the sake of kmap.
+        */
+       unsigned long maddr;
+       unsigned long ubytes, mbytes;
+       int result;
+       unsigned char *buf;
+
+       result = 0;
+       buf = segment->buf;
+       ubytes = segment->bufsz;
+       mbytes = segment->memsz;
+       maddr = segment->mem;
+       while (mbytes) {
+               struct page *page;
+               char *ptr;
+               size_t uchunk, mchunk;
+
+               page = pfn_to_page(maddr >> PAGE_SHIFT);
+               if (page == 0) {
+                       result  = -ENOMEM;
+                       goto out;
+               }
+               ptr = kmap(page);
+               ptr += maddr & ~PAGE_MASK;
+               mchunk = PAGE_SIZE - (maddr & ~PAGE_MASK);
+               if (mchunk > mbytes)
+                       mchunk = mbytes;
+
+               uchunk = mchunk;
+               if (uchunk > ubytes) {
+                       uchunk = ubytes;
+                       /* Zero the trailing part of the page */
+                       memset(ptr + uchunk, 0, mchunk - uchunk);
+               }
+               result = copy_from_user(ptr, buf, uchunk);
+               kunmap(page);
+               if (result) {
+                       result = (result < 0) ? result : -EIO;
+                       goto out;
+               }
+               ubytes -= uchunk;
+               maddr  += mchunk;
+               buf    += mchunk;
+               mbytes -= mchunk;
+       }
+out:
+       return result;
+}
+
+static int kimage_load_segment(struct kimage *image,
+                               struct kexec_segment *segment)
+{
+       int result = -ENOMEM;
+
+       switch (image->type) {
+       case KEXEC_TYPE_DEFAULT:
+               result = kimage_load_normal_segment(image, segment);
+               break;
+       case KEXEC_TYPE_CRASH:
+               result = kimage_load_crash_segment(image, segment);
+               break;
+       }
+
+       return result;
+}
+
+/*
+ * Exec Kernel system call: for obvious reasons only root may call it.
+ *
+ * This call breaks up into three pieces.
+ * - A generic part which loads the new kernel from the current
+ *   address space, and very carefully places the data in the
+ *   allocated pages.
+ *
+ * - A generic part that interacts with the kernel and tells all of
+ *   the devices to shut down.  Preventing on-going dmas, and placing
+ *   the devices in a consistent state so a later kernel can
+ *   reinitialize them.
+ *
+ * - A machine specific part that includes the syscall number
+ *   and the copies the image to it's final destination.  And
+ *   jumps into the image at entry.
+ *
+ * kexec does not sync, or unmount filesystems so if you need
+ * that to happen you need to do that yourself.
+ */
+struct kimage *kexec_image = NULL;
+static struct kimage *kexec_crash_image = NULL;
+/*
+ * A home grown binary mutex.
+ * Nothing can wait so this mutex is safe to use
+ * in interrupt context :)
+ */
+static int kexec_lock = 0;
+
+asmlinkage long sys_kexec_load(unsigned long entry, unsigned long nr_segments,
+                               struct kexec_segment __user *segments,
+                               unsigned long flags)
+{
+       struct kimage **dest_image, *image;
+       int locked;
+       int result;
+
+       /* We only trust the superuser with rebooting the system. */
+       if (!capable(CAP_SYS_BOOT))
+               return -EPERM;
+
+       /*
+        * Verify we have a legal set of flags
+        * This leaves us room for future extensions.
+        */
+       if ((flags & KEXEC_FLAGS) != (flags & ~KEXEC_ARCH_MASK))
+               return -EINVAL;
+
+       /* Verify we are on the appropriate architecture */
+       if (((flags & KEXEC_ARCH_MASK) != KEXEC_ARCH) &&
+               ((flags & KEXEC_ARCH_MASK) != KEXEC_ARCH_DEFAULT))
+               return -EINVAL;
+
+       /* Put an artificial cap on the number
+        * of segments passed to kexec_load.
+        */
+       if (nr_segments > KEXEC_SEGMENT_MAX)
+               return -EINVAL;
+
+       image = NULL;
+       result = 0;
+
+       /* Because we write directly to the reserved memory
+        * region when loading crash kernels we need a mutex here to
+        * prevent multiple crash  kernels from attempting to load
+        * simultaneously, and to prevent a crash kernel from loading
+        * over the top of a in use crash kernel.
+        *
+        * KISS: always take the mutex.
+        */
+       locked = xchg(&kexec_lock, 1);
+       if (locked)
+               return -EBUSY;
+
+       dest_image = &kexec_image;
+       if (flags & KEXEC_ON_CRASH)
+               dest_image = &kexec_crash_image;
+       if (nr_segments > 0) {
+               unsigned long i;
+
+               /* Loading another kernel to reboot into */
+               if ((flags & KEXEC_ON_CRASH) == 0)
+                       result = kimage_normal_alloc(&image, entry,
+                                                       nr_segments, segments);
+               /* Loading another kernel to switch to if this one crashes */
+               else if (flags & KEXEC_ON_CRASH) {
+                       /* Free any current crash dump kernel before
+                        * we corrupt it.
+                        */
+                       kimage_free(xchg(&kexec_crash_image, NULL));
+                       result = kimage_crash_alloc(&image, entry,
+                                                    nr_segments, segments);
+               }
+               if (result)
+                       goto out;
+
+               result = machine_kexec_prepare(image);
+               if (result)
+                       goto out;
+
+               for (i = 0; i < nr_segments; i++) {
+                       result = kimage_load_segment(image, &image->segment[i]);
+                       if (result)
+                               goto out;
+               }
+               result = kimage_terminate(image);
+               if (result)
+                       goto out;
+       }
+       /* Install the new kernel, and  Uninstall the old */
+       image = xchg(dest_image, image);
+
+out:
+       xchg(&kexec_lock, 0); /* Release the mutex */
+       kimage_free(image);
+
+       return result;
+}
+
+#ifdef CONFIG_COMPAT
+asmlinkage long compat_sys_kexec_load(unsigned long entry,
+                               unsigned long nr_segments,
+                               struct compat_kexec_segment __user *segments,
+                               unsigned long flags)
+{
+       struct compat_kexec_segment in;
+       struct kexec_segment out, __user *ksegments;
+       unsigned long i, result;
+
+       /* Don't allow clients that don't understand the native
+        * architecture to do anything.
+        */
+       if ((flags & KEXEC_ARCH_MASK) == KEXEC_ARCH_DEFAULT)
+               return -EINVAL;
+
+       if (nr_segments > KEXEC_SEGMENT_MAX)
+               return -EINVAL;
+
+       ksegments = compat_alloc_user_space(nr_segments * sizeof(out));
+       for (i=0; i < nr_segments; i++) {
+               result = copy_from_user(&in, &segments[i], sizeof(in));
+               if (result)
+                       return -EFAULT;
+
+               out.buf   = compat_ptr(in.buf);
+               out.bufsz = in.bufsz;
+               out.mem   = in.mem;
+               out.memsz = in.memsz;
+
+               result = copy_to_user(&ksegments[i], &out, sizeof(out));
+               if (result)
+                       return -EFAULT;
+       }
+
+       return sys_kexec_load(entry, nr_segments, ksegments, flags);
+}
+#endif
+
+void crash_kexec(struct pt_regs *regs)
+{
+       struct kimage *image;
+       int locked;
+
+
+       /* Take the kexec_lock here to prevent sys_kexec_load
+        * running on one cpu from replacing the crash kernel
+        * we are using after a panic on a different cpu.
+        *
+        * If the crash kernel was not located in a fixed area
+        * of memory the xchg(&kexec_crash_image) would be
+        * sufficient.  But since I reuse the memory...
+        */
+       locked = xchg(&kexec_lock, 1);
+       if (!locked) {
+               image = xchg(&kexec_crash_image, NULL);
+               if (image) {
+                       machine_crash_shutdown(regs);
+                       machine_kexec(image);
+               }
+               xchg(&kexec_lock, 0);
+       }
+}
index 1f064a63f8cfe7b7f575b82c38315bf5e79f2344..015fb69ad94da0724fcd7806aecf29405fbc7949 100644 (file)
@@ -30,12 +30,25 @@ static ssize_t hotplug_seqnum_show(struct subsystem *subsys, char *page)
 KERNEL_ATTR_RO(hotplug_seqnum);
 #endif
 
+#ifdef CONFIG_KEXEC
+#include <asm/kexec.h>
+
+static ssize_t crash_notes_show(struct subsystem *subsys, char *page)
+{
+       return sprintf(page, "%p\n", (void *)crash_notes);
+}
+KERNEL_ATTR_RO(crash_notes);
+#endif
+
 decl_subsys(kernel, NULL, NULL);
 EXPORT_SYMBOL_GPL(kernel_subsys);
 
 static struct attribute * kernel_attrs[] = {
 #ifdef CONFIG_HOTPLUG
        &hotplug_seqnum_attr.attr,
+#endif
+#ifdef CONFIG_KEXEC
+       &crash_notes_attr.attr,
 #endif
        NULL
 };
index 081f7465fc8dec17d3e69a5c9ff7c29f8165ad5b..74ba5f3e46c746059b044072b7bce99f53aa3551 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/sysrq.h>
 #include <linux/interrupt.h>
 #include <linux/nmi.h>
+#include <linux/kexec.h>
 
 int panic_timeout;
 int panic_on_oops;
@@ -63,6 +64,13 @@ NORET_TYPE void panic(const char * fmt, ...)
         unsigned long caller = (unsigned long) __builtin_return_address(0);
 #endif
 
+       /*
+        * It's possible to come here directly from a panic-assertion and not
+        * have preempt disabled. Some functions called from here want
+        * preempt to be disabled. No point enabling it later though...
+        */
+       preempt_disable();
+
        bust_spinlocks(1);
        va_start(args, fmt);
        vsnprintf(buf, sizeof(buf), fmt, args);
@@ -70,7 +78,19 @@ NORET_TYPE void panic(const char * fmt, ...)
        printk(KERN_EMERG "Kernel panic - not syncing: %s\n",buf);
        bust_spinlocks(0);
 
+       /*
+        * If we have crashed and we have a crash kernel loaded let it handle
+        * everything else.
+        * Do we want to call this before we try to display a message?
+        */
+       crash_kexec(NULL);
+
 #ifdef CONFIG_SMP
+       /*
+        * Note smp_send_stop is the usual smp shutdown function, which
+        * unfortunately means it may not be hardened to work in a panic
+        * situation.
+        */
        smp_send_stop();
 #endif
 
@@ -79,8 +99,7 @@ NORET_TYPE void panic(const char * fmt, ...)
        if (!panic_blink)
                panic_blink = no_blink;
 
-       if (panic_timeout > 0)
-       {
+       if (panic_timeout > 0) {
                /*
                 * Delay timeout seconds before rebooting the machine. 
                 * We can't use the "normal" timers since we just panicked..
index 696387ffe49c8c0cd6c1bf71dcd08f512f6d86b5..2c7121d9bff11aff162a578bd68d7934c1030104 100644 (file)
@@ -27,8 +27,8 @@ config PM_DEBUG
        like suspend support.
 
 config SOFTWARE_SUSPEND
-       bool "Software Suspend (EXPERIMENTAL)"
-       depends on EXPERIMENTAL && PM && SWAP
+       bool "Software Suspend"
+       depends on EXPERIMENTAL && PM && SWAP && ((X86 && SMP) || ((FVR || PPC32 || X86) && !SMP))
        ---help---
          Enable the possibility of suspending the machine.
          It doesn't need APM.
@@ -72,3 +72,7 @@ config PM_STD_PARTITION
          suspended image to. It will simply pick the first available swap 
          device.
 
+config SUSPEND_SMP
+       bool
+       depends on HOTPLUG_CPU && X86 && PM
+       default y
index fbdc634135a765a90b04eb224c2c38126747340c..2f438d0eaa13640a91ec78acc086c559bc523060 100644 (file)
@@ -3,9 +3,9 @@ ifeq ($(CONFIG_PM_DEBUG),y)
 EXTRA_CFLAGS   +=      -DDEBUG
 endif
 
-swsusp-smp-$(CONFIG_SMP)       += smp.o
-
 obj-y                          := main.o process.o console.o pm.o
-obj-$(CONFIG_SOFTWARE_SUSPEND) += swsusp.o $(swsusp-smp-y) disk.o
+obj-$(CONFIG_SOFTWARE_SUSPEND) += swsusp.o disk.o
+
+obj-$(CONFIG_SUSPEND_SMP)      += smp.o
 
 obj-$(CONFIG_MAGIC_SYSRQ)      += poweroff.o
index 02b6764034dcbbe7781ba9e519f44e102dc9d5a7..fb8de63c29192061a6938417bac924a55e800851 100644 (file)
@@ -117,8 +117,8 @@ static void finish(void)
 {
        device_resume();
        platform_finish();
-       enable_nonboot_cpus();
        thaw_processes();
+       enable_nonboot_cpus();
        pm_restore_console();
 }
 
@@ -131,28 +131,35 @@ static int prepare_processes(void)
 
        sys_sync();
 
+       disable_nonboot_cpus();
+
        if (freeze_processes()) {
                error = -EBUSY;
-               return error;
+               goto thaw;
        }
 
        if (pm_disk_mode == PM_DISK_PLATFORM) {
                if (pm_ops && pm_ops->prepare) {
                        if ((error = pm_ops->prepare(PM_SUSPEND_DISK)))
-                               return error;
+                               goto thaw;
                }
        }
 
        /* Free memory before shutting down devices. */
        free_some_memory();
-
        return 0;
+thaw:
+       thaw_processes();
+       enable_nonboot_cpus();
+       pm_restore_console();
+       return error;
 }
 
 static void unprepare_processes(void)
 {
-       enable_nonboot_cpus();
+       platform_finish();
        thaw_processes();
+       enable_nonboot_cpus();
        pm_restore_console();
 }
 
@@ -160,15 +167,9 @@ static int prepare_devices(void)
 {
        int error;
 
-       disable_nonboot_cpus();
-       if ((error = device_suspend(PMSG_FREEZE))) {
+       if ((error = device_suspend(PMSG_FREEZE)))
                printk("Some devices failed to suspend\n");
-               platform_finish();
-               enable_nonboot_cpus();
-               return error;
-       }
-
-       return 0;
+       return error;
 }
 
 /**
@@ -185,9 +186,9 @@ int pm_suspend_disk(void)
        int error;
 
        error = prepare_processes();
-       if (!error) {
-               error = prepare_devices();
-       }
+       if (error)
+               return error;
+       error = prepare_devices();
 
        if (error) {
                unprepare_processes();
@@ -250,7 +251,7 @@ static int software_resume(void)
 
        if ((error = prepare_processes())) {
                swsusp_close();
-               goto Cleanup;
+               goto Done;
        }
 
        pr_debug("PM: Reading swsusp image.\n");
index 4cdebc972ff2a55c7fdac702dca0c36f81905558..c94cb9e95090997aa15050412f7fc6564c997d01 100644 (file)
@@ -55,6 +55,13 @@ static int suspend_prepare(suspend_state_t state)
 
        pm_prepare_console();
 
+       disable_nonboot_cpus();
+
+       if (num_online_cpus() != 1) {
+               error = -EPERM;
+               goto Enable_cpu;
+       }
+
        if (freeze_processes()) {
                error = -EAGAIN;
                goto Thaw;
@@ -75,6 +82,8 @@ static int suspend_prepare(suspend_state_t state)
                pm_ops->finish(state);
  Thaw:
        thaw_processes();
+ Enable_cpu:
+       enable_nonboot_cpus();
        pm_restore_console();
        return error;
 }
@@ -113,6 +122,7 @@ static void suspend_finish(suspend_state_t state)
        if (pm_ops && pm_ops->finish)
                pm_ops->finish(state);
        thaw_processes();
+       enable_nonboot_cpus();
        pm_restore_console();
 }
 
@@ -150,12 +160,6 @@ static int enter_state(suspend_state_t state)
                goto Unlock;
        }
 
-       /* Suspend is hard to get right on SMP. */
-       if (num_online_cpus() != 1) {
-               error = -EPERM;
-               goto Unlock;
-       }
-
        pr_debug("PM: Preparing system for %s sleep\n", pm_states[state]);
        if ((error = suspend_prepare(state)))
                goto Unlock;
index 78d92dc6a1edc8119ae616bf184e83ae26ec27e8..0a086640bcfc15cce008901702549fd0061a498c 100644 (file)
@@ -32,7 +32,7 @@ static inline int freezeable(struct task_struct * p)
 }
 
 /* Refrigerator is place where frozen processes are stored :-). */
-void refrigerator(unsigned long flag)
+void refrigerator(void)
 {
        /* Hmm, should we be allowed to suspend when there are realtime
           processes around? */
@@ -41,14 +41,13 @@ void refrigerator(unsigned long flag)
        current->state = TASK_UNINTERRUPTIBLE;
        pr_debug("%s entered refrigerator\n", current->comm);
        printk("=");
-       current->flags &= ~PF_FREEZE;
 
+       frozen_process(current);
        spin_lock_irq(&current->sighand->siglock);
        recalc_sigpending(); /* We sent fake signal, clean it up */
        spin_unlock_irq(&current->sighand->siglock);
 
-       current->flags |= PF_FROZEN;
-       while (current->flags & PF_FROZEN)
+       while (frozen(current))
                schedule();
        pr_debug("%s left refrigerator\n", current->comm);
        current->state = save;
@@ -57,10 +56,10 @@ void refrigerator(unsigned long flag)
 /* 0 = success, else # of processes that we failed to stop */
 int freeze_processes(void)
 {
-       int todo;
-       unsigned long start_time;
+       int todo;
+       unsigned long start_time;
        struct task_struct *g, *p;
-       
+
        printk( "Stopping tasks: " );
        start_time = jiffies;
        do {
@@ -70,14 +69,12 @@ int freeze_processes(void)
                        unsigned long flags;
                        if (!freezeable(p))
                                continue;
-                       if ((p->flags & PF_FROZEN) ||
+                       if ((frozen(p)) ||
                            (p->state == TASK_TRACED) ||
                            (p->state == TASK_STOPPED))
                                continue;
 
-                       /* FIXME: smp problem here: we may not access other process' flags
-                          without locking */
-                       p->flags |= PF_FREEZE;
+                       freeze(p);
                        spin_lock_irqsave(&p->sighand->siglock, flags);
                        signal_wake_up(p, 0);
                        spin_unlock_irqrestore(&p->sighand->siglock, flags);
@@ -91,7 +88,7 @@ int freeze_processes(void)
                        return todo;
                }
        } while(todo);
-       
+
        printk( "|\n" );
        BUG_ON(in_atomic());
        return 0;
@@ -106,10 +103,7 @@ void thaw_processes(void)
        do_each_thread(g, p) {
                if (!freezeable(p))
                        continue;
-               if (p->flags & PF_FROZEN) {
-                       p->flags &= ~PF_FROZEN;
-                       wake_up_process(p);
-               } else
+               if (!thaw_process(p))
                        printk(KERN_INFO " Strange, %s not stopped\n", p->comm );
        } while_each_thread(g, p);
 
index 457c2302ed424bf05e516136d21c1884033ca1e9..bbe23079c62c46e306e95e2215623659e39d565b 100644 (file)
 #include <linux/interrupt.h>
 #include <linux/suspend.h>
 #include <linux/module.h>
+#include <linux/cpu.h>
 #include <asm/atomic.h>
 #include <asm/tlbflush.h>
 
-static atomic_t cpu_counter, freeze;
-
-
-static void smp_pause(void * data)
-{
-       struct saved_context ctxt;
-       __save_processor_state(&ctxt);
-       printk("Sleeping in:\n");
-       dump_stack();
-       atomic_inc(&cpu_counter);
-       while (atomic_read(&freeze)) {
-               /* FIXME: restore takes place at random piece inside this.
-                  This should probably be written in assembly, and
-                  preserve general-purpose registers, too
-
-                  What about stack? We may need to move to new stack here.
-
-                  This should better be ran with interrupts disabled.
-                */
-               cpu_relax();
-               barrier();
-       }
-       atomic_dec(&cpu_counter);
-       __restore_processor_state(&ctxt);
-}
-
-static cpumask_t oldmask;
+/* This is protected by pm_sem semaphore */
+static cpumask_t frozen_cpus;
 
 void disable_nonboot_cpus(void)
 {
-       oldmask = current->cpus_allowed;
-       set_cpus_allowed(current, cpumask_of_cpu(0));
-       printk("Freezing CPUs (at %d)", raw_smp_processor_id());
-       current->state = TASK_INTERRUPTIBLE;
-       schedule_timeout(HZ);
-       printk("...");
-       BUG_ON(raw_smp_processor_id() != 0);
-
-       /* FIXME: for this to work, all the CPUs must be running
-        * "idle" thread (or we deadlock). Is that guaranteed? */
+       int cpu, error;
 
-       atomic_set(&cpu_counter, 0);
-       atomic_set(&freeze, 1);
-       smp_call_function(smp_pause, NULL, 0, 0);
-       while (atomic_read(&cpu_counter) < (num_online_cpus() - 1)) {
-               cpu_relax();
-               barrier();
+       error = 0;
+       cpus_clear(frozen_cpus);
+       printk("Freezing cpus ...\n");
+       for_each_online_cpu(cpu) {
+               if (cpu == 0)
+                       continue;
+               error = cpu_down(cpu);
+               if (!error) {
+                       cpu_set(cpu, frozen_cpus);
+                       printk("CPU%d is down\n", cpu);
+                       continue;
+               }
+               printk("Error taking cpu %d down: %d\n", cpu, error);
        }
-       printk("ok\n");
+       BUG_ON(smp_processor_id() != 0);
+       if (error)
+               panic("cpus not sleeping");
 }
 
 void enable_nonboot_cpus(void)
 {
-       printk("Restarting CPUs");
-       atomic_set(&freeze, 0);
-       while (atomic_read(&cpu_counter)) {
-               cpu_relax();
-               barrier();
-       }
-       printk("...");
-       set_cpus_allowed(current, oldmask);
-       schedule();
-       printk("ok\n");
+       int cpu, error;
 
+       printk("Thawing cpus ...\n");
+       for_each_cpu_mask(cpu, frozen_cpus) {
+               error = smp_prepare_cpu(cpu);
+               if (!error)
+                       error = cpu_up(cpu);
+               if (!error) {
+                       printk("CPU%d is up\n", cpu);
+                       continue;
+               }
+               printk("Error taking cpu %d up: %d\n", cpu, error);
+               panic("Not enough cpus");
+       }
+       cpus_clear(frozen_cpus);
 }
 
-
index 53f9f8720ee40be32fd9e43ca045d97fa7a5d5a2..c285fc5a232094c9f7b5e27950525ae942bc99b1 100644 (file)
  * This file is released under the GPLv2.
  *
  * I'd like to thank the following people for their work:
- * 
+ *
  * Pavel Machek <pavel@ucw.cz>:
  * Modifications, defectiveness pointing, being with me at the very beginning,
  * suspend to swap space, stop all tasks. Port to 2.4.18-ac and 2.5.17.
  *
- * Steve Doddi <dirk@loth.demon.co.uk>: 
+ * Steve Doddi <dirk@loth.demon.co.uk>:
  * Support the possibility of hardware state restoring.
  *
  * Raph <grey.havens@earthling.net>:
@@ -84,11 +84,11 @@ extern char resume_file[];
 static unsigned int nr_copy_pages __nosavedata = 0;
 
 /* Suspend pagedir is allocated before final copy, therefore it
-   must be freed after resume 
+   must be freed after resume
 
    Warning: this is evil. There are actually two pagedirs at time of
    resume. One is "pagedir_save", which is empty frame allocated at
-   time of suspend, that must be freed. Second is "pagedir_nosave", 
+   time of suspend, that must be freed. Second is "pagedir_nosave",
    allocated at time of resume, that travels through memory not to
    collide with anything.
 
@@ -132,7 +132,7 @@ static int mark_swapfiles(swp_entry_t prev)
 {
        int error;
 
-       rw_swap_page_sync(READ, 
+       rw_swap_page_sync(READ,
                          swp_entry(root_swap, 0),
                          virt_to_page((unsigned long)&swsusp_header));
        if (!memcmp("SWAP-SPACE",swsusp_header.sig, 10) ||
@@ -140,7 +140,7 @@ static int mark_swapfiles(swp_entry_t prev)
                memcpy(swsusp_header.orig_sig,swsusp_header.sig, 10);
                memcpy(swsusp_header.sig,SWSUSP_SIG, 10);
                swsusp_header.swsusp_info = prev;
-               error = rw_swap_page_sync(WRITE, 
+               error = rw_swap_page_sync(WRITE,
                                          swp_entry(root_swap, 0),
                                          virt_to_page((unsigned long)
                                                       &swsusp_header));
@@ -174,22 +174,22 @@ static int is_resume_device(const struct swap_info_struct *swap_info)
 static int swsusp_swap_check(void) /* This is called before saving image */
 {
        int i, len;
-       
+
        len=strlen(resume_file);
        root_swap = 0xFFFF;
-       
+
        swap_list_lock();
-       for(i=0; i<MAX_SWAPFILES; i++) {
+       for (i=0; i<MAX_SWAPFILES; i++) {
                if (swap_info[i].flags == 0) {
                        swapfile_used[i]=SWAPFILE_UNUSED;
                } else {
-                       if(!len) {
+                       if (!len) {
                                printk(KERN_WARNING "resume= option should be used to set suspend device" );
-                               if(root_swap == 0xFFFF) {
+                               if (root_swap == 0xFFFF) {
                                        swapfile_used[i] = SWAPFILE_SUSPEND;
                                        root_swap = i;
                                } else
-                                       swapfile_used[i] = SWAPFILE_IGNORED;                              
+                                       swapfile_used[i] = SWAPFILE_IGNORED;
                        } else {
                                /* we ignore all swap devices that are not the resume_file */
                                if (is_resume_device(&swap_info[i])) {
@@ -209,15 +209,15 @@ static int swsusp_swap_check(void) /* This is called before saving image */
  * This is called after saving image so modification
  * will be lost after resume... and that's what we want.
  * we make the device unusable. A new call to
- * lock_swapdevices can unlock the devices. 
+ * lock_swapdevices can unlock the devices.
  */
 static void lock_swapdevices(void)
 {
        int i;
 
        swap_list_lock();
-       for(i = 0; i< MAX_SWAPFILES; i++)
-               if(swapfile_used[i] == SWAPFILE_IGNORED) {
+       for (i = 0; i< MAX_SWAPFILES; i++)
+               if (swapfile_used[i] == SWAPFILE_IGNORED) {
                        swap_info[i].flags ^= 0xFF;
                }
        swap_list_unlock();
@@ -229,7 +229,7 @@ static void lock_swapdevices(void)
  *     @loc:   Place to store the entry we used.
  *
  *     Allocate a new swap entry and 'sync' it. Note we discard -EIO
- *     errors. That is an artifact left over from swsusp. It did not 
+ *     errors. That is an artifact left over from swsusp. It did not
  *     check the return of rw_swap_page_sync() at all, since most pages
  *     written back to swap would return -EIO.
  *     This is a partial improvement, since we will at least return other
@@ -241,7 +241,7 @@ static int write_page(unsigned long addr, swp_entry_t * loc)
        int error = 0;
 
        entry = get_swap_page();
-       if (swp_offset(entry) && 
+       if (swp_offset(entry) &&
            swapfile_used[swp_type(entry)] == SWAPFILE_SUSPEND) {
                error = rw_swap_page_sync(WRITE, entry,
                                          virt_to_page(addr));
@@ -257,7 +257,7 @@ static int write_page(unsigned long addr, swp_entry_t * loc)
 /**
  *     data_free - Free the swap entries used by the saved image.
  *
- *     Walk the list of used swap entries and free each one. 
+ *     Walk the list of used swap entries and free each one.
  *     This is only used for cleanup when suspend fails.
  */
 static void data_free(void)
@@ -290,7 +290,7 @@ static int data_write(void)
                mod = 1;
 
        printk( "Writing data to swap (%d pages)...     ", nr_copy_pages );
-       for_each_pbe(p, pagedir_nosave) {
+       for_each_pbe (p, pagedir_nosave) {
                if (!(i%mod))
                        printk( "\b\b\b\b%3d%%", i / mod );
                if ((error = write_page(p->address, &(p->swap_address))))
@@ -335,7 +335,7 @@ static int close_swap(void)
 
        dump_info();
        error = write_page((unsigned long)&swsusp_info, &entry);
-       if (!error) { 
+       if (!error) {
                printk( "S" );
                error = mark_swapfiles(entry);
                printk( "|\n" );
@@ -370,7 +370,7 @@ static int write_pagedir(void)
        struct pbe * pbe;
 
        printk( "Writing pagedir...");
-       for_each_pb_page(pbe, pagedir_nosave) {
+       for_each_pb_page (pbe, pagedir_nosave) {
                if ((error = write_page((unsigned long)pbe, &swsusp_info.pagedir[n++])))
                        return error;
        }
@@ -472,7 +472,7 @@ static int save_highmem(void)
        int res = 0;
 
        pr_debug("swsusp: Saving Highmem\n");
-       for_each_zone(zone) {
+       for_each_zone (zone) {
                if (is_highmem(zone))
                        res = save_highmem_zone(zone);
                if (res)
@@ -547,7 +547,7 @@ static void count_data_pages(void)
 
        nr_copy_pages = 0;
 
-       for_each_zone(zone) {
+       for_each_zone (zone) {
                if (is_highmem(zone))
                        continue;
                mark_free_pages(zone);
@@ -562,9 +562,9 @@ static void copy_data_pages(void)
        struct zone *zone;
        unsigned long zone_pfn;
        struct pbe * pbe = pagedir_nosave;
-       
+
        pr_debug("copy_data_pages(): pages to copy: %d\n", nr_copy_pages);
-       for_each_zone(zone) {
+       for_each_zone (zone) {
                if (is_highmem(zone))
                        continue;
                mark_free_pages(zone);
@@ -702,7 +702,7 @@ static void free_image_pages(void)
 {
        struct pbe * p;
 
-       for_each_pbe(p, pagedir_save) {
+       for_each_pbe (p, pagedir_save) {
                if (p->address) {
                        ClearPageNosave(virt_to_page(p->address));
                        free_page(p->address);
@@ -719,7 +719,7 @@ static int alloc_image_pages(void)
 {
        struct pbe * p;
 
-       for_each_pbe(p, pagedir_save) {
+       for_each_pbe (p, pagedir_save) {
                p->address = get_zeroed_page(GFP_ATOMIC | __GFP_COLD);
                if (!p->address)
                        return -ENOMEM;
@@ -740,7 +740,7 @@ void swsusp_free(void)
 /**
  *     enough_free_mem - Make sure we enough free memory to snapshot.
  *
- *     Returns TRUE or FALSE after checking the number of available 
+ *     Returns TRUE or FALSE after checking the number of available
  *     free pages.
  */
 
@@ -758,11 +758,11 @@ static int enough_free_mem(void)
 /**
  *     enough_swap - Make sure we have enough swap to save the image.
  *
- *     Returns TRUE or FALSE after checking the total amount of swap 
+ *     Returns TRUE or FALSE after checking the total amount of swap
  *     space avaiable.
  *
  *     FIXME: si_swapinfo(&i) returns all swap devices information.
- *     We should only consider resume_device. 
+ *     We should only consider resume_device.
  */
 
 static int enough_swap(void)
@@ -781,18 +781,18 @@ static int swsusp_alloc(void)
 {
        int error;
 
+       pagedir_nosave = NULL;
+       nr_copy_pages = calc_nr(nr_copy_pages);
+
        pr_debug("suspend: (pages needed: %d + %d free: %d)\n",
                 nr_copy_pages, PAGES_FOR_IO, nr_free_pages());
 
-       pagedir_nosave = NULL;
        if (!enough_free_mem())
                return -ENOMEM;
 
        if (!enough_swap())
                return -ENOSPC;
 
-       nr_copy_pages = calc_nr(nr_copy_pages);
-
        if (!(pagedir_save = alloc_pagedir(nr_copy_pages))) {
                printk(KERN_ERR "suspend: Allocating pagedir failed.\n");
                return -ENOMEM;
@@ -827,8 +827,8 @@ static int suspend_prepare_image(void)
        error = swsusp_alloc();
        if (error)
                return error;
-       
-       /* During allocating of suspend pagedir, new cold pages may appear. 
+
+       /* During allocating of suspend pagedir, new cold pages may appear.
         * Kill them.
         */
        drain_local_pages();
@@ -929,21 +929,6 @@ int swsusp_resume(void)
        return error;
 }
 
-/* More restore stuff */
-
-/*
- * Returns true if given address/order collides with any orig_address 
- */
-static int does_collide_order(unsigned long addr, int order)
-{
-       int i;
-       
-       for (i=0; i < (1<<order); i++)
-               if (!PageNosaveFree(virt_to_page(addr + i * PAGE_SIZE)))
-                       return 1;
-       return 0;
-}
-
 /**
  *     On resume, for storing the PBE list and the image,
  *     we can only use memory pages that do not conflict with the pages
@@ -973,7 +958,7 @@ static unsigned long get_usable_page(unsigned gfp_mask)
        unsigned long m;
 
        m = get_zeroed_page(gfp_mask);
-       while (does_collide_order(m, 0)) {
+       while (!PageNosaveFree(virt_to_page(m))) {
                eat_page((void *)m);
                m = get_zeroed_page(gfp_mask);
                if (!m)
@@ -1045,7 +1030,7 @@ static struct pbe * swsusp_pagedir_relocate(struct pbe *pblist)
 
        /* Set page flags */
 
-       for_each_zone(zone) {
+       for_each_zone (zone) {
                for (zone_pfn = 0; zone_pfn < zone->spanned_pages; ++zone_pfn)
                        SetPageNosaveFree(pfn_to_page(zone_pfn +
                                        zone->zone_start_pfn));
@@ -1061,7 +1046,7 @@ static struct pbe * swsusp_pagedir_relocate(struct pbe *pblist)
        /* Relocate colliding pages */
 
        for_each_pb_page (pbpage, pblist) {
-               if (does_collide_order((unsigned long)pbpage, 0)) {
+               if (!PageNosaveFree(virt_to_page((unsigned long)pbpage))) {
                        m = (void *)get_usable_page(GFP_ATOMIC | __GFP_COLD);
                        if (!m) {
                                error = -ENOMEM;
@@ -1193,8 +1178,10 @@ static const char * sanity_check(void)
                return "version";
        if (strcmp(swsusp_info.uts.machine,system_utsname.machine))
                return "machine";
+#if 0
        if(swsusp_info.cpus != num_online_cpus())
                return "number of cpus";
+#endif
        return NULL;
 }
 
index 3a442bfb8beee0adfcaba1f1aca84c0f8a43db13..5092397fac29926bfab6da75fc273882b14e905d 100644 (file)
@@ -588,8 +588,7 @@ asmlinkage int vprintk(const char *fmt, va_list args)
                        log_level_unknown = 1;
        }
 
-       if (!cpu_online(smp_processor_id()) &&
-           system_state != SYSTEM_RUNNING) {
+       if (!cpu_online(smp_processor_id())) {
                /*
                 * Some console drivers may assume that per-cpu resources have
                 * been allocated.  So don't allow them to be called by this
index 52f696f11adfe68bbe5785e997f290071e8d6cf1..26967e0422014a5957f4b01bbed9a4cea40098bf 100644 (file)
@@ -263,7 +263,7 @@ static int find_resource(struct resource *root, struct resource *new,
                        new->start = min;
                if (new->end > max)
                        new->end = max;
-               new->start = (new->start + align - 1) & ~(align - 1);
+               new->start = ALIGN(new->start, align);
                if (alignf)
                        alignf(alignf_data, new, size, align);
                if (new->start < new->end && new->end - new->start >= size - 1) {
index 76080d142e3d9c08897e7b713d23dd0e2f809db0..a07cff90d849a1bb3ea1ab7a7efe2610274cb466 100644 (file)
 #define SCALE_PRIO(x, prio) \
        max(x * (MAX_PRIO - prio) / (MAX_USER_PRIO/2), MIN_TIMESLICE)
 
-static inline unsigned int task_timeslice(task_t *p)
+static unsigned int task_timeslice(task_t *p)
 {
        if (p->static_prio < NICE_TO_PRIO(0))
                return SCALE_PRIO(DEF_TIMESLICE*4, p->static_prio);
@@ -206,7 +206,7 @@ struct runqueue {
         */
        unsigned long nr_running;
 #ifdef CONFIG_SMP
-       unsigned long cpu_load;
+       unsigned long cpu_load[3];
 #endif
        unsigned long long nr_switches;
 
@@ -260,22 +260,86 @@ struct runqueue {
 
 static DEFINE_PER_CPU(struct runqueue, runqueues);
 
+/*
+ * The domain tree (rq->sd) is protected by RCU's quiescent state transition.
+ * See detach_destroy_domains: synchronize_sched for details.
+ *
+ * The domain tree of any CPU may only be accessed from within
+ * preempt-disabled sections.
+ */
 #define for_each_domain(cpu, domain) \
-       for (domain = cpu_rq(cpu)->sd; domain; domain = domain->parent)
+for (domain = rcu_dereference(cpu_rq(cpu)->sd); domain; domain = domain->parent)
 
 #define cpu_rq(cpu)            (&per_cpu(runqueues, (cpu)))
 #define this_rq()              (&__get_cpu_var(runqueues))
 #define task_rq(p)             cpu_rq(task_cpu(p))
 #define cpu_curr(cpu)          (cpu_rq(cpu)->curr)
 
-/*
- * Default context-switch locking:
- */
 #ifndef prepare_arch_switch
-# define prepare_arch_switch(rq, next) do { } while (0)
-# define finish_arch_switch(rq, next)  spin_unlock_irq(&(rq)->lock)
-# define task_running(rq, p)           ((rq)->curr == (p))
+# define prepare_arch_switch(next)     do { } while (0)
+#endif
+#ifndef finish_arch_switch
+# define finish_arch_switch(prev)      do { } while (0)
+#endif
+
+#ifndef __ARCH_WANT_UNLOCKED_CTXSW
+static inline int task_running(runqueue_t *rq, task_t *p)
+{
+       return rq->curr == p;
+}
+
+static inline void prepare_lock_switch(runqueue_t *rq, task_t *next)
+{
+}
+
+static inline void finish_lock_switch(runqueue_t *rq, task_t *prev)
+{
+       spin_unlock_irq(&rq->lock);
+}
+
+#else /* __ARCH_WANT_UNLOCKED_CTXSW */
+static inline int task_running(runqueue_t *rq, task_t *p)
+{
+#ifdef CONFIG_SMP
+       return p->oncpu;
+#else
+       return rq->curr == p;
+#endif
+}
+
+static inline void prepare_lock_switch(runqueue_t *rq, task_t *next)
+{
+#ifdef CONFIG_SMP
+       /*
+        * We can optimise this out completely for !SMP, because the
+        * SMP rebalancing from interrupt is the only thing that cares
+        * here.
+        */
+       next->oncpu = 1;
+#endif
+#ifdef __ARCH_WANT_INTERRUPTS_ON_CTXSW
+       spin_unlock_irq(&rq->lock);
+#else
+       spin_unlock(&rq->lock);
+#endif
+}
+
+static inline void finish_lock_switch(runqueue_t *rq, task_t *prev)
+{
+#ifdef CONFIG_SMP
+       /*
+        * After ->oncpu is cleared, the task can be moved to a different CPU.
+        * We must ensure this doesn't happen until the switch is completely
+        * finished.
+        */
+       smp_wmb();
+       prev->oncpu = 0;
 #endif
+#ifndef __ARCH_WANT_INTERRUPTS_ON_CTXSW
+       local_irq_enable();
+#endif
+}
+#endif /* __ARCH_WANT_UNLOCKED_CTXSW */
 
 /*
  * task_rq_lock - lock the runqueue a given task resides on and disable
@@ -309,7 +373,7 @@ static inline void task_rq_unlock(runqueue_t *rq, unsigned long *flags)
  * bump this up when changing the output format or the meaning of an existing
  * format, so that tools can adapt (or abort)
  */
-#define SCHEDSTAT_VERSION 11
+#define SCHEDSTAT_VERSION 12
 
 static int show_schedstat(struct seq_file *seq, void *v)
 {
@@ -338,6 +402,7 @@ static int show_schedstat(struct seq_file *seq, void *v)
 
 #ifdef CONFIG_SMP
                /* domain-specific stats */
+               preempt_disable();
                for_each_domain(cpu, sd) {
                        enum idle_type itype;
                        char mask_str[NR_CPUS];
@@ -356,11 +421,13 @@ static int show_schedstat(struct seq_file *seq, void *v)
                                    sd->lb_nobusyq[itype],
                                    sd->lb_nobusyg[itype]);
                        }
-                       seq_printf(seq, " %lu %lu %lu %lu %lu %lu %lu %lu\n",
+                       seq_printf(seq, " %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu\n",
                            sd->alb_cnt, sd->alb_failed, sd->alb_pushed,
-                           sd->sbe_pushed, sd->sbe_attempts,
+                           sd->sbe_cnt, sd->sbe_balanced, sd->sbe_pushed,
+                           sd->sbf_cnt, sd->sbf_balanced, sd->sbf_pushed,
                            sd->ttwu_wake_remote, sd->ttwu_move_affine, sd->ttwu_move_balance);
                }
+               preempt_enable();
 #endif
        }
        return 0;
@@ -414,22 +481,6 @@ static inline runqueue_t *this_rq_lock(void)
        return rq;
 }
 
-#ifdef CONFIG_SCHED_SMT
-static int cpu_and_siblings_are_idle(int cpu)
-{
-       int sib;
-       for_each_cpu_mask(sib, cpu_sibling_map[cpu]) {
-               if (idle_cpu(sib))
-                       continue;
-               return 0;
-       }
-
-       return 1;
-}
-#else
-#define cpu_and_siblings_are_idle(A) idle_cpu(A)
-#endif
-
 #ifdef CONFIG_SCHEDSTATS
 /*
  * Called when a process is dequeued from the active array and given
@@ -622,7 +673,7 @@ static inline void __activate_idle_task(task_t *p, runqueue_t *rq)
        rq->nr_running++;
 }
 
-static void recalc_task_prio(task_t *p, unsigned long long now)
+static int recalc_task_prio(task_t *p, unsigned long long now)
 {
        /* Caller must always ensure 'now >= p->timestamp' */
        unsigned long long __sleep_time = now - p->timestamp;
@@ -681,7 +732,7 @@ static void recalc_task_prio(task_t *p, unsigned long long now)
                }
        }
 
-       p->prio = effective_prio(p);
+       return effective_prio(p);
 }
 
 /*
@@ -704,7 +755,7 @@ static void activate_task(task_t *p, runqueue_t *rq, int local)
        }
 #endif
 
-       recalc_task_prio(p, now);
+       p->prio = recalc_task_prio(p, now);
 
        /*
         * This checks to make sure it's not an uninterruptible task
@@ -782,22 +833,12 @@ inline int task_curr(const task_t *p)
 }
 
 #ifdef CONFIG_SMP
-enum request_type {
-       REQ_MOVE_TASK,
-       REQ_SET_DOMAIN,
-};
-
 typedef struct {
        struct list_head list;
-       enum request_type type;
 
-       /* For REQ_MOVE_TASK */
        task_t *task;
        int dest_cpu;
 
-       /* For REQ_SET_DOMAIN */
-       struct sched_domain *sd;
-
        struct completion done;
 } migration_req_t;
 
@@ -819,7 +860,6 @@ static int migrate_task(task_t *p, int dest_cpu, migration_req_t *req)
        }
 
        init_completion(&req->done);
-       req->type = REQ_MOVE_TASK;
        req->task = p;
        req->dest_cpu = dest_cpu;
        list_add(&req->list, &rq->migration_queue);
@@ -886,26 +926,154 @@ void kick_process(task_t *p)
  * We want to under-estimate the load of migration sources, to
  * balance conservatively.
  */
-static inline unsigned long source_load(int cpu)
+static inline unsigned long source_load(int cpu, int type)
 {
        runqueue_t *rq = cpu_rq(cpu);
        unsigned long load_now = rq->nr_running * SCHED_LOAD_SCALE;
+       if (type == 0)
+               return load_now;
 
-       return min(rq->cpu_load, load_now);
+       return min(rq->cpu_load[type-1], load_now);
 }
 
 /*
  * Return a high guess at the load of a migration-target cpu
  */
-static inline unsigned long target_load(int cpu)
+static inline unsigned long target_load(int cpu, int type)
 {
        runqueue_t *rq = cpu_rq(cpu);
        unsigned long load_now = rq->nr_running * SCHED_LOAD_SCALE;
+       if (type == 0)
+               return load_now;
 
-       return max(rq->cpu_load, load_now);
+       return max(rq->cpu_load[type-1], load_now);
 }
 
-#endif
+/*
+ * find_idlest_group finds and returns the least busy CPU group within the
+ * domain.
+ */
+static struct sched_group *
+find_idlest_group(struct sched_domain *sd, struct task_struct *p, int this_cpu)
+{
+       struct sched_group *idlest = NULL, *this = NULL, *group = sd->groups;
+       unsigned long min_load = ULONG_MAX, this_load = 0;
+       int load_idx = sd->forkexec_idx;
+       int imbalance = 100 + (sd->imbalance_pct-100)/2;
+
+       do {
+               unsigned long load, avg_load;
+               int local_group;
+               int i;
+
+               local_group = cpu_isset(this_cpu, group->cpumask);
+               /* XXX: put a cpus allowed check */
+
+               /* Tally up the load of all CPUs in the group */
+               avg_load = 0;
+
+               for_each_cpu_mask(i, group->cpumask) {
+                       /* Bias balancing toward cpus of our domain */
+                       if (local_group)
+                               load = source_load(i, load_idx);
+                       else
+                               load = target_load(i, load_idx);
+
+                       avg_load += load;
+               }
+
+               /* Adjust by relative CPU power of the group */
+               avg_load = (avg_load * SCHED_LOAD_SCALE) / group->cpu_power;
+
+               if (local_group) {
+                       this_load = avg_load;
+                       this = group;
+               } else if (avg_load < min_load) {
+                       min_load = avg_load;
+                       idlest = group;
+               }
+               group = group->next;
+       } while (group != sd->groups);
+
+       if (!idlest || 100*this_load < imbalance*min_load)
+               return NULL;
+       return idlest;
+}
+
+/*
+ * find_idlest_queue - find the idlest runqueue among the cpus in group.
+ */
+static int find_idlest_cpu(struct sched_group *group, int this_cpu)
+{
+       unsigned long load, min_load = ULONG_MAX;
+       int idlest = -1;
+       int i;
+
+       for_each_cpu_mask(i, group->cpumask) {
+               load = source_load(i, 0);
+
+               if (load < min_load || (load == min_load && i == this_cpu)) {
+                       min_load = load;
+                       idlest = i;
+               }
+       }
+
+       return idlest;
+}
+
+/*
+ * sched_balance_self: balance the current task (running on cpu) in domains
+ * that have the 'flag' flag set. In practice, this is SD_BALANCE_FORK and
+ * SD_BALANCE_EXEC.
+ *
+ * Balance, ie. select the least loaded group.
+ *
+ * Returns the target CPU number, or the same CPU if no balancing is needed.
+ *
+ * preempt must be disabled.
+ */
+static int sched_balance_self(int cpu, int flag)
+{
+       struct task_struct *t = current;
+       struct sched_domain *tmp, *sd = NULL;
+
+       for_each_domain(cpu, tmp)
+               if (tmp->flags & flag)
+                       sd = tmp;
+
+       while (sd) {
+               cpumask_t span;
+               struct sched_group *group;
+               int new_cpu;
+               int weight;
+
+               span = sd->span;
+               group = find_idlest_group(sd, t, cpu);
+               if (!group)
+                       goto nextlevel;
+
+               new_cpu = find_idlest_cpu(group, cpu);
+               if (new_cpu == -1 || new_cpu == cpu)
+                       goto nextlevel;
+
+               /* Now try balancing at a lower domain level */
+               cpu = new_cpu;
+nextlevel:
+               sd = NULL;
+               weight = cpus_weight(span);
+               for_each_domain(cpu, tmp) {
+                       if (weight <= cpus_weight(tmp->span))
+                               break;
+                       if (tmp->flags & flag)
+                               sd = tmp;
+               }
+               /* while loop will break here if sd == NULL */
+       }
+
+       return cpu;
+}
+
+#endif /* CONFIG_SMP */
 
 /*
  * wake_idle() will wake a task on an idle cpu if task->cpu is
@@ -927,14 +1095,14 @@ static int wake_idle(int cpu, task_t *p)
 
        for_each_domain(cpu, sd) {
                if (sd->flags & SD_WAKE_IDLE) {
-                       cpus_and(tmp, sd->span, cpu_online_map);
-                       cpus_and(tmp, tmp, p->cpus_allowed);
+                       cpus_and(tmp, sd->span, p->cpus_allowed);
                        for_each_cpu_mask(i, tmp) {
                                if (idle_cpu(i))
                                        return i;
                        }
                }
-               else break;
+               else
+                       break;
        }
        return cpu;
 }
@@ -967,7 +1135,7 @@ static int try_to_wake_up(task_t * p, unsigned int state, int sync)
        runqueue_t *rq;
 #ifdef CONFIG_SMP
        unsigned long load, this_load;
-       struct sched_domain *sd;
+       struct sched_domain *sd, *this_sd = NULL;
        int new_cpu;
 #endif
 
@@ -986,70 +1154,69 @@ static int try_to_wake_up(task_t * p, unsigned int state, int sync)
        if (unlikely(task_running(rq, p)))
                goto out_activate;
 
-#ifdef CONFIG_SCHEDSTATS
+       new_cpu = cpu;
+
        schedstat_inc(rq, ttwu_cnt);
        if (cpu == this_cpu) {
                schedstat_inc(rq, ttwu_local);
-       } else {
-               for_each_domain(this_cpu, sd) {
-                       if (cpu_isset(cpu, sd->span)) {
-                               schedstat_inc(sd, ttwu_wake_remote);
-                               break;
-                       }
+               goto out_set_cpu;
+       }
+
+       for_each_domain(this_cpu, sd) {
+               if (cpu_isset(cpu, sd->span)) {
+                       schedstat_inc(sd, ttwu_wake_remote);
+                       this_sd = sd;
+                       break;
                }
        }
-#endif
 
-       new_cpu = cpu;
-       if (cpu == this_cpu || unlikely(!cpu_isset(this_cpu, p->cpus_allowed)))
+       if (unlikely(!cpu_isset(this_cpu, p->cpus_allowed)))
                goto out_set_cpu;
 
-       load = source_load(cpu);
-       this_load = target_load(this_cpu);
-
        /*
-        * If sync wakeup then subtract the (maximum possible) effect of
-        * the currently running task from the load of the current CPU:
+        * Check for affine wakeup and passive balancing possibilities.
         */
-       if (sync)
-               this_load -= SCHED_LOAD_SCALE;
+       if (this_sd) {
+               int idx = this_sd->wake_idx;
+               unsigned int imbalance;
 
-       /* Don't pull the task off an idle CPU to a busy one */
-       if (load < SCHED_LOAD_SCALE/2 && this_load > SCHED_LOAD_SCALE/2)
-               goto out_set_cpu;
+               imbalance = 100 + (this_sd->imbalance_pct - 100) / 2;
 
-       new_cpu = this_cpu; /* Wake to this CPU if we can */
+               load = source_load(cpu, idx);
+               this_load = target_load(this_cpu, idx);
 
-       /*
-        * Scan domains for affine wakeup and passive balancing
-        * possibilities.
-        */
-       for_each_domain(this_cpu, sd) {
-               unsigned int imbalance;
-               /*
-                * Start passive balancing when half the imbalance_pct
-                * limit is reached.
-                */
-               imbalance = sd->imbalance_pct + (sd->imbalance_pct - 100) / 2;
+               new_cpu = this_cpu; /* Wake to this CPU if we can */
 
-               if ((sd->flags & SD_WAKE_AFFINE) &&
-                               !task_hot(p, rq->timestamp_last_tick, sd)) {
+               if (this_sd->flags & SD_WAKE_AFFINE) {
+                       unsigned long tl = this_load;
                        /*
-                        * This domain has SD_WAKE_AFFINE and p is cache cold
-                        * in this domain.
+                        * If sync wakeup then subtract the (maximum possible)
+                        * effect of the currently running task from the load
+                        * of the current CPU:
                         */
-                       if (cpu_isset(cpu, sd->span)) {
-                               schedstat_inc(sd, ttwu_move_affine);
+                       if (sync)
+                               tl -= SCHED_LOAD_SCALE;
+
+                       if ((tl <= load &&
+                               tl + target_load(cpu, idx) <= SCHED_LOAD_SCALE) ||
+                               100*(tl + SCHED_LOAD_SCALE) <= imbalance*load) {
+                               /*
+                                * This domain has SD_WAKE_AFFINE and
+                                * p is cache cold in this domain, and
+                                * there is no bad imbalance.
+                                */
+                               schedstat_inc(this_sd, ttwu_move_affine);
                                goto out_set_cpu;
                        }
-               } else if ((sd->flags & SD_WAKE_BALANCE) &&
-                               imbalance*this_load <= 100*load) {
-                       /*
-                        * This domain has SD_WAKE_BALANCE and there is
-                        * an imbalance.
-                        */
-                       if (cpu_isset(cpu, sd->span)) {
-                               schedstat_inc(sd, ttwu_move_balance);
+               }
+
+               /*
+                * Start passive balancing when half the imbalance_pct
+                * limit is reached.
+                */
+               if (this_sd->flags & SD_WAKE_BALANCE) {
+                       if (imbalance*this_load <= 100*load) {
+                               schedstat_inc(this_sd, ttwu_move_balance);
                                goto out_set_cpu;
                        }
                }
@@ -1120,17 +1287,19 @@ int fastcall wake_up_state(task_t *p, unsigned int state)
        return try_to_wake_up(p, state, 0);
 }
 
-#ifdef CONFIG_SMP
-static int find_idlest_cpu(struct task_struct *p, int this_cpu,
-                          struct sched_domain *sd);
-#endif
-
 /*
  * Perform scheduler related setup for a newly forked process p.
  * p is forked by current.
  */
-void fastcall sched_fork(task_t *p)
+void fastcall sched_fork(task_t *p, int clone_flags)
 {
+       int cpu = get_cpu();
+
+#ifdef CONFIG_SMP
+       cpu = sched_balance_self(cpu, SD_BALANCE_FORK);
+#endif
+       set_task_cpu(p, cpu);
+
        /*
         * We mark the process as running here, but have not actually
         * inserted it onto the runqueue yet. This guarantees that
@@ -1140,17 +1309,14 @@ void fastcall sched_fork(task_t *p)
        p->state = TASK_RUNNING;
        INIT_LIST_HEAD(&p->run_list);
        p->array = NULL;
-       spin_lock_init(&p->switch_lock);
 #ifdef CONFIG_SCHEDSTATS
        memset(&p->sched_info, 0, sizeof(p->sched_info));
 #endif
+#if defined(CONFIG_SMP) && defined(__ARCH_WANT_UNLOCKED_CTXSW)
+       p->oncpu = 0;
+#endif
 #ifdef CONFIG_PREEMPT
-       /*
-        * During context-switch we hold precisely one spinlock, which
-        * schedule_tail drops. (in the common case it's this_rq()->lock,
-        * but it also can be p->switch_lock.) So we compensate with a count
-        * of 1. Also, we want to start with kernel preemption disabled.
-        */
+       /* Want to start with kernel preemption disabled. */
        p->thread_info->preempt_count = 1;
 #endif
        /*
@@ -1174,12 +1340,10 @@ void fastcall sched_fork(task_t *p)
                 * runqueue lock is not a problem.
                 */
                current->time_slice = 1;
-               preempt_disable();
                scheduler_tick();
-               local_irq_enable();
-               preempt_enable();
-       } else
-               local_irq_enable();
+       }
+       local_irq_enable();
+       put_cpu();
 }
 
 /*
@@ -1196,10 +1360,9 @@ void fastcall wake_up_new_task(task_t * p, unsigned long clone_flags)
        runqueue_t *rq, *this_rq;
 
        rq = task_rq_lock(p, &flags);
-       cpu = task_cpu(p);
-       this_cpu = smp_processor_id();
-
        BUG_ON(p->state != TASK_RUNNING);
+       this_cpu = smp_processor_id();
+       cpu = task_cpu(p);
 
        /*
         * We decrease the sleep average of forking parents
@@ -1295,23 +1458,41 @@ void fastcall sched_exit(task_t * p)
        task_rq_unlock(rq, &flags);
 }
 
+/**
+ * prepare_task_switch - prepare to switch tasks
+ * @rq: the runqueue preparing to switch
+ * @next: the task we are going to switch to.
+ *
+ * This is called with the rq lock held and interrupts off. It must
+ * be paired with a subsequent finish_task_switch after the context
+ * switch.
+ *
+ * prepare_task_switch sets up locking and calls architecture specific
+ * hooks.
+ */
+static inline void prepare_task_switch(runqueue_t *rq, task_t *next)
+{
+       prepare_lock_switch(rq, next);
+       prepare_arch_switch(next);
+}
+
 /**
  * finish_task_switch - clean up after a task-switch
  * @prev: the thread we just switched away from.
  *
- * We enter this with the runqueue still locked, and finish_arch_switch()
- * will unlock it along with doing any other architecture-specific cleanup
- * actions.
+ * finish_task_switch must be called after the context switch, paired
+ * with a prepare_task_switch call before the context switch.
+ * finish_task_switch will reconcile locking set up by prepare_task_switch,
+ * and do any other architecture-specific cleanup actions.
  *
  * Note that we may have delayed dropping an mm in context_switch(). If
  * so, we finish that here outside of the runqueue lock.  (Doing it
  * with the lock held can cause deadlocks; see schedule() for
  * details.)
  */
-static inline void finish_task_switch(task_t *prev)
+static inline void finish_task_switch(runqueue_t *rq, task_t *prev)
        __releases(rq->lock)
 {
-       runqueue_t *rq = this_rq();
        struct mm_struct *mm = rq->prev_mm;
        unsigned long prev_task_flags;
 
@@ -1329,7 +1510,8 @@ static inline void finish_task_switch(task_t *prev)
         *              Manfred Spraul <manfred@colorfullife.com>
         */
        prev_task_flags = prev->flags;
-       finish_arch_switch(rq, prev);
+       finish_arch_switch(prev);
+       finish_lock_switch(rq, prev);
        if (mm)
                mmdrop(mm);
        if (unlikely(prev_task_flags & PF_DEAD))
@@ -1343,8 +1525,12 @@ static inline void finish_task_switch(task_t *prev)
 asmlinkage void schedule_tail(task_t *prev)
        __releases(rq->lock)
 {
-       finish_task_switch(prev);
-
+       runqueue_t *rq = this_rq();
+       finish_task_switch(rq, prev);
+#ifdef __ARCH_WANT_UNLOCKED_CTXSW
+       /* In this case, finish_task_switch does not reenable preemption */
+       preempt_enable();
+#endif
        if (current->set_child_tid)
                put_user(current->pid, current->set_child_tid);
 }
@@ -1493,51 +1679,6 @@ static void double_lock_balance(runqueue_t *this_rq, runqueue_t *busiest)
        }
 }
 
-/*
- * find_idlest_cpu - find the least busy runqueue.
- */
-static int find_idlest_cpu(struct task_struct *p, int this_cpu,
-                          struct sched_domain *sd)
-{
-       unsigned long load, min_load, this_load;
-       int i, min_cpu;
-       cpumask_t mask;
-
-       min_cpu = UINT_MAX;
-       min_load = ULONG_MAX;
-
-       cpus_and(mask, sd->span, p->cpus_allowed);
-
-       for_each_cpu_mask(i, mask) {
-               load = target_load(i);
-
-               if (load < min_load) {
-                       min_cpu = i;
-                       min_load = load;
-
-                       /* break out early on an idle CPU: */
-                       if (!min_load)
-                               break;
-               }
-       }
-
-       /* add +1 to account for the new task */
-       this_load = source_load(this_cpu) + SCHED_LOAD_SCALE;
-
-       /*
-        * Would with the addition of the new task to the
-        * current CPU there be an imbalance between this
-        * CPU and the idlest CPU?
-        *
-        * Use half of the balancing threshold - new-context is
-        * a good opportunity to balance.
-        */
-       if (min_load*(100 + (sd->imbalance_pct-100)/2) < this_load*100)
-               return min_cpu;
-
-       return this_cpu;
-}
-
 /*
  * If dest_cpu is allowed for this process, migrate the task to it.
  * This is accomplished by forcing the cpu_allowed mask to only
@@ -1571,37 +1712,16 @@ out:
 }
 
 /*
- * sched_exec(): find the highest-level, exec-balance-capable
- * domain and try to migrate the task to the least loaded CPU.
- *
- * execve() is a valuable balancing opportunity, because at this point
- * the task has the smallest effective memory and cache footprint.
+ * sched_exec - execve() is a valuable balancing opportunity, because at
+ * this point the task has the smallest effective memory and cache footprint.
  */
 void sched_exec(void)
 {
-       struct sched_domain *tmp, *sd = NULL;
        int new_cpu, this_cpu = get_cpu();
-
-       /* Prefer the current CPU if there's only this task running */
-       if (this_rq()->nr_running <= 1)
-               goto out;
-
-       for_each_domain(this_cpu, tmp)
-               if (tmp->flags & SD_BALANCE_EXEC)
-                       sd = tmp;
-
-       if (sd) {
-               schedstat_inc(sd, sbe_attempts);
-               new_cpu = find_idlest_cpu(current, this_cpu, sd);
-               if (new_cpu != this_cpu) {
-                       schedstat_inc(sd, sbe_pushed);
-                       put_cpu();
-                       sched_migrate_task(current, new_cpu);
-                       return;
-               }
-       }
-out:
+       new_cpu = sched_balance_self(this_cpu, SD_BALANCE_EXEC);
        put_cpu();
+       if (new_cpu != this_cpu)
+               sched_migrate_task(current, new_cpu);
 }
 
 /*
@@ -1632,7 +1752,7 @@ void pull_task(runqueue_t *src_rq, prio_array_t *src_array, task_t *p,
  */
 static inline
 int can_migrate_task(task_t *p, runqueue_t *rq, int this_cpu,
-                    struct sched_domain *sd, enum idle_type idle)
+            struct sched_domain *sd, enum idle_type idle, int *all_pinned)
 {
        /*
         * We do not migrate tasks that are:
@@ -1640,23 +1760,24 @@ int can_migrate_task(task_t *p, runqueue_t *rq, int this_cpu,
         * 2) cannot be migrated to this CPU due to cpus_allowed, or
         * 3) are cache-hot on their current CPU.
         */
-       if (task_running(rq, p))
-               return 0;
        if (!cpu_isset(this_cpu, p->cpus_allowed))
                return 0;
+       *all_pinned = 0;
+
+       if (task_running(rq, p))
+               return 0;
 
        /*
         * Aggressive migration if:
-        * 1) the [whole] cpu is idle, or
+        * 1) task is cache cold, or
         * 2) too many balance attempts have failed.
         */
 
-       if (cpu_and_siblings_are_idle(this_cpu) || \
-                       sd->nr_balance_failed > sd->cache_nice_tries)
+       if (sd->nr_balance_failed > sd->cache_nice_tries)
                return 1;
 
        if (task_hot(p, rq->timestamp_last_tick, sd))
-                       return 0;
+               return 0;
        return 1;
 }
 
@@ -1669,16 +1790,18 @@ int can_migrate_task(task_t *p, runqueue_t *rq, int this_cpu,
  */
 static int move_tasks(runqueue_t *this_rq, int this_cpu, runqueue_t *busiest,
                      unsigned long max_nr_move, struct sched_domain *sd,
-                     enum idle_type idle)
+                     enum idle_type idle, int *all_pinned)
 {
        prio_array_t *array, *dst_array;
        struct list_head *head, *curr;
-       int idx, pulled = 0;
+       int idx, pulled = 0, pinned = 0;
        task_t *tmp;
 
-       if (max_nr_move <= 0 || busiest->nr_running <= 1)
+       if (max_nr_move == 0)
                goto out;
 
+       pinned = 1;
+
        /*
         * We first consider expired tasks. Those will likely not be
         * executed in the near future, and they are most likely to
@@ -1717,7 +1840,7 @@ skip_queue:
 
        curr = curr->prev;
 
-       if (!can_migrate_task(tmp, busiest, this_cpu, sd, idle)) {
+       if (!can_migrate_task(tmp, busiest, this_cpu, sd, idle, &pinned)) {
                if (curr != head)
                        goto skip_queue;
                idx++;
@@ -1746,6 +1869,9 @@ out:
         * inside pull_task().
         */
        schedstat_add(sd, lb_gained[idle], pulled);
+
+       if (all_pinned)
+               *all_pinned = pinned;
        return pulled;
 }
 
@@ -1760,8 +1886,15 @@ find_busiest_group(struct sched_domain *sd, int this_cpu,
 {
        struct sched_group *busiest = NULL, *this = NULL, *group = sd->groups;
        unsigned long max_load, avg_load, total_load, this_load, total_pwr;
+       int load_idx;
 
        max_load = this_load = total_load = total_pwr = 0;
+       if (idle == NOT_IDLE)
+               load_idx = sd->busy_idx;
+       else if (idle == NEWLY_IDLE)
+               load_idx = sd->newidle_idx;
+       else
+               load_idx = sd->idle_idx;
 
        do {
                unsigned long load;
@@ -1776,9 +1909,9 @@ find_busiest_group(struct sched_domain *sd, int this_cpu,
                for_each_cpu_mask(i, group->cpumask) {
                        /* Bias balancing toward cpus of our domain */
                        if (local_group)
-                               load = target_load(i);
+                               load = target_load(i, load_idx);
                        else
-                               load = source_load(i);
+                               load = source_load(i, load_idx);
 
                        avg_load += load;
                }
@@ -1792,12 +1925,10 @@ find_busiest_group(struct sched_domain *sd, int this_cpu,
                if (local_group) {
                        this_load = avg_load;
                        this = group;
-                       goto nextgroup;
                } else if (avg_load > max_load) {
                        max_load = avg_load;
                        busiest = group;
                }
-nextgroup:
                group = group->next;
        } while (group != sd->groups);
 
@@ -1870,15 +2001,9 @@ nextgroup:
 
        /* Get rid of the scaling factor, rounding down as we divide */
        *imbalance = *imbalance / SCHED_LOAD_SCALE;
-
        return busiest;
 
 out_balanced:
-       if (busiest && (idle == NEWLY_IDLE ||
-                       (idle == SCHED_IDLE && max_load > SCHED_LOAD_SCALE)) ) {
-               *imbalance = 1;
-               return busiest;
-       }
 
        *imbalance = 0;
        return NULL;
@@ -1894,7 +2019,7 @@ static runqueue_t *find_busiest_queue(struct sched_group *group)
        int i;
 
        for_each_cpu_mask(i, group->cpumask) {
-               load = source_load(i);
+               load = source_load(i, 0);
 
                if (load > max_load) {
                        max_load = load;
@@ -1905,6 +2030,12 @@ static runqueue_t *find_busiest_queue(struct sched_group *group)
        return busiest;
 }
 
+/*
+ * Max backoff if we encounter pinned tasks. Pretty arbitrary value, but
+ * so long as it is large enough.
+ */
+#define MAX_PINNED_INTERVAL    512
+
 /*
  * Check this_cpu to ensure it is balanced within domain. Attempt to move
  * tasks if there is an imbalance.
@@ -1917,7 +2048,8 @@ static int load_balance(int this_cpu, runqueue_t *this_rq,
        struct sched_group *group;
        runqueue_t *busiest;
        unsigned long imbalance;
-       int nr_moved;
+       int nr_moved, all_pinned = 0;
+       int active_balance = 0;
 
        spin_lock(&this_rq->lock);
        schedstat_inc(sd, lb_cnt[idle]);
@@ -1934,15 +2066,7 @@ static int load_balance(int this_cpu, runqueue_t *this_rq,
                goto out_balanced;
        }
 
-       /*
-        * This should be "impossible", but since load
-        * balancing is inherently racy and statistical,
-        * it could happen in theory.
-        */
-       if (unlikely(busiest == this_rq)) {
-               WARN_ON(1);
-               goto out_balanced;
-       }
+       BUG_ON(busiest == this_rq);
 
        schedstat_add(sd, lb_imbalance[idle], imbalance);
 
@@ -1956,9 +2080,15 @@ static int load_balance(int this_cpu, runqueue_t *this_rq,
                 */
                double_lock_balance(this_rq, busiest);
                nr_moved = move_tasks(this_rq, this_cpu, busiest,
-                                               imbalance, sd, idle);
+                                               imbalance, sd, idle,
+                                               &all_pinned);
                spin_unlock(&busiest->lock);
+
+               /* All tasks on this runqueue were pinned by CPU affinity */
+               if (unlikely(all_pinned))
+                       goto out_balanced;
        }
+
        spin_unlock(&this_rq->lock);
 
        if (!nr_moved) {
@@ -1966,36 +2096,38 @@ static int load_balance(int this_cpu, runqueue_t *this_rq,
                sd->nr_balance_failed++;
 
                if (unlikely(sd->nr_balance_failed > sd->cache_nice_tries+2)) {
-                       int wake = 0;
 
                        spin_lock(&busiest->lock);
                        if (!busiest->active_balance) {
                                busiest->active_balance = 1;
                                busiest->push_cpu = this_cpu;
-                               wake = 1;
+                               active_balance = 1;
                        }
                        spin_unlock(&busiest->lock);
-                       if (wake)
+                       if (active_balance)
                                wake_up_process(busiest->migration_thread);
 
                        /*
                         * We've kicked active balancing, reset the failure
                         * counter.
                         */
-                       sd->nr_balance_failed = sd->cache_nice_tries;
+                       sd->nr_balance_failed = sd->cache_nice_tries+1;
                }
-
-               /*
-                * We were unbalanced, but unsuccessful in move_tasks(),
-                * so bump the balance_interval to lessen the lock contention.
-                */
-               if (sd->balance_interval < sd->max_interval)
-                       sd->balance_interval++;
-       } else {
+       } else
                sd->nr_balance_failed = 0;
 
+       if (likely(!active_balance)) {
                /* We were unbalanced, so reset the balancing interval */
                sd->balance_interval = sd->min_interval;
+       } else {
+               /*
+                * If we've begun active balancing, start to back off. This
+                * case may not be covered by the all_pinned logic if there
+                * is only 1 task on the busy runqueue (because we don't call
+                * move_tasks).
+                */
+               if (sd->balance_interval < sd->max_interval)
+                       sd->balance_interval *= 2;
        }
 
        return nr_moved;
@@ -2005,8 +2137,10 @@ out_balanced:
 
        schedstat_inc(sd, lb_balanced[idle]);
 
+       sd->nr_balance_failed = 0;
        /* tune up the balancing interval */
-       if (sd->balance_interval < sd->max_interval)
+       if ((all_pinned && sd->balance_interval < MAX_PINNED_INTERVAL) ||
+                       (sd->balance_interval < sd->max_interval))
                sd->balance_interval *= 2;
 
        return 0;
@@ -2030,31 +2164,36 @@ static int load_balance_newidle(int this_cpu, runqueue_t *this_rq,
        schedstat_inc(sd, lb_cnt[NEWLY_IDLE]);
        group = find_busiest_group(sd, this_cpu, &imbalance, NEWLY_IDLE);
        if (!group) {
-               schedstat_inc(sd, lb_balanced[NEWLY_IDLE]);
                schedstat_inc(sd, lb_nobusyg[NEWLY_IDLE]);
-               goto out;
+               goto out_balanced;
        }
 
        busiest = find_busiest_queue(group);
-       if (!busiest || busiest == this_rq) {
-               schedstat_inc(sd, lb_balanced[NEWLY_IDLE]);
+       if (!busiest) {
                schedstat_inc(sd, lb_nobusyq[NEWLY_IDLE]);
-               goto out;
+               goto out_balanced;
        }
 
+       BUG_ON(busiest == this_rq);
+
        /* Attempt to move tasks */
        double_lock_balance(this_rq, busiest);
 
        schedstat_add(sd, lb_imbalance[NEWLY_IDLE], imbalance);
        nr_moved = move_tasks(this_rq, this_cpu, busiest,
-                                       imbalance, sd, NEWLY_IDLE);
+                                       imbalance, sd, NEWLY_IDLE, NULL);
        if (!nr_moved)
                schedstat_inc(sd, lb_failed[NEWLY_IDLE]);
+       else
+               sd->nr_balance_failed = 0;
 
        spin_unlock(&busiest->lock);
-
-out:
        return nr_moved;
+
+out_balanced:
+       schedstat_inc(sd, lb_balanced[NEWLY_IDLE]);
+       sd->nr_balance_failed = 0;
+       return 0;
 }
 
 /*
@@ -2086,56 +2225,42 @@ static inline void idle_balance(int this_cpu, runqueue_t *this_rq)
 static void active_load_balance(runqueue_t *busiest_rq, int busiest_cpu)
 {
        struct sched_domain *sd;
-       struct sched_group *cpu_group;
        runqueue_t *target_rq;
-       cpumask_t visited_cpus;
-       int cpu;
+       int target_cpu = busiest_rq->push_cpu;
+
+       if (busiest_rq->nr_running <= 1)
+               /* no task to move */
+               return;
+
+       target_rq = cpu_rq(target_cpu);
 
        /*
-        * Search for suitable CPUs to push tasks to in successively higher
-        * domains with SD_LOAD_BALANCE set.
+        * This condition is "impossible", if it occurs
+        * we need to fix it.  Originally reported by
+        * Bjorn Helgaas on a 128-cpu setup.
         */
-       visited_cpus = CPU_MASK_NONE;
-       for_each_domain(busiest_cpu, sd) {
-               if (!(sd->flags & SD_LOAD_BALANCE))
-                       /* no more domains to search */
-                       break;
+       BUG_ON(busiest_rq == target_rq);
 
-               schedstat_inc(sd, alb_cnt);
+       /* move a task from busiest_rq to target_rq */
+       double_lock_balance(busiest_rq, target_rq);
 
-               cpu_group = sd->groups;
-               do {
-                       for_each_cpu_mask(cpu, cpu_group->cpumask) {
-                               if (busiest_rq->nr_running <= 1)
-                                       /* no more tasks left to move */
-                                       return;
-                               if (cpu_isset(cpu, visited_cpus))
-                                       continue;
-                               cpu_set(cpu, visited_cpus);
-                               if (!cpu_and_siblings_are_idle(cpu) || cpu == busiest_cpu)
-                                       continue;
-
-                               target_rq = cpu_rq(cpu);
-                               /*
-                                * This condition is "impossible", if it occurs
-                                * we need to fix it.  Originally reported by
-                                * Bjorn Helgaas on a 128-cpu setup.
-                                */
-                               BUG_ON(busiest_rq == target_rq);
-
-                               /* move a task from busiest_rq to target_rq */
-                               double_lock_balance(busiest_rq, target_rq);
-                               if (move_tasks(target_rq, cpu, busiest_rq,
-                                               1, sd, SCHED_IDLE)) {
-                                       schedstat_inc(sd, alb_pushed);
-                               } else {
-                                       schedstat_inc(sd, alb_failed);
-                               }
-                               spin_unlock(&target_rq->lock);
-                       }
-                       cpu_group = cpu_group->next;
-               } while (cpu_group != sd->groups);
-       }
+       /* Search for an sd spanning us and the target CPU. */
+       for_each_domain(target_cpu, sd)
+               if ((sd->flags & SD_LOAD_BALANCE) &&
+                       cpu_isset(busiest_cpu, sd->span))
+                               break;
+
+       if (unlikely(sd == NULL))
+               goto out;
+
+       schedstat_inc(sd, alb_cnt);
+
+       if (move_tasks(target_rq, target_cpu, busiest_rq, 1, sd, SCHED_IDLE, NULL))
+               schedstat_inc(sd, alb_pushed);
+       else
+               schedstat_inc(sd, alb_failed);
+out:
+       spin_unlock(&target_rq->lock);
 }
 
 /*
@@ -2156,18 +2281,23 @@ static void rebalance_tick(int this_cpu, runqueue_t *this_rq,
        unsigned long old_load, this_load;
        unsigned long j = jiffies + CPU_OFFSET(this_cpu);
        struct sched_domain *sd;
+       int i;
 
-       /* Update our load */
-       old_load = this_rq->cpu_load;
        this_load = this_rq->nr_running * SCHED_LOAD_SCALE;
-       /*
-        * Round up the averaging division if load is increasing. This
-        * prevents us from getting stuck on 9 if the load is 10, for
-        * example.
-        */
-       if (this_load > old_load)
-               old_load++;
-       this_rq->cpu_load = (old_load + this_load) / 2;
+       /* Update our load */
+       for (i = 0; i < 3; i++) {
+               unsigned long new_load = this_load;
+               int scale = 1 << i;
+               old_load = this_rq->cpu_load[i];
+               /*
+                * Round up the averaging division if load is increasing. This
+                * prevents us from getting stuck on 9 if the load is 10, for
+                * example.
+                */
+               if (new_load > old_load)
+                       new_load += scale-1;
+               this_rq->cpu_load[i] = (old_load*(scale-1) + new_load) / scale;
+       }
 
        for_each_domain(this_cpu, sd) {
                unsigned long interval;
@@ -2447,11 +2577,15 @@ out:
 #ifdef CONFIG_SCHED_SMT
 static inline void wake_sleeping_dependent(int this_cpu, runqueue_t *this_rq)
 {
-       struct sched_domain *sd = this_rq->sd;
+       struct sched_domain *tmp, *sd = NULL;
        cpumask_t sibling_map;
        int i;
 
-       if (!(sd->flags & SD_SHARE_CPUPOWER))
+       for_each_domain(this_cpu, tmp)
+               if (tmp->flags & SD_SHARE_CPUPOWER)
+                       sd = tmp;
+
+       if (!sd)
                return;
 
        /*
@@ -2492,13 +2626,17 @@ static inline void wake_sleeping_dependent(int this_cpu, runqueue_t *this_rq)
 
 static inline int dependent_sleeper(int this_cpu, runqueue_t *this_rq)
 {
-       struct sched_domain *sd = this_rq->sd;
+       struct sched_domain *tmp, *sd = NULL;
        cpumask_t sibling_map;
        prio_array_t *array;
        int ret = 0, i;
        task_t *p;
 
-       if (!(sd->flags & SD_SHARE_CPUPOWER))
+       for_each_domain(this_cpu, tmp)
+               if (tmp->flags & SD_SHARE_CPUPOWER)
+                       sd = tmp;
+
+       if (!sd)
                return 0;
 
        /*
@@ -2613,7 +2751,7 @@ asmlinkage void __sched schedule(void)
        struct list_head *queue;
        unsigned long long now;
        unsigned long run_time;
-       int cpu, idx;
+       int cpu, idx, new_prio;
 
        /*
         * Test if we are atomic.  Since do_exit() needs to call into
@@ -2735,9 +2873,14 @@ go_idle:
                        delta = delta * (ON_RUNQUEUE_WEIGHT * 128 / 100) / 128;
 
                array = next->array;
-               dequeue_task(next, array);
-               recalc_task_prio(next, next->timestamp + delta);
-               enqueue_task(next, array);
+               new_prio = recalc_task_prio(next, next->timestamp + delta);
+
+               if (unlikely(next->prio != new_prio)) {
+                       dequeue_task(next, array);
+                       next->prio = new_prio;
+                       enqueue_task(next, array);
+               } else
+                       requeue_task(next, array);
        }
        next->activated = 0;
 switch_tasks:
@@ -2761,11 +2904,15 @@ switch_tasks:
                rq->curr = next;
                ++*switch_count;
 
-               prepare_arch_switch(rq, next);
+               prepare_task_switch(rq, next);
                prev = context_switch(rq, prev, next);
                barrier();
-
-               finish_task_switch(prev);
+               /*
+                * this_rq must be evaluated again because prev may have moved
+                * CPUs since it called schedule(), thus the 'rq' on its stack
+                * frame will be invalid.
+                */
+               finish_task_switch(this_rq(), prev);
        } else
                spin_unlock_irq(&rq->lock);
 
@@ -3384,13 +3531,24 @@ recheck:
        if ((policy == SCHED_NORMAL) != (param->sched_priority == 0))
                return -EINVAL;
 
-       if ((policy == SCHED_FIFO || policy == SCHED_RR) &&
-           param->sched_priority > p->signal->rlim[RLIMIT_RTPRIO].rlim_cur &&
-           !capable(CAP_SYS_NICE))
-               return -EPERM;
-       if ((current->euid != p->euid) && (current->euid != p->uid) &&
-           !capable(CAP_SYS_NICE))
-               return -EPERM;
+       /*
+        * Allow unprivileged RT tasks to decrease priority:
+        */
+       if (!capable(CAP_SYS_NICE)) {
+               /* can't change policy */
+               if (policy != p->policy)
+                       return -EPERM;
+               /* can't increase priority */
+               if (policy != SCHED_NORMAL &&
+                   param->sched_priority > p->rt_priority &&
+                   param->sched_priority >
+                               p->signal->rlim[RLIMIT_RTPRIO].rlim_cur)
+                       return -EPERM;
+               /* can't change other user's priorities */
+               if ((current->euid != p->euid) &&
+                   (current->euid != p->uid))
+                       return -EPERM;
+       }
 
        retval = security_task_setscheduler(p, policy, param);
        if (retval)
@@ -4030,6 +4188,9 @@ void __devinit init_idle(task_t *idle, int cpu)
 
        spin_lock_irqsave(&rq->lock, flags);
        rq->curr = rq->idle = idle;
+#if defined(CONFIG_SMP) && defined(__ARCH_WANT_UNLOCKED_CTXSW)
+       idle->oncpu = 1;
+#endif
        set_tsk_need_resched(idle);
        spin_unlock_irqrestore(&rq->lock, flags);
 
@@ -4174,8 +4335,7 @@ static int migration_thread(void * data)
                struct list_head *head;
                migration_req_t *req;
 
-               if (current->flags & PF_FREEZE)
-                       refrigerator(PF_FREEZE);
+               try_to_freeze();
 
                spin_lock_irq(&rq->lock);
 
@@ -4200,17 +4360,9 @@ static int migration_thread(void * data)
                req = list_entry(head->next, migration_req_t, list);
                list_del_init(head->next);
 
-               if (req->type == REQ_MOVE_TASK) {
-                       spin_unlock(&rq->lock);
-                       __migrate_task(req->task, cpu, req->dest_cpu);
-                       local_irq_enable();
-               } else if (req->type == REQ_SET_DOMAIN) {
-                       rq->sd = req->sd;
-                       spin_unlock_irq(&rq->lock);
-               } else {
-                       spin_unlock_irq(&rq->lock);
-                       WARN_ON(1);
-               }
+               spin_unlock(&rq->lock);
+               __migrate_task(req->task, cpu, req->dest_cpu);
+               local_irq_enable();
 
                complete(&req->done);
        }
@@ -4441,7 +4593,6 @@ static int migration_call(struct notifier_block *nfb, unsigned long action,
                        migration_req_t *req;
                        req = list_entry(rq->migration_queue.next,
                                         migration_req_t, list);
-                       BUG_ON(req->type != REQ_MOVE_TASK);
                        list_del_init(&req->list);
                        complete(&req->done);
                }
@@ -4472,12 +4623,17 @@ int __init migration_init(void)
 #endif
 
 #ifdef CONFIG_SMP
-#define SCHED_DOMAIN_DEBUG
+#undef SCHED_DOMAIN_DEBUG
 #ifdef SCHED_DOMAIN_DEBUG
 static void sched_domain_debug(struct sched_domain *sd, int cpu)
 {
        int level = 0;
 
+       if (!sd) {
+               printk(KERN_DEBUG "CPU%d attaching NULL sched-domain.\n", cpu);
+               return;
+       }
+
        printk(KERN_DEBUG "CPU%d attaching sched-domain:\n", cpu);
 
        do {
@@ -4560,37 +4716,81 @@ static void sched_domain_debug(struct sched_domain *sd, int cpu)
 #define sched_domain_debug(sd, cpu) {}
 #endif
 
+static int sd_degenerate(struct sched_domain *sd)
+{
+       if (cpus_weight(sd->span) == 1)
+               return 1;
+
+       /* Following flags need at least 2 groups */
+       if (sd->flags & (SD_LOAD_BALANCE |
+                        SD_BALANCE_NEWIDLE |
+                        SD_BALANCE_FORK |
+                        SD_BALANCE_EXEC)) {
+               if (sd->groups != sd->groups->next)
+                       return 0;
+       }
+
+       /* Following flags don't use groups */
+       if (sd->flags & (SD_WAKE_IDLE |
+                        SD_WAKE_AFFINE |
+                        SD_WAKE_BALANCE))
+               return 0;
+
+       return 1;
+}
+
+static int sd_parent_degenerate(struct sched_domain *sd,
+                                               struct sched_domain *parent)
+{
+       unsigned long cflags = sd->flags, pflags = parent->flags;
+
+       if (sd_degenerate(parent))
+               return 1;
+
+       if (!cpus_equal(sd->span, parent->span))
+               return 0;
+
+       /* Does parent contain flags not in child? */
+       /* WAKE_BALANCE is a subset of WAKE_AFFINE */
+       if (cflags & SD_WAKE_AFFINE)
+               pflags &= ~SD_WAKE_BALANCE;
+       /* Flags needing groups don't count if only 1 group in parent */
+       if (parent->groups == parent->groups->next) {
+               pflags &= ~(SD_LOAD_BALANCE |
+                               SD_BALANCE_NEWIDLE |
+                               SD_BALANCE_FORK |
+                               SD_BALANCE_EXEC);
+       }
+       if (~cflags & pflags)
+               return 0;
+
+       return 1;
+}
+
 /*
  * Attach the domain 'sd' to 'cpu' as its base domain.  Callers must
  * hold the hotplug lock.
  */
-void __devinit cpu_attach_domain(struct sched_domain *sd, int cpu)
+void cpu_attach_domain(struct sched_domain *sd, int cpu)
 {
-       migration_req_t req;
-       unsigned long flags;
        runqueue_t *rq = cpu_rq(cpu);
-       int local = 1;
-
-       sched_domain_debug(sd, cpu);
+       struct sched_domain *tmp;
 
-       spin_lock_irqsave(&rq->lock, flags);
-
-       if (cpu == smp_processor_id() || !cpu_online(cpu)) {
-               rq->sd = sd;
-       } else {
-               init_completion(&req.done);
-               req.type = REQ_SET_DOMAIN;
-               req.sd = sd;
-               list_add(&req.list, &rq->migration_queue);
-               local = 0;
+       /* Remove the sched domains which do not contribute to scheduling. */
+       for (tmp = sd; tmp; tmp = tmp->parent) {
+               struct sched_domain *parent = tmp->parent;
+               if (!parent)
+                       break;
+               if (sd_parent_degenerate(tmp, parent))
+                       tmp->parent = parent->parent;
        }
 
-       spin_unlock_irqrestore(&rq->lock, flags);
+       if (sd && sd_degenerate(sd))
+               sd = sd->parent;
 
-       if (!local) {
-               wake_up_process(rq->migration_thread);
-               wait_for_completion(&req.done);
-       }
+       sched_domain_debug(sd, cpu);
+
+       rcu_assign_pointer(rq->sd, sd);
 }
 
 /* cpus with isolated domains */
@@ -4622,7 +4822,7 @@ __setup ("isolcpus=", isolated_cpu_setup);
  * covered by the given span, and will set each group's ->cpumask correctly,
  * and ->cpu_power to 0.
  */
-void __devinit init_sched_build_groups(struct sched_group groups[],
+void init_sched_build_groups(struct sched_group groups[],
                        cpumask_t span, int (*group_fn)(int cpu))
 {
        struct sched_group *first = NULL, *last = NULL;
@@ -4658,13 +4858,14 @@ void __devinit init_sched_build_groups(struct sched_group groups[],
 
 
 #ifdef ARCH_HAS_SCHED_DOMAIN
-extern void __devinit arch_init_sched_domains(void);
-extern void __devinit arch_destroy_sched_domains(void);
+extern void build_sched_domains(const cpumask_t *cpu_map);
+extern void arch_init_sched_domains(const cpumask_t *cpu_map);
+extern void arch_destroy_sched_domains(const cpumask_t *cpu_map);
 #else
 #ifdef CONFIG_SCHED_SMT
 static DEFINE_PER_CPU(struct sched_domain, cpu_domains);
 static struct sched_group sched_group_cpus[NR_CPUS];
-static int __devinit cpu_to_cpu_group(int cpu)
+static int cpu_to_cpu_group(int cpu)
 {
        return cpu;
 }
@@ -4672,7 +4873,7 @@ static int __devinit cpu_to_cpu_group(int cpu)
 
 static DEFINE_PER_CPU(struct sched_domain, phys_domains);
 static struct sched_group sched_group_phys[NR_CPUS];
-static int __devinit cpu_to_phys_group(int cpu)
+static int cpu_to_phys_group(int cpu)
 {
 #ifdef CONFIG_SCHED_SMT
        return first_cpu(cpu_sibling_map[cpu]);
@@ -4685,7 +4886,7 @@ static int __devinit cpu_to_phys_group(int cpu)
 
 static DEFINE_PER_CPU(struct sched_domain, node_domains);
 static struct sched_group sched_group_nodes[MAX_NUMNODES];
-static int __devinit cpu_to_node_group(int cpu)
+static int cpu_to_node_group(int cpu)
 {
        return cpu_to_node(cpu);
 }
@@ -4716,39 +4917,28 @@ static void check_sibling_maps(void)
 #endif
 
 /*
- * Set up scheduler domains and groups.  Callers must hold the hotplug lock.
+ * Build sched domains for a given set of cpus and attach the sched domains
+ * to the individual cpus
  */
-static void __devinit arch_init_sched_domains(void)
+static void build_sched_domains(const cpumask_t *cpu_map)
 {
        int i;
-       cpumask_t cpu_default_map;
-
-#if defined(CONFIG_SCHED_SMT) && defined(CONFIG_NUMA)
-       check_sibling_maps();
-#endif
-       /*
-        * Setup mask for cpus without special case scheduling requirements.
-        * For now this just excludes isolated cpus, but could be used to
-        * exclude other special cases in the future.
-        */
-       cpus_complement(cpu_default_map, cpu_isolated_map);
-       cpus_and(cpu_default_map, cpu_default_map, cpu_online_map);
 
        /*
-        * Set up domains. Isolated domains just stay on the dummy domain.
+        * Set up domains for cpus specified by the cpu_map.
         */
-       for_each_cpu_mask(i, cpu_default_map) {
+       for_each_cpu_mask(i, *cpu_map) {
                int group;
                struct sched_domain *sd = NULL, *p;
                cpumask_t nodemask = node_to_cpumask(cpu_to_node(i));
 
-               cpus_and(nodemask, nodemask, cpu_default_map);
+               cpus_and(nodemask, nodemask, *cpu_map);
 
 #ifdef CONFIG_NUMA
                sd = &per_cpu(node_domains, i);
                group = cpu_to_node_group(i);
                *sd = SD_NODE_INIT;
-               sd->span = cpu_default_map;
+               sd->span = *cpu_map;
                sd->groups = &sched_group_nodes[group];
 #endif
 
@@ -4766,7 +4956,7 @@ static void __devinit arch_init_sched_domains(void)
                group = cpu_to_cpu_group(i);
                *sd = SD_SIBLING_INIT;
                sd->span = cpu_sibling_map[i];
-               cpus_and(sd->span, sd->span, cpu_default_map);
+               cpus_and(sd->span, sd->span, *cpu_map);
                sd->parent = p;
                sd->groups = &sched_group_cpus[group];
 #endif
@@ -4776,7 +4966,7 @@ static void __devinit arch_init_sched_domains(void)
        /* Set up CPU (sibling) groups */
        for_each_online_cpu(i) {
                cpumask_t this_sibling_map = cpu_sibling_map[i];
-               cpus_and(this_sibling_map, this_sibling_map, cpu_default_map);
+               cpus_and(this_sibling_map, this_sibling_map, *cpu_map);
                if (i != first_cpu(this_sibling_map))
                        continue;
 
@@ -4789,7 +4979,7 @@ static void __devinit arch_init_sched_domains(void)
        for (i = 0; i < MAX_NUMNODES; i++) {
                cpumask_t nodemask = node_to_cpumask(i);
 
-               cpus_and(nodemask, nodemask, cpu_default_map);
+               cpus_and(nodemask, nodemask, *cpu_map);
                if (cpus_empty(nodemask))
                        continue;
 
@@ -4799,12 +4989,12 @@ static void __devinit arch_init_sched_domains(void)
 
 #ifdef CONFIG_NUMA
        /* Set up node groups */
-       init_sched_build_groups(sched_group_nodes, cpu_default_map,
+       init_sched_build_groups(sched_group_nodes, *cpu_map,
                                        &cpu_to_node_group);
 #endif
 
        /* Calculate CPU power for physical packages and nodes */
-       for_each_cpu_mask(i, cpu_default_map) {
+       for_each_cpu_mask(i, *cpu_map) {
                int power;
                struct sched_domain *sd;
 #ifdef CONFIG_SCHED_SMT
@@ -4828,7 +5018,7 @@ static void __devinit arch_init_sched_domains(void)
        }
 
        /* Attach the domains */
-       for_each_online_cpu(i) {
+       for_each_cpu_mask(i, *cpu_map) {
                struct sched_domain *sd;
 #ifdef CONFIG_SCHED_SMT
                sd = &per_cpu(cpu_domains, i);
@@ -4838,41 +5028,85 @@ static void __devinit arch_init_sched_domains(void)
                cpu_attach_domain(sd, i);
        }
 }
+/*
+ * Set up scheduler domains and groups.  Callers must hold the hotplug lock.
+ */
+static void arch_init_sched_domains(cpumask_t *cpu_map)
+{
+       cpumask_t cpu_default_map;
+
+#if defined(CONFIG_SCHED_SMT) && defined(CONFIG_NUMA)
+       check_sibling_maps();
+#endif
+       /*
+        * Setup mask for cpus without special case scheduling requirements.
+        * For now this just excludes isolated cpus, but could be used to
+        * exclude other special cases in the future.
+        */
+       cpus_andnot(cpu_default_map, *cpu_map, cpu_isolated_map);
+
+       build_sched_domains(&cpu_default_map);
+}
 
-#ifdef CONFIG_HOTPLUG_CPU
-static void __devinit arch_destroy_sched_domains(void)
+static void arch_destroy_sched_domains(const cpumask_t *cpu_map)
 {
        /* Do nothing: everything is statically allocated. */
 }
-#endif
 
 #endif /* ARCH_HAS_SCHED_DOMAIN */
 
 /*
- * Initial dummy domain for early boot and for hotplug cpu. Being static,
- * it is initialized to zero, so all balancing flags are cleared which is
- * what we want.
+ * Detach sched domains from a group of cpus specified in cpu_map
+ * These cpus will now be attached to the NULL domain
  */
-static struct sched_domain sched_domain_dummy;
+static inline void detach_destroy_domains(const cpumask_t *cpu_map)
+{
+       int i;
+
+       for_each_cpu_mask(i, *cpu_map)
+               cpu_attach_domain(NULL, i);
+       synchronize_sched();
+       arch_destroy_sched_domains(cpu_map);
+}
+
+/*
+ * Partition sched domains as specified by the cpumasks below.
+ * This attaches all cpus from the cpumasks to the NULL domain,
+ * waits for a RCU quiescent period, recalculates sched
+ * domain information and then attaches them back to the
+ * correct sched domains
+ * Call with hotplug lock held
+ */
+void partition_sched_domains(cpumask_t *partition1, cpumask_t *partition2)
+{
+       cpumask_t change_map;
+
+       cpus_and(*partition1, *partition1, cpu_online_map);
+       cpus_and(*partition2, *partition2, cpu_online_map);
+       cpus_or(change_map, *partition1, *partition2);
+
+       /* Detach sched domains from all of the affected cpus */
+       detach_destroy_domains(&change_map);
+       if (!cpus_empty(*partition1))
+               build_sched_domains(partition1);
+       if (!cpus_empty(*partition2))
+               build_sched_domains(partition2);
+}
 
 #ifdef CONFIG_HOTPLUG_CPU
 /*
  * Force a reinitialization of the sched domains hierarchy.  The domains
  * and groups cannot be updated in place without racing with the balancing
- * code, so we temporarily attach all running cpus to a "dummy" domain
+ * code, so we temporarily attach all running cpus to the NULL domain
  * which will prevent rebalancing while the sched domains are recalculated.
  */
 static int update_sched_domains(struct notifier_block *nfb,
                                unsigned long action, void *hcpu)
 {
-       int i;
-
        switch (action) {
        case CPU_UP_PREPARE:
        case CPU_DOWN_PREPARE:
-               for_each_online_cpu(i)
-                       cpu_attach_domain(&sched_domain_dummy, i);
-               arch_destroy_sched_domains();
+               detach_destroy_domains(&cpu_online_map);
                return NOTIFY_OK;
 
        case CPU_UP_CANCELED:
@@ -4888,7 +5122,7 @@ static int update_sched_domains(struct notifier_block *nfb,
        }
 
        /* The hotplug lock is already held by cpu_up/cpu_down */
-       arch_init_sched_domains();
+       arch_init_sched_domains(&cpu_online_map);
 
        return NOTIFY_OK;
 }
@@ -4897,7 +5131,7 @@ static int update_sched_domains(struct notifier_block *nfb,
 void __init sched_init_smp(void)
 {
        lock_cpu_hotplug();
-       arch_init_sched_domains();
+       arch_init_sched_domains(&cpu_online_map);
        unlock_cpu_hotplug();
        /* XXX: Theoretical race here - CPU may be hotplugged now */
        hotcpu_notifier(update_sched_domains, 0);
@@ -4927,13 +5161,15 @@ void __init sched_init(void)
 
                rq = cpu_rq(i);
                spin_lock_init(&rq->lock);
+               rq->nr_running = 0;
                rq->active = rq->arrays;
                rq->expired = rq->arrays + 1;
                rq->best_expired_prio = MAX_PRIO;
 
 #ifdef CONFIG_SMP
-               rq->sd = &sched_domain_dummy;
-               rq->cpu_load = 0;
+               rq->sd = NULL;
+               for (j = 1; j < 3; j++)
+                       rq->cpu_load[j] = 0;
                rq->active_balance = 0;
                rq->push_cpu = 0;
                rq->migration_thread = NULL;
index d1258729a5f9cdf6674b897b273036e1dee29291..ca1186eef9380cd5e633f644a0891d1dacc5bd16 100644 (file)
@@ -213,7 +213,7 @@ static inline int has_pending_signals(sigset_t *signal, sigset_t *blocked)
 fastcall void recalc_sigpending_tsk(struct task_struct *t)
 {
        if (t->signal->group_stop_count > 0 ||
-           (t->flags & PF_FREEZE) ||
+           (freezing(t)) ||
            PENDING(&t->pending, &t->blocked) ||
            PENDING(&t->signal->shared_pending, &t->blocked))
                set_tsk_thread_flag(t, TIF_SIGPENDING);
@@ -2231,8 +2231,7 @@ sys_rt_sigtimedwait(const sigset_t __user *uthese,
                        current->state = TASK_INTERRUPTIBLE;
                        timeout = schedule_timeout(timeout);
 
-                       if (current->flags & PF_FREEZE)
-                               refrigerator(PF_FREEZE);
+                       try_to_freeze();
                        spin_lock_irq(&current->sighand->siglock);
                        sig = dequeue_signal(current, &these, &info);
                        current->blocked = current->real_blocked;
index da24bc1292db4b6529709b6a9173e68f5251d3d8..9a24374c23bc4f69116d264991689b1aaa9c38fe 100644 (file)
@@ -16,6 +16,8 @@
 #include <linux/init.h>
 #include <linux/highuid.h>
 #include <linux/fs.h>
+#include <linux/kernel.h>
+#include <linux/kexec.h>
 #include <linux/workqueue.h>
 #include <linux/device.h>
 #include <linux/key.h>
@@ -405,6 +407,7 @@ asmlinkage long sys_reboot(int magic1, int magic2, unsigned int cmd, void __user
        case LINUX_REBOOT_CMD_HALT:
                notifier_call_chain(&reboot_notifier_list, SYS_HALT, NULL);
                system_state = SYSTEM_HALT;
+               device_suspend(PMSG_SUSPEND);
                device_shutdown();
                printk(KERN_EMERG "System halted.\n");
                machine_halt();
@@ -415,6 +418,7 @@ asmlinkage long sys_reboot(int magic1, int magic2, unsigned int cmd, void __user
        case LINUX_REBOOT_CMD_POWER_OFF:
                notifier_call_chain(&reboot_notifier_list, SYS_POWER_OFF, NULL);
                system_state = SYSTEM_POWER_OFF;
+               device_suspend(PMSG_SUSPEND);
                device_shutdown();
                printk(KERN_EMERG "Power down.\n");
                machine_power_off();
@@ -431,11 +435,30 @@ asmlinkage long sys_reboot(int magic1, int magic2, unsigned int cmd, void __user
 
                notifier_call_chain(&reboot_notifier_list, SYS_RESTART, buffer);
                system_state = SYSTEM_RESTART;
+               device_suspend(PMSG_FREEZE);
                device_shutdown();
                printk(KERN_EMERG "Restarting system with command '%s'.\n", buffer);
                machine_restart(buffer);
                break;
 
+#ifdef CONFIG_KEXEC
+       case LINUX_REBOOT_CMD_KEXEC:
+       {
+               struct kimage *image;
+               image = xchg(&kexec_image, 0);
+               if (!image) {
+                       unlock_kernel();
+                       return -EINVAL;
+               }
+               notifier_call_chain(&reboot_notifier_list, SYS_RESTART, NULL);
+               system_state = SYSTEM_RESTART;
+               device_shutdown();
+               printk(KERN_EMERG "Starting new kernel\n");
+               machine_shutdown();
+               machine_kexec(image);
+               break;
+       }
+#endif
 #ifdef CONFIG_SOFTWARE_SUSPEND
        case LINUX_REBOOT_CMD_SW_SUSPEND:
                {
index 6f15bea7d1a83dc363826c5bcdb2c0013feaebc0..29196ce9b40f09a9398d78e1c4ee555dd93f6c04 100644 (file)
@@ -18,6 +18,8 @@ cond_syscall(sys_acct);
 cond_syscall(sys_lookup_dcookie);
 cond_syscall(sys_swapon);
 cond_syscall(sys_swapoff);
+cond_syscall(sys_kexec_load);
+cond_syscall(compat_sys_kexec_load);
 cond_syscall(sys_init_module);
 cond_syscall(sys_delete_module);
 cond_syscall(sys_socketpair);
index 24a4d12d5aa9b40bc8e2ea57dde06f1075e70135..270ee7fadbd83d0d90ee732ffd7904c3b8c34d65 100644 (file)
@@ -1000,8 +1000,7 @@ int do_sysctl(int __user *name, int nlen, void __user *oldval, size_t __user *ol
                int error = parse_table(name, nlen, oldval, oldlenp, 
                                        newval, newlen, head->ctl_table,
                                        &context);
-               if (context)
-                       kfree(context);
+               kfree(context);
                if (error != -ENOTDIR)
                        return error;
                tmp = tmp->next;
index 51ff917c959029d8b51e13696c34df5a62ee1def..f2a11887a72680605bc9af158132a4fd104fbe24 100644 (file)
@@ -1597,7 +1597,7 @@ void msleep(unsigned int msecs)
 EXPORT_SYMBOL(msleep);
 
 /**
- * msleep_interruptible - sleep waiting for waitqueue interruptions
+ * msleep_interruptible - sleep waiting for signals
  * @msecs: Time in milliseconds to sleep for
  */
 unsigned long msleep_interruptible(unsigned int msecs)
index 455833a9e31a3e0d347967e6f881420750864602..eeb429a52152bf51e34c5f67f96d8404d66ddf2e 100644 (file)
@@ -63,32 +63,16 @@ config REED_SOLOMON_ENC16
 config REED_SOLOMON_DEC16
        boolean
 
+#
+# Textsearch support is select'ed if needed
+#
 config TEXTSEARCH
-       boolean "Textsearch infrastructure"
-       default y
-       help
-         Say Y here if you want to provide a textsearch infrastructure
-         to other subsystems.
+       boolean
 
 config TEXTSEARCH_KMP
-       depends on TEXTSEARCH
-       tristate "Knuth-Morris-Pratt"
-       help
-         Say Y here if you want to be able to search text using the
-         Knuth-Morris-Pratt textsearch algorithm.
-
-         To compile this code as a module, choose M here: the
-         module will be called ts_kmp.
+       tristate
 
 config TEXTSEARCH_FSM
-       depends on TEXTSEARCH
-       tristate "Finite state machine"
-       help
-         Say Y here if you want to be able to search text using a
-         naive finite state machine approach implementing a subset
-         of regular expressions.
-
-         To compile this code as a module, choose M here: the
-         module will be called ts_fsm.
+       tristate
 
 endmenu
index d1388a5ce89c37c6934a5ac8384443a902365b5e..fb9371fdd44a43c4e8e4fc9304f0ee00d3b4df8c 100644 (file)
@@ -289,7 +289,6 @@ EXPORT_SYMBOL(__bitmap_weight);
 
 #define CHUNKSZ                                32
 #define nbits_to_hold_value(val)       fls(val)
-#define roundup_power2(val,modulus)    (((val) + (modulus) - 1) & ~((modulus) - 1))
 #define unhex(c)                       (isdigit(c) ? (c - '0') : (toupper(c) - 'A' + 10))
 #define BASEDEC 10             /* fancier cpuset lists input in decimal */
 
@@ -316,7 +315,7 @@ int bitmap_scnprintf(char *buf, unsigned int buflen,
        if (chunksz == 0)
                chunksz = CHUNKSZ;
 
-       i = roundup_power2(nmaskbits, CHUNKSZ) - CHUNKSZ;
+       i = ALIGN(nmaskbits, CHUNKSZ) - CHUNKSZ;
        for (; i >= 0; i -= CHUNKSZ) {
                chunkmask = ((1ULL << chunksz) - 1);
                word = i / BITS_PER_LONG;
index 2f7f1148dfde3379921d54f44b5b41c4d167390a..1cdabe3065f932d1edde271b2421ce6844ccb84c 100644 (file)
@@ -41,7 +41,7 @@ void sha_transform(__u32 *digest, const char *in, __u32 *W)
        __u32 a, b, c, d, e, t, i;
 
        for (i = 0; i < 16; i++)
-               W[i] = be32_to_cpu(((const __u32 *)in)[i]);
+               W[i] = be32_to_cpu(((const __be32 *)in)[i]);
 
        for (i = 0; i < 64; i++)
                W[i+16] = rol32(W[i+13] ^ W[i+8] ^ W[i+2] ^ W[i], 1);
index f82f7aebbee31be3b81469a40a070b95e5954f60..c1330cc197835ae66bffaa2baacc032ace0020b4 100644 (file)
@@ -33,6 +33,14 @@ EXPORT_SYMBOL(max_pfn);              /* This is exported so
                                 * dma_get_required_mask(), which uses
                                 * it, can be an inline function */
 
+#ifdef CONFIG_CRASH_DUMP
+/*
+ * If we have booted due to a crash, max_pfn will be a very low value. We need
+ * to know the amount of memory that the previous kernel used.
+ */
+unsigned long saved_max_pfn;
+#endif
+
 /* return the number of _pages_ that will be allocated for the boot bitmap */
 unsigned long __init bootmem_bootmap_pages (unsigned long pages)
 {
@@ -57,7 +65,7 @@ static unsigned long __init init_bootmem_core (pg_data_t *pgdat,
        pgdat->pgdat_next = pgdat_list;
        pgdat_list = pgdat;
 
-       mapsize = (mapsize + (sizeof(long) - 1UL)) & ~(sizeof(long) - 1UL);
+       mapsize = ALIGN(mapsize, sizeof(long));
        bdata->node_bootmem_map = phys_to_virt(mapstart << PAGE_SHIFT);
        bdata->node_boot_start = (start << PAGE_SHIFT);
        bdata->node_low_pfn = end;
@@ -178,7 +186,7 @@ __alloc_bootmem_core(struct bootmem_data *bdata, unsigned long size,
        } else
                preferred = 0;
 
-       preferred = ((preferred + align - 1) & ~(align - 1)) >> PAGE_SHIFT;
+       preferred = ALIGN(preferred, align) >> PAGE_SHIFT;
        preferred += offset;
        areasize = (size+PAGE_SIZE-1)/PAGE_SIZE;
        incr = align >> PAGE_SHIFT ? : 1;
@@ -219,7 +227,7 @@ found:
         */
        if (align < PAGE_SIZE &&
            bdata->last_offset && bdata->last_pos+1 == start) {
-               offset = (bdata->last_offset+align-1) & ~(align-1);
+               offset = ALIGN(bdata->last_offset, align);
                BUG_ON(offset > PAGE_SIZE);
                remaining_size = PAGE_SIZE-offset;
                if (size < remaining_size) {
index 7332194d7afddfd816e27eaec2eebb17a4059a24..c11418dd94e810f4c8d9c4aa7ed2fae6d8aba290 100644 (file)
@@ -1851,8 +1851,11 @@ generic_file_direct_write(struct kiocb *iocb, const struct iovec *iov,
         * i_sem is held, which protects generic_osync_inode() from
         * livelocking.
         */
-       if (written >= 0 && file->f_flags & O_SYNC)
-               generic_osync_inode(inode, mapping, OSYNC_METADATA);
+       if (written >= 0 && ((file->f_flags & O_SYNC) || IS_SYNC(inode))) {
+               int err = generic_osync_inode(inode, mapping, OSYNC_METADATA);
+               if (err < 0)
+                       written = err;
+       }
        if (written == count && !is_sync_kiocb(iocb))
                written = -EIOCBQUEUED;
        return written;
@@ -1951,7 +1954,9 @@ generic_file_buffered_write(struct kiocb *iocb, const struct iovec *iov,
                                if (unlikely(nr_segs > 1)) {
                                        filemap_set_next_iovec(&cur_iov,
                                                        &iov_base, status);
-                                       buf = cur_iov->iov_base + iov_base;
+                                       if (count)
+                                               buf = cur_iov->iov_base +
+                                                       iov_base;
                                } else {
                                        iov_base += status;
                                }
index c256175742ac8612ab49d542ead03efc50789a3c..beabdefa6254a521da762d3a7c44274b29553edd 100644 (file)
@@ -1139,7 +1139,7 @@ int remap_pfn_range(struct vm_area_struct *vma, unsigned long addr,
 {
        pgd_t *pgd;
        unsigned long next;
-       unsigned long end = addr + size;
+       unsigned long end = addr + PAGE_ALIGN(size);
        struct mm_struct *mm = vma->vm_mm;
        int err;
 
index 667c76df1ec24a04ba73f165a51b8afc91d47b26..2e605a19ce57d0611c7a6619feeace3b03680bfb 100644 (file)
@@ -127,7 +127,7 @@ out:
        return ret;
 }
 
-#if defined(CONFIG_SOFTWARE_SUSPEND) || defined(CONFIG_PM_DISK)
+#ifdef CONFIG_SOFTWARE_SUSPEND
 /*
  * A scruffy utility function to read or write an arbitrary swap page
  * and wait on the I/O.  The caller must have a ref on the page.
index 38ce279cc8cdf4fa3a83e29a8ffb509a0551c447..d6781951267eb654a522529658aaa06199d1772f 100644 (file)
@@ -105,7 +105,7 @@ static int __pdflush(struct pdflush_work *my_work)
                spin_unlock_irq(&pdflush_lock);
 
                schedule();
-               if (try_to_freeze(PF_FREEZE)) {
+               if (try_to_freeze()) {
                        spin_lock_irq(&pdflush_lock);
                        continue;
                }
index 4b8e62a193708b7c12808cdb0eccfad61a38bce5..1fa312a8db7751aee563a9c6affaa0e1aa26007f 100644 (file)
@@ -1216,8 +1216,8 @@ static int kswapd(void *p)
        order = 0;
        for ( ; ; ) {
                unsigned long new_order;
-               if (current->flags & PF_FREEZE)
-                       refrigerator(PF_FREEZE);
+
+               try_to_freeze();
 
                prepare_to_wait(&pgdat->kswapd_wait, &wait, TASK_INTERRUPTIBLE);
                new_order = pgdat->kswapd_max_order;
index 690e88ba24846296c8c957da52ca5966bf142584..3470834331207da5c008f45a09291dd924927e3c 100644 (file)
@@ -1,32 +1,6 @@
 #
 # IP configuration
 #
-choice 
-       prompt "Choose IP: FIB lookup"
-       depends on INET
-       default IP_FIB_HASH
-
-config IP_FIB_HASH
-       bool "FIB_HASH"
-       ---help---
-       Current FIB is very proven and good enough for most users.
-
-config IP_FIB_TRIE
-       bool "FIB_TRIE"
-       ---help---
-       Use new experimental LC-trie as FIB lookup algoritm. 
-        This improves lookup performance
-       
-       LC-trie is described in:
-       
-       IP-address lookup using LC-tries. Stefan Nilsson and Gunnar Karlsson
-       IEEE Journal on Selected Areas in Communications, 17(6):1083-1092, June 1999
-       An experimental study of compression methods for dynamic tries
-       Stefan Nilsson and Matti Tikkanen. Algorithmica, 33(1):19-33, 2002.
-       http://www.nada.kth.se/~snilsson/public/papers/dyntrie2/
-       
-endchoice
-
 config IP_MULTICAST
        bool "IP: multicasting"
        depends on INET
@@ -79,6 +53,44 @@ config IP_ADVANCED_ROUTER
 
          If unsure, say N here.
 
+choice 
+       prompt "Choose IP: FIB lookup algorithm (choose FIB_HASH if unsure)"
+       depends on IP_ADVANCED_ROUTER
+       default IP_FIB_HASH
+
+config IP_FIB_HASH
+       bool "FIB_HASH"
+       ---help---
+       Current FIB is very proven and good enough for most users.
+
+config IP_FIB_TRIE
+       bool "FIB_TRIE"
+       ---help---
+       Use new experimental LC-trie as FIB lookup algoritm. 
+        This improves lookup performance if you have a large
+       number of routes.
+
+       LC-trie is a longest matching prefix lookup algorithm which
+       performs better than FIB_HASH for large routing tables.
+       But, it consumes more memory and is more complex.
+       
+       LC-trie is described in:
+       
+       IP-address lookup using LC-tries. Stefan Nilsson and Gunnar Karlsson
+       IEEE Journal on Selected Areas in Communications, 17(6):1083-1092, June 1999
+       An experimental study of compression methods for dynamic tries
+       Stefan Nilsson and Matti Tikkanen. Algorithmica, 33(1):19-33, 2002.
+       http://www.nada.kth.se/~snilsson/public/papers/dyntrie2/
+       
+endchoice
+
+# If the user does not enable advanced routing, he gets the safe
+# default of the fib-hash algorithm.
+config IP_FIB_HASH
+       bool
+       depends on !IP_ADVANCED_ROUTER
+       default y
+
 config IP_MULTIPLE_TABLES
        bool "IP: policy routing"
        depends on IP_ADVANCED_ROUTER
@@ -433,9 +445,22 @@ config IP_TCPDIAG
 config IP_TCPDIAG_IPV6
        def_bool (IP_TCPDIAG=y && IPV6=y) || (IP_TCPDIAG=m && IPV6)
 
+config TCP_CONG_ADVANCED
+       bool "TCP: advanced congestion control"
+       depends on INET
+       default y
+       ---help---
+         Support for selection of various TCP congestion control
+         modules.
+
+         Nearly all users can safely say no here, and a safe default
+         selection will be made (BIC-TCP with new Reno as a fallback).
+
+         If unsure, say N.
+
 # TCP Reno is builtin (required as fallback)
 menu "TCP congestion control"
-       depends on INET
+       depends on TCP_CONG_ADVANCED
 
 config TCP_CONG_BIC
        tristate "Binary Increase Congestion (BIC) control"
@@ -523,5 +548,10 @@ config TCP_CONG_SCALABLE
 
 endmenu
 
+config TCP_CONG_BIC
+       boolean
+       depends on !TCP_CONG_ADVANCED
+       default y
+
 source "net/ipv4/ipvs/Kconfig"
 
index 2b537f425a17d6bd7d9485299cc72bc96bed2998..dada34a77b2194ab9750d2cdc518032f0fa413df 100644 (file)
@@ -138,7 +138,7 @@ static int rxrpc_krxiod(void *arg)
 
                _debug("### End Work");
 
-               try_to_freeze(PF_FREEZE);
+               try_to_freeze();
 
                 /* discard pending signals */
                rxrpc_discard_my_signals();
index 6020c89d9228846b6478e03dacd7860e7beb01ce..1aadd026d3542151e0eeb8b6c99f35a24c6779e0 100644 (file)
@@ -107,7 +107,7 @@ static int rxrpc_krxsecd(void *arg)
 
                _debug("### End Inbound Calls");
 
-               try_to_freeze(PF_FREEZE);
+               try_to_freeze();
 
                 /* discard pending signals */
                rxrpc_discard_my_signals();
index 249c2b0290bbfeae3bedccecf82af87301769b7f..3ac81cdd1211ce2c58fa4729b65fabe464097294 100644 (file)
@@ -90,7 +90,7 @@ static int krxtimod(void *arg)
                        complete_and_exit(&krxtimod_dead, 0);
                }
 
-               try_to_freeze(PF_FREEZE);
+               try_to_freeze();
 
                /* discard pending signals */
                rxrpc_discard_my_signals();
index 447b89e556b12f6f2039e584d7ba00be2f54d655..7bac249258e3a32bc91e658deaf1e335077a2b81 100644 (file)
@@ -453,10 +453,11 @@ config NET_EMATCH_TEXT
        tristate "Textsearch"
        depends on NET_EMATCH
        select TEXTSEARCH
+       select TEXTSEARCH_KMP
+       select TEXTSEARCH_FSM
        ---help---
          Say Y here if you want to be ablt to classify packets based on
-         textsearch comparisons. Please select the appropriate textsearch
-         algorithms in the Library section.
+         textsearch comparisons.
 
          To compile this code as a module, choose M here: the
          module will be called em_text.
index 05907035bc96105d67fe124eef6793647b696d43..56db8f13e6cb40c4cf9ecb765923993564c16c7e 100644 (file)
@@ -1185,8 +1185,8 @@ svc_recv(struct svc_serv *serv, struct svc_rqst *rqstp, long timeout)
        arg->page_len = (pages-2)*PAGE_SIZE;
        arg->len = (pages-1)*PAGE_SIZE;
        arg->tail[0].iov_len = 0;
-       
-       try_to_freeze(PF_FREEZE);
+
+       try_to_freeze();
        if (signalled())
                return -EINTR;
 
@@ -1227,7 +1227,7 @@ svc_recv(struct svc_serv *serv, struct svc_rqst *rqstp, long timeout)
 
                schedule_timeout(timeout);
 
-               try_to_freeze(PF_FREEZE);
+               try_to_freeze();
 
                spin_lock_bh(&serv->sv_lock);
                remove_wait_queue(&rqstp->rq_wait, &wait);
index eca92405948fbfd69222f5494c40801efe99a78b..269f217918a3c736087a4577aa5389ed38c5410b 100644 (file)
@@ -970,7 +970,7 @@ tcp_read_request(struct rpc_xprt *xprt, skb_reader_t *desc)
                goto out;
        }
 
-       dprintk("RPC:      XID %08x read %u bytes\n",
+       dprintk("RPC:      XID %08x read %Zd bytes\n",
                        ntohl(xprt->tcp_xid), r);
        dprintk("RPC:      xprt = %p, tcp_copied = %lu, tcp_offset = %u, tcp_reclen = %u\n",
                        xprt, xprt->tcp_copied, xprt->tcp_offset, xprt->tcp_reclen);
@@ -1006,7 +1006,7 @@ tcp_read_discard(struct rpc_xprt *xprt, skb_reader_t *desc)
        desc->count -= len;
        desc->offset += len;
        xprt->tcp_offset += len;
-       dprintk("RPC:      discarded %u bytes\n", len);
+       dprintk("RPC:      discarded %Zu bytes\n", len);
        tcp_check_recm(xprt);
 }
 
index 8ca7ecdb68fbb662fbe1f470410e25ddb520980a..cb02baa63256ba691501ac65ddea70cadb1112c4 100644 (file)
@@ -52,7 +52,7 @@ FILEONLY *internalfunctions;
 FILEONLY *externalfunctions;
 FILEONLY *symbolsonly;
 
-typedef void FILELINE(char * file, signed char * line);
+typedef void FILELINE(char * file, char * line);
 FILELINE * singlefunctions;
 FILELINE * entity_system;
 
@@ -148,9 +148,9 @@ struct symfile * filename_exist(char * filename)
  * Files are separated by tabs.
  */
 void adddep(char * file)                  { printf("\t%s", file); }
-void adddep2(char * file, signed char * line)     { line = line; adddep(file); }
+void adddep2(char * file, char * line)     { line = line; adddep(file); }
 void noaction(char * line)                { line = line; }
-void noaction2(char * file, signed char * line)   { file = file; line = line; }
+void noaction2(char * file, char * line)   { file = file; line = line; }
 
 /* Echo the line without further action */
 void printline(char * line)               { printf("%s", line); }
@@ -179,8 +179,8 @@ void find_export_symbols(char * filename)
                        perror(real_filename);
                }
                while(fgets(line, MAXLINESZ, fp)) {
-                       signed char *p;
-                       signed char *e;
+                       char *p;
+                       char *e;
                        if (((p = strstr(line, "EXPORT_SYMBOL_GPL")) != 0) ||
                             ((p = strstr(line, "EXPORT_SYMBOL")) != 0)) {
                                /* Skip EXPORT_SYMBOL{_GPL} */
@@ -253,7 +253,7 @@ void extfunc(char * filename) { docfunctions(filename, FUNCTION);   }
  * Call kernel-doc with the following parameters:
  * kernel-doc -docbook -function function1 [-function function2]
  */
-void singfunc(char * filename, signed char * line)
+void singfunc(char * filename, char * line)
 {
        char *vec[200]; /* Enough for specific functions */
         int i, idx = 0;
@@ -290,7 +290,7 @@ void singfunc(char * filename, signed char * line)
 void parse_file(FILE *infile)
 {
        char line[MAXLINESZ];
-       signed char * s;
+       char * s;
        while(fgets(line, MAXLINESZ, infile)) {
                if (line[0] == '!') {
                        s = line + 2;
index 7f42c5d8a5a2f70bde413c21241fee3a1376d08e..0b61bea869f7580d0d5af1d5c56345be61a8597c 100644 (file)
@@ -212,23 +212,23 @@ void use_config(char *m, int slen)
                if (*p == '_')
                        *p = '/';
                else
-                       *p = tolower((unsigned char)*p);
+                       *p = tolower((int)*p);
        }
        printf("    $(wildcard include/config/%s.h) \\\n", s);
 }
 
-void parse_config_file(signed char *map, size_t len)
+void parse_config_file(char *map, size_t len)
 {
        int *end = (int *) (map + len);
        /* start at +1, so that p can never be < map */
        int *m   = (int *) map + 1;
-       signed char *p, *q;
+       char *p, *q;
 
        for (; m < end; m++) {
-               if (*m == INT_CONF) { p = (signed char *) m  ; goto conf; }
-               if (*m == INT_ONFI) { p = (signed char *) m-1; goto conf; }
-               if (*m == INT_NFIG) { p = (signed char *) m-2; goto conf; }
-               if (*m == INT_FIG_) { p = (signed char *) m-3; goto conf; }
+               if (*m == INT_CONF) { p = (char *) m  ; goto conf; }
+               if (*m == INT_ONFI) { p = (char *) m-1; goto conf; }
+               if (*m == INT_NFIG) { p = (char *) m-2; goto conf; }
+               if (*m == INT_FIG_) { p = (char *) m-3; goto conf; }
                continue;
        conf:
                if (p > map + len - 7)
@@ -291,9 +291,9 @@ void do_config_file(char *filename)
 
 void parse_dep_file(void *map, size_t len)
 {
-       signed char *m = map;
-       signed char *end = m + len;
-       signed char *p;
+       char *m = map;
+       char *end = m + len;
+       char *p;
        char s[PATH_MAX];
 
        p = strchr(m, ':');
index 60fc4d8ebaa9caba1f32fc8d221d8fcce14000db..459c45276cb1a4288f77f18fe327ae0c6bd312fb 100644 (file)
@@ -104,7 +104,7 @@ int main(int argc, const char * argv [])
     /* Read config lines. */
     while (fgets(line, buffer_size, fp_config))
     {
-       const signed char * str_config;
+       const char * str_config;
        int is_same;
        int itarget;
 
index 70e7264c69420427097ca27788efd31053ad632d..bc20cab9d0d6b184d9c3479d3b20584ac386b4d5 100644 (file)
@@ -31,14 +31,14 @@ char *defconfig_file;
 static int indent = 1;
 static int valid_stdin = 1;
 static int conf_cnt;
-static signed char line[128];
+static char line[128];
 static struct menu *rootEntry;
 
 static char nohelp_text[] = N_("Sorry, no help available for this option yet.\n");
 
-static void strip(signed char *str)
+static void strip(char *str)
 {
-       signed char *p = str;
+       char *p = str;
        int l;
 
        while ((isspace(*p)))
index 2755c459d780b48e1c067be5d81a14528c2e3b90..02f670cc6bb9350f6db1ea2ecd14513565ca3746 100644 (file)
@@ -27,10 +27,10 @@ const char *conf_confnames[] = {
        NULL,
 };
 
-static char *conf_expand_value(const signed char *in)
+static char *conf_expand_value(const char *in)
 {
        struct symbol *sym;
-       const signed char *src;
+       const char *src;
        static char res_value[SYMBOL_MAXLENGTH];
        char *dst, name[SYMBOL_MAXLENGTH];
 
index e5db10ca956420f8a3ba8159597f3c537ef963f5..457bec29511dfb60d47428d9a18029353aef92e1 100644 (file)
@@ -20,6 +20,7 @@
 #include <string.h>
 #include <termios.h>
 #include <unistd.h>
+#include <locale.h>
 
 #define LKC_DIRECT_LINK
 #include "lkc.h"
@@ -254,8 +255,8 @@ search_help[] = N_(
        "          USB$ => find all CONFIG_ symbols ending with USB\n"
        "\n");
 
-static signed char buf[4096], *bufptr = buf;
-static signed char input_buf[4096];
+static char buf[4096], *bufptr = buf;
+static char input_buf[4096];
 static char filename[PATH_MAX+1] = ".config";
 static char *args[1024], **argptr = args;
 static int indent;
index 3304d37bb379e1b23afbe732c4d2c93513c9e6d6..fb89f9844465587caa5f3333eabf1a877e0e0848 100644 (file)
@@ -980,7 +980,7 @@ void unregister_key_type(struct key_type *ktype)
        spin_unlock(&key_serial_lock);
 
        /* make sure everyone revalidates their keys */
-       synchronize_kernel();
+       synchronize_rcu();
 
        /* we should now be able to destroy the payloads of all the keys of
         * this type with impunity */
index 34db087bbcc7d0cdcb08266bdaf840067adb1311..9b0369c5a223acbf951178e87ebbb0789458b507 100644 (file)
@@ -234,7 +234,7 @@ static int install_session_keyring(struct task_struct *tsk,
        ret = 0;
 
        /* we're using RCU on the pointer */
-       synchronize_kernel();
+       synchronize_rcu();
        key_put(old);
  error:
        return ret;
index 87302a49067bd091d3bfa970524088b929f5e298..17a1189f1ff81c4a1e9f8686ba4f493cb6c96939 100644 (file)
@@ -1658,9 +1658,8 @@ static int selinux_bprm_secureexec (struct linux_binprm *bprm)
 
 static void selinux_bprm_free_security(struct linux_binprm *bprm)
 {
-       struct bprm_security_struct *bsec = bprm->security;
+       kfree(bprm->security);
        bprm->security = NULL;
-       kfree(bsec);
 }
 
 extern struct vfsmount *selinuxfs_mount;
@@ -2477,6 +2476,17 @@ static int selinux_file_mprotect(struct vm_area_struct *vma,
                prot = reqprot;
 
 #ifndef CONFIG_PPC32
+       if ((prot & PROT_EXEC) && !(vma->vm_flags & VM_EXECUTABLE) &&
+          (vma->vm_start >= vma->vm_mm->start_brk &&
+           vma->vm_end <= vma->vm_mm->brk)) {
+               /*
+                * We are making an executable mapping in the brk region.
+                * This has an additional execheap check.
+                */
+               rc = task_has_perm(current, current, PROCESS__EXECHEAP);
+               if (rc)
+                       return rc;
+       }
        if (vma->vm_file != NULL && vma->anon_vma != NULL && (prot & PROT_EXEC)) {
                /*
                 * We are making executable a file mapping that has
@@ -2488,6 +2498,16 @@ static int selinux_file_mprotect(struct vm_area_struct *vma,
                if (rc)
                        return rc;
        }
+       if (!vma->vm_file && (prot & PROT_EXEC) &&
+               vma->vm_start <= vma->vm_mm->start_stack &&
+               vma->vm_end >= vma->vm_mm->start_stack) {
+               /* Attempt to make the process stack executable.
+                * This has an additional execstack check.
+                */
+               rc = task_has_perm(current, current, PROCESS__EXECSTACK);
+               if (rc)
+                       return rc;
+       }
 #endif
 
        return file_map_prot_check(vma->vm_file, prot, vma->vm_flags&VM_SHARED);
index 8928bb4d3c538145e41e8db8c92ba1d67b4f0504..1deb59e1b76257dab1129f0050ce0f727aceeb30 100644 (file)
@@ -70,6 +70,8 @@
    S_(SECCLASS_PROCESS, PROCESS__DYNTRANSITION, "dyntransition")
    S_(SECCLASS_PROCESS, PROCESS__SETCURRENT, "setcurrent")
    S_(SECCLASS_PROCESS, PROCESS__EXECMEM, "execmem")
+   S_(SECCLASS_PROCESS, PROCESS__EXECSTACK, "execstack")
+   S_(SECCLASS_PROCESS, PROCESS__EXECHEAP, "execheap")
    S_(SECCLASS_MSGQ, MSGQ__ENQUEUE, "enqueue")
    S_(SECCLASS_MSG, MSG__SEND, "send")
    S_(SECCLASS_MSG, MSG__RECEIVE, "receive")
index bdfce4ca8f8e06366f7d831f8637b3af755a02b9..a78b5d59c9fc008f638200a1764c3a1e2e7a646e 100644 (file)
 #define PROCESS__DYNTRANSITION                    0x00800000UL
 #define PROCESS__SETCURRENT                       0x01000000UL
 #define PROCESS__EXECMEM                          0x02000000UL
+#define PROCESS__EXECSTACK                        0x04000000UL
+#define PROCESS__EXECHEAP                         0x08000000UL
 
 #define IPC__CREATE                               0x00000001UL
 #define IPC__DESTROY                              0x00000002UL
index 07221568b5059dac724b8a2c19cae9ccee6982d8..8eb140dd2e4b3bda4906f717491bb740b4450e50 100644 (file)
@@ -951,8 +951,7 @@ static int sel_make_bools(void)
        u32 sid;
 
        /* remove any existing files */
-       if (bool_pending_values)
-               kfree(bool_pending_values);
+       kfree(bool_pending_values);
 
        sel_remove_bools(dir);
 
@@ -997,10 +996,8 @@ static int sel_make_bools(void)
 out:
        free_page((unsigned long)page);
        if (names) {
-               for (i = 0; i < num; i++) {
-                       if (names[i])
-                               kfree(names[i]);
-               }
+               for (i = 0; i < num; i++)
+                       kfree(names[i]);
                kfree(names);
        }
        return ret;
index b53441184aca727a5a2ba15c14969004cc6c9a15..e2057f5a411a470372efcf919bfa502daa5149d9 100644 (file)
@@ -166,16 +166,14 @@ static void cond_list_destroy(struct cond_node *list)
 
 void cond_policydb_destroy(struct policydb *p)
 {
-       if (p->bool_val_to_struct != NULL)
-               kfree(p->bool_val_to_struct);
+       kfree(p->bool_val_to_struct);
        avtab_destroy(&p->te_cond_avtab);
        cond_list_destroy(p->cond_list);
 }
 
 int cond_init_bool_indexes(struct policydb *p)
 {
-       if (p->bool_val_to_struct)
-               kfree(p->bool_val_to_struct);
+       kfree(p->bool_val_to_struct);
        p->bool_val_to_struct = (struct cond_bool_datum**)
                kmalloc(p->p_bools.nprim * sizeof(struct cond_bool_datum*), GFP_KERNEL);
        if (!p->bool_val_to_struct)
@@ -185,8 +183,7 @@ int cond_init_bool_indexes(struct policydb *p)
 
 int cond_destroy_bool(void *key, void *datum, void *p)
 {
-       if (key)
-               kfree(key);
+       kfree(key);
        kfree(datum);
        return 0;
 }
index 14190efbf333b83c8d270ec83af2d5e7628f21a6..785c33cf486491afc6b2d50d568d5db884b31723 100644 (file)
@@ -590,17 +590,12 @@ void policydb_destroy(struct policydb *p)
                hashtab_destroy(p->symtab[i].table);
        }
 
-       for (i = 0; i < SYM_NUM; i++) {
-               if (p->sym_val_to_name[i])
-                       kfree(p->sym_val_to_name[i]);
-       }
+       for (i = 0; i < SYM_NUM; i++)
+               kfree(p->sym_val_to_name[i]);
 
-       if (p->class_val_to_struct)
-               kfree(p->class_val_to_struct);
-       if (p->role_val_to_struct)
-               kfree(p->role_val_to_struct);
-       if (p->user_val_to_struct)
-               kfree(p->user_val_to_struct);
+       kfree(p->class_val_to_struct);
+       kfree(p->role_val_to_struct);
+       kfree(p->user_val_to_struct);
 
        avtab_destroy(&p->te_avtab);
 
index b6149147d5cb6ef585f09846d03819f454259e45..922bb45054aa415acd3d4efaa24242d85f39d072 100644 (file)
@@ -1705,11 +1705,9 @@ out:
 err:
        if (*names) {
                for (i = 0; i < *len; i++)
-                       if ((*names)[i])
-                               kfree((*names)[i]);
+                       kfree((*names)[i]);
        }
-       if (*values)
-               kfree(*values);
+       kfree(*values);
        goto out;
 }
 
index e537bd66a707795e1e2edcec4483fbe0977f87dd..3b1fafc8f4f56c91417b7728ea998b0c3f438412 100644 (file)
@@ -6,7 +6,7 @@
 # Prompt user for primary drivers.
 config SOUND_BT878
        tristate "BT878 audio dma"
-       depends on SOUND_PRIME!=n && SOUND
+       depends on SOUND_PRIME
        ---help---
          Audio DMA support for bt878 based grabber boards.  As you might have
          already noticed, bt878 is listed with two functions in /proc/pci.
@@ -22,7 +22,7 @@ config SOUND_BT878
 
 config SOUND_CMPCI
        tristate "C-Media PCI (CMI8338/8738)"
-       depends on SOUND_PRIME!=n && SOUND && PCI
+       depends on SOUND_PRIME && PCI
        help
          Say Y or M if you have a PCI sound card using the CMI8338
          or the CMI8738 chipset.  Data on these chips are available at
@@ -61,7 +61,7 @@ config SOUND_CMPCI_JOYSTICK
 
 config SOUND_EMU10K1
        tristate "Creative SBLive! (EMU10K1)"
-       depends on SOUND_PRIME!=n && SOUND && PCI
+       depends on SOUND_PRIME && PCI
        ---help---
          Say Y or M if you have a PCI sound card using the EMU10K1 chipset,
          such as the Creative SBLive!, SB PCI512 or Emu-APS.
@@ -87,7 +87,7 @@ config MIDI_EMU10K1
 
 config SOUND_FUSION
        tristate "Crystal SoundFusion (CS4280/461x)"
-       depends on SOUND_PRIME!=n && SOUND
+       depends on SOUND_PRIME
        help
          This module drives the Crystal SoundFusion devices (CS4280/46xx
          series) when wired as native sound drivers with AC97 codecs.  If
@@ -95,14 +95,14 @@ config SOUND_FUSION
 
 config SOUND_CS4281
        tristate "Crystal Sound CS4281"
-       depends on SOUND_PRIME!=n && SOUND
+       depends on SOUND_PRIME
        help
          Picture and feature list at
          <http://www.pcbroker.com/crystal4281.html>.
 
 config SOUND_BCM_CS4297A
        tristate "Crystal Sound CS4297a (for Swarm)"
-       depends on SOUND_PRIME!=n && SIBYTE_SWARM && SOUND
+       depends on SOUND_PRIME && SIBYTE_SWARM
        help
          The BCM91250A has a Crystal CS4297a on synchronous serial
          port B (in addition to the DB-9 serial port).  Say Y or M
@@ -112,7 +112,7 @@ config SOUND_BCM_CS4297A
 
 config SOUND_ES1370
        tristate "Ensoniq AudioPCI (ES1370)"
-       depends on SOUND_PRIME!=n && SOUND && PCI
+       depends on SOUND_PRIME && PCI
        help
          Say Y or M if you have a PCI sound card utilizing the Ensoniq
          ES1370 chipset, such as Ensoniq's AudioPCI (non-97). To find
@@ -125,7 +125,7 @@ config SOUND_ES1370
 
 config SOUND_ES1371
        tristate "Creative Ensoniq AudioPCI 97 (ES1371)"
-       depends on SOUND_PRIME!=n && SOUND && PCI
+       depends on SOUND_PRIME && PCI
        help
          Say Y or M if you have a PCI sound card utilizing the Ensoniq
          ES1371 chipset, such as Ensoniq's AudioPCI97. To find out if
@@ -138,7 +138,7 @@ config SOUND_ES1371
 
 config SOUND_ESSSOLO1
        tristate "ESS Technology Solo1" 
-       depends on SOUND_PRIME!=n && SOUND && PCI
+       depends on SOUND_PRIME && PCI
        help
          Say Y or M if you have a PCI sound card utilizing the ESS Technology
          Solo1 chip. To find out if your sound card uses a
@@ -149,7 +149,7 @@ config SOUND_ESSSOLO1
 
 config SOUND_MAESTRO
        tristate "ESS Maestro, Maestro2, Maestro2E driver"
-       depends on SOUND_PRIME!=n && SOUND && PCI
+       depends on SOUND_PRIME && PCI
        help
          Say Y or M if you have a sound system driven by ESS's Maestro line
          of PCI sound chips.  These include the Maestro 1, Maestro 2, and
@@ -158,28 +158,28 @@ config SOUND_MAESTRO
 
 config SOUND_MAESTRO3
        tristate "ESS Maestro3/Allegro driver (EXPERIMENTAL)"
-       depends on SOUND_PRIME!=n && SOUND && PCI && EXPERIMENTAL
+       depends on SOUND_PRIME && PCI && EXPERIMENTAL
        help
          Say Y or M if you have a sound system driven by ESS's Maestro 3
          PCI sound chip.
 
 config SOUND_ICH
        tristate "Intel ICH (i8xx) audio support"
-       depends on SOUND_PRIME!=n && PCI
+       depends on SOUND_PRIME && PCI
        help
          Support for integral audio in Intel's I/O Controller Hub (ICH)
          chipset, as used on the 810/820/840 motherboards.
 
 config SOUND_HARMONY
        tristate "PA Harmony audio driver"
-       depends on GSC_LASI && SOUND_PRIME!=n
+       depends on GSC_LASI && SOUND_PRIME
        help
          Say 'Y' or 'M' to include support for Harmony soundchip
          on HP 712, 715/new and many other GSC based machines.
 
 config SOUND_SONICVIBES
        tristate "S3 SonicVibes"
-       depends on SOUND_PRIME!=n && SOUND
+       depends on SOUND_PRIME
        help
          Say Y or M if you have a PCI sound card utilizing the S3
          SonicVibes chipset. To find out if your sound card uses a
@@ -190,7 +190,7 @@ config SOUND_SONICVIBES
 
 config SOUND_VWSND
        tristate "SGI Visual Workstation Sound"
-       depends on SOUND_PRIME!=n && X86_VISWS && SOUND
+       depends on SOUND_PRIME && X86_VISWS
        help
          Say Y or M if you have an SGI Visual Workstation and you want to be
          able to use its on-board audio.  Read
@@ -199,18 +199,18 @@ config SOUND_VWSND
 
 config SOUND_HAL2
        tristate "SGI HAL2 sound (EXPERIMENTAL)"
-       depends on SOUND_PRIME!=n && SOUND && SGI_IP22 && EXPERIMENTAL
+       depends on SOUND_PRIME && SGI_IP22 && EXPERIMENTAL
        help
          Say Y or M if you have an SGI Indy system and want to be able to
          use it's on-board A2 audio system.
 
 config SOUND_IT8172
        tristate "IT8172G Sound"
-       depends on SOUND_PRIME!=n && (MIPS_ITE8172 || MIPS_IVR) && SOUND
+       depends on SOUND_PRIME && (MIPS_ITE8172 || MIPS_IVR)
 
 config SOUND_VRC5477
        tristate "NEC Vrc5477 AC97 sound"
-       depends on SOUND_PRIME!=n && DDB5477 && SOUND
+       depends on SOUND_PRIME && DDB5477
        help
          Say Y here to enable sound support for the NEC Vrc5477 chip, an
          integrated, multi-function controller chip for MIPS CPUs.  Works
@@ -218,15 +218,15 @@ config SOUND_VRC5477
 
 config SOUND_AU1000
        tristate "Au1000 Sound"
-       depends on SOUND_PRIME!=n && (SOC_AU1000 || SOC_AU1100 || SOC_AU1500) && SOUND
+       depends on SOUND_PRIME && (SOC_AU1000 || SOC_AU1100 || SOC_AU1500)
 
 config SOUND_AU1550_AC97
        tristate "Au1550 AC97 Sound"
-       depends on SOUND_PRIME!=n && SOC_AU1550 && SOUND
+       depends on SOUND_PRIME && SOC_AU1550
 
 config SOUND_TRIDENT
        tristate "Trident 4DWave DX/NX, SiS 7018 or ALi 5451 PCI Audio Core"
-       depends on SOUND_PRIME!=n && SOUND
+       depends on SOUND_PRIME
        ---help---
          Say Y or M if you have a PCI sound card utilizing the Trident
          4DWave-DX/NX chipset or your mother board chipset has SiS 7018
@@ -267,7 +267,7 @@ config SOUND_TRIDENT
 
 config SOUND_MSNDCLAS
        tristate "Support for Turtle Beach MultiSound Classic, Tahiti, Monterey"
-       depends on SOUND_PRIME!=n && SOUND && (m || !STANDALONE)
+       depends on SOUND_PRIME && (m || !STANDALONE)
        help
          Say M here if you have a Turtle Beach MultiSound Classic, Tahiti or
          Monterey (not for the Pinnacle or Fiji).
@@ -331,7 +331,7 @@ config MSNDCLAS_IO
 
 config SOUND_MSNDPIN
        tristate "Support for Turtle Beach MultiSound Pinnacle, Fiji"
-       depends on SOUND_PRIME!=n && SOUND && (m || !STANDALONE)
+       depends on SOUND_PRIME && (m || !STANDALONE)
        help
          Say M here if you have a Turtle Beach MultiSound Pinnacle or Fiji.
          See <file:Documentation/sound/oss/MultiSound> for important information
@@ -492,7 +492,7 @@ config MSND_FIFOSIZE
 
 config SOUND_VIA82CXXX
        tristate "VIA 82C686 Audio Codec"
-       depends on SOUND_PRIME!=n && PCI
+       depends on SOUND_PRIME && PCI
        help
          Say Y here to include support for the audio codec found on VIA
          82Cxxx-based chips. Typically these are built into a motherboard.
@@ -512,7 +512,7 @@ config MIDI_VIA82CXXX
 
 config SOUND_OSS
        tristate "OSS sound modules"
-       depends on SOUND_PRIME!=n && SOUND
+       depends on SOUND_PRIME
        help
          OSS is the Open Sound System suite of sound card drivers.  They make
          sound programming easier since they provide a common API.  Say Y or
@@ -1077,7 +1077,7 @@ config SOUND_WAVEARTIST
 
 config SOUND_TVMIXER
        tristate "TV card (bt848) mixer support"
-       depends on SOUND_PRIME!=n && SOUND && I2C
+       depends on SOUND_PRIME && I2C
        help
          Support for audio mixer facilities on the BT848 TV frame-grabber
          card.
@@ -1088,11 +1088,11 @@ config SOUND_KAHLUA
 
 config SOUND_ALI5455
        tristate "ALi5455 audio support"
-       depends on SOUND_PRIME!=n && PCI
+       depends on SOUND_PRIME && PCI
 
 config SOUND_FORTE
        tristate "ForteMedia FM801 driver"
-       depends on SOUND_PRIME!=n && PCI
+       depends on SOUND_PRIME && PCI
        help
          Say Y or M if you want driver support for the ForteMedia FM801 PCI
          audio controller (Abit AU10, Genius Sound Maker, HP Workstation
@@ -1100,7 +1100,7 @@ config SOUND_FORTE
 
 config SOUND_RME96XX
        tristate "RME Hammerfall (RME96XX) support"
-       depends on SOUND_PRIME!=n && PCI
+       depends on SOUND_PRIME && PCI
        help
          Say Y or M if you have a Hammerfall or Hammerfall light
          multichannel card from RME. If you want to access advanced
@@ -1108,11 +1108,11 @@ config SOUND_RME96XX
 
 config SOUND_AD1980
        tristate "AD1980 front/back switch plugin"
-       depends on SOUND_PRIME!=n
+       depends on SOUND_PRIME
 
 config SOUND_SH_DAC_AUDIO
        tristate "SuperH DAC audio support"
-       depends on SOUND_PRIME!=n && SOUND && CPU_SH3
+       depends on SOUND_PRIME && CPU_SH3
 
 config SOUND_SH_DAC_AUDIO_CHANNEL
        int "    DAC channel"
index 22dae5d0fda3f392f787b46cc5f0fc943fdc4207..95586de02028cf57d4a628044885953b92ba57f0 100644 (file)
@@ -592,7 +592,7 @@ typedef struct mixer_def mixer_ent;
   {{reg_l, pola_l, pos_l, len_l}, {reg_r, pola_r, pos_r, len_r}}
 
 
-mixer_ent mix_devices[SOUND_MIXER_NRDEVICES][2] = {
+static mixer_ent mix_devices[SOUND_MIXER_NRDEVICES][2] = {
 MIX_ENT(SOUND_MIXER_VOLUME,    14, 1, 8, 5,    14, 1, 0, 5),
 MIX_ENT(SOUND_MIXER_BASS,       0, 0, 0, 0,     0, 0, 0, 0),
 MIX_ENT(SOUND_MIXER_TREBLE,     0, 0, 0, 0,     0, 0, 0, 0),
index 4384dac3f7949008285e71f94eec5123e27050b9..7c835abd99bc9ab2abc919b3cb8da9c48341004c 100644 (file)
@@ -2178,8 +2178,7 @@ void ad1848_unload(int io_base, int irq, int dma_playback, int dma_capture, int
                
        if (devc != NULL)
        {
-               if(audio_devs[dev]->portc!=NULL)
-                       kfree(audio_devs[dev]->portc);
+               kfree(audio_devs[dev]->portc);
                release_region(devc->base, 4);
 
                if (!share_dma)
index b767c621fd09060ebd5575e4b8a3a9382c69e0ea..2cfd214e4c2a42e0b48f6f4c134e131bc8a03166 100644 (file)
@@ -277,8 +277,7 @@ static void ad1889_free_dev(ad1889_dev_t *dev)
 
        for (j = 0; j < AD_MAX_STATES; j++) {
                dmabuf = &dev->state[j].dmabuf;
-               if (dmabuf->rawbuf != NULL) 
-                       kfree(dmabuf->rawbuf);
+               kfree(dmabuf->rawbuf);
        }
 
        kfree(dev);
index 34720e66dae1b1f6e071427c3a410d044e9ff5b1..74dcca78c6c0c8c7697bf038450ccc1258f5ba4a 100644 (file)
 #include <linux/smp_lock.h>
 #include <linux/bitops.h>
 #include <linux/wait.h>
+#include <linux/dma-mapping.h>
 
 #include <asm/io.h>
 #include <asm/page.h>
@@ -3058,7 +3059,7 @@ static int __devinit cm_probe(struct pci_dev *pcidev, const struct pci_device_id
                return -ENODEV;
        if (pcidev->irq == 0)
                return -ENODEV;
-       i = pci_set_dma_mask(pcidev, 0xffffffff);
+       i = pci_set_dma_mask(pcidev, DMA_32BIT_MASK);
        if (i) {
                printk(KERN_WARNING "cmpci: architecture does not support 32bit PCI busmaster DMA\n");
                return i;
index 5281b88987f35bc30f56c0bbe3b5633f24ec2116..33108661e671340d75a0a373fab0933525e86242 100644 (file)
@@ -671,14 +671,10 @@ static void PMacIrqCleanup(void)
        release_OF_resource(awacs_node, 1);
        release_OF_resource(awacs_node, 2);
 
-       if (awacs_tx_cmd_space)
-               kfree(awacs_tx_cmd_space);
-       if (awacs_rx_cmd_space)
-               kfree(awacs_rx_cmd_space);
-       if (beep_dbdma_cmd_space)
-               kfree(beep_dbdma_cmd_space);
-       if (beep_buf)
-               kfree(beep_buf);
+       kfree(awacs_tx_cmd_space);
+       kfree(awacs_rx_cmd_space);
+       kfree(beep_dbdma_cmd_space);
+       kfree(beep_buf);
 #ifdef CONFIG_PMAC_PBOOK
        pmu_unregister_sleep_notifier(&awacs_sleep_notifier);
 #endif
@@ -2301,8 +2297,7 @@ if (count <= 0)
 #endif
 
        if ((write_sq.max_count + 1) > number_of_tx_cmd_buffers) {
-               if (awacs_tx_cmd_space)
-                       kfree(awacs_tx_cmd_space);
+               kfree(awacs_tx_cmd_space);
                number_of_tx_cmd_buffers = 0;
 
                /* we need nbufs + 1 (for the loop) and we should request + 1
@@ -2360,8 +2355,7 @@ if (count <= 0)
 #endif
 
        if ((read_sq.max_count+1) > number_of_rx_cmd_buffers ) {
-               if (awacs_rx_cmd_space)
-                       kfree(awacs_rx_cmd_space);
+               kfree(awacs_rx_cmd_space);
                number_of_rx_cmd_buffers = 0;
 
                /* we need nbufs + 1 (for the loop) and we should request + 1 again
@@ -2805,7 +2799,7 @@ __init setup_beep(void)
        beep_buf = (short *) kmalloc(BEEP_BUFLEN * 4, GFP_KERNEL);
        if (beep_buf == NULL) {
                printk(KERN_ERR "dmasound_pmac: no memory for beep buffer\n");
-               if( beep_dbdma_cmd_space ) kfree(beep_dbdma_cmd_space) ;
+               kfree(beep_dbdma_cmd_space) ;
                return -ENOMEM ;
        }
        return 0 ;
index 33dea3d56c1e138bdc461e8f255bce857104766a..b40b5f97aacea3a5240b845e10745dcc77c22cf3 100644 (file)
@@ -523,10 +523,8 @@ void emu10k1_seq_midi_close(int dev)
        card = midi_devs[dev]->devc;
        emu10k1_mpuout_close(card);
 
-       if (card->seq_mididev) {
-               kfree(card->seq_mididev);
-               card->seq_mididev = NULL;
-       }
+       kfree(card->seq_mididev);
+       card->seq_mididev = NULL;
 }
 
 int emu10k1_seq_midi_out(int dev, unsigned char midi_byte)
index 4094be55f3be335338fd120224a0fba22c6ce711..4e3baca7d41f3d2856accd469e0292d749a07e47 100644 (file)
@@ -213,8 +213,7 @@ void emu10k1_pt_stop(struct emu10k1_card *card)
                                sblive_writeptr(card, SPCS0 + i, 0, pt->old_spcs[i]);
                }
                pt->state = PT_STATE_INACTIVE;
-               if(pt->buf)
-                       kfree(pt->buf);
+               kfree(pt->buf);
        }
 }
 
index 056091cff2663343938d139245b1e5bb0e6708d1..886f61c1c34aba01500a917bdcd208cce0593a64 100644 (file)
 #include <linux/spinlock.h>
 #include <linux/gameport.h>
 #include <linux/wait.h>
+#include <linux/dma-mapping.h>
 
 #include <asm/io.h>
 #include <asm/page.h>
@@ -2569,7 +2570,7 @@ static int __devinit es1370_probe(struct pci_dev *pcidev, const struct pci_devic
                return -ENODEV;
        if (pcidev->irq == 0) 
                return -ENODEV;
-       i = pci_set_dma_mask(pcidev, 0xffffffff);
+       i = pci_set_dma_mask(pcidev, DMA_32BIT_MASK);
        if (i) {
                printk(KERN_WARNING "es1370: architecture does not support 32bit PCI busmaster DMA\n");
                return i;
index a50fddaeea2163c94cab2eaea8144fe42c207941..9266b777387b058b95f90c014672aa2e76fc668c 100644 (file)
 #include <linux/ac97_codec.h>
 #include <linux/gameport.h>
 #include <linux/wait.h>
+#include <linux/dma-mapping.h>
 
 #include <asm/io.h>
 #include <asm/page.h>
@@ -2804,7 +2805,7 @@ static int __devinit es1371_probe(struct pci_dev *pcidev, const struct pci_devic
                return -ENODEV;
        if (pcidev->irq == 0) 
                return -ENODEV;
-       i = pci_set_dma_mask(pcidev, 0xffffffff);
+       i = pci_set_dma_mask(pcidev, DMA_32BIT_MASK);
        if (i) {
                printk(KERN_WARNING "es1371: architecture does not support 32bit PCI busmaster DMA\n");
                return i;
index 6b3b9a99579dbf8fb05490e889a05d8dbcf4a3c3..fb09065d07c87ed4de22487e8dafaeefb6c67a7a 100644 (file)
 #include <linux/smp_lock.h>
 #include <linux/gameport.h>
 #include <linux/wait.h>
+#include <linux/dma-mapping.h>
 
 #include <asm/io.h>
 #include <asm/page.h>
@@ -2326,7 +2327,7 @@ static int __devinit solo1_probe(struct pci_dev *pcidev, const struct pci_device
         * to 24 bits first, then 32 bits (playback only) if that fails.
         */
        if (pci_set_dma_mask(pcidev, 0x00ffffff) &&
-           pci_set_dma_mask(pcidev, 0xffffffff)) {
+           pci_set_dma_mask(pcidev, DMA_32BIT_MASK)) {
                printk(KERN_WARNING "solo1: architecture does not support 24bit or 32bit PCI busmaster DMA\n");
                return -ENODEV;
        }
index 52d2db4bc312fadeddff95c9f1d8d0f3fba80823..3dce504e6d6d764ee330e47392238553e7fccf8a 100644 (file)
@@ -2356,7 +2356,7 @@ ess_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos)
        }
 
 rec_return_free:
-       if(combbuf) kfree(combbuf);
+       kfree(combbuf);
        return ret;
 }
 
index b66f53fa8db03ca57296ba6ea091579440f82639..0aac54c68f01fa13c124ee5715c4f6f0b9b23124 100644 (file)
@@ -1240,8 +1240,7 @@ void unload_mpu401(struct address_info *hw_config)
                p=mpu401_synth_operations[n];
                sound_unload_mididev(n);
                sound_unload_timerdev(hw_config->slots[2]);
-               if(p)
-                       kfree(p);
+               kfree(p);
        }
 }
 
index eae7d99d6826300d94cd82d5d1850654c196d5b9..21e07b5081f2bdb5ad44fc453bd0c7ca60ec5ac8 100644 (file)
@@ -128,9 +128,6 @@ struct nm256_info
     struct nm256_info *next_card;
 };
 
-/* Debug flag--bigger numbers mean more output. */
-extern int nm256_debug;
-
 /* The BIOS signature. */
 #define NM_SIGNATURE 0x4e4d0000
 /* Signature mask. */
@@ -284,7 +281,7 @@ nm256_readBuffer8 (struct nm256_info *card, u8 *dst, int port, int offset,
 }
 
 /* Returns a non-zero value if we should use the coefficient cache. */
-extern int nm256_cachedCoefficients (struct nm256_info *card);
+static int nm256_cachedCoefficients (struct nm256_info *card);
 
 #endif
 \f
index f9166e13519201f9118185e919489b1e2d1cbc66..66970062eb363a3bd48493039d4e0f239525f798 100644 (file)
 #include <linux/delay.h>
 #include <linux/spinlock.h>
 #include "sound_config.h"
-#include "nm256.h"
-#include "nm256_coeff.h"
 
-int nm256_debug;
+static int nm256_debug;
 static int force_load;
 
+#include "nm256.h"
+#include "nm256_coeff.h"
+
 /* 
  * The size of the playback reserve.  When the playback buffer has less
  * than NM256_PLAY_WMARK_SIZE bytes to output, we request a new
@@ -138,7 +139,7 @@ static int usecache;
 static int buffertop;
 
 /* Check to see if we're using the bank of cached coefficients. */
-int
+static int
 nm256_cachedCoefficients (struct nm256_info *card)
 {
     return usecache;
index 0ceecc20077ba75aef3412529bf8fde1a9530391..6fc07f3cb33b79cc258363445762ab4bce2bbb92 100644 (file)
@@ -4650,7 +4650,7 @@ nm256_loadAllCoefficients (struct nm256_info *card)
     card->coeffsCurrent = 1;
 }
 
-void
+static void
 nm256_loadCoefficient (struct nm256_info *card, int which, int number)
 {
     static u16 addrs[3] = { 0x1c, 0x21c, 0x408 };
index b4278eecc9171dc0123809589249d236b4111b30..7609c68a89f44ca4fab2b2a4c9f915a29bcb72fe 100644 (file)
@@ -1750,9 +1750,7 @@ static unsigned int rme96xx_poll(struct file *file, struct poll_table_struct *wa
 
 
 static struct file_operations rme96xx_audio_fops = {
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
        .owner   = THIS_MODULE,
-#endif
        .read    = rme96xx_read,
        .write   = rme96xx_write,
        .poll    = rme96xx_poll,
@@ -1852,9 +1850,7 @@ static int rme96xx_mixer_release(struct inode *inode, struct file *file)
 }
 
 static /*const*/ struct file_operations rme96xx_mixer_fops = {
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
        .owner   = THIS_MODULE,
-#endif
        .ioctl   = rme96xx_mixer_ioctl,
        .open    = rme96xx_mixer_open,
        .release = rme96xx_mixer_release,
index ce359e6c933aa0ae3962a202e2c253492899093d..5f955e3d2e26926e6e59612416466d78bced3db3 100644 (file)
@@ -915,8 +915,8 @@ void sb_dsp_unload(struct address_info *hw_config, int sbmpu)
        }
        else
                release_region(hw_config->io_base, 16);
-       if(detected_devc)
-               kfree(detected_devc);
+
+       kfree(detected_devc);
 }
 
 /*
index 50ca646294502a4e1d5dbf84d757684bfcc5e77f..9ed5211c3168156f05f8d0f9e89d4191c9f48c2e 100644 (file)
@@ -991,7 +991,6 @@ static void __init sscape_pnp_init_hw(sscape_info* devc)
        unsigned i;
        static  char code_file_name[23] = "/sndscape/sndscape.cox";
        
-       int sscape_sb_enable            = 0;
        int sscape_joystic_enable       = 0x7f;
        int sscape_mic_enable           = 0;
        int sscape_ext_midi             = 0;            
@@ -1015,14 +1014,9 @@ static void __init sscape_pnp_init_hw(sscape_info* devc)
        sscape_write( devc, 2, devc->ic_type == IC_ODIE ? 0x70 : 0x40);
        sscape_write( devc, 3, ( devc -> dma << 4) | 0x80);
 
-       if ( sscape_sb_enable )
-               sscape_write (devc, 4, 0xF0 | (sb_irq << 2) | midi_irq);
-       else    
-               sscape_write (devc, 4, 0xF0 | (midi_irq<<2) | midi_irq);
+       sscape_write (devc, 4, 0xF0 | (midi_irq<<2) | midi_irq);
 
        i = 0x10; //sscape_read(devc, 9) & (devc->ic_type == IC_ODIE ? 0xf0 : 0xc0);
-       if ( sscape_sb_enable )
-               i |= devc->ic_type == IC_ODIE ? 0x05 : 0x07;        
        if (sscape_joystic_enable) i |= 8;
        
        sscape_write (devc, 9, i);
index 077b7679766590c52bd0d2390fd117f919aa8f39..a7ef04fab075b1a7bd7dd7e377d26f1555380f8e 100644 (file)
@@ -39,8 +39,6 @@ static void *midi_mem = NULL;
  */
 
 
-void            (*midi_input_intr) (int dev, unsigned char data);
-
 static int v_midi_open (int dev, int mode,
              void            (*input) (int dev, unsigned char data),
              void            (*output) (int dev)
index cce1278dc487c419f8752382e0f2f47b8c8c5743..b92ba89216389ad4bc9b2896964fc856e5de6b00 100644 (file)
@@ -151,11 +151,11 @@ static int (*midi_load_patch) (int devno, int format, const char __user *addr,
 
 /*** Module-accessible parameters ***************************************/
 
-int wf_raw;     /* we normally check for "raw state" to firmware
-                  loading. if set, then during driver loading, the
-                  state of the board is ignored, and we reset the
-                  board and load the firmware anyway.
-               */
+static int wf_raw;     /* we normally check for "raw state" to firmware
+                          loading. if set, then during driver loading, the
+                          state of the board is ignored, and we reset the
+                          board and load the firmware anyway.
+                       */
                   
 static int fx_raw = 1; /* if this is zero, we'll leave the FX processor in
                          whatever state it is when the driver is loaded.
@@ -2911,7 +2911,7 @@ int __init detect_wffx (void)
        return 0;
 }      
 
-void
+static void
 wffx_mute (int onoff)
     
 {